Commit 532bb60a authored by Simon Horlick's avatar Simon Horlick Committed by Fiona Glaser
Browse files

MBAFF: Track what interlace decision the decoder is using

parent 313d3770
......@@ -623,8 +623,10 @@ struct x264_t
int i_mb_topleft_y;
int i_mb_topright_y;
x264_left_table_t *left_index_table;
int i_mb_top_mbpair_xy;
int topleft_partition;
int b_allow_skip;
int field_decoding_flag;
/**** thread synchronization ends here ****/
/* subsequent variables are either thread-local or constant,
......@@ -748,7 +750,6 @@ struct x264_t
/* number of neighbors (top and left) that used 8x8 dct */
int i_neighbour_transform_size;
int i_neighbour_interlaced;
/* neighbor CBPs */
int i_cbp_top;
......
......@@ -458,7 +458,7 @@ void x264_macroblock_thread_init( x264_t *h )
(h->sh.i_type == SLICE_TYPE_B && h->mb.i_subpel_refine >= 9));
h->mb.b_dct_decimate = h->sh.i_type == SLICE_TYPE_B ||
(h->param.analyse.b_dct_decimate && h->sh.i_type != SLICE_TYPE_I);
h->mb.i_mb_prev_xy = -1;
/* fdec: fenc:
* yyyyyyy
......@@ -623,6 +623,7 @@ static void inline x264_macroblock_cache_load_neighbours( x264_t *h, int mb_x, i
h->mb.i_mb_topright_xy = -1;
h->mb.i_mb_topleft_y = -1;
h->mb.i_mb_topright_y = -1;
h->mb.i_mb_top_mbpair_xy = h->mb.i_mb_xy - 2*h->mb.i_mb_stride;
h->mb.i_mb_type_top = -1;
h->mb.i_mb_type_left[0] = h->mb.i_mb_type_left[1] = -1;
h->mb.i_mb_type_topleft = -1;
......@@ -884,9 +885,6 @@ void x264_macroblock_cache_load( x264_t *h, int mb_x, int mb_y )
{
h->mb.pic.i_fref[0] = h->i_ref[0] << h->mb.b_interlaced;
h->mb.pic.i_fref[1] = h->i_ref[1] << h->mb.b_interlaced;
h->mb.cache.i_neighbour_interlaced =
!!(h->mb.i_neighbour & MB_LEFT && h->mb.field[left[0]])
+ !!(h->mb.i_neighbour & MB_TOP && h->mb.field[top]);
}
if( !h->param.b_interlaced )
......@@ -1109,11 +1107,17 @@ void x264_macroblock_cache_load( x264_t *h, int mb_x, int mb_y )
}
}
if( h->sh.b_mbaff && mb_x == 0 && !(mb_y&1) && mb_y > 0 )
h->mb.field_decoding_flag = h->mb.field[h->mb.i_mb_xy - h->mb.i_mb_stride];
/* Check whether skip here would cause decoder to predict interlace mode incorrectly.
* FIXME: It might be better to change the interlace type rather than forcing a skip to be non-skip. */
h->mb.b_allow_skip = 1;
if( h->sh.b_mbaff )
{
if( h->mb.b_interlaced != h->mb.field_decoding_flag &&
h->mb.i_mb_prev_xy >= 0 && IS_SKIP(h->mb.type[h->mb.i_mb_prev_xy]) )
h->mb.b_allow_skip = 0;
if( (mb_y&1) && IS_SKIP(h->mb.type[h->mb.i_mb_xy - h->mb.i_mb_stride]) )
{
if( h->mb.i_neighbour & MB_LEFT )
......
......@@ -66,15 +66,31 @@ static inline void x264_cabac_mb_type_intra( x264_t *h, x264_cabac_t *cb, int i_
}
}
#if !RDO_SKIP_BS
static void x264_cabac_field_decoding_flag( x264_t *h, x264_cabac_t *cb )
{
int ctx = 0;
ctx += h->mb.field_decoding_flag & !!h->mb.i_mb_x;
ctx += (h->mb.i_mb_top_mbpair_xy >= 0
&& h->mb.slice_table[h->mb.i_mb_top_mbpair_xy] == h->sh.i_first_mb
&& h->mb.field[h->mb.i_mb_top_mbpair_xy]);
x264_cabac_encode_decision_noup( cb, 70 + ctx, h->mb.b_interlaced );
h->mb.field_decoding_flag = h->mb.b_interlaced;
}
#endif
static void x264_cabac_mb_type( x264_t *h, x264_cabac_t *cb )
{
const int i_mb_type = h->mb.i_type;
#if !RDO_SKIP_BS
if( h->sh.b_mbaff &&
(!(h->mb.i_mb_y & 1) || IS_SKIP(h->mb.type[h->mb.i_mb_xy - h->mb.i_mb_stride])) )
{
x264_cabac_encode_decision_noup( cb, 70 + h->mb.cache.i_neighbour_interlaced, h->mb.b_interlaced );
x264_cabac_field_decoding_flag( h, cb );
}
#endif
if( h->sh.i_type == SLICE_TYPE_I )
{
......
......@@ -2015,6 +2015,7 @@ static int x264_slice_write( x264_t *h )
last_emu_check = h->out.bs.p;
h->mb.i_last_qp = h->sh.i_qp;
h->mb.i_last_dqp = 0;
h->mb.field_decoding_flag = 0;
i_mb_y = h->sh.i_first_mb / h->mb.i_mb_width;
i_mb_x = h->sh.i_first_mb % h->mb.i_mb_width;
......
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