]> 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 151a52a734e7a4f16abb761d7484b2c5050961f0..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
@@ -167,6 +164,16 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
         print_guid(&g);
         printf("  size=0x%"PRIx64"\n", gsize);
 #endif
+        if (!memcmp(&g, &data_header, sizeof(GUID))) {
+            asf->data_object_offset = url_ftell(pb);
+            // if not streaming, gsize is not unlimited (how?), and there is enough space in the file..
+            if (!(asf->hdr.flags & 0x01) && gsize >= 100) {
+                asf->data_object_size = gsize - 24;
+            } else {
+                asf->data_object_size = (uint64_t)-1;
+            }
+            break;
+        }
         if (gsize < 24)
             goto fail;
         if (!memcmp(&g, &file_header, sizeof(GUID))) {
@@ -188,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);
 
@@ -234,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);
@@ -246,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)) {
@@ -323,19 +337,10 @@ 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));
-        } else if (!memcmp(&g, &data_header, sizeof(GUID))) {
-            asf->data_object_offset = url_ftell(pb);
-            // if not streaming, gsize is not unlimited (how?), and there is enough space in the file..
-            if (!(asf->hdr.flags & 0x01) && gsize != (uint64_t)-1 && gsize >= 24) {
-                asf->data_object_size = gsize - 24;
-            } else {
-                asf->data_object_size = (uint64_t)-1;
-            }
-            break;
         } else if (!memcmp(&g, &comment_header, sizeof(GUID))) {
             int len1, len2, len3, len4, len5;
 
@@ -540,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;
@@ -557,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