Commit bbb25e6a authored by Dmitry Kovalev's avatar Dmitry Kovalev Committed by Gerrit Code Review

Merge "Adding RefBuffer struct."

parents f73b2143 ba41e9d4
......@@ -161,9 +161,6 @@ int vp9_alloc_frame_buffers(VP9_COMMON *cm, int width, int height) {
cm->new_fb_idx = cm->fb_count - 1;
cm->fb_idx_ref_cnt[cm->new_fb_idx] = 1;
for (i = 0; i < REFS_PER_FRAME; i++)
cm->active_ref_idx[i] = i;
for (i = 0; i < REF_FRAMES; i++) {
cm->ref_frame_map[i] = i;
cm->fb_idx_ref_cnt[i] = 1;
......
......@@ -212,11 +212,17 @@ struct macroblockd_plane {
#define BLOCK_OFFSET(x, i) ((x) + (i) * 16)
typedef struct RefBuffer {
// TODO(dkovalev): idx is not really required and should be removed, now it
// is used in vp9_onyxd_if.c
int idx;
YV12_BUFFER_CONFIG *buf;
struct scale_factors sf;
} RefBuffer;
typedef struct macroblockd {
struct macroblockd_plane plane[MAX_MB_PLANE];
const struct scale_factors *scale_factors[2];
MODE_INFO *last_mi;
int mode_info_stride;
......@@ -235,7 +241,7 @@ typedef struct macroblockd {
int mb_to_bottom_edge;
/* pointers to reference frames */
const YV12_BUFFER_CONFIG *ref_buf[2];
RefBuffer *block_refs[2];
/* pointer to current frame */
const YV12_BUFFER_CONFIG *cur_buf;
......
......@@ -121,8 +121,8 @@ typedef struct VP9Common {
// roll new_fb_idx into it.
// Each frame can reference REFS_PER_FRAME buffers
int active_ref_idx[REFS_PER_FRAME];
struct scale_factors active_ref_scale[REFS_PER_FRAME];
RefBuffer frame_refs[REFS_PER_FRAME];
int new_fb_idx;
YV12_BUFFER_CONFIG post_proc_buffer;
......@@ -224,13 +224,6 @@ typedef struct VP9Common {
uint32_t fb_idx_ref_lru_count;
} VP9_COMMON;
// ref == 0 => LAST_FRAME
// ref == 1 => GOLDEN_FRAME
// ref == 2 => ALTREF_FRAME
static YV12_BUFFER_CONFIG *get_frame_ref_buffer(VP9_COMMON *cm, int ref) {
return &cm->yv12_fb[cm->active_ref_idx[ref]];
}
static YV12_BUFFER_CONFIG *get_frame_new_buffer(VP9_COMMON *cm) {
return &cm->yv12_fb[cm->new_fb_idx];
}
......
......@@ -153,7 +153,7 @@ static void build_inter_predictors(MACROBLOCKD *xd, int plane, int block,
int ref;
for (ref = 0; ref < 1 + is_compound; ++ref) {
const struct scale_factors *const sf = xd->scale_factors[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;
......@@ -256,7 +256,7 @@ static void dec_build_inter_predictors(MACROBLOCKD *xd, int plane, int block,
int ref;
for (ref = 0; ref < 1 + is_compound; ++ref) {
const struct scale_factors *const sf = xd->scale_factors[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;
......@@ -283,7 +283,7 @@ static void dec_build_inter_predictors(MACROBLOCKD *xd, int plane, int block,
int xs, ys, x0, y0, x0_16, y0_16, x1, y1, frame_width,
frame_height, subpel_x, subpel_y;
uint8_t *ref_frame, *buf_ptr;
const YV12_BUFFER_CONFIG *ref_buf = xd->ref_buf[ref];
const YV12_BUFFER_CONFIG *ref_buf = xd->block_refs[ref]->buf;
// Get reference frame pointer, width and height.
if (plane == 0) {
......@@ -390,14 +390,3 @@ void vp9_dec_build_inter_predictors_sb(MACROBLOCKD *xd, int mi_row, int mi_col,
}
}
}
// TODO(dkovalev: find better place for this function)
void vp9_setup_scale_factors(VP9_COMMON *cm, int i) {
const int ref = cm->active_ref_idx[i];
struct scale_factors *const sf = &cm->active_ref_scale[i];
YV12_BUFFER_CONFIG *const fb = &cm->yv12_fb[ref];
vp9_setup_scale_factors_for_frame(sf,
fb->y_crop_width, fb->y_crop_height,
cm->width, cm->height);
}
......@@ -92,10 +92,8 @@ static void setup_pre_planes(MACROBLOCKD *xd, int i,
static void set_scale_factors(VP9_COMMON *cm, MACROBLOCKD *xd,
int ref0, int ref1) {
xd->scale_factors[0] = &cm->active_ref_scale[ref0 >= 0 ? ref0 : 0];
xd->scale_factors[1] = &cm->active_ref_scale[ref1 >= 0 ? ref1 : 0];
xd->block_refs[0] = &cm->frame_refs[ref0 >= 0 ? ref0 : 0];
xd->block_refs[1] = &cm->frame_refs[ref1 >= 0 ? ref1 : 0];
}
void vp9_setup_scale_factors(VP9_COMMON *cm, int i);
#endif // VP9_COMMON_VP9_RECONINTER_H_
......@@ -378,18 +378,13 @@ static void set_offsets(VP9_COMMON *const cm, MACROBLOCKD *const xd,
static void set_ref(VP9_COMMON *const cm, MACROBLOCKD *const xd,
int idx, int mi_row, int mi_col) {
MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
const int ref = mbmi->ref_frame[idx] - LAST_FRAME;
const YV12_BUFFER_CONFIG *cfg = get_frame_ref_buffer(cm, ref);
const struct scale_factors *sf = &cm->active_ref_scale[ref];
xd->ref_buf[idx] = cfg;
if (!vp9_is_valid_scale(sf))
RefBuffer *ref_buffer = &cm->frame_refs[mbmi->ref_frame[idx] - LAST_FRAME];
xd->block_refs[idx] = ref_buffer;
if (!vp9_is_valid_scale(&ref_buffer->sf))
vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
"Invalid scale factors");
xd->scale_factors[idx] = sf;
setup_pre_planes(xd, idx, cfg, mi_row, mi_col, xd->scale_factors[idx]);
xd->corrupted |= cfg->corrupted;
setup_pre_planes(xd, idx, ref_buffer->buf, mi_row, mi_col, &ref_buffer->sf);
xd->corrupted |= ref_buffer->buf->corrupted;
}
static void decode_modes_b(VP9_COMMON *const cm, MACROBLOCKD *const xd,
......@@ -737,9 +732,9 @@ static void setup_frame_size_with_refs(VP9D_COMP *pbi,
int found = 0, i;
for (i = 0; i < REFS_PER_FRAME; ++i) {
if (vp9_rb_read_bit(rb)) {
YV12_BUFFER_CONFIG *const cfg = get_frame_ref_buffer(cm, i);
width = cfg->y_crop_width;
height = cfg->y_crop_height;
YV12_BUFFER_CONFIG *const buf = cm->frame_refs[i].buf;
width = buf->y_crop_width;
height = buf->y_crop_height;
found = 1;
break;
}
......@@ -1171,8 +1166,10 @@ static size_t read_uncompressed_header(VP9D_COMP *pbi,
pbi->refresh_frame_flags = (1 << REF_FRAMES) - 1;
for (i = 0; i < REFS_PER_FRAME; ++i)
cm->active_ref_idx[i] = cm->new_fb_idx;
for (i = 0; i < REFS_PER_FRAME; ++i) {
cm->frame_refs[i].idx = cm->new_fb_idx;
cm->frame_refs[i].buf = get_frame_new_buffer(cm);
}
setup_frame_size(pbi, rb);
} else {
......@@ -1191,7 +1188,9 @@ static size_t read_uncompressed_header(VP9D_COMP *pbi,
for (i = 0; i < REFS_PER_FRAME; ++i) {
const int ref = vp9_rb_read_literal(rb, REF_FRAMES_LOG2);
cm->active_ref_idx[i] = cm->ref_frame_map[ref];
const int idx = cm->ref_frame_map[ref];
cm->frame_refs[i].idx = idx;
cm->frame_refs[i].buf = &cm->yv12_fb[idx];
cm->ref_frame_sign_bias[LAST_FRAME + i] = vp9_rb_read_bit(rb);
}
......@@ -1201,9 +1200,13 @@ static size_t read_uncompressed_header(VP9D_COMP *pbi,
cm->mcomp_filter_type = read_interp_filter_type(rb);
for (i = 0; i < REFS_PER_FRAME; ++i) {
vp9_setup_scale_factors(cm, i);
if (vp9_is_scaled(&cm->active_ref_scale[i]))
vp9_extend_frame_borders(&cm->yv12_fb[cm->active_ref_idx[i]],
RefBuffer *const ref_buf = &cm->frame_refs[i];
vp9_setup_scale_factors_for_frame(&ref_buf->sf,
ref_buf->buf->y_crop_width,
ref_buf->buf->y_crop_height,
cm->width, cm->height);
if (vp9_is_scaled(&ref_buf->sf))
vp9_extend_frame_borders(ref_buf->buf,
cm->subsampling_x, cm->subsampling_y);
}
}
......
......@@ -219,7 +219,7 @@ vpx_codec_err_t vp9_set_reference_dec(VP9D_PTR ptr, VP9_REFFRAME ref_frame_flag,
YV12_BUFFER_CONFIG *sd) {
VP9D_COMP *pbi = (VP9D_COMP *) ptr;
VP9_COMMON *cm = &pbi->common;
int *ref_fb_ptr = NULL;
RefBuffer *ref_buf = NULL;
/* TODO(jkoleszar): The decoder doesn't have any real knowledge of what the
* encoder is using the frame buffers for. This is just a stub to keep the
......@@ -227,21 +227,23 @@ vpx_codec_err_t vp9_set_reference_dec(VP9D_PTR ptr, VP9_REFFRAME ref_frame_flag,
* later commit that adds VP9-specific controls for this functionality.
*/
if (ref_frame_flag == VP9_LAST_FLAG) {
ref_fb_ptr = &pbi->common.active_ref_idx[0];
ref_buf = &cm->frame_refs[0];
} else if (ref_frame_flag == VP9_GOLD_FLAG) {
ref_fb_ptr = &pbi->common.active_ref_idx[1];
ref_buf = &cm->frame_refs[1];
} else if (ref_frame_flag == VP9_ALT_FLAG) {
ref_fb_ptr = &pbi->common.active_ref_idx[2];
ref_buf = &cm->frame_refs[2];
} else {
vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
"Invalid reference frame");
return pbi->common.error.error_code;
}
if (!equal_dimensions(&cm->yv12_fb[*ref_fb_ptr], sd)) {
if (!equal_dimensions(ref_buf->buf, sd)) {
vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
"Incorrect buffer dimensions");
} else {
int *ref_fb_ptr = &ref_buf->idx;
// Find an empty frame buffer.
const int free_fb = get_free_fb(cm);
// Decrease fb_idx_ref_cnt since it will be increased again in
......@@ -250,7 +252,8 @@ vpx_codec_err_t vp9_set_reference_dec(VP9D_PTR ptr, VP9_REFFRAME ref_frame_flag,
// Manage the reference counters and copy image.
ref_cnt_fb(cm->fb_idx_ref_cnt, ref_fb_ptr, free_fb);
vp8_yv12_copy_frame(sd, &cm->yv12_fb[*ref_fb_ptr]);
ref_buf->buf = &cm->yv12_fb[*ref_fb_ptr];
vp8_yv12_copy_frame(sd, ref_buf->buf);
}
return pbi->common.error.error_code;
......@@ -285,7 +288,7 @@ static void swap_frame_buffers(VP9D_COMP *pbi) {
// Invalidate these references until the next frame starts.
for (ref_index = 0; ref_index < 3; ref_index++)
cm->active_ref_idx[ref_index] = INT_MAX;
cm->frame_refs[ref_index].idx = INT_MAX;
}
int vp9_receive_compressed_data(VP9D_PTR ptr,
......@@ -317,8 +320,8 @@ int vp9_receive_compressed_data(VP9D_PTR ptr,
* at this point, but if it becomes so, [0] may not always be the correct
* thing to do here.
*/
if (cm->active_ref_idx[0] != INT_MAX)
get_frame_ref_buffer(cm, 0)->corrupted = 1;
if (cm->frame_refs[0].idx != INT_MAX)
cm->frame_refs[0].buf->corrupted = 1;
}
cm->new_fb_idx = get_free_fb(cm);
......@@ -334,8 +337,8 @@ int vp9_receive_compressed_data(VP9D_PTR ptr,
* at this point, but if it becomes so, [0] may not always be the correct
* thing to do here.
*/
if (cm->active_ref_idx[0] != INT_MAX)
get_frame_ref_buffer(cm, 0)->corrupted = 1;
if (cm->frame_refs[0].idx != INT_MAX)
cm->frame_refs[0].buf->corrupted = 1;
if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
......
......@@ -2588,9 +2588,8 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled,
for (ref = 0; ref < 1 + is_compound; ++ref) {
YV12_BUFFER_CONFIG *cfg = &cm->yv12_fb[cm->ref_frame_map[
get_ref_frame_idx(cpi, mbmi->ref_frame[ref])]];
setup_pre_planes(xd, ref, cfg, mi_row, mi_col, xd->scale_factors[ref]);
setup_pre_planes(xd, ref, cfg, mi_row, mi_col, &xd->block_refs[ref]->sf);
}
vp9_build_inter_predictors_sb(xd, mi_row, mi_col, MAX(bsize, BLOCK_8X8));
}
......
......@@ -3303,6 +3303,7 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags,
VP9_COMMON *cm = &cpi->common;
struct vpx_usec_timer cmptimer;
YV12_BUFFER_CONFIG *force_src_buffer = NULL;
const int refs[] = { cpi->lst_fb_idx, cpi->gld_fb_idx, cpi->alt_fb_idx };
int i;
// FILE *fp_out = fopen("enc_frame_type.txt", "a");
......@@ -3504,16 +3505,13 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags,
}
#endif
/* Get the mapping of L/G/A to the reference buffer pool */
cm->active_ref_idx[0] = cm->ref_frame_map[cpi->lst_fb_idx];
cm->active_ref_idx[1] = cm->ref_frame_map[cpi->gld_fb_idx];
cm->active_ref_idx[2] = cm->ref_frame_map[cpi->alt_fb_idx];
#if 0 // CONFIG_MULTIPLE_ARF
if (cpi->multi_arf_enabled) {
fprintf(fp_out, " idx(%d, %d, %d, %d) active(%d, %d, %d)",
cpi->lst_fb_idx, cpi->gld_fb_idx, cpi->alt_fb_idx, cm->new_fb_idx,
cm->active_ref_idx[0], cm->active_ref_idx[1], cm->active_ref_idx[2]);
cm->ref_frame_map[cpi->lst_fb_idx],
cm->ref_frame_map[cpi->gld_fb_idx],
cm->ref_frame_map[cpi->alt_fb_idx]);
if (cpi->refresh_alt_ref_frame)
fprintf(fp_out, " type:ARF");
if (cpi->rc.is_src_frame_alt_ref)
......@@ -3530,12 +3528,20 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags,
cm->subsampling_x, cm->subsampling_y,
VP9BORDERINPIXELS, NULL, NULL, NULL);
// Calculate scaling factors for each of the 3 available references
for (i = 0; i < REFS_PER_FRAME; ++i) {
vp9_setup_scale_factors(cm, i);
if (vp9_is_scaled(&cm->active_ref_scale[i]))
vp9_extend_frame_borders(&cm->yv12_fb[cm->active_ref_idx[i]],
cm->subsampling_x, cm->subsampling_y);
const int idx = cm->ref_frame_map[refs[i]];
YV12_BUFFER_CONFIG *const buf = &cm->yv12_fb[idx];
RefBuffer *const ref_buf = &cm->frame_refs[i];
ref_buf->buf = buf;
ref_buf->idx = idx;
vp9_setup_scale_factors_for_frame(&ref_buf->sf,
buf->y_crop_width, buf->y_crop_height,
cm->width, cm->height);
if (vp9_is_scaled(&ref_buf->sf))
vp9_extend_frame_borders(buf, cm->subsampling_x, cm->subsampling_y);
}
vp9_setup_interp_filters(&cpi->mb.e_mbd, DEFAULT_INTERP_FILTER, cm);
......
......@@ -1524,7 +1524,7 @@ static int64_t encode_inter_mb_segment(VP9_COMP *cpi,
vp9_build_inter_predictor(pre, pd->pre[ref].stride,
dst, pd->dst.stride,
&mi->bmi[i].as_mv[ref].as_mv,
xd->scale_factors[ref],
&xd->block_refs[ref]->sf,
width, height, ref, &xd->subpix, MV_PRECISION_Q3,
mi_col * MI_SIZE + 4 * (i % 2),
mi_row * MI_SIZE + 4 * (i / 2));
......@@ -2268,8 +2268,7 @@ static void setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x,
YV12_BUFFER_CONFIG *yv12 = &cm->yv12_fb[cpi->common.ref_frame_map[idx]];
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
const struct scale_factors *const sf =
&cpi->common.active_ref_scale[frame_type - 1];
const struct scale_factors *const sf = &cm->frame_refs[frame_type - 1].sf;
// TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this
......@@ -2540,7 +2539,7 @@ static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
ref_yv12[!id].stride,
second_pred, pw,
&frame_mv[refs[!id]].as_mv,
xd->scale_factors[!id],
&xd->block_refs[!id]->sf,
pw, ph, 0,
&xd->subpix, MV_PRECISION_Q3,
mi_col * MI_SIZE, mi_row * MI_SIZE);
......@@ -3965,11 +3964,11 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
// TODO(jingning, jkoleszar): scaling reference frame not supported for
// sub8x8 blocks.
if (ref_frame > 0 &&
vp9_is_scaled(&cpi->common.active_ref_scale[ref_frame - 1]))
vp9_is_scaled(&cpi->common.frame_refs[ref_frame - 1].sf))
continue;
if (second_ref_frame > 0 &&
vp9_is_scaled(&cpi->common.active_ref_scale[second_ref_frame - 1]))
vp9_is_scaled(&cpi->common.frame_refs[second_ref_frame - 1].sf))
continue;
set_scale_factors(cm, xd, ref_frame - 1, second_ref_frame - 1);
......
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