utvideoenc: optimize and simplify mangle_rgb_planes
[ffmpeg.git] / libavformat / mov.c
index 786bfcf..256e81f 100644 (file)
@@ -131,6 +131,74 @@ static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
     return 0;
 }
 
     return 0;
 }
 
+static int mov_read_custom_metadata(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+    char key[1024]={0}, data[1024]={0};
+    int i;
+    AVStream *st;
+    MOVStreamContext *sc;
+
+    if (c->fc->nb_streams < 1)
+        return 0;
+    st = c->fc->streams[c->fc->nb_streams-1];
+    sc = st->priv_data;
+
+    if (atom.size <= 8) return 0;
+
+    for (i = 0; i < 3; i++) { // Parse up to three sub-atoms looking for name and data.
+        int data_size = avio_rb32(pb);
+        int tag = avio_rl32(pb);
+        int str_size = 0, skip_size = 0;
+        char *target = NULL;
+
+        switch (tag) {
+        case MKTAG('n','a','m','e'):
+            avio_rb32(pb); // version/flags
+            str_size = skip_size = data_size - 12;
+            atom.size -= 12;
+            target = key;
+            break;
+        case MKTAG('d','a','t','a'):
+            avio_rb32(pb); // version/flags
+            avio_rb32(pb); // reserved (zero)
+            str_size = skip_size = data_size - 16;
+            atom.size -= 16;
+            target = data;
+            break;
+        default:
+            skip_size = data_size - 8;
+            str_size = 0;
+            break;
+        }
+
+        if (target) {
+            str_size = FFMIN3(sizeof(data)-1, str_size, atom.size);
+            avio_read(pb, target, str_size);
+            target[str_size] = 0;
+        }
+        atom.size -= skip_size;
+
+        // If we didn't read the full data chunk for the sub-atom, skip to the end of it.
+        if (skip_size > str_size) avio_skip(pb, skip_size - str_size);
+    }
+
+    if (*key && *data) {
+        if (strcmp(key, "iTunSMPB") == 0) {
+            int priming, remainder, samples;
+            if(sscanf(data, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
+                if(priming>0 && priming<16384)
+                    sc->start_pad = priming;
+                return 1;
+            }
+        }
+        if (strcmp(key, "cdec") == 0) {
+//             av_dict_set(&st->metadata, key, data, 0);
+            return 1;
+        }
+    }
+    return 0;
+}
+
 static const uint32_t mac_to_unicode[128] = {
     0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
     0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
 static const uint32_t mac_to_unicode[128] = {
     0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
     0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
@@ -221,6 +289,9 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     uint32_t data_type = 0, str_size;
     int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
 
     uint32_t data_type = 0, str_size;
     int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
 
+    if (c->itunes_metadata && atom.type == MKTAG('-','-','-','-'))
+        return mov_read_custom_metadata(c, pb, atom);
+
     switch (atom.type) {
     case MKTAG(0xa9,'n','a','m'): key = "title";     break;
     case MKTAG(0xa9,'a','u','t'):
     switch (atom.type) {
     case MKTAG(0xa9,'n','a','m'): key = "title";     break;
     case MKTAG(0xa9,'a','u','t'):
@@ -870,7 +941,7 @@ static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 
 /* FIXME modify qdm2/svq3/h264 decoders to take full atom as extradata */
 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
 
 /* FIXME modify qdm2/svq3/h264 decoders to take full atom as extradata */
 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
-                              enum CodecID codec_id)
+                              enum AVCodecID codec_id)
 {
     AVStream *st;
     uint64_t size;
 {
     AVStream *st;
     uint64_t size;
@@ -1753,6 +1824,9 @@ static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
         sc->ctts_data[i].count   = count;
         sc->ctts_data[i].duration= duration;
 
         sc->ctts_data[i].count   = count;
         sc->ctts_data[i].duration= duration;
 
+        av_dlog(c->fc, "count=%d, duration=%d\n",
+                count, duration);
+
         if (FFABS(duration) > (1<<28) && i+2<entries) {
             av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
             av_freep(&sc->ctts_data);
         if (FFABS(duration) > (1<<28) && i+2<entries) {
             av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
             av_freep(&sc->ctts_data);
@@ -2532,6 +2606,7 @@ static int mov_read_tref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 static const MOVParseTableEntry mov_default_parse_table[] = {
 { MKTAG('A','C','L','R'), mov_read_avid },
 { MKTAG('A','P','R','G'), mov_read_avid },
 static const MOVParseTableEntry mov_default_parse_table[] = {
 { MKTAG('A','C','L','R'), mov_read_avid },
 { MKTAG('A','P','R','G'), mov_read_avid },
+{ MKTAG('A','A','L','P'), mov_read_avid },
 { MKTAG('A','R','E','S'), mov_read_avid },
 { MKTAG('a','v','s','s'), mov_read_avss },
 { MKTAG('c','h','p','l'), mov_read_chpl },
 { MKTAG('A','R','E','S'), mov_read_avid },
 { MKTAG('a','v','s','s'), mov_read_avss },
 { MKTAG('c','h','p','l'), mov_read_chpl },
@@ -2662,6 +2737,10 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
             left = a.size - avio_tell(pb) + start_pos;
             if (left > 0) /* skip garbage at atom end */
                 avio_skip(pb, left);
             left = a.size - avio_tell(pb) + start_pos;
             if (left > 0) /* skip garbage at atom end */
                 avio_skip(pb, left);
+            else if(left < 0) {
+                av_log(c->fc, AV_LOG_DEBUG, "undoing overread of %d in '%.4s'\n", -left, (char*)&a.type);
+                avio_seek(pb, left, SEEK_CUR);
+            }
         }
 
         total_size += a.size;
         }
 
         total_size += a.size;
@@ -2963,7 +3042,8 @@ static int mov_read_header(AVFormatContext *s)
         AVStream *st = s->streams[i];
         MOVStreamContext *sc = st->priv_data;
         if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->codec->codec_id == AV_CODEC_ID_AAC) {
         AVStream *st = s->streams[i];
         MOVStreamContext *sc = st->priv_data;
         if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->codec->codec_id == AV_CODEC_ID_AAC) {
-            sc->start_pad = 2112;
+            if(!sc->start_pad)
+                sc->start_pad = 1024;
             st->skip_samples = sc->start_pad;
         }
     }
             st->skip_samples = sc->start_pad;
         }
     }