Commit db80497d authored by Loren Merritt's avatar Loren Merritt

temporal predictors for 16x16 motion search.



git-svn-id: svn://svn.videolan.org/x264/trunk@314 df754926-b1dd-0310-bc7b-ec298dee348c
parent 7e165477
......@@ -631,59 +631,77 @@ void x264_mb_load_mv_direct8x8( x264_t *h, int idx )
}
/* This just improves encoder performance, it's not part of the spec */
void x264_mb_predict_mv_ref16x16( x264_t *h, int i_list, int i_ref, int mvc[5][2], int *i_mvc )
void x264_mb_predict_mv_ref16x16( x264_t *h, int i_list, int i_ref, int mvc[8][2], int *i_mvc )
{
int16_t (*mvr)[2] = h->mb.mvr[i_list][i_ref];
int i = 0;
/* temporal */
if( h->sh.i_type == SLICE_TYPE_B )
#define SET_MVP(mvp) { \
mvc[i][0] = mvp[0]; \
mvc[i][1] = mvp[1]; \
i++; \
}
/* b_direct */
if( h->sh.i_type == SLICE_TYPE_B
&& h->mb.cache.ref[i_list][x264_scan8[12]] == i_ref )
{
if( h->mb.cache.ref[i_list][x264_scan8[12]] == i_ref )
{
/* FIXME: use direct_mv to be clearer? */
int16_t *mvp = h->mb.cache.mv[i_list][x264_scan8[12]];
mvc[i][0] = mvp[0];
mvc[i][1] = mvp[1];
i++;
}
SET_MVP( h->mb.cache.mv[i_list][x264_scan8[12]] );
}
/* spatial */
/* spatial predictors */
if( h->mb.i_neighbour & MB_LEFT )
{
int i_mb_l = h->mb.i_mb_xy - 1;
/* skip MBs didn't go through the whole search process, so mvr is undefined */
if( !IS_SKIP( h->mb.type[i_mb_l] ) )
{
mvc[i][0] = mvr[i_mb_l][0];
mvc[i][1] = mvr[i_mb_l][1];
i++;
}
SET_MVP( mvr[i_mb_l] );
}
if( h->mb.i_neighbour & MB_TOP )
{
int i_mb_t = h->mb.i_mb_xy - h->mb.i_mb_stride;
if( !IS_SKIP( h->mb.type[i_mb_t] ) )
{
mvc[i][0] = mvr[i_mb_t][0];
mvc[i][1] = mvr[i_mb_t][1];
i++;
}
SET_MVP( mvr[i_mb_t] );
if( h->mb.i_neighbour & MB_TOPLEFT && !IS_SKIP( h->mb.type[i_mb_t - 1] ) )
{
mvc[i][0] = mvr[i_mb_t - 1][0];
mvc[i][1] = mvr[i_mb_t - 1][1];
i++;
}
SET_MVP( mvr[i_mb_t-1] );
if( h->mb.i_mb_x < h->mb.i_mb_stride - 1 && !IS_SKIP( h->mb.type[i_mb_t + 1] ) )
{
mvc[i][0] = mvr[i_mb_t + 1][0];
mvc[i][1] = mvr[i_mb_t + 1][1];
i++;
SET_MVP( mvr[i_mb_t+1] );
}
#undef SET_MVP
/* temporal predictors */
if( h->fref0[0]->i_ref[0] > 0 )
{
x264_frame_t *l0 = h->fref0[0];
int ref_col_cur, ref_col_prev = -1;
int scale = 0;
#define SET_TMVP(dx, dy) { \
int i_b4 = h->mb.i_b4_xy + dx*4 + dy*4*h->mb.i_b4_stride; \
int i_b8 = h->mb.i_b8_xy + dx*2 + dy*2*h->mb.i_b8_stride; \
ref_col_cur = l0->ref[0][i_b8]; \
if( ref_col_cur >= 0 ) \
{ \
/* TODO: calc once per frame and tablize? */\
if( ref_col_cur != ref_col_prev ) \
scale = 256 * (h->fenc->i_poc - h->fref0[i_ref]->i_poc) \
/ (l0->i_poc - l0->ref_poc[0][ref_col_cur]); \
mvc[i][0] = l0->mv[0][i_b4][0] * scale / 256; \
mvc[i][1] = l0->mv[0][i_b4][1] * scale / 256; \
i++; \
ref_col_prev = ref_col_cur; \
} \
}
SET_TMVP(0,0);
if( h->mb.i_mb_x < h->sps->i_mb_width-1 )
SET_TMVP(1,0);
if( h->mb.i_mb_y < h->sps->i_mb_height-1 )
SET_TMVP(0,1);
#undef SET_TMVP
}
*i_mvc = i;
}
......
......@@ -213,7 +213,7 @@ void x264_mb_load_mv_direct8x8( x264_t *h, int idx );
* set mvc with D_16x16 prediction.
* uses all neighbors, even those that didn't end up using this ref.
* h->mb. need only valid values from other blocks */
void x264_mb_predict_mv_ref16x16( x264_t *h, int i_list, int i_ref, int mvc[5][2], int *i_mvc );
void x264_mb_predict_mv_ref16x16( x264_t *h, int i_list, int i_ref, int mvc[8][2], int *i_mvc );
int x264_mb_predict_intra4x4_mode( x264_t *h, int idx );
......
......@@ -675,7 +675,7 @@ static void x264_mb_analyse_inter_p16x16( x264_t *h, x264_mb_analysis_t *a )
{
x264_me_t m;
int i_ref;
int mvc[4][2], i_mvc;
int mvc[7][2], i_mvc;
int i_fullpel_thresh = INT_MAX;
int *p_fullpel_thresh = h->i_ref0>1 ? &i_fullpel_thresh : NULL;
......@@ -1053,7 +1053,7 @@ static void x264_mb_analyse_inter_b16x16( x264_t *h, x264_mb_analysis_t *a )
x264_me_t m;
int i_ref;
int mvc[5][2], i_mvc;
int mvc[8][2], i_mvc;
int i_fullpel_thresh = INT_MAX;
int *p_fullpel_thresh = h->i_ref0>1 ? &i_fullpel_thresh : NULL;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment