[FFmpeg-devel] [RFC] use ff_avc_find_startcode in ff_find_start_code

Reimar Döffinger Reimar.Doeffinger
Tue Feb 19 12:04:08 CET 2008


Hello,
On Mon, Feb 18, 2008 at 11:07:38PM +0100, Reimar D?ffinger wrote:
> First I wonder if that ff_find_start_code function is
> not quite buggy anyway, or is it intentional that it searches for 
> 00 00 01 00 in the part involving the state but for 00 00 01 ?? in the
> later code? If so, could somebody document the code?.
> Anyway, this is a quite ugly patch that makes the function use
> ff_avc_find_startcode (since that is in lavf, it can't be used as is of
> course).
> It probably also breaks the original use of ff_avc_find_startcode,
> though I found the current behaviour a bit strange as well, and this
> function is undocumented, too.
> This causes at least a 6% speedup when decoding
> http://samples.mplayerhq.hu/GXF/THX_Science_FLT_1920.gxf (I only tested
> with MPlayer though).

This one is a bit faster, but still not as fast as the original when
using ffmpeg/ffplay but much faster when using mplayer (whether the data
is in the cache or not really seems to be what makes the difference?!)...

Greetings,
Reimar D?ffinger
-------------- next part --------------
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 6b14339..815d898 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -97,6 +97,8 @@ void ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *src_s
     }
 }
 
+uint8_t *ff_avc_find_startcode(uint8_t *p, uint8_t *end);
+
 const uint8_t *ff_find_start_code(const uint8_t * restrict p, const uint8_t *end, uint32_t * restrict state){
     int i;
 
@@ -111,6 +113,8 @@ const uint8_t *ff_find_start_code(const uint8_t * restrict p, const uint8_t *end
             return p;
     }
 
+START_TIMER
+#if 0
     while(p<end){
         if     (p[-1] > 1      ) p+= 3;
         else if(p[-2]          ) p+= 2;
@@ -120,6 +124,11 @@ const uint8_t *ff_find_start_code(const uint8_t * restrict p, const uint8_t *end
             break;
         }
     }
+#else
+    p = ff_avc_find_startcode(p-3, end);
+    p = FFMIN(p + 4, end);
+#endif
+STOP_TIMER("test")
 
     p= FFMIN(p, end)-4;
     *state= AV_RB32(p);
diff --git a/libavformat/avc.c b/libavformat/avc.c
index ade113c..62ae7bf 100644
--- a/libavformat/avc.c
+++ b/libavformat/avc.c
@@ -32,22 +32,29 @@ uint8_t *ff_avc_find_startcode(uint8_t *p, uint8_t *end)
 
     for( end -= 3; p < end; p += 4 ) {
         uint32_t x = *(uint32_t*)p;
-//      if( (x - 0x01000100) & (~x) & 0x80008000 ) // little endian
-//      if( (x - 0x00010001) & (~x) & 0x00800080 ) // big endian
-        if( (x - 0x01010101) & (~x) & 0x80808080 ) { // generic
-            if( p[1] == 0 ) {
-                if( p[0] == 0 && p[2] == 1 )
-                    return p-1;
-                if( p[2] == 0 && p[3] == 1 )
-                    return p;
-            }
-            if( p[3] == 0 ) {
-                if( p[2] == 0 && p[4] == 1 )
-                    return p+1;
-                if( p[4] == 0 && p[5] == 1 )
-                    return p+2;
-            }
+#ifdef WORDS_BIGENDIAN
+        if( (x - 0x00010001) & (~x) & 0x00800080 ) {
+            if ((x & 0xffffff00) == 0x00000100)
+                return p;
+            if ((x & 0x00ffffff) == 0x00000001)
+                return p+1;
+            if ((x & 0x0000ffff) == 0 && p[4] == 1)
+                return p+2;
+            if ((x & 0x000000ff) == 0 && p[4] == 0 && p[5] == 1)
+                return p+3;
+        }
+#else
+        if( (x - 0x01000100) & (~x) & 0x80008000 ) {
+            if ((x & 0x00ffffff) == 0x00010000)
+                return p;
+            if ((x & 0xffffff00) == 0x01000000)
+                return p+1;
+            if ((x & 0xffff0000) == 0 && p[4] == 1)
+                return p+2;
+            if ((x & 0xff000000) == 0 && p[4] == 0 && p[5] == 1)
+                return p+3;
         }
+#endif
     }
 
     for( end += 3; p < end; p++ ) {



More information about the ffmpeg-devel mailing list