]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/mov.c
fix double free, priv_data is freed in av_open_input_stream
[ffmpeg] / libavformat / mov.c
index 638245eb2cb9a2cbf037640ac8be6b0cbc1de6d5..5eb258e36da49ea2adde27d0e3495425e975f23f 100644 (file)
@@ -94,7 +94,7 @@ const CodecTag ff_mov_obj_type[] = {
     { CODEC_ID_MP2       , 107 },
     { CODEC_ID_MJPEG     , 108 },
     { CODEC_ID_PCM_S16LE , 224 },
-    { CODEC_ID_VORBIS    , 225 },
+    { CODEC_ID_VORBIS    , 221 },
     { CODEC_ID_AC3       , 226 },
     { CODEC_ID_PCM_ALAW  , 227 },
     { CODEC_ID_PCM_MULAW , 228 },
@@ -322,7 +322,7 @@ typedef struct MOVContext {
     int mp4; /* set to 1 as soon as we are sure that the file is an .mp4 file (even some header parsing depends on this) */
     AVFormatContext *fc;
     int time_scale;
-    int duration; /* duration of the longest track */
+    int64_t duration; /* duration of the longest track */
     int found_moov; /* when both 'moov' and 'mdat' sections has been found */
     int found_mdat; /* we suppose we have enough data to read the file */
     int64_t mdat_size;
@@ -668,24 +668,30 @@ static int mov_read_moov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
 
 static int mov_read_mdhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
 {
-    int version;
+    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
+    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
+    int version = get_byte(pb);
     int lang;
 
-    version = get_byte(pb); /* version */
     if (version > 1)
         return 1; /* unsupported */
 
     get_byte(pb); get_byte(pb);
     get_byte(pb); /* flags */
 
-    (version==1)?get_be64(pb):get_be32(pb); /* creation time */
-    (version==1)?get_be64(pb):get_be32(pb); /* modification time */
+    if (version == 1) {
+        get_be64(pb);
+        get_be64(pb);
+    } else {
+        get_be32(pb); /* creation time */
+        get_be32(pb); /* modification time */
+    }
 
-    c->streams[c->fc->nb_streams-1]->time_scale = get_be32(pb);
-    c->fc->streams[c->fc->nb_streams-1]->duration = (version==1)?get_be64(pb):get_be32(pb); /* duration */
+    sc->time_scale = get_be32(pb);
+    st->duration = (version == 1) ? get_be64(pb) : get_be32(pb); /* duration */
 
     lang = get_be16(pb); /* language */
-    ff_mov_lang_to_iso639(lang, c->fc->streams[c->fc->nb_streams-1]->language);
+    ff_mov_lang_to_iso639(lang, st->language);
     get_be16(pb); /* quality */
 
     return 0;
@@ -940,12 +946,18 @@ static int mov_read_stsd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
                 (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff, (format >> 24) & 0xff,
                 st->codec->codec_type);
         st->codec->codec_tag = format;
-        /* codec_type is set earlier by read_hdlr */
-        if(st->codec->codec_type==CODEC_TYPE_VIDEO) {
-            /* for MPEG4: set codec type by looking for it */
+        id = codec_get_id(mov_audio_tags, format);
+        if (id > 0) {
+            st->codec->codec_type = CODEC_TYPE_AUDIO;
+        } else if (format != MKTAG('m', 'p', '4', 's')) { /* skip old asf mpeg4 tag */
             id = codec_get_id(mov_video_tags, format);
-            if(id <= 0)
+            if (id <= 0)
                 id = codec_get_id(codec_bmp_tags, format);
+            if (id > 0)
+                st->codec->codec_type = CODEC_TYPE_VIDEO;
+        }
+
+        if(st->codec->codec_type==CODEC_TYPE_VIDEO) {
             st->codec->codec_id = id;
             get_be16(pb); /* version */
             get_be16(pb); /* revision level */
@@ -1052,7 +1064,7 @@ static int mov_read_stsd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
         } else if(st->codec->codec_type==CODEC_TYPE_AUDIO) {
             uint16_t version = get_be16(pb);
 
-            st->codec->codec_id = codec_get_id(mov_audio_tags, format);
+            st->codec->codec_id = id;
             get_be16(pb); /* revision level */
             get_be32(pb); /* vendor */
 
@@ -1067,10 +1079,12 @@ static int mov_read_stsd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
             st->codec->sample_rate = ((get_be32(pb) >> 16));
 
             switch (st->codec->codec_id) {
+            case CODEC_ID_PCM_S16LE:
             case CODEC_ID_PCM_S16BE:
                 if (st->codec->bits_per_sample == 8)
                     st->codec->codec_id = CODEC_ID_PCM_S8;
-                /* fall */
+                st->codec->bit_rate = st->codec->sample_rate * 8;
+                break;
             case CODEC_ID_PCM_U8:
                 if (st->codec->bits_per_sample == 16)
                     st->codec->codec_id = CODEC_ID_PCM_S16BE;
@@ -1120,6 +1134,11 @@ static int mov_read_stsd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
     if(st->codec->codec_type==CODEC_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1) {
         st->codec->sample_rate= sc->time_scale;
     }
+#ifdef CONFIG_FAAD
+    if(st->codec->codec_id ==CODEC_ID_AAC) {
+        st->codec->sample_rate= 0; /* let faad init parameters properly */
+    }
+#endif
 
     return 0;
 }
@@ -1276,7 +1295,7 @@ av_log(NULL, AV_LOG_DEBUG, "track[%i].stts.entries = %i\n", c->fc->nb_streams-1,
 
         dprintf("sample_count=%d, sample_duration=%d\n",sample_count,sample_duration);
 
-        duration+=sample_duration*sample_count;
+        duration+=(int64_t)sample_duration*sample_count;
         total_sample_count+=sample_count;
     }
 
@@ -1339,12 +1358,8 @@ static int mov_read_trak(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
 
 static int mov_read_tkhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
 {
-    AVStream *st;
-    int version;
-
-    st = c->fc->streams[c->fc->nb_streams-1];
-
-    version = get_byte(pb); /* version */
+    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
+    int version = get_byte(pb);
 
     get_byte(pb); get_byte(pb);
     get_byte(pb); /* flags */