[x264-devel] commit: Add temporal predictor support to interlaced encoding ( Jason Garrett-Glaser )

git version control git at videolan.org
Tue Feb 23 11:05:35 CET 2010


x264 | branch: master | Jason Garrett-Glaser <darkshikari at gmail.com> | Thu Feb 18 10:37:57 2010 -0800| [10e9e95cb90f01fcbdb182c2ae05dac336b6eed3] | committer: Jason Garrett-Glaser 

Add temporal predictor support to interlaced encoding
0.5-1% better compression in interlaced mode

> http://git.videolan.org/gitweb.cgi/x264.git/?a=commit;h=10e9e95cb90f01fcbdb182c2ae05dac336b6eed3
---

 common/frame.h      |    2 +-
 common/macroblock.c |   26 +++++++++++++++++++-------
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/common/frame.h b/common/frame.h
index 6e7de50..0566b1e 100644
--- a/common/frame.h
+++ b/common/frame.h
@@ -85,7 +85,7 @@ typedef struct x264_frame
     int8_t  *ref[2];
     int     i_ref[2];
     int     ref_poc[2][16];
-    int     inv_ref_poc[16]; // inverse values (list0 only) to avoid divisions in MB encoding
+    int16_t inv_ref_poc[2][32]; // inverse values (list0 only) to avoid divisions in MB encoding
 
     /* for adaptive B-frame decision.
      * contains the SATD cost of the lowres frame encoded in various modes
diff --git a/common/macroblock.c b/common/macroblock.c
index 2573415..68c7e06 100644
--- a/common/macroblock.c
+++ b/common/macroblock.c
@@ -447,10 +447,14 @@ void x264_mb_predict_mv_ref16x16( x264_t *h, int i_list, int i_ref, int16_t mvc[
 #undef SET_MVP
 
     /* temporal predictors */
-    /* FIXME temporal scaling w/ interlace */
-    if( h->fref0[0]->i_ref[0] > 0 && !h->sh.b_mbaff )
+    if( h->fref0[0]->i_ref[0] > 0 )
     {
         x264_frame_t *l0 = h->fref0[0];
+        int field = h->mb.i_mb_y&1;
+        int curpoc = h->fdec->i_poc + field*h->sh.i_delta_poc_bottom;
+        int refpoc = h->fref0[i_ref>>h->sh.b_mbaff]->i_poc;
+        if( h->sh.b_mbaff && field^(i_ref&1) )
+            refpoc += h->sh.i_delta_poc_bottom;
 
 #define SET_TMVP(dx, dy) { \
             int i_b4 = h->mb.i_b4_xy + dx*4 + dy*4*h->mb.i_b4_stride; \
@@ -458,7 +462,7 @@ void x264_mb_predict_mv_ref16x16( x264_t *h, int i_list, int i_ref, int16_t mvc[
             int ref_col = l0->ref[0][i_b8]; \
             if( ref_col >= 0 ) \
             { \
-                int scale = (h->fdec->i_poc - h->fdec->ref_poc[0][i_ref]) * l0->inv_ref_poc[ref_col];\
+                int scale = (curpoc - refpoc) * l0->inv_ref_poc[h->mb.b_interlaced&field][ref_col];\
                 mvc[i][0] = (l0->mv[0][i_b4][0]*scale + 128) >> 8;\
                 mvc[i][1] = (l0->mv[0][i_b4][1]*scale + 128) >> 8;\
                 i++; \
@@ -479,11 +483,19 @@ void x264_mb_predict_mv_ref16x16( x264_t *h, int i_list, int i_ref, int16_t mvc[
 /* Set up a lookup table for delta pocs to reduce an IDIV to an IMUL */
 static void setup_inverse_delta_pocs( x264_t *h )
 {
-    int i;
-    for( i = 0; i < h->i_ref0; i++ )
+    int i, field;
+    for( field = 0; field <= h->sh.b_mbaff; field++ )
     {
-        int delta = h->fdec->i_poc - h->fref0[i]->i_poc;
-        h->fdec->inv_ref_poc[i] = (256 + delta/2) / delta;
+        int curpoc = h->fdec->i_poc + field*h->sh.i_delta_poc_bottom;
+        for( i = 0; i < (h->i_ref0<<h->sh.b_mbaff); i++ )
+        {
+            int refpoc = h->fref0[i>>h->sh.b_mbaff]->i_poc;
+            if( h->sh.b_mbaff && field^(i&1) )
+                refpoc += h->sh.i_delta_poc_bottom;
+            int delta = curpoc - refpoc;
+
+            h->fdec->inv_ref_poc[field][i] = (256 + delta/2) / delta;
+        }
     }
 }
 



More information about the x264-devel mailing list