Make find_frame_end() merge 2 mpeg2 field pictures. This should make mpeg2
authorMichael Niedermayer <michaelni@gmx.at>
Wed, 20 Feb 2008 19:45:38 +0000 (19:45 +0000)
committerMichael Niedermayer <michaelni@gmx.at>
Wed, 20 Feb 2008 19:45:38 +0000 (19:45 +0000)
field pictures much more digestable.

Originally committed as revision 12160 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/mpeg12.c

index 7f3a181..56b456a 100644 (file)
@@ -2182,29 +2182,43 @@ int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size)
     int i;
     uint32_t state= pc->state;
 
-    i=0;
-    if(!pc->frame_start_found){
-        for(i=0; i<buf_size; i++){
+    /* EOF considered as end of frame */
+    if (buf_size == 0)
+        return 0;
+
+/*
+ 0  frame start         -> 1/4
+ 1  first_SEQEXT        -> 0/2
+ 2  first field start   -> 3/0
+ 3  second_SEQEXT       -> 2/0
+ 4  searching end
+*/
+
+    for(i=0; i<buf_size; i++){
+        assert(pc->frame_start_found>=0 && pc->frame_start_found<=4);
+        if(pc->frame_start_found&1){
+            if(state == EXT_START_CODE && (buf[i]&0xF0) != 0x80)
+                pc->frame_start_found--;
+            else if(state == EXT_START_CODE+2){
+                if((buf[i]&3) == 3) pc->frame_start_found= 0;
+                else                pc->frame_start_found= (pc->frame_start_found+1)&3;
+            }
+            state++;
+        }else{
             i= ff_find_start_code(buf+i, buf+buf_size, &state) - buf - 1;
-            if(state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE){
+            if(pc->frame_start_found==0 && state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE){
                 i++;
-                pc->frame_start_found=1;
-                break;
+                pc->frame_start_found=4;
             }
             if(state == SEQ_END_CODE){
                 pc->state=-1;
                 return i+1;
             }
-        }
-    }
-
-    if(pc->frame_start_found){
-        /* EOF considered as end of frame */
-        if (buf_size == 0)
-            return 0;
-        for(; i<buf_size; i++){
-            i= ff_find_start_code(buf+i, buf+buf_size, &state) - buf - 1;
-            if((state&0xFFFFFF00) == 0x100){
+            if(pc->frame_start_found==2 && state == SEQ_START_CODE)
+                pc->frame_start_found= 0;
+            if(pc->frame_start_found<4 && state == EXT_START_CODE)
+                pc->frame_start_found++;
+            if(pc->frame_start_found == 4 && (state&0xFFFFFF00) == 0x100){
                 if(state < SLICE_MIN_START_CODE || state > SLICE_MAX_START_CODE){
                     pc->frame_start_found=0;
                     pc->state=-1;