Commit 9daf3154 authored by Adrian Grange's avatar Adrian Grange Committed by Paul Wilkins
Browse files

Superblock encoding order

This is the first patch to add superblock (32x32) coding
order capabilities. It does not yet do any mode selection
at the SB level, that will follow in a further patch.

This patch encodes rows of SBs rather than
MBs, each SB contains 2x2 MBs.

Two intra prediction modes have been disabled since they
require reconstructed data for the above-right MB which
may not have been encoded yet (e.g. for the bottom right
MB in each SB).

Results on the one test clip I have tried (720p GIPS clip)
suggest that it is somewhere around 0.2dB worse than the
baseline version, so there may be bugs.

It has been tested with no experiments enabled and with
the following 3 experiments enabled:
  --enable-enhanced_interp
  --enable-high_precision_mv
  --enable-sixteenth_subpel_uv
in each case the decode buffer matches the recon buffer
(using "cmp" to compare the dumped/decoded frames).
Note: Testing these experiments individually created
errors.

Some problems were found with other experiments but it
is unclear what state these experiments are in:
  --enable-comp_intra_pred
  --enable-newentropy
  --enable-uvintra

This code has not been extensively tested yet, so there
is every likelihood that further bugs remain. I also
intend to do some code cleanup & refactoring in tandem
with the next patch that adds the 32x32 modes.

Change-Id: I1eba7f740a70b3510df58db53464535ef881b4d9
parent 78ecbc98
...@@ -224,6 +224,7 @@ EXPERIMENT_LIST=" ...@@ -224,6 +224,7 @@ EXPERIMENT_LIST="
sixteenth_subpel_uv sixteenth_subpel_uv
comp_intra_pred comp_intra_pred
newentropy newentropy
superblocks
" "
CONFIG_LIST=" CONFIG_LIST="
external_build external_build
......
...@@ -337,6 +337,9 @@ typedef struct MacroBlockD ...@@ -337,6 +337,9 @@ typedef struct MacroBlockD
#if CONFIG_RUNTIME_CPU_DETECT #if CONFIG_RUNTIME_CPU_DETECT
struct VP8_COMMON_RTCD *rtcd; struct VP8_COMMON_RTCD *rtcd;
#endif #endif
int mb_index; // Index of the MB in the SB (0..3)
} MACROBLOCKD; } MACROBLOCKD;
......
...@@ -81,7 +81,7 @@ void vp8_find_near_mvs ...@@ -81,7 +81,7 @@ void vp8_find_near_mvs
else else
cnt[CNT_INTRA] += 2; cnt[CNT_INTRA] += 2;
} }
/* Process above left or the one frome last frame */ /* Process above left or the one from last frame */
if ( aboveleft->mbmi.ref_frame != INTRA_FRAME|| if ( aboveleft->mbmi.ref_frame != INTRA_FRAME||
(lf_here->mbmi.ref_frame==LAST_FRAME && refframe == LAST_FRAME)) (lf_here->mbmi.ref_frame==LAST_FRAME && refframe == LAST_FRAME))
{ {
......
...@@ -666,7 +666,6 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, ...@@ -666,7 +666,6 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
const int mis = pbi->common.mode_info_stride; const int mis = pbi->common.mode_info_stride;
MACROBLOCKD *const xd = & pbi->mb; MACROBLOCKD *const xd = & pbi->mb;
int index = mb_row * pbi->common.mb_cols + mb_col;
int_mv *const mv = & mbmi->mv; int_mv *const mv = & mbmi->mv;
int mb_to_left_edge; int mb_to_left_edge;
int mb_to_right_edge; int mb_to_right_edge;
...@@ -1017,91 +1016,75 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, ...@@ -1017,91 +1016,75 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
void vp8_decode_mode_mvs(VP8D_COMP *pbi) void vp8_decode_mode_mvs(VP8D_COMP *pbi)
{ {
MODE_INFO *mi = pbi->common.mi; int i;
VP8_COMMON *cm = &pbi->common;
MODE_INFO *prev_mi = pbi->common.prev_mi; MODE_INFO *mi = cm->mi;
int sb_row, sb_col;
int sb_rows = (cm->mb_rows + 1)>>1;
int sb_cols = (cm->mb_cols + 1)>>1;
int row_delta[4] = { 0, +1, 0, -1};
int col_delta[4] = {+1, -1, +1, +1};
int mb_row = -1; MODE_INFO *prev_mi = cm->prev_mi;
#if 0
FILE *statsfile;
statsfile = fopen("decsegmap.stt", "a");
fprintf(statsfile, "\n" );
#endif
mb_mode_mv_init(pbi); mb_mode_mv_init(pbi);
#if CONFIG_QIMODE #if CONFIG_QIMODE
if(pbi->common.frame_type==KEY_FRAME && !pbi->common.kf_ymode_probs_update) if(cm->frame_type==KEY_FRAME && !cm->kf_ymode_probs_update)
{ {
pbi->common.kf_ymode_probs_index = vp8_read_literal(&pbi->bc, 3); cm->kf_ymode_probs_index = vp8_read_literal(&pbi->bc, 3);
} }
#endif #endif
while (++mb_row < pbi->common.mb_rows) for (sb_row=0; sb_row<sb_rows; sb_row++)
{ {
int mb_col = -1; int mb_col = 0;
int mb_to_top_edge; int mb_row = (sb_row <<1);
int mb_to_bottom_edge;
pbi->mb.mb_to_top_edge =
mb_to_top_edge = -((mb_row * 16)) << 3;
mb_to_top_edge -= LEFT_TOP_MARGIN;
pbi->mb.mb_to_bottom_edge =
mb_to_bottom_edge = ((pbi->common.mb_rows - 1 - mb_row) * 16) << 3;
mb_to_bottom_edge += RIGHT_BOTTOM_MARGIN;
#if 0 for (sb_col=0; sb_col<sb_cols; sb_col++)
fprintf(statsfile, "\n" );
#endif
while (++mb_col < pbi->common.mb_cols)
{ {
/*read_mb_modes_mv(pbi, xd->mode_info_context, &xd->mode_info_context->mbmi, mb_row, mb_col);*/ for ( i=0; i<4; i++ )
if(pbi->common.frame_type == KEY_FRAME)
{
//printf("<%d %d> \n", mb_row, mb_col);
vp8_kfread_modes(pbi, mi, mb_row, mb_col);
}
else
{ {
read_mb_modes_mv(pbi, mi, &mi->mbmi, int mb_to_top_edge;
prev_mi, int mb_to_bottom_edge;
mb_row, mb_col);
}
//printf("%3d", mi->mbmi.mode); int dy = row_delta[i];
int dx = col_delta[i];
int offset_extended = dy * cm->mode_info_stride + dx;
/* if ((mb_row >= cm->mb_rows) || (mb_col >= cm->mb_cols))
if(pbi->common.current_video_frame==7) {
{ /* next macroblock */
FILE *fmode=fopen("kfmode.txt", "a"); mb_row += dy;
fprintf(fmode, "%3d:%3d:%d\n",mb_row, mb_col, mi->mbmi.mode); mb_col += dx;
fclose(fmode); mi += offset_extended;
prev_mi += offset_extended;
continue;
}
}*/ pbi->mb.mb_to_top_edge = mb_to_top_edge = -((mb_row * 16)) << 3;
/* mb_to_top_edge -= LEFT_TOP_MARGIN;
if(mi->mbmi.mode==I8X8_PRED)
{
printf("F%3d:%d:%d\n", pbi->common.current_video_frame, mb_row, mb_col);
}
*/
#if 0
fprintf(statsfile, "%2d%2d%2d ",
mi->mbmi.segment_id, mi->mbmi.ref_frame, mi->mbmi.mode );
#endif
prev_mi++;
mi++; /* next macroblock */
}
// printf("\n");
prev_mi++;
mi++; /* skip left predictor each row */
}
#if 0 pbi->mb.mb_to_bottom_edge =
fclose(statsfile); mb_to_bottom_edge =
#endif ((pbi->common.mb_rows - 1 - mb_row) * 16) << 3;
mb_to_bottom_edge += RIGHT_BOTTOM_MARGIN;
if(cm->frame_type == KEY_FRAME)
vp8_kfread_modes(pbi, mi, mb_row, mb_col);
else
read_mb_modes_mv(pbi, mi, &mi->mbmi, prev_mi, mb_row,
mb_col);
/* next macroblock */
mb_row += dy;
mb_col += dx;
mi += offset_extended;
prev_mi += offset_extended;
}
}
mi += cm->mode_info_stride + (1 - (cm->mb_cols & 0x1));
prev_mi += cm->mode_info_stride + (1 - (cm->mb_cols & 0x1));
}
} }
...@@ -240,8 +240,6 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, ...@@ -240,8 +240,6 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
} }
#endif #endif
if (xd->segmentation_enabled) if (xd->segmentation_enabled)
mb_init_dequantizer(pbi, xd); mb_init_dequantizer(pbi, xd);
...@@ -256,10 +254,14 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, ...@@ -256,10 +254,14 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
RECON_INVOKE(&pbi->common.rtcd.recon, RECON_INVOKE(&pbi->common.rtcd.recon,
build_intra_predictors_mby)(xd); build_intra_predictors_mby)(xd);
} }
#if 0
// Intra-modes requiring recon data from top-right
// MB have been temporarily disabled.
else else
{ {
vp8_intra_prediction_down_copy(xd); vp8_intra_prediction_down_copy(xd);
} }
#endif
} }
} }
else else
...@@ -431,7 +433,6 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, ...@@ -431,7 +433,6 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
(xd->qcoeff+16*16, xd->block[16].dequant, (xd->qcoeff+16*16, xd->block[16].dequant,
xd->predictor+16*16, xd->dst.u_buffer, xd->dst.v_buffer, xd->predictor+16*16, xd->dst.u_buffer, xd->dst.v_buffer,
xd->dst.uv_stride, xd->eobs+16); xd->dst.uv_stride, xd->eobs+16);
} }
...@@ -459,102 +460,139 @@ static int get_delta_q(vp8_reader *bc, int prev, int *q_update) ...@@ -459,102 +460,139 @@ static int get_delta_q(vp8_reader *bc, int prev, int *q_update)
FILE *vpxlog = 0; FILE *vpxlog = 0;
#endif #endif
/* Decode a row of Superblocks (2x2 region of MBs) */
static void static void
decode_mb_row(VP8D_COMP *pbi, VP8_COMMON *pc, int mb_row, MACROBLOCKD *xd) decode_sb_row(VP8D_COMP *pbi, VP8_COMMON *pc, int mbrow, MACROBLOCKD *xd)
{ {
int i;
int sb_col;
int mb_row, mb_col;
int recon_yoffset, recon_uvoffset; int recon_yoffset, recon_uvoffset;
int mb_col;
int ref_fb_idx = pc->lst_fb_idx; int ref_fb_idx = pc->lst_fb_idx;
int dst_fb_idx = pc->new_fb_idx; int dst_fb_idx = pc->new_fb_idx;
int recon_y_stride = pc->yv12_fb[ref_fb_idx].y_stride; int recon_y_stride = pc->yv12_fb[ref_fb_idx].y_stride;
int recon_uv_stride = pc->yv12_fb[ref_fb_idx].uv_stride; int recon_uv_stride = pc->yv12_fb[ref_fb_idx].uv_stride;
int row_delta[4] = { 0, +1, 0, -1};
int col_delta[4] = {+1, -1, +1, +1};
int sb_cols = (pc->mb_cols + 1)>>1;
ENTROPY_CONTEXT_PLANES left_context[2];
vpx_memset(&pc->left_context, 0, sizeof(pc->left_context)); // For a SB there are 2 left contexts, each pertaining to a MB row within
recon_yoffset = mb_row * recon_y_stride * 16; vpx_memset(left_context, 0, sizeof(left_context));
recon_uvoffset = mb_row * recon_uv_stride * 8;
/* reset above block coeffs */
xd->above_context = pc->above_context;
xd->up_available = (mb_row != 0);
xd->mb_to_top_edge = -((mb_row * 16)) << 3; mb_row = mbrow;
xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3; mb_col = 0;
for (mb_col = 0; mb_col < pc->mb_cols; mb_col++) for (sb_col=0; sb_col<sb_cols; sb_col++)
{ {
/* Distance of Mb to the various image edges. // Process the 4 MBs within the SB in the order:
* These are specified to 8th pel as they are always compared to values // top-left, top-right, bottom-left, bottom-right
* that are in 1/8th pel units for ( i=0; i<4; i++ )
*/ {
xd->mb_to_left_edge = -((mb_col * 16) << 3); int dy = row_delta[i];
xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3; int dx = col_delta[i];
int offset_extended = dy * xd->mode_info_stride + dx;
update_blockd_bmi(xd); if ((mb_row >= pc->mb_rows) || (mb_col >= pc->mb_cols))
{
// MB lies outside frame, skip on to next
mb_row += dy;
mb_col += dx;
xd->mode_info_context += offset_extended;
continue;
}
xd->dst.y_buffer = pc->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset; #ifdef DEC_DEBUG
xd->dst.u_buffer = pc->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset; dec_debug = (pc->current_video_frame==0 && mb_row==0 && mb_col==0);
xd->dst.v_buffer = pc->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset; #endif
// Copy in the appropriate left context for this MB row
vpx_memcpy (&pc->left_context,
&left_context[i>>1],
sizeof(ENTROPY_CONTEXT_PLANES));
xd->left_available = (mb_col != 0); // Set above context pointer
xd->above_context = pc->above_context + mb_col;
/* Select the appropriate reference frame for this MB */ /* Distance of Mb to the various image edges.
if (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME) * These are specified to 8th pel as they are always compared to
ref_fb_idx = pc->lst_fb_idx; * values that are in 1/8th pel units
else if (xd->mode_info_context->mbmi.ref_frame == GOLDEN_FRAME) */
ref_fb_idx = pc->gld_fb_idx; xd->mb_to_top_edge = -((mb_row * 16)) << 3;
else xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;
ref_fb_idx = pc->alt_fb_idx;
xd->pre.y_buffer = pc->yv12_fb[ref_fb_idx].y_buffer + recon_yoffset; xd->mb_to_left_edge = -((mb_col * 16) << 3);
xd->pre.u_buffer = pc->yv12_fb[ref_fb_idx].u_buffer + recon_uvoffset; xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
xd->pre.v_buffer = pc->yv12_fb[ref_fb_idx].v_buffer + recon_uvoffset;
if (xd->mode_info_context->mbmi.second_ref_frame) xd->up_available = (mb_row != 0);
{ xd->left_available = (mb_col != 0);
int second_ref_fb_idx;
update_blockd_bmi(xd);
recon_yoffset = (mb_row * recon_y_stride * 16) + (mb_col * 16);
recon_uvoffset = (mb_row * recon_uv_stride * 8) + (mb_col * 8);
xd->dst.y_buffer = pc->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
xd->dst.u_buffer = pc->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
xd->dst.v_buffer = pc->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
/* Select the appropriate reference frame for this MB */ /* Select the appropriate reference frame for this MB */
if (xd->mode_info_context->mbmi.second_ref_frame == LAST_FRAME) if (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME)
second_ref_fb_idx = pc->lst_fb_idx; ref_fb_idx = pc->lst_fb_idx;
else if (xd->mode_info_context->mbmi.second_ref_frame == GOLDEN_FRAME) else if (xd->mode_info_context->mbmi.ref_frame == GOLDEN_FRAME)
second_ref_fb_idx = pc->gld_fb_idx; ref_fb_idx = pc->gld_fb_idx;
else else
second_ref_fb_idx = pc->alt_fb_idx; ref_fb_idx = pc->alt_fb_idx;
xd->second_pre.y_buffer = pc->yv12_fb[second_ref_fb_idx].y_buffer + recon_yoffset; xd->pre.y_buffer = pc->yv12_fb[ref_fb_idx].y_buffer +recon_yoffset;
xd->second_pre.u_buffer = pc->yv12_fb[second_ref_fb_idx].u_buffer + recon_uvoffset; xd->pre.u_buffer = pc->yv12_fb[ref_fb_idx].u_buffer +recon_uvoffset;
xd->second_pre.v_buffer = pc->yv12_fb[second_ref_fb_idx].v_buffer + recon_uvoffset; xd->pre.v_buffer = pc->yv12_fb[ref_fb_idx].v_buffer +recon_uvoffset;
}
if (xd->mode_info_context->mbmi.ref_frame != INTRA_FRAME) if (xd->mode_info_context->mbmi.second_ref_frame)
{ {
/* propagate errors from reference frames */ int second_ref_fb_idx;
xd->corrupted |= pc->yv12_fb[ref_fb_idx].corrupted;
} /* Select the appropriate reference frame for this MB */
if (xd->mode_info_context->mbmi.second_ref_frame == LAST_FRAME)
second_ref_fb_idx = pc->lst_fb_idx;
else if (xd->mode_info_context->mbmi.second_ref_frame ==
GOLDEN_FRAME)
second_ref_fb_idx = pc->gld_fb_idx;
else
second_ref_fb_idx = pc->alt_fb_idx;
xd->second_pre.y_buffer =
pc->yv12_fb[second_ref_fb_idx].y_buffer + recon_yoffset;
xd->second_pre.u_buffer =
pc->yv12_fb[second_ref_fb_idx].u_buffer + recon_uvoffset;
xd->second_pre.v_buffer =
pc->yv12_fb[second_ref_fb_idx].v_buffer + recon_uvoffset;
}
#ifdef DEC_DEBUG if (xd->mode_info_context->mbmi.ref_frame != INTRA_FRAME)
dec_debug = (pc->current_video_frame==1 && mb_row==4 && mb_col==0); {
#endif /* propagate errors from reference frames */
decode_macroblock(pbi, xd, mb_row * pc->mb_cols + mb_col); xd->corrupted |= pc->yv12_fb[ref_fb_idx].corrupted;
}
/* check if the boolean decoder has suffered an error */ decode_macroblock(pbi, xd, mb_row * pc->mb_cols + mb_col);
xd->corrupted |= vp8dx_bool_error(xd->current_bc);
recon_yoffset += 16;
recon_uvoffset += 8;
++xd->mode_info_context; /* next mb */ /* check if the boolean decoder has suffered an error */
xd->corrupted |= vp8dx_bool_error(xd->current_bc);
xd->above_context++; // Store the modified left context for the MB row locally
vpx_memcpy (&left_context[i>>1],
&pc->left_context,
sizeof(ENTROPY_CONTEXT_PLANES));
// skip to next MB
xd->mode_info_context += offset_extended;
mb_row += dy;
mb_col += dx;
}
} }
/* adjust to the next row of mbs */ /* skip prediction column */
vp8_extend_mb_row( xd->mode_info_context += 1 - (pc->mb_cols & 0x1) + xd->mode_info_stride;
&pc->yv12_fb[dst_fb_idx],
xd->dst.y_buffer + 16, xd->dst.u_buffer + 8, xd->dst.v_buffer + 8
);
++xd->mode_info_context; /* skip prediction column */
} }
static unsigned int read_partition_size(const unsigned char *cx_size) static unsigned int read_partition_size(const unsigned char *cx_size)
...@@ -797,8 +835,6 @@ int vp8_decode_frame(VP8D_COMP *pbi) ...@@ -797,8 +835,6 @@ int vp8_decode_frame(VP8D_COMP *pbi)
if (Width != pc->Width || Height != pc->Height) if (Width != pc->Width || Height != pc->Height)
{ {
int prev_mb_rows = pc->mb_rows;
if (pc->Width <= 0) if (pc->Width <= 0)
{ {
pc->Width = Width; pc->Width = Width;
...@@ -1228,10 +1264,10 @@ int vp8_decode_frame(VP8D_COMP *pbi) ...@@ -1228,10 +1264,10 @@ int vp8_decode_frame(VP8D_COMP *pbi)
// Resset the macroblock mode info context to the start of the list // Resset the macroblock mode info context to the start of the list
xd->mode_info_context = pc->mi; xd->mode_info_context = pc->mi;
/* Decode a row of macro blocks */ /* Decode a row of superblocks */
for (mb_row = 0; mb_row < pc->mb_rows; mb_row++) for (mb_row = 0; mb_row < pc->mb_rows; mb_row+=2)
{ {
decode_mb_row(pbi, pc, mb_row, xd); decode_sb_row(pbi, pc, mb_row, xd);
} }
corrupt_tokens |= xd->corrupted; corrupt_tokens |= xd->corrupted;
......
...@@ -477,7 +477,8 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign ...@@ -477,7 +477,8 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
} }
#if CONFIG_DEBUG #if CONFIG_DEBUG
vp8_recon_write_yuv_frame("recon.yuv", cm->frame_to_show); if(cm->show_frame)
vp8_recon_write_yuv_frame("recon.yuv", cm->frame_to_show);
#endif #endif
vp8_clear_system_state(); vp8_clear_system_state();
......
This diff is collapsed.
...@@ -61,14 +61,31 @@ typedef struct ...@@ -61,14 +61,31 @@ typedef struct
} bmi[16]; } bmi[16];
} PARTITION_INFO; } PARTITION_INFO;
// Structure to hold snapshot of coding context during the mode picking process
// TODO Do we need all of these?
typedef struct typedef struct
{ {
DECLARE_ALIGNED(16, short, src_diff[400]); // 16x16 Y 8x8 U 8x8 V 4x4 2nd Y MODE_INFO mic;
PARTITION_INFO partition_info;
int_mv best_ref_mv;
int rate;
int distortion;
int intra_error;
int best_mode_index;
int rddiv;
int rdmult;
} PICK_MODE_CONTEXT;
typedef struct
{
DECLARE_ALIGNED(16, short, src_diff[400]); // 16x16 Y 8x8 U 8x8 V 4x4 2nd Y
DECLARE_ALIGNED(16, short, coeff[400]); // 16x16 Y 8x8 U 8x8 V 4x4 2nd Y DECLARE_ALIGNED(16, short, coeff[400]); // 16x16 Y 8x8 U 8x8 V 4x4 2nd Y
DECLARE_ALIGNED(16, unsigned char, thismb[256]); DECLARE_ALIGNED(16, unsigned char, thismb[256]); // 16x16 Y
unsigned char *thismb_ptr; unsigned char *thismb_ptr;
// 16 Y blocks, 4 U blocks, 4 V blocks, 1 DC 2nd order block each with 16 entries // 16 Y blocks, 4 U blocks, 4 V blocks,
// 1 DC 2nd order block each with 16 entries
BLOCK block[25]; BLOCK block[25];
YV12_BUFFER_CONFIG src; YV12_BUFFER_CONFIG src;
...@@ -113,7 +130,6 @@ typedef struct ...@@ -113,7 +130,6 @@ typedef struct
int mv_row_min; int mv_row_min;
int mv_row_max; int mv_row_max;
int vector_range; // Used to monitor limiting range of recent vectors to guide search.
int skip; int skip;
int encode_breakout; int encode_breakout;
...@@ -135,6 +151,16 @@ typedef struct ...@@ -135,6 +151,16 @@ typedef struct
int optimize; int optimize;
int q_index; int q_index;
int encode_as_sb;
// Structure to hold context for each of the 4 MBs within a SB:
// when encoded as 4 independent MBs:
PICK_MODE_CONTEXT mb_context[4];
#if CONFIG_SUPERBLOCKS
// when 4 MBs share coding parameters: