]> granicus.if.org Git - libx264/commitdiff
Add subme=0 (fullpel motion estimation only)
authorFiona Glaser <fiona@x264.com>
Tue, 11 Nov 2008 07:34:02 +0000 (23:34 -0800)
committerFiona Glaser <fiona@x264.com>
Tue, 11 Nov 2008 07:34:02 +0000 (23:34 -0800)
Only for experimental purposes and ultra-fast encoding.  Probably not a good idea for firstpass.

common/frame.c
common/macroblock.c
encoder/encoder.c
encoder/me.c
x264.c

index 4c20cddcd3a8811ce5c623c8dfe2217742926488..b190de74226ddc03d10e549d649e8311b631d456 100644 (file)
@@ -61,10 +61,18 @@ x264_frame_t *x264_frame_new( x264_t *h )
     }
     /* all 4 luma planes allocated together, since the cacheline split code
      * requires them to be in-phase wrt cacheline alignment. */
-    CHECKED_MALLOC( frame->buffer[0], 4*luma_plane_size);
-    for( i = 0; i < 4; i++ )
-        frame->filtered[i] = frame->buffer[0] + i*luma_plane_size + frame->i_stride[0] * i_padv + PADH;
-    frame->plane[0] = frame->filtered[0];
+    if( h->param.analyse.i_subpel_refine )
+    {
+        CHECKED_MALLOC( frame->buffer[0], 4*luma_plane_size);
+        for( i = 0; i < 4; i++ )
+            frame->filtered[i] = frame->buffer[0] + i*luma_plane_size + frame->i_stride[0] * i_padv + PADH;
+        frame->plane[0] = frame->filtered[0];
+    }
+    else
+    {
+        CHECKED_MALLOC( frame->buffer[0], luma_plane_size);
+        frame->plane[0] = frame->buffer[0] + frame->i_stride[0] * i_padv + PADH;
+    }
 
     if( h->frames.b_have_lowres )
     {
index ebddd01b0b8e1000680e395647e607c8656a1f0e..0ee4880b683fdaf958ebcbf4938967f76e514882 100644 (file)
@@ -488,9 +488,6 @@ void x264_mb_predict_mv_ref16x16( x264_t *h, int i_list, int i_ref, int16_t mvc[
 #undef SET_TMVP
     }
 
-    if(i == 0)
-        *(uint32_t*)mvc[i] = 0;
-
     *i_mvc = i;
 }
 
index c22f7b0cf5cf6a9e35a45c46518da8d8454e18a2..fbb2ea1da1d7d25aec5c7ae2d63eeef7ffe6fa51 100644 (file)
@@ -441,7 +441,11 @@ static int x264_validate_parameters( x264_t *h )
     if( h->param.i_keyint_max <= 0 )
         h->param.i_keyint_max = 1;
     h->param.i_keyint_min = x264_clip3( h->param.i_keyint_min, 1, h->param.i_keyint_max/2+1 );
-
+    if( !h->param.analyse.i_subpel_refine && h->param.analyse.i_direct_mv_pred > X264_DIRECT_PRED_SPATIAL )
+    {
+        x264_log( h, X264_LOG_WARNING, "subme=0 + direct=temporal is not supported\n" );
+        h->param.analyse.i_direct_mv_pred = X264_DIRECT_PRED_SPATIAL;
+    }
     h->param.i_bframe = x264_clip3( h->param.i_bframe, 0, X264_BFRAME_MAX );
     h->param.i_bframe_bias = x264_clip3( h->param.i_bframe_bias, -90, 100 );
     h->param.b_bframe_pyramid = h->param.b_bframe_pyramid && h->param.i_bframe > 1;
@@ -474,7 +478,7 @@ static int x264_validate_parameters( x264_t *h )
     if( h->param.analyse.i_me_method == X264_ME_TESA &&
         (h->mb.b_lossless || h->param.analyse.i_subpel_refine <= 1) )
         h->param.analyse.i_me_method = X264_ME_ESA;
-    h->param.analyse.i_subpel_refine = x264_clip3( h->param.analyse.i_subpel_refine, 1, 9 );
+    h->param.analyse.i_subpel_refine = x264_clip3( h->param.analyse.i_subpel_refine, 0, 9 );
     h->param.analyse.b_mixed_references = h->param.analyse.b_mixed_references && h->param.i_frame_reference > 1;
     h->param.analyse.inter &= X264_ANALYSE_PSUB16x16|X264_ANALYSE_PSUB8x8|X264_ANALYSE_BSUB16x16|
                               X264_ANALYSE_I4x4|X264_ANALYSE_I8x8;
@@ -820,7 +824,9 @@ int x264_encoder_reconfig( x264_t *h, x264_param_t *param )
     COPY( analyse.i_direct_mv_pred );
     COPY( analyse.i_me_range );
     COPY( analyse.i_noise_reduction );
-    COPY( analyse.i_subpel_refine );
+    /* We can't switch out of subme=0 during encoding. */
+    if( h->param.analyse.i_subpel_refine )
+        COPY( analyse.i_subpel_refine );
     COPY( analyse.i_trellis );
     COPY( analyse.b_chroma_me );
     COPY( analyse.b_dct_decimate );
@@ -1002,8 +1008,11 @@ static void x264_fdec_filter_row( x264_t *h, int mb_y )
     if( b_hpel )
     {
         x264_frame_expand_border( h, h->fdec, min_y, b_end );
-        x264_frame_filter( h, h->fdec, min_y, b_end );
-        x264_frame_expand_border_filtered( h, h->fdec, min_y, b_end );
+        if( h->param.analyse.i_subpel_refine )
+        {
+            x264_frame_filter( h, h->fdec, min_y, b_end );
+            x264_frame_expand_border_filtered( h, h->fdec, min_y, b_end );
+        }
     }
 
     if( h->param.i_threads > 1 && h->fdec->b_kept_as_ref )
index 8d1d4750f03e95984aa1b47fc78b462f4b2b73ae..1f40d48db2f4c8a8d93286a947fbe9a653709c90 100644 (file)
@@ -32,7 +32,7 @@
  * the subme=8,9 values are much higher because any amount of satd search makes
  * up its time by reducing the number of qpel-rd iterations. */
 static const int subpel_iterations[][4] =
-   {{1,0,0,0},
+   {{0,0,0,0},
     {1,1,0,0},
     {0,1,1,0},
     {0,2,1,0},
@@ -165,7 +165,7 @@ void x264_me_search_ref( x264_t *h, x264_me_t *m, int16_t (*mvc)[2], int i_mvc,
     uint8_t *p_fref = m->p_fref[0];
     DECLARE_ALIGNED_16( uint8_t pix[16*16] );
 
-    int i = 0, j;
+    int i, j;
     int dir;
     int costs[6];
 
@@ -190,7 +190,7 @@ void x264_me_search_ref( x264_t *h, x264_me_t *m, int16_t (*mvc)[2], int i_mvc,
     {
         uint32_t bmv = pack16to32_mask(bmx,bmy);
         COST_MV_HPEL( bmx, bmy );
-        do
+        for( i = 0; i < i_mvc; i++ )
         {
             if( *(uint32_t*)mvc[i] && (bmv - *(uint32_t*)mvc[i]) )
             {
@@ -198,7 +198,7 @@ void x264_me_search_ref( x264_t *h, x264_me_t *m, int16_t (*mvc)[2], int i_mvc,
                 int my = x264_clip3( mvc[i][1], mv_y_min*4, mv_y_max*4 );
                 COST_MV_HPEL( mx, my );
             }
-        } while( ++i < i_mvc );
+        }
         bmx = ( bpred_mx + 2 ) >> 2;
         bmy = ( bpred_my + 2 ) >> 2;
         COST_MV( bmx, bmy );
@@ -214,7 +214,7 @@ void x264_me_search_ref( x264_t *h, x264_me_t *m, int16_t (*mvc)[2], int i_mvc,
          * sensible to remove the cost of the MV from the rounded MVP to avoid unfairly
          * biasing against use of the predicted motion vector. */
         bcost -= BITS_MVD( pmx, pmy );
-        do
+        for( i = 0; i < i_mvc; i++ )
         {
             int mx = (mvc[i][0] + 2) >> 2;
             int my = (mvc[i][1] + 2) >> 2;
@@ -224,7 +224,7 @@ void x264_me_search_ref( x264_t *h, x264_me_t *m, int16_t (*mvc)[2], int i_mvc,
                 my = x264_clip3( my, mv_y_min, mv_y_max );
                 COST_MV( mx, my );
             }
-        } while( ++i < i_mvc );
+        }
     }
     COST_MV( 0, 0 );
 
diff --git a/x264.c b/x264.c
index 3bc4028a56f9f3131612c676e7177e023fa278f5..e8febc281e0714e8d599e8f269ce8992e2a0015e 100644 (file)
--- a/x264.c
+++ b/x264.c
@@ -249,7 +249,8 @@ static void Help( x264_param_t *defaults, int b_longhelp )
     H1( "      --mvrange <integer>     Maximum motion vector length [-1 (auto)]\n" );
     H1( "      --mvrange-thread <int>  Minimum buffer between threads [-1 (auto)]\n" );
     H0( "  -m, --subme <integer>       Subpixel motion estimation and mode decision [%d]\n", defaults->analyse.i_subpel_refine );
-    H1( "                                  - 1: SAD mode decision, one qpel iteration\n"
+    H1( "                                  - 0: fullpel only (not recommended)\n"
+        "                                  - 1: SAD mode decision, one qpel iteration\n"
         "                                  - 2: SATD mode decision\n"
         "                                  - 3-5: Progressively more qpel\n"
         "                                  - 6: RD mode decision for I/P-frames\n"