]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/mov.c
Merge commit 'aa51b0492bfced6d650fb5ff419e2b13fde6833d'
[ffmpeg] / libavformat / mov.c
index ab859181f5d7f132d17c92e108c52af362f9aa42..767833ed05620929e741fac0b0716c1439c7e2ad 100644 (file)
@@ -83,6 +83,7 @@ static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
         snprintf(buf, sizeof(buf), "%d", current);
     else
         snprintf(buf, sizeof(buf), "%d/%d", current, total);
+    c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
     av_dict_set(&c->fc->metadata, key, buf, 0);
 
     return 0;
@@ -99,6 +100,7 @@ static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
     avio_r8(pb);
 
     snprintf(buf, sizeof(buf), "%d", avio_r8(pb));
+    c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
     av_dict_set(&c->fc->metadata, key, buf, 0);
 
     return 0;
@@ -110,6 +112,7 @@ static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb,
     char buf[16];
 
     snprintf(buf, sizeof(buf), "%d", avio_r8(pb));
+    c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
     av_dict_set(&c->fc->metadata, key, buf, 0);
 
     return 0;
@@ -125,6 +128,7 @@ static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
     genre = avio_r8(pb);
     if (genre < 1 || genre > ID3v1_GENRE_MAX)
         return 0;
+    c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
     av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
 
     return 0;
@@ -254,6 +258,7 @@ static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
         snprintf(key2, sizeof(key2), "%s-%s", key, language);
         av_dict_set(&c->fc->metadata, key2, buf, 0);
     }
+    c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
     return av_dict_set(&c->fc->metadata, key, buf, 0);
 }
 
@@ -318,6 +323,8 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
         return mov_metadata_raw(c, pb, atom.size, "quicktime_version");
     case MKTAG( 'l','o','c','i'):
         return mov_metadata_loci(c, pb, atom.size);
+    case MKTAG( 'X','M','P','_'):
+        return mov_metadata_raw(c, pb, atom.size, "xmp");
     }
 
     if (c->itunes_metadata && atom.size > 8) {
@@ -370,6 +377,7 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
                 return ret < 0 ? ret : AVERROR_INVALIDDATA;
             str[str_size] = 0;
         }
+        c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
         av_dict_set(&c->fc->metadata, key, str, 0);
         if (*language && strcmp(language, "und")) {
             snprintf(key2, sizeof(key2), "%s-%s", key, language);
@@ -483,7 +491,7 @@ static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
             avio_skip(pb, 16);
 
             for (type = 0; type != -1 && avio_tell(pb) < next; ) {
-                if(url_feof(pb))
+                if(avio_feof(pb))
                     return AVERROR_EOF;
                 type = avio_rb16(pb);
                 len = avio_rb16(pb);
@@ -1005,7 +1013,10 @@ static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 
 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
-    return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
+    int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
+    if(ret == 0)
+        ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
+    return ret;
 }
 
 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
@@ -1529,6 +1540,26 @@ static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
                 st->codec->flags2 |= CODEC_FLAG2_DROP_FRAME_TIMECODE;
             st->codec->time_base.den = st->codec->extradata[16]; /* number of frame */
             st->codec->time_base.num = 1;
+            if (size > 30) {
+                uint32_t len = AV_RB32(st->codec->extradata + 18); /* name atom length */
+                uint32_t format = AV_RB32(st->codec->extradata + 22);
+                if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
+                    uint16_t str_size = AV_RB16(st->codec->extradata + 26); /* string length */
+                    if (str_size > 0 && size >= (int)str_size + 26) {
+                        char *reel_name = av_malloc(str_size + 1);
+                        if (!reel_name)
+                            return AVERROR(ENOMEM);
+                        memcpy(reel_name, st->codec->extradata + 30, str_size);
+                        reel_name[str_size] = 0; /* Add null terminator */
+                        /* don't add reel_name if emtpy string */
+                        if (*reel_name == 0) {
+                            av_free(reel_name);
+                        } else {
+                            av_dict_set(&st->metadata, "reel_name", reel_name,  AV_DICT_DONT_STRDUP_VAL);
+                        }
+                    }
+                }
+            }
         }
     } else {
         /* other codec type, just skip (rtp, mp4s ...) */
@@ -3151,7 +3182,7 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 
     if (atom.size < 0)
         atom.size = INT64_MAX;
-    while (total_size + 8 <= atom.size && !url_feof(pb)) {
+    while (total_size + 8 <= atom.size && !avio_feof(pb)) {
         int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
         a.size = atom.size;
         a.type=0;
@@ -3699,7 +3730,7 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
         avio_seek(s->pb, mov->next_root_atom, SEEK_SET);
         mov->next_root_atom = 0;
         if (mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX }) < 0 ||
-            url_feof(s->pb))
+            avio_feof(s->pb))
             return AVERROR_EOF;
         av_dlog(s, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
         goto retry;