mov.c: Check for stsd + m1s tag indicating MOV-wrapped MPEG-PS, and force continued...
authorPetter Ericson <petter.ericson@codemill.se>
Wed, 17 Oct 2012 14:53:19 +0000 (16:53 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Fri, 19 Oct 2012 14:07:49 +0000 (16:07 +0200)
Fixes Ticket241
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
libavformat/mov.c

index 7e653236aca819ebdc296428ded9dc03e251ba4e..b296c248ffddb48c700067f3f32e2d120cd77f7f 100644 (file)
@@ -2861,43 +2861,72 @@ static int mov_probe(AVProbeData *p)
     int64_t offset;
     uint32_t tag;
     int score = 0;
+    int moov_offset = -1;
 
     /* check file header */
     offset = 0;
     for (;;) {
         /* ignore invalid offset */
         if ((offset + 8) > (unsigned int)p->buf_size)
-            return score;
+            break;
         tag = AV_RL32(p->buf + offset + 4);
         switch(tag) {
         /* check for obvious tags */
-        case MKTAG('j','P',' ',' '): /* jpeg 2000 signature */
         case MKTAG('m','o','o','v'):
+            moov_offset = offset + 4;
+        case MKTAG('j','P',' ',' '): /* jpeg 2000 signature */
         case MKTAG('m','d','a','t'):
         case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
         case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
         case MKTAG('f','t','y','p'):
-            return AVPROBE_SCORE_MAX;
+            score  = AVPROBE_SCORE_MAX;
+            offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
+            break;
         /* those are more common words, so rate then a bit less */
         case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
         case MKTAG('w','i','d','e'):
         case MKTAG('f','r','e','e'):
         case MKTAG('j','u','n','k'):
         case MKTAG('p','i','c','t'):
-            return AVPROBE_SCORE_MAX - 5;
+            score  = FFMAX(score, AVPROBE_SCORE_MAX - 5);
+            offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
+            break;
         case MKTAG(0x82,0x82,0x7f,0x7d):
         case MKTAG('s','k','i','p'):
         case MKTAG('u','u','i','d'):
         case MKTAG('p','r','f','l'):
-            offset = AV_RB32(p->buf+offset) + offset;
             /* if we only find those cause probedata is too small at least rate them */
-            score = AVPROBE_SCORE_MAX - 50;
+            score  = FFMAX(score, AVPROBE_SCORE_MAX - 50);
+            offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
             break;
         default:
-            /* unrecognized tag */
-            return score;
+            offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
+        }
+    }
+    if(tag > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
+        /* moov atom in the header - we should make sure that this is not a
+         * MOV-packed MPEG-PS */
+        offset = moov_offset;
+
+        while(offset < (p->buf_size - 20)){ /* Sufficient space */
+               /* We found an actual stsd atom */
+            if(AV_RL32(p->buf+offset)       == MKTAG('s','t','s','d') &&
+               /* Make sure there's only one stream */
+               AV_RB32(p->buf + offset + 8)  == 1 &&
+               AV_RL32(p->buf + offset + 16) == MKTAG('m','1','s',' ')
+            ){
+                av_log(NULL, AV_LOG_WARNING, "Found m1s tag indicating this is a MOV-packed MPEG-PS.\n");
+                /* We found an stsd atom describing an MPEG-PS-in-MOV, return a
+                 * low score to force expanding the probe window until
+                 * mpegps_probe finds what it needs */
+                return 5;
+            }else
+                /* Keep looking */
+                offset+=2;
         }
     }
+
+    return score;
 }
 
 // must be done after parsing all trak because there's no order requirement