Index: source/libvpx/vp9/decoder/vp9_decodeframe.c |
diff --git a/source/libvpx/vp9/decoder/vp9_decodeframe.c b/source/libvpx/vp9/decoder/vp9_decodeframe.c |
index 8840750fdbf106c5af93c2a37c701976a62d10d9..eb9b7971074419e5e08c3f60744e0fcea0c36a64 100644 |
--- a/source/libvpx/vp9/decoder/vp9_decodeframe.c |
+++ b/source/libvpx/vp9/decoder/vp9_decodeframe.c |
@@ -276,14 +276,14 @@ static void inverse_transform_block(MACROBLOCKD* xd, int plane, int block, |
#endif // CONFIG_VP9_HIGHBITDEPTH |
if (eob == 1) { |
- vpx_memset(dqcoeff, 0, 2 * sizeof(dqcoeff[0])); |
+ memset(dqcoeff, 0, 2 * sizeof(dqcoeff[0])); |
} else { |
if (tx_type == DCT_DCT && tx_size <= TX_16X16 && eob <= 10) |
- vpx_memset(dqcoeff, 0, 4 * (4 << tx_size) * sizeof(dqcoeff[0])); |
+ memset(dqcoeff, 0, 4 * (4 << tx_size) * sizeof(dqcoeff[0])); |
else if (tx_size == TX_32X32 && eob <= 34) |
- vpx_memset(dqcoeff, 0, 256 * sizeof(dqcoeff[0])); |
+ memset(dqcoeff, 0, 256 * sizeof(dqcoeff[0])); |
else |
- vpx_memset(dqcoeff, 0, (16 << (tx_size << 1)) * sizeof(dqcoeff[0])); |
+ memset(dqcoeff, 0, (16 << (tx_size << 1)) * sizeof(dqcoeff[0])); |
} |
} |
} |
@@ -293,8 +293,7 @@ struct intra_args { |
MACROBLOCKD *xd; |
FRAME_COUNTS *counts; |
vp9_reader *r; |
- const int16_t *const y_dequant; |
- const int16_t *const uv_dequant; |
+ int seg_id; |
}; |
static void predict_and_reconstruct_intra_block(int plane, int block, |
@@ -304,11 +303,9 @@ static void predict_and_reconstruct_intra_block(int plane, int block, |
VP9_COMMON *const cm = args->cm; |
MACROBLOCKD *const xd = args->xd; |
struct macroblockd_plane *const pd = &xd->plane[plane]; |
- MODE_INFO *const mi = xd->mi[0].src_mi; |
+ MODE_INFO *const mi = xd->mi[0]; |
const PREDICTION_MODE mode = (plane == 0) ? get_y_mode(mi, block) |
: mi->mbmi.uv_mode; |
- const int16_t *const dequant = (plane == 0) ? args->y_dequant |
- : args->uv_dequant; |
int x, y; |
uint8_t *dst; |
txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &x, &y); |
@@ -322,7 +319,7 @@ static void predict_and_reconstruct_intra_block(int plane, int block, |
if (!mi->mbmi.skip) { |
const int eob = vp9_decode_block_tokens(cm, xd, args->counts, plane, block, |
plane_bsize, x, y, tx_size, |
- args->r, dequant); |
+ args->r, args->seg_id); |
inverse_transform_block(xd, plane, block, tx_size, dst, pd->dst.stride, |
eob); |
} |
@@ -334,8 +331,7 @@ struct inter_args { |
vp9_reader *r; |
FRAME_COUNTS *counts; |
int *eobtotal; |
- const int16_t *const y_dequant; |
- const int16_t *const uv_dequant; |
+ int seg_id; |
}; |
static void reconstruct_inter_block(int plane, int block, |
@@ -345,12 +341,10 @@ static void reconstruct_inter_block(int plane, int block, |
VP9_COMMON *const cm = args->cm; |
MACROBLOCKD *const xd = args->xd; |
struct macroblockd_plane *const pd = &xd->plane[plane]; |
- const int16_t *const dequant = (plane == 0) ? args->y_dequant |
- : args->uv_dequant; |
int x, y, eob; |
txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &x, &y); |
eob = vp9_decode_block_tokens(cm, xd, args->counts, plane, block, plane_bsize, |
- x, y, tx_size, args->r, dequant); |
+ x, y, tx_size, args->r, args->seg_id); |
inverse_transform_block(xd, plane, block, tx_size, |
&pd->dst.buf[4 * y * pd->dst.stride + 4 * x], |
pd->dst.stride, eob); |
@@ -367,13 +361,12 @@ static MB_MODE_INFO *set_offsets(VP9_COMMON *const cm, MACROBLOCKD *const xd, |
const int offset = mi_row * cm->mi_stride + mi_col; |
int x, y; |
- xd->mi = cm->mi + offset; |
- xd->mi[0].src_mi = &xd->mi[0]; // Point to self. |
- xd->mi[0].mbmi.sb_type = bsize; |
- |
+ xd->mi = cm->mi_grid_visible + offset; |
+ xd->mi[0] = &cm->mi[offset]; |
+ xd->mi[0]->mbmi.sb_type = bsize; |
for (y = 0; y < y_mis; ++y) |
for (x = !y; x < x_mis; ++x) { |
- xd->mi[y * cm->mi_stride + x].src_mi = &xd->mi[0]; |
+ xd->mi[y * cm->mi_stride + x] = xd->mi[0]; |
} |
set_skip_context(xd, mi_row, mi_col); |
@@ -383,7 +376,7 @@ static MB_MODE_INFO *set_offsets(VP9_COMMON *const cm, MACROBLOCKD *const xd, |
set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols); |
vp9_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col); |
- return &xd->mi[0].mbmi; |
+ return &xd->mi[0]->mbmi; |
} |
static void decode_block(VP9Decoder *const pbi, MACROBLOCKD *const xd, |
@@ -393,8 +386,6 @@ static void decode_block(VP9Decoder *const pbi, MACROBLOCKD *const xd, |
vp9_reader *r, BLOCK_SIZE bsize) { |
VP9_COMMON *const cm = &pbi->common; |
const int less8x8 = bsize < BLOCK_8X8; |
- int16_t y_dequant[2], uv_dequant[2]; |
- int qindex = cm->base_qindex; |
MB_MODE_INFO *mbmi = set_offsets(cm, xd, tile, bsize, mi_row, mi_col); |
vp9_read_mode_info(pbi, xd, counts, tile, mi_row, mi_col, r); |
@@ -403,17 +394,10 @@ static void decode_block(VP9Decoder *const pbi, MACROBLOCKD *const xd, |
if (mbmi->skip) { |
reset_skip_context(xd, bsize); |
- } else if (cm->seg.enabled) { |
- qindex = vp9_get_qindex(&cm->seg, mbmi->segment_id, cm->base_qindex); |
} |
- y_dequant[0] = vp9_dc_quant(qindex, cm->y_dc_delta_q, cm->bit_depth); |
- y_dequant[1] = vp9_ac_quant(qindex, 0, cm->bit_depth); |
- uv_dequant[0] = vp9_dc_quant(qindex, cm->uv_dc_delta_q, cm->bit_depth); |
- uv_dequant[1] = vp9_ac_quant(qindex, cm->uv_ac_delta_q, cm->bit_depth); |
- |
if (!is_inter_block(mbmi)) { |
- struct intra_args arg = {cm, xd, counts, r , y_dequant, uv_dequant}; |
+ struct intra_args arg = {cm, xd, counts, r, mbmi->segment_id}; |
vp9_foreach_transformed_block(xd, bsize, |
predict_and_reconstruct_intra_block, &arg); |
} else { |
@@ -423,8 +407,7 @@ static void decode_block(VP9Decoder *const pbi, MACROBLOCKD *const xd, |
// Reconstruction |
if (!mbmi->skip) { |
int eobtotal = 0; |
- struct inter_args arg = {cm, xd, r, counts, &eobtotal, y_dequant, |
- uv_dequant}; |
+ struct inter_args arg = {cm, xd, r, counts, &eobtotal, mbmi->segment_id}; |
vp9_foreach_transformed_block(xd, bsize, reconstruct_inter_block, &arg); |
if (!less8x8 && eobtotal == 0) |
mbmi->skip = 1; // skip loopfilter |
@@ -648,11 +631,39 @@ static void setup_quantization(VP9_COMMON *const cm, MACROBLOCKD *const xd, |
cm->y_dc_delta_q == 0 && |
cm->uv_dc_delta_q == 0 && |
cm->uv_ac_delta_q == 0; |
+ |
#if CONFIG_VP9_HIGHBITDEPTH |
xd->bd = (int)cm->bit_depth; |
#endif |
} |
+static void setup_segmentation_dequant(VP9_COMMON *const cm) { |
+ // Build y/uv dequant values based on segmentation. |
+ if (cm->seg.enabled) { |
+ int i; |
+ for (i = 0; i < MAX_SEGMENTS; ++i) { |
+ const int qindex = vp9_get_qindex(&cm->seg, i, cm->base_qindex); |
+ cm->y_dequant[i][0] = vp9_dc_quant(qindex, cm->y_dc_delta_q, |
+ cm->bit_depth); |
+ cm->y_dequant[i][1] = vp9_ac_quant(qindex, 0, cm->bit_depth); |
+ cm->uv_dequant[i][0] = vp9_dc_quant(qindex, cm->uv_dc_delta_q, |
+ cm->bit_depth); |
+ cm->uv_dequant[i][1] = vp9_ac_quant(qindex, cm->uv_ac_delta_q, |
+ cm->bit_depth); |
+ } |
+ } else { |
+ const int qindex = cm->base_qindex; |
+ // When segmentation is disabled, only the first value is used. The |
+ // remaining are don't cares. |
+ cm->y_dequant[0][0] = vp9_dc_quant(qindex, cm->y_dc_delta_q, cm->bit_depth); |
+ cm->y_dequant[0][1] = vp9_ac_quant(qindex, 0, cm->bit_depth); |
+ cm->uv_dequant[0][0] = vp9_dc_quant(qindex, cm->uv_dc_delta_q, |
+ cm->bit_depth); |
+ cm->uv_dequant[0][1] = vp9_ac_quant(qindex, cm->uv_ac_delta_q, |
+ cm->bit_depth); |
+ } |
+} |
+ |
static INTERP_FILTER read_interp_filter(struct vp9_read_bit_buffer *rb) { |
const INTERP_FILTER literal_to_filter[] = { EIGHTTAP_SMOOTH, |
EIGHTTAP, |
@@ -941,11 +952,11 @@ static const uint8_t *decode_tiles(VP9Decoder *pbi, |
// Note: this memset assumes above_context[0], [1] and [2] |
// are allocated as part of the same buffer. |
- vpx_memset(cm->above_context, 0, |
- sizeof(*cm->above_context) * MAX_MB_PLANE * 2 * aligned_cols); |
+ memset(cm->above_context, 0, |
+ sizeof(*cm->above_context) * MAX_MB_PLANE * 2 * aligned_cols); |
- vpx_memset(cm->above_seg_context, 0, |
- sizeof(*cm->above_seg_context) * aligned_cols); |
+ memset(cm->above_seg_context, 0, |
+ sizeof(*cm->above_seg_context) * aligned_cols); |
get_tile_buffers(pbi, data, data_end, tile_cols, tile_rows, tile_buffers); |
@@ -1075,13 +1086,7 @@ static int tile_worker_hook(TileWorkerData *const tile_data, |
static int compare_tile_buffers(const void *a, const void *b) { |
const TileBuffer *const buf1 = (const TileBuffer*)a; |
const TileBuffer *const buf2 = (const TileBuffer*)b; |
- if (buf1->size < buf2->size) { |
- return 1; |
- } else if (buf1->size == buf2->size) { |
- return 0; |
- } else { |
- return -1; |
- } |
+ return (int)(buf2->size - buf1->size); |
} |
static const uint8_t *decode_tiles_mt(VP9Decoder *pbi, |
@@ -1142,10 +1147,10 @@ static const uint8_t *decode_tiles_mt(VP9Decoder *pbi, |
// Note: this memset assumes above_context[0], [1] and [2] |
// are allocated as part of the same buffer. |
- vpx_memset(cm->above_context, 0, |
- sizeof(*cm->above_context) * MAX_MB_PLANE * 2 * aligned_mi_cols); |
- vpx_memset(cm->above_seg_context, 0, |
- sizeof(*cm->above_seg_context) * aligned_mi_cols); |
+ memset(cm->above_context, 0, |
+ sizeof(*cm->above_context) * MAX_MB_PLANE * 2 * aligned_mi_cols); |
+ memset(cm->above_seg_context, 0, |
+ sizeof(*cm->above_seg_context) * aligned_mi_cols); |
// Load tile data into tile_buffers |
get_tile_buffers(pbi, data, data_end, tile_cols, tile_rows, tile_buffers); |
@@ -1367,7 +1372,7 @@ static size_t read_uncompressed_header(VP9Decoder *pbi, |
setup_frame_size(cm, rb); |
if (pbi->need_resync) { |
- vpx_memset(&cm->ref_frame_map, -1, sizeof(cm->ref_frame_map)); |
+ memset(&cm->ref_frame_map, -1, sizeof(cm->ref_frame_map)); |
pbi->need_resync = 0; |
} |
} else { |
@@ -1398,7 +1403,7 @@ static size_t read_uncompressed_header(VP9Decoder *pbi, |
pbi->refresh_frame_flags = vp9_rb_read_literal(rb, REF_FRAMES); |
setup_frame_size(cm, rb); |
if (pbi->need_resync) { |
- vpx_memset(&cm->ref_frame_map, -1, sizeof(cm->ref_frame_map)); |
+ memset(&cm->ref_frame_map, -1, sizeof(cm->ref_frame_map)); |
pbi->need_resync = 0; |
} |
} else if (pbi->need_resync != 1) { /* Skip if need resync */ |
@@ -1487,6 +1492,7 @@ static size_t read_uncompressed_header(VP9Decoder *pbi, |
setup_loopfilter(&cm->lf, rb); |
setup_quantization(cm, &pbi->mb, rb); |
setup_segmentation(&cm->seg, rb); |
+ setup_segmentation_dequant(cm); |
setup_tile_info(cm, rb); |
sz = vp9_rb_read_literal(rb, 16); |
@@ -1807,162 +1813,134 @@ static void high_build_mc_border(const uint8_t *src8, int src_stride, |
#endif // CONFIG_VP9_HIGHBITDEPTH |
void dec_build_inter_predictors(VP9Decoder *const pbi, MACROBLOCKD *xd, |
- int plane, int block, int bw, int bh, int x, |
- int y, int w, int h, int mi_x, int mi_y) { |
+ int plane, int bw, int bh, int x, |
+ int y, int w, int h, int mi_x, int mi_y, |
+ const InterpKernel *kernel, |
+ const struct scale_factors *sf, |
+ struct buf_2d *pre_buf, struct buf_2d *dst_buf, |
+ const MV* mv, RefCntBuffer *ref_frame_buf, |
+ int is_scaled, int ref) { |
struct macroblockd_plane *const pd = &xd->plane[plane]; |
- const MODE_INFO *mi = xd->mi[0].src_mi; |
- const int is_compound = has_second_ref(&mi->mbmi); |
- const InterpKernel *kernel = vp9_get_interp_kernel(mi->mbmi.interp_filter); |
- int ref; |
- |
- for (ref = 0; ref < 1 + is_compound; ++ref) { |
- const struct scale_factors *const sf = &xd->block_refs[ref]->sf; |
- struct buf_2d *const pre_buf = &pd->pre[ref]; |
- struct buf_2d *const dst_buf = &pd->dst; |
- uint8_t *const dst = dst_buf->buf + dst_buf->stride * y + x; |
- const MV mv = mi->mbmi.sb_type < BLOCK_8X8 |
- ? average_split_mvs(pd, mi, ref, block) |
- : mi->mbmi.mv[ref].as_mv; |
+ uint8_t *const dst = dst_buf->buf + dst_buf->stride * y + x; |
+ MV32 scaled_mv; |
+ int xs, ys, x0, y0, x0_16, y0_16, frame_width, frame_height, |
+ buf_stride, subpel_x, subpel_y; |
+ uint8_t *ref_frame, *buf_ptr; |
+ |
+ // Get reference frame pointer, width and height. |
+ if (plane == 0) { |
+ frame_width = ref_frame_buf->buf.y_crop_width; |
+ frame_height = ref_frame_buf->buf.y_crop_height; |
+ ref_frame = ref_frame_buf->buf.y_buffer; |
+ } else { |
+ frame_width = ref_frame_buf->buf.uv_crop_width; |
+ frame_height = ref_frame_buf->buf.uv_crop_height; |
+ ref_frame = plane == 1 ? ref_frame_buf->buf.u_buffer |
+ : ref_frame_buf->buf.v_buffer; |
+ } |
- const MV mv_q4 = clamp_mv_to_umv_border_sb(xd, &mv, bw, bh, |
+ if (is_scaled) { |
+ const MV mv_q4 = clamp_mv_to_umv_border_sb(xd, mv, bw, bh, |
pd->subsampling_x, |
pd->subsampling_y); |
+ // Co-ordinate of containing block to pixel precision. |
+ int x_start = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)); |
+ int y_start = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)); |
+ |
+ // Co-ordinate of the block to 1/16th pixel precision. |
+ x0_16 = (x_start + x) << SUBPEL_BITS; |
+ y0_16 = (y_start + y) << SUBPEL_BITS; |
+ |
+ // Co-ordinate of current block in reference frame |
+ // to 1/16th pixel precision. |
+ x0_16 = sf->scale_value_x(x0_16, sf); |
+ y0_16 = sf->scale_value_y(y0_16, sf); |
+ |
+ // Map the top left corner of the block into the reference frame. |
+ x0 = sf->scale_value_x(x_start + x, sf); |
+ y0 = sf->scale_value_y(y_start + y, sf); |
+ |
+ // Scale the MV and incorporate the sub-pixel offset of the block |
+ // in the reference frame. |
+ scaled_mv = vp9_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf); |
+ xs = sf->x_step_q4; |
+ ys = sf->y_step_q4; |
+ } else { |
+ // Co-ordinate of containing block to pixel precision. |
+ x0 = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)) + x; |
+ y0 = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)) + y; |
- MV32 scaled_mv; |
- int xs, ys, x0, y0, x0_16, y0_16, y1, frame_width, frame_height, |
- buf_stride, subpel_x, subpel_y; |
- uint8_t *ref_frame, *buf_ptr; |
- const int idx = xd->block_refs[ref]->idx; |
- BufferPool *const pool = pbi->common.buffer_pool; |
- RefCntBuffer *const ref_frame_buf = &pool->frame_bufs[idx]; |
- const int is_scaled = vp9_is_scaled(sf); |
- |
- // Get reference frame pointer, width and height. |
- if (plane == 0) { |
- frame_width = ref_frame_buf->buf.y_crop_width; |
- frame_height = ref_frame_buf->buf.y_crop_height; |
- ref_frame = ref_frame_buf->buf.y_buffer; |
- } else { |
- frame_width = ref_frame_buf->buf.uv_crop_width; |
- frame_height = ref_frame_buf->buf.uv_crop_height; |
- ref_frame = plane == 1 ? ref_frame_buf->buf.u_buffer |
- : ref_frame_buf->buf.v_buffer; |
- } |
- |
- if (is_scaled) { |
- // Co-ordinate of containing block to pixel precision. |
- int x_start = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)); |
- int y_start = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)); |
- |
- // Co-ordinate of the block to 1/16th pixel precision. |
- x0_16 = (x_start + x) << SUBPEL_BITS; |
- y0_16 = (y_start + y) << SUBPEL_BITS; |
- |
- // Co-ordinate of current block in reference frame |
- // to 1/16th pixel precision. |
- x0_16 = sf->scale_value_x(x0_16, sf); |
- y0_16 = sf->scale_value_y(y0_16, sf); |
- |
- // Map the top left corner of the block into the reference frame. |
- x0 = sf->scale_value_x(x_start + x, sf); |
- y0 = sf->scale_value_y(y_start + y, sf); |
- |
- // Scale the MV and incorporate the sub-pixel offset of the block |
- // in the reference frame. |
- scaled_mv = vp9_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf); |
- xs = sf->x_step_q4; |
- ys = sf->y_step_q4; |
- } else { |
- // Co-ordinate of containing block to pixel precision. |
- x0 = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)) + x; |
- y0 = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)) + y; |
- |
- // Co-ordinate of the block to 1/16th pixel precision. |
- x0_16 = x0 << SUBPEL_BITS; |
- y0_16 = y0 << SUBPEL_BITS; |
+ // Co-ordinate of the block to 1/16th pixel precision. |
+ x0_16 = x0 << SUBPEL_BITS; |
+ y0_16 = y0 << SUBPEL_BITS; |
- scaled_mv.row = mv_q4.row; |
- scaled_mv.col = mv_q4.col; |
- xs = ys = 16; |
+ scaled_mv.row = mv->row * (1 << (1 - pd->subsampling_y)); |
+ scaled_mv.col = mv->col * (1 << (1 - pd->subsampling_x)); |
+ xs = ys = 16; |
+ } |
+ subpel_x = scaled_mv.col & SUBPEL_MASK; |
+ subpel_y = scaled_mv.row & SUBPEL_MASK; |
+ |
+ // Calculate the top left corner of the best matching block in the |
+ // reference frame. |
+ x0 += scaled_mv.col >> SUBPEL_BITS; |
+ y0 += scaled_mv.row >> SUBPEL_BITS; |
+ x0_16 += scaled_mv.col; |
+ y0_16 += scaled_mv.row; |
+ |
+ // Get reference block pointer. |
+ buf_ptr = ref_frame + y0 * pre_buf->stride + x0; |
+ buf_stride = pre_buf->stride; |
+ |
+ // Do border extension if there is motion or the |
+ // width/height is not a multiple of 8 pixels. |
+ if (is_scaled || scaled_mv.col || scaled_mv.row || |
+ (frame_width & 0x7) || (frame_height & 0x7)) { |
+ int y1 = (y0_16 + (h - 1) * ys) >> SUBPEL_BITS; |
+ |
+ // Get reference block bottom right horizontal coordinate. |
+ int x1 = (x0_16 + (w - 1) * xs) >> SUBPEL_BITS; |
+ int x_pad = 0, y_pad = 0; |
+ |
+ if (subpel_x || (sf->x_step_q4 != SUBPEL_SHIFTS)) { |
+ x0 -= VP9_INTERP_EXTEND - 1; |
+ x1 += VP9_INTERP_EXTEND; |
+ x_pad = 1; |
} |
- subpel_x = scaled_mv.col & SUBPEL_MASK; |
- subpel_y = scaled_mv.row & SUBPEL_MASK; |
- |
- // Calculate the top left corner of the best matching block in the |
- // reference frame. |
- x0 += scaled_mv.col >> SUBPEL_BITS; |
- y0 += scaled_mv.row >> SUBPEL_BITS; |
- x0_16 += scaled_mv.col; |
- y0_16 += scaled_mv.row; |
- |
- // Get reference block pointer. |
- buf_ptr = ref_frame + y0 * pre_buf->stride + x0; |
- buf_stride = pre_buf->stride; |
- |
- // Get reference block bottom right vertical coordinate. |
- y1 = ((y0_16 + (h - 1) * ys) >> SUBPEL_BITS) + 1; |
- |
- // Do border extension if there is motion or the |
- // width/height is not a multiple of 8 pixels. |
- if (is_scaled || scaled_mv.col || scaled_mv.row || |
- (frame_width & 0x7) || (frame_height & 0x7)) { |
- // Get reference block bottom right horizontal coordinate. |
- int x1 = ((x0_16 + (w - 1) * xs) >> SUBPEL_BITS) + 1; |
- int x_pad = 0, y_pad = 0; |
- |
- if (subpel_x || (sf->x_step_q4 != SUBPEL_SHIFTS)) { |
- x0 -= VP9_INTERP_EXTEND - 1; |
- x1 += VP9_INTERP_EXTEND; |
- x_pad = 1; |
- } |
- if (subpel_y || (sf->y_step_q4 != SUBPEL_SHIFTS)) { |
- y0 -= VP9_INTERP_EXTEND - 1; |
- y1 += VP9_INTERP_EXTEND; |
- y_pad = 1; |
- } |
+ if (subpel_y || (sf->y_step_q4 != SUBPEL_SHIFTS)) { |
+ y0 -= VP9_INTERP_EXTEND - 1; |
+ y1 += VP9_INTERP_EXTEND; |
+ y_pad = 1; |
+ } |
- // Wait until reference block is ready. Pad 7 more pixels as last 7 |
- // pixels of each superblock row can be changed by next superblock row. |
- if (pbi->frame_parallel_decode) |
- vp9_frameworker_wait(pbi->frame_worker_owner, ref_frame_buf, |
- MAX(0, (y1 + 7) << (plane == 0 ? 0 : 1))); |
- |
- // Skip border extension if block is inside the frame. |
- if (x0 < 0 || x0 > frame_width - 1 || x1 < 0 || x1 > frame_width - 1 || |
- y0 < 0 || y0 > frame_height - 1 || y1 < 0 || y1 > frame_height - 1) { |
- uint8_t *buf_ptr1 = ref_frame + y0 * pre_buf->stride + x0; |
- // Extend the border. |
+ // Wait until reference block is ready. Pad 7 more pixels as last 7 |
+ // pixels of each superblock row can be changed by next superblock row. |
+ if (pbi->frame_parallel_decode) |
+ vp9_frameworker_wait(pbi->frame_worker_owner, ref_frame_buf, |
+ MAX(0, (y1 + 7)) << (plane == 0 ? 0 : 1)); |
+ |
+ // Skip border extension if block is inside the frame. |
+ if (x0 < 0 || x0 > frame_width - 1 || x1 < 0 || x1 > frame_width - 1 || |
+ y0 < 0 || y0 > frame_height - 1 || y1 < 0 || y1 > frame_height - 1) { |
+ uint8_t *buf_ptr1 = ref_frame + y0 * pre_buf->stride + x0; |
+ // Extend the border. |
#if CONFIG_VP9_HIGHBITDEPTH |
- if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { |
- high_build_mc_border(buf_ptr1, |
- pre_buf->stride, |
- xd->mc_buf_high, |
- x1 - x0 + 1, |
- x0, |
- y0, |
- x1 - x0 + 1, |
- y1 - y0 + 1, |
- frame_width, |
- frame_height); |
- buf_stride = x1 - x0 + 1; |
- buf_ptr = CONVERT_TO_BYTEPTR(xd->mc_buf_high) + |
- y_pad * 3 * buf_stride + x_pad * 3; |
- } else { |
- build_mc_border(buf_ptr1, |
- pre_buf->stride, |
- xd->mc_buf, |
- x1 - x0 + 1, |
- x0, |
- y0, |
- x1 - x0 + 1, |
- y1 - y0 + 1, |
- frame_width, |
- frame_height); |
- buf_stride = x1 - x0 + 1; |
- buf_ptr = xd->mc_buf + y_pad * 3 * buf_stride + x_pad * 3; |
- } |
-#else |
+ if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { |
+ high_build_mc_border(buf_ptr1, |
+ pre_buf->stride, |
+ xd->mc_buf_high, |
+ x1 - x0 + 1, |
+ x0, |
+ y0, |
+ x1 - x0 + 1, |
+ y1 - y0 + 1, |
+ frame_width, |
+ frame_height); |
+ buf_stride = x1 - x0 + 1; |
+ buf_ptr = CONVERT_TO_BYTEPTR(xd->mc_buf_high) + |
+ y_pad * 3 * buf_stride + x_pad * 3; |
+ } else { |
build_mc_border(buf_ptr1, |
pre_buf->stride, |
xd->mc_buf, |
@@ -1975,28 +1953,43 @@ void dec_build_inter_predictors(VP9Decoder *const pbi, MACROBLOCKD *xd, |
frame_height); |
buf_stride = x1 - x0 + 1; |
buf_ptr = xd->mc_buf + y_pad * 3 * buf_stride + x_pad * 3; |
-#endif // CONFIG_VP9_HIGHBITDEPTH |
} |
- } else { |
- // Wait until reference block is ready. Pad 7 more pixels as last 7 |
- // pixels of each superblock row can be changed by next superblock row. |
- if (pbi->frame_parallel_decode) |
- vp9_frameworker_wait(pbi->frame_worker_owner, ref_frame_buf, |
- MAX(0, (y1 + 7) << (plane == 0 ? 0 : 1))); |
+#else |
+ build_mc_border(buf_ptr1, |
+ pre_buf->stride, |
+ xd->mc_buf, |
+ x1 - x0 + 1, |
+ x0, |
+ y0, |
+ x1 - x0 + 1, |
+ y1 - y0 + 1, |
+ frame_width, |
+ frame_height); |
+ buf_stride = x1 - x0 + 1; |
+ buf_ptr = xd->mc_buf + y_pad * 3 * buf_stride + x_pad * 3; |
+#endif // CONFIG_VP9_HIGHBITDEPTH |
} |
+ } else { |
+ // Wait until reference block is ready. Pad 7 more pixels as last 7 |
+ // pixels of each superblock row can be changed by next superblock row. |
+ if (pbi->frame_parallel_decode) { |
+ const int y1 = ((y0_16 + (h - 1) * ys) >> SUBPEL_BITS) + 1; |
+ vp9_frameworker_wait(pbi->frame_worker_owner, ref_frame_buf, |
+ MAX(0, (y1 + 7)) << (plane == 0 ? 0 : 1)); |
+ } |
+ } |
#if CONFIG_VP9_HIGHBITDEPTH |
- if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { |
- high_inter_predictor(buf_ptr, buf_stride, dst, dst_buf->stride, subpel_x, |
- subpel_y, sf, w, h, ref, kernel, xs, ys, xd->bd); |
- } else { |
- inter_predictor(buf_ptr, buf_stride, dst, dst_buf->stride, subpel_x, |
- subpel_y, sf, w, h, ref, kernel, xs, ys); |
- } |
-#else |
+ if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { |
+ high_inter_predictor(buf_ptr, buf_stride, dst, dst_buf->stride, subpel_x, |
+ subpel_y, sf, w, h, ref, kernel, xs, ys, xd->bd); |
+ } else { |
inter_predictor(buf_ptr, buf_stride, dst, dst_buf->stride, subpel_x, |
subpel_y, sf, w, h, ref, kernel, xs, ys); |
-#endif // CONFIG_VP9_HIGHBITDEPTH |
} |
+#else |
+ inter_predictor(buf_ptr, buf_stride, dst, dst_buf->stride, subpel_x, |
+ subpel_y, sf, w, h, ref, kernel, xs, ys); |
+#endif // CONFIG_VP9_HIGHBITDEPTH |
} |
void vp9_dec_build_inter_predictors_sb(VP9Decoder *const pbi, MACROBLOCKD *xd, |
@@ -2005,24 +1998,50 @@ void vp9_dec_build_inter_predictors_sb(VP9Decoder *const pbi, MACROBLOCKD *xd, |
int plane; |
const int mi_x = mi_col * MI_SIZE; |
const int mi_y = mi_row * MI_SIZE; |
+ const MODE_INFO *mi = xd->mi[0]; |
+ const InterpKernel *kernel = vp9_get_interp_kernel(mi->mbmi.interp_filter); |
+ const BLOCK_SIZE sb_type = mi->mbmi.sb_type; |
+ const int is_compound = has_second_ref(&mi->mbmi); |
+ |
for (plane = 0; plane < MAX_MB_PLANE; ++plane) { |
const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, |
&xd->plane[plane]); |
+ struct macroblockd_plane *const pd = &xd->plane[plane]; |
+ struct buf_2d *const dst_buf = &pd->dst; |
const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize]; |
const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize]; |
+ |
const int bw = 4 * num_4x4_w; |
const int bh = 4 * num_4x4_h; |
- |
- if (xd->mi[0].src_mi->mbmi.sb_type < BLOCK_8X8) { |
- int i = 0, x, y; |
- assert(bsize == BLOCK_8X8); |
- for (y = 0; y < num_4x4_h; ++y) |
- for (x = 0; x < num_4x4_w; ++x) |
- dec_build_inter_predictors(pbi, xd, plane, i++, bw, bh, |
- 4 * x, 4 * y, 4, 4, mi_x, mi_y); |
- } else { |
- dec_build_inter_predictors(pbi, xd, plane, 0, bw, bh, |
- 0, 0, bw, bh, mi_x, mi_y); |
+ int ref; |
+ |
+ for (ref = 0; ref < 1 + is_compound; ++ref) { |
+ const struct scale_factors *const sf = &xd->block_refs[ref]->sf; |
+ struct buf_2d *const pre_buf = &pd->pre[ref]; |
+ const int idx = xd->block_refs[ref]->idx; |
+ BufferPool *const pool = pbi->common.buffer_pool; |
+ RefCntBuffer *const ref_frame_buf = &pool->frame_bufs[idx]; |
+ const int is_scaled = vp9_is_scaled(sf); |
+ |
+ if (sb_type < BLOCK_8X8) { |
+ int i = 0, x, y; |
+ assert(bsize == BLOCK_8X8); |
+ for (y = 0; y < num_4x4_h; ++y) { |
+ for (x = 0; x < num_4x4_w; ++x) { |
+ const MV mv = average_split_mvs(pd, mi, ref, i++); |
+ dec_build_inter_predictors(pbi, xd, plane, bw, bh, |
+ 4 * x, 4 * y, 4, 4, mi_x, mi_y, kernel, |
+ sf, pre_buf, dst_buf, &mv, |
+ ref_frame_buf, is_scaled, ref); |
+ } |
+ } |
+ } else { |
+ const MV mv = mi->mbmi.mv[ref].as_mv; |
+ dec_build_inter_predictors(pbi, xd, plane, bw, bh, |
+ 0, 0, bw, bh, mi_x, mi_y, kernel, |
+ sf, pre_buf, dst_buf, &mv, ref_frame_buf, |
+ is_scaled, ref); |
+ } |
} |
} |
} |