summaryrefslogtreecommitdiff
path: root/vp9/encoder/vp9_svc_layercontext.c
diff options
context:
space:
mode:
authorJerome Jiang <jianj@google.com>2018-08-06 11:37:43 -0700
committerJerome Jiang <jianj@google.com>2018-08-09 13:56:46 -0700
commita66da313805f41076fd05358a65c1084f646f348 (patch)
tree8332b6ceae06c3bb5cbddbcb1bba1ae5891c80c5 /vp9/encoder/vp9_svc_layercontext.c
parentaab2aff9aa264d573852f4dce34bea47708cf1be (diff)
downloadlibvpx-a66da313805f41076fd05358a65c1084f646f348.tar
libvpx-a66da313805f41076fd05358a65c1084f646f348.tar.gz
libvpx-a66da313805f41076fd05358a65c1084f646f348.tar.bz2
libvpx-a66da313805f41076fd05358a65c1084f646f348.zip
vp9-svc: Update to SET/GET_SVC_REF_FRAME_CONFIG api
Add update_buffer_slot to SVC API to allow for refreshing any of the 8 reference buffers. Remove frame_flags from the struct. Remove svc tests from vp8 build. BUG=b/112292577 Change-Id: I0551c349d2b311227245a8ed1639cdbbaf5bc5db
Diffstat (limited to 'vp9/encoder/vp9_svc_layercontext.c')
-rw-r--r--vp9/encoder/vp9_svc_layercontext.c120
1 files changed, 82 insertions, 38 deletions
diff --git a/vp9/encoder/vp9_svc_layercontext.c b/vp9/encoder/vp9_svc_layercontext.c
index 0b7e7fe80..2154d144a 100644
--- a/vp9/encoder/vp9_svc_layercontext.c
+++ b/vp9/encoder/vp9_svc_layercontext.c
@@ -660,6 +660,23 @@ static void set_flags_and_fb_idx_for_temporal_mode_noLayering(
reset_fb_idx_unused(cpi);
}
+static void set_flags_and_fb_idx_bypass_via_set_ref_frame_config(
+ VP9_COMP *const cpi) {
+ SVC *const svc = &cpi->svc;
+ int sl = svc->spatial_layer_id = svc->spatial_layer_to_encode;
+ cpi->ext_refresh_frame_flags_pending = 1;
+ cpi->lst_fb_idx = svc->lst_fb_idx[sl];
+ cpi->gld_fb_idx = svc->gld_fb_idx[sl];
+ cpi->alt_fb_idx = svc->alt_fb_idx[sl];
+ cpi->ext_refresh_last_frame = 0;
+ cpi->ext_refresh_golden_frame = 0;
+ cpi->ext_refresh_alt_ref_frame = 0;
+ cpi->ref_frame_flags = 0;
+ if (svc->reference_last[sl]) cpi->ref_frame_flags |= VP9_LAST_FLAG;
+ if (svc->reference_golden[sl]) cpi->ref_frame_flags |= VP9_GOLD_FLAG;
+ if (svc->reference_altref[sl]) cpi->ref_frame_flags |= VP9_ALT_FLAG;
+}
+
void vp9_copy_flags_ref_update_idx(VP9_COMP *const cpi) {
SVC *const svc = &cpi->svc;
static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
@@ -668,10 +685,23 @@ void vp9_copy_flags_ref_update_idx(VP9_COMP *const cpi) {
svc->lst_fb_idx[sl] = cpi->lst_fb_idx;
svc->gld_fb_idx[sl] = cpi->gld_fb_idx;
svc->alt_fb_idx[sl] = cpi->alt_fb_idx;
-
+ // For the fixed SVC mode: pass the refresh_lst/gld/alt_frame flags to the
+ // update_buffer_slot, this is needed for the GET_SVC_REF_FRAME_CONFIG api.
+ if (svc->temporal_layering_mode != VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
+ int ref;
+ for (ref = 0; ref < REF_FRAMES; ++ref) {
+ svc->update_buffer_slot[sl] &= ~(1 << ref);
+ if ((ref == svc->lst_fb_idx[sl] && cpi->refresh_last_frame) ||
+ (ref == svc->gld_fb_idx[sl] && cpi->refresh_golden_frame) ||
+ (ref == svc->alt_fb_idx[sl] && cpi->refresh_alt_ref_frame))
+ svc->update_buffer_slot[sl] |= (1 << ref);
+ }
+ }
+ // TODO(jianj): Remove these 3, deprecated.
svc->update_last[sl] = (uint8_t)cpi->refresh_last_frame;
svc->update_golden[sl] = (uint8_t)cpi->refresh_golden_frame;
svc->update_altref[sl] = (uint8_t)cpi->refresh_alt_ref_frame;
+
svc->reference_last[sl] =
(uint8_t)(cpi->ref_frame_flags & flag_list[LAST_FRAME]);
svc->reference_golden[sl] =
@@ -701,23 +731,8 @@ int vp9_one_pass_cbr_svc_start_layer(VP9_COMP *const cpi) {
set_flags_and_fb_idx_for_temporal_mode2(cpi);
} else if (svc->temporal_layering_mode ==
VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
- // In the BYPASS/flexible mode, the encoder is relying on the application
- // to specify, for each spatial layer, the flags and buffer indices for the
- // layering.
- // Note that the check (cpi->ext_refresh_frame_flags_pending == 0) is
- // needed to support the case where the frame flags may be passed in via
- // vpx_codec_encode(), which can be used for the temporal-only svc case.
- // TODO(marpan): Consider adding an enc_config parameter to better handle
- // this case.
- if (cpi->ext_refresh_frame_flags_pending == 0) {
- int sl;
- svc->spatial_layer_id = svc->spatial_layer_to_encode;
- sl = svc->spatial_layer_id;
- vp9_apply_encoding_flags(cpi, svc->ext_frame_flags[sl]);
- cpi->lst_fb_idx = svc->lst_fb_idx[sl];
- cpi->gld_fb_idx = svc->gld_fb_idx[sl];
- cpi->alt_fb_idx = svc->alt_fb_idx[sl];
- }
+ if (cpi->ext_refresh_frame_flags_pending == 0)
+ set_flags_and_fb_idx_bypass_via_set_ref_frame_config(cpi);
}
if (cpi->lst_fb_idx == svc->buffer_gf_temporal_ref[0].idx ||
@@ -772,13 +787,18 @@ int vp9_one_pass_cbr_svc_start_layer(VP9_COMP *const cpi) {
memset(&svc->lst_fb_idx, -1, sizeof(svc->lst_fb_idx));
memset(&svc->gld_fb_idx, -1, sizeof(svc->lst_fb_idx));
memset(&svc->alt_fb_idx, -1, sizeof(svc->lst_fb_idx));
+ // These are set by API before the superframe is encoded and they are
+ // passed to encoder layer by layer. Don't reset them on layer 0 in bypass
+ // mode.
+ vp9_zero(svc->update_buffer_slot);
+ vp9_zero(svc->reference_last);
+ vp9_zero(svc->reference_golden);
+ vp9_zero(svc->reference_altref);
+ // TODO(jianj): Remove these 3, deprecated.
+ vp9_zero(svc->update_last);
+ vp9_zero(svc->update_golden);
+ vp9_zero(svc->update_altref);
}
- vp9_zero(svc->update_last);
- vp9_zero(svc->update_golden);
- vp9_zero(svc->update_altref);
- vp9_zero(svc->reference_last);
- vp9_zero(svc->reference_golden);
- vp9_zero(svc->reference_altref);
}
lc = &svc->layer_context[svc->spatial_layer_id * svc->number_temporal_layers +
@@ -835,8 +855,13 @@ int vp9_one_pass_cbr_svc_start_layer(VP9_COMP *const cpi) {
svc->non_reference_frame = 0;
if (cpi->common.frame_type != KEY_FRAME && !cpi->ext_refresh_last_frame &&
- !cpi->ext_refresh_golden_frame && !cpi->ext_refresh_alt_ref_frame) {
+ !cpi->ext_refresh_golden_frame && !cpi->ext_refresh_alt_ref_frame)
svc->non_reference_frame = 1;
+ // For non-flexible mode, where update_buffer_slot is used, need to check if
+ // all buffer slots are not refreshed.
+ if (svc->temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
+ if (svc->update_buffer_slot[svc->spatial_layer_id] != 0)
+ svc->non_reference_frame = 0;
}
if (svc->spatial_layer_id == 0) svc->high_source_sad_superframe = 0;
@@ -940,16 +965,17 @@ void vp9_svc_check_reset_layer_rc_flag(VP9_COMP *const cpi) {
void vp9_svc_constrain_inter_layer_pred(VP9_COMP *const cpi) {
VP9_COMMON *const cm = &cpi->common;
+ SVC *const svc = &cpi->svc;
// Check for disabling inter-layer (spatial) prediction, if
// svc.disable_inter_layer_pred is set. If the previous spatial layer was
// dropped then disable the prediction from this (scaled) reference.
// For INTER_LAYER_PRED_OFF_NONKEY: inter-layer prediction is disabled
// on key frames or if any spatial layer is a sync layer.
- if ((cpi->svc.disable_inter_layer_pred == INTER_LAYER_PRED_OFF_NONKEY &&
- !cpi->svc.layer_context[cpi->svc.temporal_layer_id].is_key_frame &&
- !cpi->svc.superframe_has_layer_sync) ||
- cpi->svc.disable_inter_layer_pred == INTER_LAYER_PRED_OFF ||
- cpi->svc.drop_spatial_layer[cpi->svc.spatial_layer_id - 1]) {
+ if ((svc->disable_inter_layer_pred == INTER_LAYER_PRED_OFF_NONKEY &&
+ !svc->layer_context[svc->temporal_layer_id].is_key_frame &&
+ !svc->superframe_has_layer_sync) ||
+ svc->disable_inter_layer_pred == INTER_LAYER_PRED_OFF ||
+ svc->drop_spatial_layer[svc->spatial_layer_id - 1]) {
MV_REFERENCE_FRAME ref_frame;
static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
VP9_ALT_FLAG };
@@ -967,7 +993,7 @@ void vp9_svc_constrain_inter_layer_pred(VP9_COMP *const cpi) {
// prediction (the reference that is scaled) is not the previous spatial layer
// from the same superframe, then we disable inter-layer prediction.
// Only need to check when inter_layer prediction is not set to OFF mode.
- if (cpi->svc.disable_inter_layer_pred != INTER_LAYER_PRED_OFF) {
+ if (svc->disable_inter_layer_pred != INTER_LAYER_PRED_OFF) {
// We only use LAST and GOLDEN for prediction in real-time mode, so we
// check both here.
MV_REFERENCE_FRAME ref_frame;
@@ -985,14 +1011,15 @@ void vp9_svc_constrain_inter_layer_pred(VP9_COMP *const cpi) {
int fb_idx =
ref_frame == LAST_FRAME ? cpi->lst_fb_idx : cpi->gld_fb_idx;
int ref_flag = ref_frame == LAST_FRAME ? VP9_LAST_FLAG : VP9_GOLD_FLAG;
- int sl = cpi->svc.spatial_layer_id;
+ int sl = svc->spatial_layer_id;
int disable = 1;
- if ((fb_idx == cpi->svc.lst_fb_idx[sl - 1] &&
- cpi->svc.update_last[sl - 1]) ||
- (fb_idx == cpi->svc.gld_fb_idx[sl - 1] &&
- cpi->svc.update_golden[sl - 1]) ||
- (fb_idx == cpi->svc.alt_fb_idx[sl - 1] &&
- cpi->svc.update_altref[sl - 1]))
+ if (fb_idx < 0) continue;
+ if ((fb_idx == svc->lst_fb_idx[sl - 1] &&
+ (svc->update_buffer_slot[sl - 1] & (1 << fb_idx))) ||
+ (fb_idx == svc->gld_fb_idx[sl - 1] &&
+ (svc->update_buffer_slot[sl - 1] & (1 << fb_idx))) ||
+ (fb_idx == svc->alt_fb_idx[sl - 1] &&
+ (svc->update_buffer_slot[sl - 1] & (1 << fb_idx))))
disable = 0;
if (disable) cpi->ref_frame_flags &= (~ref_flag);
}
@@ -1098,3 +1125,20 @@ void vp9_svc_update_ref_frame_buffer_idx(VP9_COMP *const cpi) {
svc->fb_idx_base[cpi->alt_fb_idx] = 1;
}
}
+
+void vp9_svc_update_ref_frame_bypass_mode(VP9_COMP *const cpi) {
+ // For non-flexible/bypass SVC mode: check for refreshing other buffer
+ // slots.
+ SVC *const svc = &cpi->svc;
+ VP9_COMMON *const cm = &cpi->common;
+ BufferPool *const pool = cm->buffer_pool;
+ int i;
+ for (i = 0; i < REF_FRAMES; i++) {
+ if (cm->frame_type == KEY_FRAME ||
+ svc->update_buffer_slot[svc->spatial_layer_id] & (1 << i)) {
+ ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[i], cm->new_fb_idx);
+ svc->fb_idx_spatial_layer_id[i] = svc->spatial_layer_id;
+ svc->fb_idx_temporal_layer_id[i] = svc->temporal_layer_id;
+ }
+ }
+}