]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/aacdec.c
avformat: Constify all muxer/demuxers
[ffmpeg] / libavformat / aacdec.c
index 685458b9114d03864fb6d962227d1debcb747dff..ba468909e9dec2495e699d145fe055d2225d85be 100644 (file)
@@ -20,6 +20,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/avassert.h"
 #include "libavutil/intreadwrite.h"
 #include "avformat.h"
 #include "avio_internal.h"
@@ -30,7 +31,7 @@
 
 #define ADTS_HEADER_SIZE 7
 
-static int adts_aac_probe(AVProbeData *p)
+static int adts_aac_probe(const AVProbeData *p)
 {
     int max_frames = 0, first_frames = 0;
     int fsize, frames;
@@ -79,10 +80,31 @@ static int adts_aac_probe(AVProbeData *p)
         return 0;
 }
 
+static int adts_aac_resync(AVFormatContext *s)
+{
+    uint16_t state;
+
+    // skip data until an ADTS frame is found
+    state = avio_r8(s->pb);
+    while (!avio_feof(s->pb) && avio_tell(s->pb) < s->probesize) {
+        state = (state << 8) | avio_r8(s->pb);
+        if ((state >> 4) != 0xFFF)
+            continue;
+        avio_seek(s->pb, -2, SEEK_CUR);
+        break;
+    }
+    if (s->pb->eof_reached)
+        return AVERROR_EOF;
+    if ((state >> 4) != 0xFFF)
+        return AVERROR_INVALIDDATA;
+
+    return 0;
+}
+
 static int adts_aac_read_header(AVFormatContext *s)
 {
     AVStream *st;
-    uint16_t state;
+    int ret;
 
     st = avformat_new_stream(s, NULL);
     if (!st)
@@ -100,17 +122,9 @@ static int adts_aac_read_header(AVFormatContext *s)
         avio_seek(s->pb, cur, SEEK_SET);
     }
 
-    // skip data until the first ADTS frame is found
-    state = avio_r8(s->pb);
-    while (!avio_feof(s->pb) && avio_tell(s->pb) < s->probesize) {
-        state = (state << 8) | avio_r8(s->pb);
-        if ((state >> 4) != 0xFFF)
-            continue;
-        avio_seek(s->pb, -2, SEEK_CUR);
-        break;
-    }
-    if ((state >> 4) != 0xFFF)
-        return AVERROR_INVALIDDATA;
+    ret = adts_aac_resync(s);
+    if (ret < 0)
+        return ret;
 
     // LCM of all possible ADTS sample rates
     avpriv_set_pts_info(st, 64, 1, 28224000);
@@ -122,18 +136,17 @@ static int handle_id3(AVFormatContext *s, AVPacket *pkt)
 {
     AVDictionary *metadata = NULL;
     AVIOContext ioctx;
-    ID3v2ExtraMeta *id3v2_extra_meta = NULL;
+    ID3v2ExtraMeta *id3v2_extra_meta;
     int ret;
 
     ret = av_append_packet(s->pb, pkt, ff_id3v2_tag_len(pkt->data) - pkt->size);
     if (ret < 0) {
-        av_packet_unref(pkt);
         return ret;
     }
 
     ffio_init_context(&ioctx, pkt->data, pkt->size, 0, NULL, NULL, NULL, NULL);
     ff_id3v2_read_dict(&ioctx, &metadata, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta);
-    if ((ret = ff_id3v2_parse_priv_dict(&metadata, &id3v2_extra_meta)) < 0)
+    if ((ret = ff_id3v2_parse_priv_dict(&metadata, id3v2_extra_meta)) < 0)
         goto error;
 
     if (metadata) {
@@ -154,44 +167,46 @@ static int adts_aac_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
     int ret, fsize;
 
-    // Parse all the ID3 headers between frames
-    while (1) {
-        ret = av_get_packet(s->pb, pkt, FFMAX(ID3v2_HEADER_SIZE, ADTS_HEADER_SIZE));
-        if (ret >= ID3v2_HEADER_SIZE && ff_id3v2_match(pkt->data, ID3v2_DEFAULT_MAGIC)) {
-            if ((ret = handle_id3(s, pkt)) >= 0) {
-                continue;
-            }
-        }
-        break;
-    }
-
+retry:
+    ret = av_get_packet(s->pb, pkt, ADTS_HEADER_SIZE);
     if (ret < 0)
         return ret;
 
     if (ret < ADTS_HEADER_SIZE) {
-        av_packet_unref(pkt);
         return AVERROR(EIO);
     }
 
     if ((AV_RB16(pkt->data) >> 4) != 0xfff) {
-        av_packet_unref(pkt);
-        return AVERROR_INVALIDDATA;
+        // Parse all the ID3 headers between frames
+        int append = ID3v2_HEADER_SIZE - ADTS_HEADER_SIZE;
+
+        av_assert2(append > 0);
+        ret = av_append_packet(s->pb, pkt, append);
+        if (ret != append) {
+            return AVERROR(EIO);
+        }
+        if (!ff_id3v2_match(pkt->data, ID3v2_DEFAULT_MAGIC)) {
+            av_packet_unref(pkt);
+            ret = adts_aac_resync(s);
+        } else
+            ret = handle_id3(s, pkt);
+        if (ret < 0)
+            return ret;
+
+        goto retry;
     }
 
     fsize = (AV_RB32(pkt->data + 3) >> 13) & 0x1FFF;
     if (fsize < ADTS_HEADER_SIZE) {
-        av_packet_unref(pkt);
         return AVERROR_INVALIDDATA;
     }
 
     ret = av_append_packet(s->pb, pkt, fsize - pkt->size);
-    if (ret < 0)
-        av_packet_unref(pkt);
 
     return ret;
 }
 
-AVInputFormat ff_aac_demuxer = {
+const AVInputFormat ff_aac_demuxer = {
     .name         = "aac",
     .long_name    = NULL_IF_CONFIG_SMALL("raw ADTS AAC (Advanced Audio Coding)"),
     .read_probe   = adts_aac_probe,