Facilitate on-the-fly padding in decoder
Functional changes have been done to facilitate
on-the-fly padding in decoder.
Change-Id: Ic305ff5405aa8c0569141b03b7954156f1e9f94a
diff --git a/av1/common/reconinter.c b/av1/common/reconinter.c
index 92d4bf3..8c5b8a7 100644
--- a/av1/common/reconinter.c
+++ b/av1/common/reconinter.c
@@ -32,23 +32,26 @@
// This function will determine whether or not to create a warped
// prediction.
-static INLINE int allow_warp(const MB_MODE_INFO *const mbmi,
- const WarpTypesAllowed *const warp_types,
- const WarpedMotionParams *const gm_params,
- int build_for_obmc, int x_scale, int y_scale,
- WarpedMotionParams *final_warp_params) {
+int av1_allow_warp(const MB_MODE_INFO *const mbmi,
+ const WarpTypesAllowed *const warp_types,
+ const WarpedMotionParams *const gm_params,
+ int build_for_obmc, int x_scale, int y_scale,
+ WarpedMotionParams *final_warp_params) {
if (x_scale != SCALE_SUBPEL_SHIFTS || y_scale != SCALE_SUBPEL_SHIFTS)
return 0;
- *final_warp_params = default_warp_params;
+ if (final_warp_params != NULL) *final_warp_params = default_warp_params;
if (build_for_obmc) return 0;
if (warp_types->local_warp_allowed && !mbmi->wm_params[0].invalid) {
- memcpy(final_warp_params, &mbmi->wm_params[0], sizeof(*final_warp_params));
+ if (final_warp_params != NULL)
+ memcpy(final_warp_params, &mbmi->wm_params[0],
+ sizeof(*final_warp_params));
return 1;
} else if (warp_types->global_warp_allowed && !gm_params->invalid) {
- memcpy(final_warp_params, gm_params, sizeof(*final_warp_params));
+ if (final_warp_params != NULL)
+ memcpy(final_warp_params, gm_params, sizeof(*final_warp_params));
return 1;
}
@@ -72,9 +75,9 @@
WarpedMotionParams final_warp_params;
const int do_warp =
(w >= 8 && h >= 8 &&
- allow_warp(mi, warp_types, &xd->global_motion[mi->ref_frame[ref]],
- build_for_obmc, subpel_params->xs, subpel_params->ys,
- &final_warp_params));
+ av1_allow_warp(mi, warp_types, &xd->global_motion[mi->ref_frame[ref]],
+ build_for_obmc, subpel_params->xs, subpel_params->ys,
+ &final_warp_params));
if (do_warp && xd->cur_frame_force_integer_mv == 0) {
const struct macroblockd_plane *const pd = &xd->plane[plane];
const struct buf_2d *const pre_buf = &pd->pre[ref];
diff --git a/av1/common/reconinter.h b/av1/common/reconinter.h
index 49641fa..aa3aefc 100644
--- a/av1/common/reconinter.h
+++ b/av1/common/reconinter.h
@@ -448,6 +448,11 @@
void av1_jnt_comp_weight_assign(const AV1_COMMON *cm, const MB_MODE_INFO *mbmi,
int order_idx, int *fwd_offset, int *bck_offset,
int *use_jnt_comp_avg, int is_compound);
+int av1_allow_warp(const MB_MODE_INFO *const mbmi,
+ const WarpTypesAllowed *const warp_types,
+ const WarpedMotionParams *const gm_params,
+ int build_for_obmc, int x_scale, int y_scale,
+ WarpedMotionParams *final_warp_params);
#ifdef __cplusplus
} // extern "C"
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 2086dd9..ac9aa29 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -336,11 +336,18 @@
aom_merge_corrupted_flag(&xd->corrupted, reader_corrupted_flag);
}
+typedef struct PadBlock {
+ int x0;
+ int x1;
+ int y0;
+ int y1;
+} PadBlock;
+
static INLINE void dec_calc_subpel_params(
MACROBLOCKD *xd, const struct scale_factors *const sf, const MV mv,
int plane, const int pre_x, const int pre_y, int x, int y,
- struct buf_2d *const pre_buf, uint8_t **pre, SubpelParams *subpel_params,
- int bw, int bh) {
+ struct buf_2d *const pre_buf, SubpelParams *subpel_params, int bw, int bh,
+ PadBlock *block) {
struct macroblockd_plane *const pd = &xd->plane[plane];
const int is_scaled = av1_is_scaled(sf);
if (is_scaled) {
@@ -363,20 +370,40 @@
pos_y = clamp(pos_y, top, bottom);
pos_x = clamp(pos_x, left, right);
- *pre = pre_buf->buf0 + (pos_y >> SCALE_SUBPEL_BITS) * pre_buf->stride +
- (pos_x >> SCALE_SUBPEL_BITS);
subpel_params->subpel_x = pos_x & SCALE_SUBPEL_MASK;
subpel_params->subpel_y = pos_y & SCALE_SUBPEL_MASK;
subpel_params->xs = sf->x_step_q4;
subpel_params->ys = sf->y_step_q4;
+
+ // Get reference block top left coordinate.
+ block->x0 = pos_x >> SCALE_SUBPEL_BITS;
+ block->y0 = pos_y >> SCALE_SUBPEL_BITS;
+
+ // Get reference block bottom right coordinate.
+ block->x1 =
+ ((pos_x + (bw - 1) * subpel_params->xs) >> SCALE_SUBPEL_BITS) + 1;
+ block->y1 =
+ ((pos_y + (bh - 1) * subpel_params->ys) >> SCALE_SUBPEL_BITS) + 1;
} else {
+ // Get block position in current frame.
+ int pos_x = (pre_x + x) << SUBPEL_BITS;
+ int pos_y = (pre_y + y) << SUBPEL_BITS;
+
const MV mv_q4 = clamp_mv_to_umv_border_sb(
xd, &mv, bw, bh, pd->subsampling_x, pd->subsampling_y);
subpel_params->xs = subpel_params->ys = SCALE_SUBPEL_SHIFTS;
subpel_params->subpel_x = (mv_q4.col & SUBPEL_MASK) << SCALE_EXTRA_BITS;
subpel_params->subpel_y = (mv_q4.row & SUBPEL_MASK) << SCALE_EXTRA_BITS;
- *pre = pre_buf->buf + (y + (mv_q4.row >> SUBPEL_BITS)) * pre_buf->stride +
- (x + (mv_q4.col >> SUBPEL_BITS));
+
+ // Get reference block top left coordinate.
+ pos_x += mv_q4.col;
+ pos_y += mv_q4.row;
+ block->x0 = pos_x >> SUBPEL_BITS;
+ block->y0 = pos_y >> SUBPEL_BITS;
+
+ // Get reference block bottom right coordinate.
+ block->x1 = (pos_x >> SUBPEL_BITS) + (bw - 1) + 1;
+ block->y1 = (pos_y >> SUBPEL_BITS) + (bh - 1) + 1;
}
}
@@ -438,6 +465,7 @@
const struct buf_2d orig_pred_buf[2] = { pd->pre[0], pd->pre[1] };
int row = row_start;
+ int src_stride;
for (int y = 0; y < b8_h; y += b4_h) {
int col = col_start;
for (int x = 0; x < b8_w; x += b4_w) {
@@ -474,13 +502,15 @@
uint8_t *pre;
SubpelParams subpel_params;
+ PadBlock block;
WarpTypesAllowed warp_types;
warp_types.global_warp_allowed = is_global[ref];
warp_types.local_warp_allowed = this_mbmi->motion_mode == WARPED_CAUSAL;
dec_calc_subpel_params(xd, sf, mv, plane, pre_x, pre_y, x, y, pre_buf,
- &pre, &subpel_params, bw, bh);
-
+ &subpel_params, bw, bh, &block);
+ pre = pre_buf->buf0 + block.y0 * pre_buf->stride + block.x0;
+ src_stride = pre_buf->stride;
conv_params.ref = ref;
conv_params.do_average = ref;
if (is_masked_compound_type(mi->interinter_compound_type)) {
@@ -489,8 +519,8 @@
}
av1_make_inter_predictor(
- pre, pre_buf->stride, dst, dst_buf->stride, &subpel_params, sf,
- b4_w, b4_h, &conv_params, this_mbmi->interp_filters, &warp_types,
+ pre, src_stride, dst, dst_buf->stride, &subpel_params, sf, b4_w,
+ b4_h, &conv_params, this_mbmi->interp_filters, &warp_types,
(mi_x >> pd->subsampling_x) + x, (mi_y >> pd->subsampling_y) + y,
plane, ref, mi, build_for_obmc, xd, cm->allow_warped_motion);
@@ -509,14 +539,18 @@
uint8_t *pre[2];
SubpelParams subpel_params[2];
DECLARE_ALIGNED(32, uint16_t, tmp_dst[MAX_SB_SIZE * MAX_SB_SIZE]);
+ int src_stride[2];
for (ref = 0; ref < 1 + is_compound; ++ref) {
const struct scale_factors *const sf =
is_intrabc ? &cm->sf_identity : &xd->block_refs[ref]->sf;
struct buf_2d *const pre_buf = is_intrabc ? dst_buf : &pd->pre[ref];
const MV mv = mi->mv[ref].as_mv;
+ PadBlock block;
dec_calc_subpel_params(xd, sf, mv, plane, pre_x, pre_y, 0, 0, pre_buf,
- &pre[ref], &subpel_params[ref], bw, bh);
+ &subpel_params[ref], bw, bh, &block);
+ pre[ref] = pre_buf->buf0 + block.y0 * pre_buf->stride + block.x0;
+ src_stride[ref] = pre_buf->stride;
}
ConvolveParams conv_params = get_conv_params_no_round(
@@ -528,7 +562,6 @@
for (ref = 0; ref < 1 + is_compound; ++ref) {
const struct scale_factors *const sf =
is_intrabc ? &cm->sf_identity : &xd->block_refs[ref]->sf;
- struct buf_2d *const pre_buf = is_intrabc ? dst_buf : &pd->pre[ref];
WarpTypesAllowed warp_types;
warp_types.global_warp_allowed = is_global[ref];
warp_types.local_warp_allowed = mi->motion_mode == WARPED_CAUSAL;
@@ -541,13 +574,13 @@
if (ref && is_masked_compound_type(mi->interinter_compound_type))
av1_make_masked_inter_predictor(
- pre[ref], pre_buf->stride, dst, dst_buf->stride,
+ pre[ref], src_stride[ref], dst, dst_buf->stride,
&subpel_params[ref], sf, bw, bh, &conv_params, mi->interp_filters,
plane, &warp_types, mi_x >> pd->subsampling_x,
mi_y >> pd->subsampling_y, ref, xd, cm->allow_warped_motion);
else
av1_make_inter_predictor(
- pre[ref], pre_buf->stride, dst, dst_buf->stride,
+ pre[ref], src_stride[ref], dst, dst_buf->stride,
&subpel_params[ref], sf, bw, bh, &conv_params, mi->interp_filters,
&warp_types, mi_x >> pd->subsampling_x, mi_y >> pd->subsampling_y,
plane, ref, mi, build_for_obmc, xd, cm->allow_warped_motion);