changeset 4592:9fc8acda3223 libavcodec

rewrite find_frame_end() new code correctly splits long start codes, also its about twice as fast
author michael
date Sun, 25 Feb 2007 02:38:08 +0000
parents 16c24b902f43
children 2aea8bf268d8
files h264.c
diffstat 1 files changed, 41 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/h264.c	Sun Feb 25 00:35:30 2007 +0000
+++ b/h264.c	Sun Feb 25 02:38:08 2007 +0000
@@ -7990,36 +7990,45 @@
 //printf("first %02X%02X%02X%02X\n", buf[0], buf[1],buf[2],buf[3]);
 //    mb_addr= pc->mb_addr - 1;
     state= pc->state;
-    for(i=0; i<=buf_size; i++){
-        if((state&0xFFFFFF1F) == 0x101 || (state&0xFFFFFF1F) == 0x102 || (state&0xFFFFFF1F) == 0x105){
-            tprintf("find_frame_end new startcode = %08x, frame_start_found = %d, pos = %d\n", state, pc->frame_start_found, i);
-            if(pc->frame_start_found){
-                // If there isn't one more byte in the buffer
-                // the test on first_mb_in_slice cannot be done yet
-                // do it at next call.
-                if (i >= buf_size) break;
-                if (buf[i] & 0x80) {
-                    // first_mb_in_slice is 0, probably the first nal of a new
-                    // slice
-                    tprintf("find_frame_end frame_end_found, state = %08x, pos = %d\n", state, i);
-                    pc->state=-1;
+    if(state>13)
+        state= 7;
+
+    for(i=0; i<buf_size; i++){
+        if(state==7){
+            for(; i<buf_size; i++){
+                if(!buf[i]){
+                    state=2;
+                    break;
+                }
+            }
+        }else if(state<=2){
+            if(buf[i]==1)   state^= 5; //2->7, 1->4, 0->5
+            else if(buf[i]) state = 7;
+            else            state>>=1; //2->1, 1->0, 0->0
+        }else if(state<=5){
+            int v= buf[i] & 0x1F;
+            if(v==7 || v==8 || v==9){
+                if(pc->frame_start_found){
+                    i++;
+found:
+                    pc->state=7;
                     pc->frame_start_found= 0;
-                    return i-4;
+                    return i-(state&5);
                 }
-            }
-            pc->frame_start_found = 1;
-        }
-        if((state&0xFFFFFF1F) == 0x107 || (state&0xFFFFFF1F) == 0x108 || (state&0xFFFFFF1F) == 0x109){
-           if(pc->frame_start_found){
-                pc->state=-1;
-                pc->frame_start_found= 0;
-                return i-4;
-           }
-        }
-        if (i<buf_size)
-            state= (state<<8) | buf[i];
-    }
-
+            }else if(v==1 || v==2 || v==5){
+                if(pc->frame_start_found){
+                    state+=8;
+                    continue;
+                }else
+                    pc->frame_start_found = 1;
+            }
+            state= 7;
+        }else{
+            if(buf[i] & 0x80)
+                goto found;
+            state= 7;
+        }
+    }
     pc->state= state;
     return END_NOT_FOUND;
 }
@@ -8042,6 +8051,10 @@
         return buf_size;
     }
 
+    if(next<0){
+        find_frame_end(h, &pc->buffer[pc->last_index + next], -next); //update state
+    }
+
     *poutbuf = (uint8_t *)buf;
     *poutbuf_size = buf_size;
     return next;