]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/asf.c
add 'wide' reversed tag in probe, detect broken xdcam files xdcam_hd_1080i60.mov
[ffmpeg] / libavformat / asf.c
index 3cc869d724054be1c37595e07f74b016385b4ced..009dd7a94cb483cad501e46318f2111677e284ad 100644 (file)
@@ -119,9 +119,6 @@ static void get_str16_nolen(ByteIOContext *pb, int len, char *buf, int buf_size)
 static int asf_probe(AVProbeData *pd)
 {
     /* check file header */
-    if (pd->buf_size <= 32)
-        return 0;
-
     if (!memcmp(pd->buf, &asf_header, sizeof(GUID)))
         return AVPROBE_SCORE_MAX;
     else
@@ -148,10 +145,8 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
     int size, i;
     int64_t gsize;
     AVRational dar[128];
-    uint32_t bitrate[128];
 
     memset(dar, 0, sizeof(dar));
-    memset(bitrate, 0, sizeof(bitrate));
 
     get_guid(pb, &g);
     if (memcmp(&g, &asf_header, sizeof(GUID)))
@@ -200,7 +195,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
             uint64_t total_size;
             unsigned int tag1;
             int64_t pos1, pos2;
-            int test_for_ext_stream_audio;
+            int test_for_ext_stream_audio, is_dvr_ms_audio=0;
 
             pos1 = url_ftell(pb);
 
@@ -246,6 +241,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
                 get_guid(pb, &g);
                 if (!memcmp(&g, &ext_stream_audio_stream, sizeof(GUID))) {
                     type = CODEC_TYPE_AUDIO;
+                    is_dvr_ms_audio=1;
                     get_guid(pb, &g);
                     get_le32(pb);
                     get_le32(pb);
@@ -258,7 +254,13 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
             st->codec->codec_type = type;
             if (type == CODEC_TYPE_AUDIO) {
                 get_wav_header(pb, st->codec, type_specific_size);
-                st->need_parsing = 1;
+                if (is_dvr_ms_audio) {
+                    // codec_id and codec_tag are unreliable in dvr_ms
+                    // files. Set them later by probing stream.
+                    st->codec->codec_id = CODEC_ID_NONE;
+                    st->codec->codec_tag = 0;
+                }
+                st->need_parsing = AVSTREAM_PARSE_FULL;
                 /* We have to init the frame size at some point .... */
                 pos2 = url_ftell(pb);
                 if (gsize >= (pos2 + 8 - pos1 + 24)) {
@@ -335,7 +337,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
                 st->codec->codec_tag = tag1;
                 st->codec->codec_id = codec_get_id(codec_bmp_tags, tag1);
                 if(tag1 == MKTAG('D', 'V', 'R', ' '))
-                    st->need_parsing = 1;
+                    st->need_parsing = AVSTREAM_PARSE_FULL;
             }
             pos2 = url_ftell(pb);
             url_fskip(pb, gsize - (pos2 - pos1 + 24));
@@ -419,13 +421,13 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
             }
         } else if (!memcmp(&g, &ext_stream_header, sizeof(GUID))) {
             int ext_len, payload_ext_ct, stream_ct;
-            uint32_t ext_d, leak_rate, stream_num;
+            uint32_t ext_d;
             int64_t pos_ex_st;
             pos_ex_st = url_ftell(pb);
 
             get_le64(pb); // starttime
             get_le64(pb); // endtime
-            leak_rate = get_le32(pb); // leak-datarate
+            get_le32(pb); // leak-datarate
             get_le32(pb); // bucket-datasize
             get_le32(pb); // init-bucket-fullness
             get_le32(pb); // alt-leak-datarate
@@ -433,15 +435,12 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
             get_le32(pb); // alt-init-bucket-fullness
             get_le32(pb); // max-object-size
             get_le32(pb); // flags (reliable,seekable,no_cleanpoints?,resend-live-cleanpoints, rest of bits reserved)
-            stream_num = get_le16(pb); // stream-num
+            get_le16(pb); // stream-num
             get_le16(pb); // stream-language-id-index
             get_le64(pb); // avg frametime in 100ns units
             stream_ct = get_le16(pb); //stream-name-count
             payload_ext_ct = get_le16(pb); //payload-extension-system-count
 
-            if (stream_num < 128)
-                bitrate[stream_num] = leak_rate;
-
             for (i=0; i<stream_ct; i++){
                 get_le16(pb);
                 ext_len = get_le16(pb);
@@ -505,13 +504,11 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
 
     for(i=0; i<128; i++){
         int stream_num= asf->asfid2avid[i];
-        if(stream_num>=0){
+        if(stream_num>=0 && dar[i].num>0 && dar[i].den>0){
             AVCodecContext *codec= s->streams[stream_num]->codec;
-            codec->bit_rate = bitrate[i];
-            if (dar[i].num > 0 && dar[i].den > 0)
-                av_reduce(&codec->sample_aspect_ratio.num,
-                        &codec->sample_aspect_ratio.den,
-                        dar[i].num, dar[i].den, INT_MAX);
+            av_reduce(&codec->sample_aspect_ratio.num,
+                    &codec->sample_aspect_ratio.den,
+                    dar[i].num, dar[i].den, INT_MAX);
 //av_log(NULL, AV_LOG_ERROR, "dar %d:%d sar=%d:%d\n", dar[i].num, dar[i].den, codec->sample_aspect_ratio.num, codec->sample_aspect_ratio.den);
         }
     }
@@ -548,7 +545,7 @@ static int asf_get_packet(AVFormatContext *s)
     ASFContext *asf = s->priv_data;
     ByteIOContext *pb = &s->pb;
     uint32_t packet_length, padsize;
-    int rsize = 9;
+    int rsize = 8;
     int c, d, e, off;
 
     off= (url_ftell(&s->pb) - s->data_offset) % asf->packet_size + 3;
@@ -565,23 +562,21 @@ static int asf_get_packet(AVFormatContext *s)
         if (!url_feof(pb))
             av_log(s, AV_LOG_ERROR, "ff asf bad header %x  at:%"PRId64"\n", c, url_ftell(pb));
     }
-    if ((c & 0x0f) == 2) { // always true for now
+    if ((c & 0x8f) == 0x82) {
         if (d || e) {
             if (!url_feof(pb))
                 av_log(s, AV_LOG_ERROR, "ff asf bad non zero\n");
             return -1;
         }
+        c= get_byte(pb);
         d= get_byte(pb);
-        e= get_byte(pb);
-        rsize+=2;
-/*    }else{
-        if (!url_feof(pb))
-            printf("ff asf bad header %x  at:%"PRId64"\n", c, url_ftell(pb));
-        return AVERROR_IO;*/
+        rsize+=3;
+    }else{
+        url_fseek(pb, -1, SEEK_CUR); //FIXME
     }
 
-    asf->packet_flags = d;
-    asf->packet_property = e;
+    asf->packet_flags    = c;
+    asf->packet_property = d;
 
     DO_2BITS(asf->packet_flags >> 5, packet_length, asf->packet_size);
     DO_2BITS(asf->packet_flags >> 1, padsize, 0); // sequence ignored