Commit 497d1951 authored by Thomas Daede's avatar Thomas Daede

Normalize set/get reference ctrls to use ref frame index.

Change-Id: I61165218afefe7fc59ad06a0abe0180754cdf7bd
parent 099b1221
......@@ -45,9 +45,7 @@ extern "C" {
enum aom_com_control_id {
/*!\brief pass in an external frame into decoder to be used as reference frame
*/
AOM_SET_REFERENCE = 1,
AOM_COPY_REFERENCE = 2, /**< get a copy of reference frame from the decoder */
AOM_SET_POSTPROC = 3, /**< set the decoder's post processing settings */
AOM_SET_POSTPROC = 3, /**< set the decoder's post processing settings */
AOM_SET_DBG_COLOR_REF_FRAME =
4, /**< set the reference frames to color for each macroblock */
AOM_SET_DBG_COLOR_MB_MODES = 5, /**< set which macro block modes to color */
......@@ -59,6 +57,9 @@ enum aom_com_control_id {
* AOM_DECODER_CTRL_ID_START range next time we're ready to break the ABI.
*/
AV1_GET_REFERENCE = 128, /**< get a pointer to a reference frame */
AV1_SET_REFERENCE = 129, /**< write a frame into a reference buffer */
AV1_COPY_REFERENCE =
130, /**< get a copy of reference frame from the decoder */
AOM_COMMON_CTRL_ID_MAX,
AV1_GET_NEW_FRAME_IMAGE = 192, /**< get a pointer to the new frame */
......@@ -98,25 +99,6 @@ typedef struct aom_postproc_cfg {
int noise_level; /**< the strength of additive noise, valid range [0, 16] */
} aom_postproc_cfg_t;
/*!\brief reference frame type
*
* The set of macros define the type of AOM reference frames
*/
typedef enum aom_ref_frame_type {
AOM_LAST_FRAME = 1,
AOM_GOLD_FRAME = 2,
AOM_ALTR_FRAME = 4
} aom_ref_frame_type_t;
/*!\brief reference frame data struct
*
* Define the data struct to access aom reference frames.
*/
typedef struct aom_ref_frame {
aom_ref_frame_type_t frame_type; /**< which reference frame */
aom_image_t img; /**< reference frame data in image format */
} aom_ref_frame_t;
/*!\brief AV1 specific reference frame data struct
*
* Define the data struct to access av1 reference frames.
......@@ -131,10 +113,6 @@ typedef struct av1_ref_frame {
*
* defines the data type for each of AOM decoder control function requires
*/
AOM_CTRL_USE_TYPE(AOM_SET_REFERENCE, aom_ref_frame_t *)
#define AOM_CTRL_AOM_SET_REFERENCE
AOM_CTRL_USE_TYPE(AOM_COPY_REFERENCE, aom_ref_frame_t *)
#define AOM_CTRL_AOM_COPY_REFERENCE
AOM_CTRL_USE_TYPE(AOM_SET_POSTPROC, aom_postproc_cfg_t *)
#define AOM_CTRL_AOM_SET_POSTPROC
AOM_CTRL_USE_TYPE(AOM_SET_DBG_COLOR_REF_FRAME, int)
......@@ -147,6 +125,10 @@ AOM_CTRL_USE_TYPE(AOM_SET_DBG_DISPLAY_MV, int)
#define AOM_CTRL_AOM_SET_DBG_DISPLAY_MV
AOM_CTRL_USE_TYPE(AV1_GET_REFERENCE, av1_ref_frame_t *)
#define AOM_CTRL_AV1_GET_REFERENCE
AOM_CTRL_USE_TYPE(AV1_SET_REFERENCE, av1_ref_frame_t *)
#define AOM_CTRL_AV1_SET_REFERENCE
AOM_CTRL_USE_TYPE(AV1_COPY_REFERENCE, av1_ref_frame_t *)
#define AOM_CTRL_AV1_COPY_REFERENCE
AOM_CTRL_USE_TYPE(AV1_GET_NEW_FRAME_IMAGE, aom_image_t *)
#define AOM_CTRL_AV1_GET_NEW_FRAME_IMAGE
......
......@@ -1294,14 +1294,13 @@ static const aom_codec_cx_pkt_t *encoder_get_cxdata(aom_codec_alg_priv_t *ctx,
static aom_codec_err_t ctrl_set_reference(aom_codec_alg_priv_t *ctx,
va_list args) {
aom_ref_frame_t *const frame = va_arg(args, aom_ref_frame_t *);
av1_ref_frame_t *const frame = va_arg(args, av1_ref_frame_t *);
if (frame != NULL) {
YV12_BUFFER_CONFIG sd;
image2yuvconfig(&frame->img, &sd);
av1_set_reference_enc(ctx->cpi, ref_frame_to_av1_reframe(frame->frame_type),
&sd);
av1_set_reference_enc(ctx->cpi, frame->idx, &sd);
return AOM_CODEC_OK;
} else {
return AOM_CODEC_INVALID_PARAM;
......@@ -1310,14 +1309,13 @@ static aom_codec_err_t ctrl_set_reference(aom_codec_alg_priv_t *ctx,
static aom_codec_err_t ctrl_copy_reference(aom_codec_alg_priv_t *ctx,
va_list args) {
aom_ref_frame_t *const frame = va_arg(args, aom_ref_frame_t *);
av1_ref_frame_t *const frame = va_arg(args, av1_ref_frame_t *);
if (frame != NULL) {
YV12_BUFFER_CONFIG sd;
image2yuvconfig(&frame->img, &sd);
av1_copy_reference_enc(ctx->cpi,
ref_frame_to_av1_reframe(frame->frame_type), &sd);
av1_copy_reference_enc(ctx->cpi, frame->idx, &sd);
return AOM_CODEC_OK;
} else {
return AOM_CODEC_INVALID_PARAM;
......@@ -1500,11 +1498,11 @@ static aom_codec_err_t ctrl_set_ans_window_size_log2(aom_codec_alg_priv_t *ctx,
#endif
static aom_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
{ AOM_COPY_REFERENCE, ctrl_copy_reference },
{ AV1_COPY_REFERENCE, ctrl_copy_reference },
{ AOME_USE_REFERENCE, ctrl_use_reference },
// Setters
{ AOM_SET_REFERENCE, ctrl_set_reference },
{ AV1_SET_REFERENCE, ctrl_set_reference },
{ AOM_SET_POSTPROC, ctrl_set_previewpp },
{ AOME_SET_ROI_MAP, ctrl_set_roi_map },
{ AOME_SET_ACTIVEMAP, ctrl_set_active_map },
......
......@@ -876,7 +876,7 @@ static aom_codec_err_t decoder_set_fb_fn(
static aom_codec_err_t ctrl_set_reference(aom_codec_alg_priv_t *ctx,
va_list args) {
aom_ref_frame_t *const data = va_arg(args, aom_ref_frame_t *);
av1_ref_frame_t *const data = va_arg(args, av1_ref_frame_t *);
// Only support this function in serial decode.
if (ctx->frame_parallel_decode) {
......@@ -885,13 +885,12 @@ static aom_codec_err_t ctrl_set_reference(aom_codec_alg_priv_t *ctx,
}
if (data) {
aom_ref_frame_t *const frame = (aom_ref_frame_t *)data;
av1_ref_frame_t *const frame = data;
YV12_BUFFER_CONFIG sd;
AVxWorker *const worker = ctx->frame_workers;
FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1;
image2yuvconfig(&frame->img, &sd);
return av1_set_reference_dec(&frame_worker_data->pbi->common,
ref_frame_to_av1_reframe(frame->frame_type),
return av1_set_reference_dec(&frame_worker_data->pbi->common, frame->idx,
&sd);
} else {
return AOM_CODEC_INVALID_PARAM;
......@@ -900,7 +899,7 @@ static aom_codec_err_t ctrl_set_reference(aom_codec_alg_priv_t *ctx,
static aom_codec_err_t ctrl_copy_reference(aom_codec_alg_priv_t *ctx,
va_list args) {
const aom_ref_frame_t *const frame = va_arg(args, aom_ref_frame_t *);
const av1_ref_frame_t *const frame = va_arg(args, av1_ref_frame_t *);
// Only support this function in serial decode.
if (ctx->frame_parallel_decode) {
......@@ -913,8 +912,7 @@ static aom_codec_err_t ctrl_copy_reference(aom_codec_alg_priv_t *ctx,
AVxWorker *const worker = ctx->frame_workers;
FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1;
image2yuvconfig(&frame->img, &sd);
return av1_copy_reference_dec(frame_worker_data->pbi,
(AOM_REFFRAME)frame->frame_type, &sd);
return av1_copy_reference_dec(frame_worker_data->pbi, frame->idx, &sd);
} else {
return AOM_CODEC_INVALID_PARAM;
}
......@@ -1209,10 +1207,10 @@ static aom_codec_err_t ctrl_set_inspection_callback(aom_codec_alg_priv_t *ctx,
}
static aom_codec_ctrl_fn_map_t decoder_ctrl_maps[] = {
{ AOM_COPY_REFERENCE, ctrl_copy_reference },
{ AV1_COPY_REFERENCE, ctrl_copy_reference },
// Setters
{ AOM_SET_REFERENCE, ctrl_set_reference },
{ AV1_SET_REFERENCE, ctrl_set_reference },
{ AOM_SET_POSTPROC, ctrl_set_postproc },
{ AOM_SET_DBG_COLOR_REF_FRAME, ctrl_set_dbg_options },
{ AOM_SET_DBG_COLOR_MB_MODES, ctrl_set_dbg_options },
......
......@@ -142,13 +142,4 @@ static aom_codec_err_t image2yuvconfig(const aom_image_t *img,
return AOM_CODEC_OK;
}
static AOM_REFFRAME ref_frame_to_av1_reframe(aom_ref_frame_type_t frame) {
switch (frame) {
case AOM_LAST_FRAME: return AOM_LAST_FLAG;
case AOM_GOLD_FRAME: return AOM_GOLD_FLAG;
case AOM_ALTR_FRAME: return AOM_ALT_FLAG;
}
assert(0 && "Invalid Reference Frame");
return AOM_LAST_FLAG;
}
#endif // AV1_AV1_IFACE_COMMON_H_
......@@ -184,107 +184,36 @@ static int equal_dimensions(const YV12_BUFFER_CONFIG *a,
a->uv_height == b->uv_height && a->uv_width == b->uv_width;
}
aom_codec_err_t av1_copy_reference_dec(AV1Decoder *pbi,
AOM_REFFRAME ref_frame_flag,
aom_codec_err_t av1_copy_reference_dec(AV1Decoder *pbi, int idx,
YV12_BUFFER_CONFIG *sd) {
AV1_COMMON *cm = &pbi->common;
/* 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
* aomenc --test-decode functionality working, and will be replaced in a
* later commit that adds AV1-specific controls for this functionality.
*/
if (ref_frame_flag == AOM_LAST_FLAG) {
const YV12_BUFFER_CONFIG *const cfg = get_ref_frame(cm, 0);
if (cfg == NULL) {
aom_internal_error(&cm->error, AOM_CODEC_ERROR,
"No 'last' reference frame");
return AOM_CODEC_ERROR;
}
if (!equal_dimensions(cfg, sd))
aom_internal_error(&cm->error, AOM_CODEC_ERROR,
"Incorrect buffer dimensions");
else
aom_yv12_copy_frame(cfg, sd);
} else {
aom_internal_error(&cm->error, AOM_CODEC_ERROR, "Invalid reference frame");
const YV12_BUFFER_CONFIG *const cfg = get_ref_frame(cm, idx);
if (cfg == NULL) {
aom_internal_error(&cm->error, AOM_CODEC_ERROR, "No reference frame");
return AOM_CODEC_ERROR;
}
if (!equal_dimensions(cfg, sd))
aom_internal_error(&cm->error, AOM_CODEC_ERROR,
"Incorrect buffer dimensions");
else
aom_yv12_copy_frame(cfg, sd);
return cm->error.error_code;
}
aom_codec_err_t av1_set_reference_dec(AV1_COMMON *cm,
AOM_REFFRAME ref_frame_flag,
aom_codec_err_t av1_set_reference_dec(AV1_COMMON *cm, int idx,
YV12_BUFFER_CONFIG *sd) {
int idx;
YV12_BUFFER_CONFIG *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
// aomenc --test-decode functionality working, and will be replaced in a
// later commit that adds AV1-specific controls for this functionality.
// (Yunqing) The set_reference control depends on the following setting in
// encoder.
// cpi->lst_fb_idx = 0;
// #if CONFIG_EXT_REFS
// cpi->lst2_fb_idx = 1;
// cpi->lst3_fb_idx = 2;
// cpi->gld_fb_idx = 3;
// cpi->bwd_fb_idx = 4;
// #if CONFIG_ALTREF2
// cpi->alt2_fb_idx = 5;
// cpi->alt_fb_idx = 6;
// #else // !CONFIG_ALTREF2
// cpi->alt_fb_idx = 5;
// #endif // CONFIG_ALTREF2
// #else // CONFIG_EXT_REFS
// cpi->gld_fb_idx = 1;
// cpi->alt_fb_idx = 2;
// #endif // CONFIG_EXT_REFS
// TODO(zoeliu): To revisit following code and reconsider what assumption we
// may take on the reference frame buffer virtual indexes
if (ref_frame_flag == AOM_LAST_FLAG) {
idx = cm->ref_frame_map[0];
#if CONFIG_EXT_REFS
} else if (ref_frame_flag == AOM_LAST2_FLAG) {
idx = cm->ref_frame_map[1];
} else if (ref_frame_flag == AOM_LAST3_FLAG) {
idx = cm->ref_frame_map[2];
} else if (ref_frame_flag == AOM_GOLD_FLAG) {
idx = cm->ref_frame_map[3];
} else if (ref_frame_flag == AOM_BWD_FLAG) {
idx = cm->ref_frame_map[4];
#if CONFIG_ALTREF2
} else if (ref_frame_flag == AOM_ALT2_FLAG) {
idx = cm->ref_frame_map[5];
} else if (ref_frame_flag == AOM_ALT_FLAG) {
idx = cm->ref_frame_map[6];
#else // !CONFIG_ALTREF2
} else if (ref_frame_flag == AOM_ALT_FLAG) {
idx = cm->ref_frame_map[5];
#endif // CONFIG_ALTREF2
#else // !CONFIG_EXT_REFS
} else if (ref_frame_flag == AOM_GOLD_FLAG) {
idx = cm->ref_frame_map[1];
} else if (ref_frame_flag == AOM_ALT_FLAG) {
idx = cm->ref_frame_map[2];
#endif // CONFIG_EXT_REFS
} else {
aom_internal_error(&cm->error, AOM_CODEC_ERROR, "Invalid reference frame");
return cm->error.error_code;
}
// Get the destination reference buffer.
ref_buf = get_ref_frame(cm, idx);
if (idx < 0 || idx >= FRAME_BUFFERS) {
aom_internal_error(&cm->error, AOM_CODEC_ERROR,
"Invalid reference frame map");
return cm->error.error_code;
if (ref_buf == NULL) {
aom_internal_error(&cm->error, AOM_CODEC_ERROR, "No reference frame");
return AOM_CODEC_ERROR;
}
// Get the destination reference buffer.
ref_buf = &cm->buffer_pool->frame_bufs[idx].buf;
if (!equal_dimensions(ref_buf, sd)) {
aom_internal_error(&cm->error, AOM_CODEC_ERROR,
"Incorrect buffer dimensions");
......
......@@ -150,12 +150,10 @@ int av1_get_raw_frame(struct AV1Decoder *pbi, YV12_BUFFER_CONFIG *sd);
int av1_get_frame_to_show(struct AV1Decoder *pbi, YV12_BUFFER_CONFIG *frame);
aom_codec_err_t av1_copy_reference_dec(struct AV1Decoder *pbi,
AOM_REFFRAME ref_frame_flag,
aom_codec_err_t av1_copy_reference_dec(struct AV1Decoder *pbi, int idx,
YV12_BUFFER_CONFIG *sd);
aom_codec_err_t av1_set_reference_dec(AV1_COMMON *cm,
AOM_REFFRAME ref_frame_flag,
aom_codec_err_t av1_set_reference_dec(AV1_COMMON *cm, int idx,
YV12_BUFFER_CONFIG *sd);
static INLINE uint8_t read_marker(aom_decrypt_cb decrypt_cb,
......
......@@ -3052,35 +3052,9 @@ void av1_update_reference(AV1_COMP *cpi, int ref_frame_flags) {
cpi->ext_refresh_frame_flags_pending = 1;
}
static YV12_BUFFER_CONFIG *get_av1_ref_frame_buffer(
AV1_COMP *cpi, AOM_REFFRAME ref_frame_flag) {
MV_REFERENCE_FRAME ref_frame = NONE_FRAME;
if (ref_frame_flag == AOM_LAST_FLAG) ref_frame = LAST_FRAME;
#if CONFIG_EXT_REFS
else if (ref_frame_flag == AOM_LAST2_FLAG)
ref_frame = LAST2_FRAME;
else if (ref_frame_flag == AOM_LAST3_FLAG)
ref_frame = LAST3_FRAME;
#endif // CONFIG_EXT_REFS
else if (ref_frame_flag == AOM_GOLD_FLAG)
ref_frame = GOLDEN_FRAME;
#if CONFIG_EXT_REFS
else if (ref_frame_flag == AOM_BWD_FLAG)
ref_frame = BWDREF_FRAME;
#if CONFIG_ALTREF2
else if (ref_frame_flag == AOM_ALT2_FLAG)
ref_frame = ALTREF2_FRAME;
#endif // CONFIG_ALTREF2
#endif // CONFIG_EXT_REFS
else if (ref_frame_flag == AOM_ALT_FLAG)
ref_frame = ALTREF_FRAME;
return ref_frame == NONE_FRAME ? NULL : get_ref_frame_buffer(cpi, ref_frame);
}
int av1_copy_reference_enc(AV1_COMP *cpi, AOM_REFFRAME ref_frame_flag,
YV12_BUFFER_CONFIG *sd) {
YV12_BUFFER_CONFIG *cfg = get_av1_ref_frame_buffer(cpi, ref_frame_flag);
int av1_copy_reference_enc(AV1_COMP *cpi, int idx, YV12_BUFFER_CONFIG *sd) {
AV1_COMMON *const cm = &cpi->common;
YV12_BUFFER_CONFIG *cfg = get_ref_frame(cm, idx);
if (cfg) {
aom_yv12_copy_frame(cfg, sd);
return 0;
......@@ -3089,9 +3063,9 @@ int av1_copy_reference_enc(AV1_COMP *cpi, AOM_REFFRAME ref_frame_flag,
}
}
int av1_set_reference_enc(AV1_COMP *cpi, AOM_REFFRAME ref_frame_flag,
YV12_BUFFER_CONFIG *sd) {
YV12_BUFFER_CONFIG *cfg = get_av1_ref_frame_buffer(cpi, ref_frame_flag);
int av1_set_reference_enc(AV1_COMP *cpi, int idx, YV12_BUFFER_CONFIG *sd) {
AV1_COMMON *const cm = &cpi->common;
YV12_BUFFER_CONFIG *cfg = get_ref_frame(cm, idx);
if (cfg) {
aom_yv12_copy_frame(sd, cfg);
return 0;
......
......@@ -633,11 +633,9 @@ int av1_use_as_reference(AV1_COMP *cpi, int ref_frame_flags);
void av1_update_reference(AV1_COMP *cpi, int ref_frame_flags);
int av1_copy_reference_enc(AV1_COMP *cpi, AOM_REFFRAME ref_frame_flag,
YV12_BUFFER_CONFIG *sd);
int av1_copy_reference_enc(AV1_COMP *cpi, int idx, YV12_BUFFER_CONFIG *sd);
int av1_set_reference_enc(AV1_COMP *cpi, AOM_REFFRAME ref_frame_flag,
YV12_BUFFER_CONFIG *sd);
int av1_set_reference_enc(AV1_COMP *cpi, int idx, YV12_BUFFER_CONFIG *sd);
int av1_update_entropy(AV1_COMP *cpi, int update);
......
......@@ -270,18 +270,18 @@ int main(int argc, char **argv) {
while (aom_img_read(&raw, infile)) {
if (limit && frame_in >= limit) break;
if (update_frame_num > 1 && frame_out + 1 == update_frame_num) {
aom_ref_frame_t ref;
ref.frame_type = AOM_LAST_FRAME;
av1_ref_frame_t ref;
ref.idx = 0;
ref.img = raw;
// Set reference frame in encoder.
if (aom_codec_control(&ecodec, AOM_SET_REFERENCE, &ref))
if (aom_codec_control(&ecodec, AV1_SET_REFERENCE, &ref))
die_codec(&ecodec, "Failed to set reference frame");
printf(" <SET_REF>");
// If set_reference in decoder is commented out, the enc/dec mismatch
// would be seen.
if (test_decode) {
if (aom_codec_control(&dcodec, AOM_SET_REFERENCE, &ref))
if (aom_codec_control(&dcodec, AV1_SET_REFERENCE, &ref))
die_codec(&dcodec, "Failed to set reference frame");
}
}
......
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