--------------------------------------------------------------------------------------
引用
Index: common/common.c
===================================================================
--- common/common.c(revision 675)
+++ common/common.c(working copy)
@@ -441,6 +441,8 @@
p->analyse.i_mv_range_thread = atoi(value);
OPT2("subme", "subq")
p->analyse.i_subpel_refine = atoi(value);
+OPT2("me-prepass", "meprepass")
+p->analyse.i_me_prepass = atobool(value);
OPT("bime")
p->analyse.b_bidir_me = atobool(value);
OPT("chroma-me")
@@ -879,6 +881,7 @@
s += sprintf( s, " analyse=%#x:%#x", p->analyse.intra, p->analyse.inter );
s += sprintf( s, " me=%s", x264_motion_est_names[ p->analyse.i_me_method ] );
s += sprintf( s, " subme=%d", p->analyse.i_subpel_refine );
+s += sprintf( s, " me-prepass=%d", p->analyse.i_me_prepass );
s += sprintf( s, " brdo=%d", p->analyse.b_bframe_rdo );
s += sprintf( s, " mixed_ref=%d", p->analyse.b_mixed_references );
s += sprintf( s, " me_range=%d", p->analyse.i_me_range );
Index: encoder/me.c
===================================================================
--- encoder/me.c(revision 675)
+++ encoder/me.c(working copy)
@@ -61,6 +61,23 @@
COPY3_IF_LT( bpred_cost, cost, bpred_mx, mx, bpred_my, my ); \
}
+#define COST_MV_HPEL2( mx, my, cost ) \
+{ \
+int stride = 16; \
+uint8_t *src = h->mc.get_ref( m->p_fref, m->i_stride[0], pix, &stride, mx, my, bw, bh ); \
+cost = h->pixf.fpelcmp[i_pixel]( m->p_fenc[0], FENC_STRIDE, src, stride ) \
+ + p_cost_mvx[ mx ] + p_cost_mvy[ my ]; \
+}
+
+#define COST_MV_HPEL3( mx, my) \
+{ \
+int stride = 16; \
+uint8_t *src = h->mc.get_ref( m->p_fref, m->i_stride[0], pix, &stride, mx, my, bw, bh ); \
+int cost = h->pixf.fpelcmp[i_pixel]( m->p_fenc[0], FENC_STRIDE, src, stride ) \
+ + p_cost_mvx[ mx ] + p_cost_mvy[ my ]; \
+COPY3_IF_LT( bestcost, cost, bestx, mx, besty, my ); \
+}
+
#define COST_MV_X3_DIR( m0x, m0y, m1x, m1y, m2x, m2y, costs )\
{\
uint8_t *pix_base = p_fref + bmx + bmy*m->i_stride[0];\
@@ -177,18 +194,85 @@
pmx = ( bmx + 2 ) >> 2;
pmy = ( bmy + 2 ) >> 2;
bcost = COST_MAX;
-
+
/* try extra predictors if provided */
if( h->mb.i_subpel_refine >= 3 )
{
COST_MV_HPEL( bmx, bmy );
-for( i = 0; i < i_mvc; i++ )
+if(!h->param.analyse.i_me_prepass)
{
- const int mx = x264_clip3( mvc[0], mv_x_min*4, mv_x_max*4 );
- const int my = x264_clip3( mvc[1], mv_y_min*4, mv_y_max*4 );
- if( mx != bpred_mx || my != bpred_my )
- COST_MV_HPEL( mx, my );
+for( i = 0; i < i_mvc; i++ )
+{
+ const int mx = x264_clip3( mvc[0], mv_x_min*4, mv_x_max*4 );
+ const int my = x264_clip3( mvc[1], mv_y_min*4, mv_y_max*4 );
+ if( mx != bpred_mx || my != bpred_my )
+ COST_MV_HPEL( mx, my );
+}
+}
+else
+{
+for( i = 0; i < i_mvc; i++ )
+{
+const int mx = x264_clip3( mvc[0], mv_x_min*4, mv_x_max*4 );
+const int my = x264_clip3( mvc[1], mv_y_min*4, mv_y_max*4 );
+int doSearch = 1;
+int j;
+for(j = 0; j < i; j++)
+{
+if(mvc[0] == mvc[j][0] && mvc[1] == mvc[j][1]) doSearch = 0;
+}
+if( ( mx != bpred_mx || my != bpred_my ) && doSearch)
+{
+int bestcost;
+int bestx = mx;
+int besty = my;
+COST_MV_HPEL2( mx, my, bestcost );
+COPY3_IF_LT( bpred_cost, bestcost, bpred_mx, bestx, bpred_my, besty );
+if(bestcost < 2*bpred_cost)
+{
+int n;
+int dir = -2;
+COST_MV_HPEL2(bestx-4,besty,costs[0]);
+COST_MV_HPEL2(bestx-2,besty+4,costs[1]);
+COST_MV_HPEL2(bestx+2,besty+4,costs[2]);
+COST_MV_HPEL2(bestx+4,besty,costs[3]);
+COST_MV_HPEL2(bestx+2,besty-4,costs[4]);
+COST_MV_HPEL2(bestx-2,besty-4,costs[5]);
+COPY2_IF_LT( bestcost, costs[0], dir, 0 );
+COPY2_IF_LT( bestcost, costs[1], dir, 1 );
+COPY2_IF_LT( bestcost, costs[2], dir, 2 );
+COPY2_IF_LT( bestcost, costs[3], dir, 3 );
+COPY2_IF_LT( bestcost, costs[4], dir, 4 );
+COPY2_IF_LT( bestcost, costs[5], dir, 5 );
+if( dir != -2 )
+{
+static const int hex2[8][2] = {{-2,-4}, {-4,0}, {-2,4}, {2,4}, {4,0}, {2,-4}, {-2,-4}, {-4,0}};
+bestx += hex2[dir+1][0];
+besty += hex2[dir+1][1];
+for( n = 1; n < i_me_range && CHECK_MVRANGE4(bestx, besty); n++ )
+{
+static const int mod6[8] = {5,0,1,2,3,4,5,0};
+const int odir = mod6[dir+1];
+COST_MV_HPEL2(hex2[odir+0][0]+bestx,hex2[odir+0][1]+besty,costs[0]);
+COST_MV_HPEL2(hex2[odir+1][0]+bestx,hex2[odir+1][1]+besty,costs[1]);
+COST_MV_HPEL2(hex2[odir+2][0]+bestx,hex2[odir+2][1]+besty,costs[2]);
+dir = -2;
+COPY2_IF_LT( bestcost, costs[0], dir, odir-1 );
+COPY2_IF_LT( bestcost, costs[1], dir, odir );
+COPY2_IF_LT( bestcost, costs[2], dir, odir+1 );
+if( dir == -2 )
+break;
+bestx += hex2[dir+1][0];
+besty += hex2[dir+1][1];
+}
+}
+COST_MV_HPEL3(bestx+2,besty-2);
+COST_MV_HPEL3(bestx+2,besty);
+COST_MV_HPEL3(bestx+2,besty+2);
+COST_MV_HPEL3(bestx,besty-2);
+COST_MV_HPEL3(bestx,besty+2);
+COST_MV_HPEL3(bestx-2,besty-2);
+COST_MV_HPEL3(bestx-2,besty);
+COST_MV_HPEL3(bestx-2,besty+2);
+COPY3_IF_LT(bpred_cost,bestcost,bpred_mx,bestx,bpred_my,besty);
+}
+}
+}
}
bmx = ( bpred_mx + 2 ) >> 2;
bmy = ( bpred_my + 2 ) >> 2;
COST_MV( bmx, bmy );
}
Index: x264.c
===================================================================
--- x264.c(revision 675)
+++ x264.c(working copy)
@@ -232,7 +232,8 @@
H1( " --mvrange-thread Minimum buffer between threads [-1 (auto)]\n" );
H0( " -m, --subme Subpixel motion estimation and partition\n"
" decision quality: 1=fast, 7=best. [%d]\n", defaults->analyse.i_subpel_refine );
-H0( " --b-rdo RD based mode decision for B-frames. Requires subme 6.\n" );
+H0( " --me-prepassRun an ME prepass on predictors. Requires subme 3 or higher.\n");
+H0( " --b-rdo RD based mode decision for B-frames. Requires subme 6 or higher.\n" );
H0( " --mixed-refsDecide references on a per partition basis\n" );
H1( " --no-chroma-me Ignore chroma in motion estimation\n" );
H1( " --bime Jointly optimize both MVs in B-frames\n" );
@@ -398,6 +399,7 @@
{ "mvrange", required_argument, NULL, 0 },
{ "mvrange-thread", required_argument, NULL, 0 },
{ "subme", required_argument, NULL, 'm' },
+{ "me-prepass", no_argument,NULL, 0 },
{ "b-rdo", no_argument, NULL, 0 },
{ "mixed-refs", no_argument,NULL, 0 },
{ "no-chroma-me", no_argument, NULL, 0 },
Index: x264.h
===================================================================
--- x264.h(revision 675)
+++ x264.h(working copy)
@@ -220,6 +220,7 @@
int i_mv_range; /* maximum length of a mv (in pixels). -1 = auto, based on level */
int i_mv_range_thread; /* minimum space between threads. -1 = auto, based on number of threads. */
int i_subpel_refine; /* subpixel motion estimation quality */
+int i_me_prepass; /* run an ME prepass on predictors */
int b_bidir_me; /* jointly optimize both MVs in B-frames */
int b_chroma_me; /* chroma ME for subpel and mode decision in P-frames */
int b_bframe_rdo; /* RD based mode decision for B-frames */