diff options
author | Minghai Shang <minghai@google.com> | 2014-05-01 10:53:47 -0700 |
---|---|---|
committer | Gerrit Code Review <gerrit@gerrit.golo.chromium.org> | 2014-05-01 10:53:47 -0700 |
commit | 528a5c28b313fbcc7da6264f7151d26a610ddcfd (patch) | |
tree | c981455db5f05fc5b539214823561c969defcd69 /vp9/encoder | |
parent | 1d29ce53fe75cf03481f6044caa2b1cbbfc08c92 (diff) | |
parent | f916a3e256bc0e54852b48ec741c594aa58e2f26 (diff) | |
download | libvpx-528a5c28b313fbcc7da6264f7151d26a610ddcfd.tar libvpx-528a5c28b313fbcc7da6264f7151d26a610ddcfd.tar.gz libvpx-528a5c28b313fbcc7da6264f7151d26a610ddcfd.tar.bz2 libvpx-528a5c28b313fbcc7da6264f7151d26a610ddcfd.zip |
Merge "[svc rc] RC improvement for key frames in upper layers for spatial svc."
Diffstat (limited to 'vp9/encoder')
-rw-r--r-- | vp9/encoder/vp9_encoder.h | 3 | ||||
-rw-r--r-- | vp9/encoder/vp9_firstpass.c | 21 | ||||
-rw-r--r-- | vp9/encoder/vp9_ratectrl.c | 5 | ||||
-rw-r--r-- | vp9/encoder/vp9_svc_layercontext.c | 13 | ||||
-rw-r--r-- | vp9/encoder/vp9_svc_layercontext.h | 4 |
5 files changed, 36 insertions, 10 deletions
diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h index 132b479e2..edd45948d 100644 --- a/vp9/encoder/vp9_encoder.h +++ b/vp9/encoder/vp9_encoder.h @@ -594,7 +594,8 @@ static INLINE YV12_BUFFER_CONFIG *get_ref_frame_buffer( // alt ref frames tend to be coded at a higher than ambient quality static INLINE int frame_is_boosted(const VP9_COMP *cpi) { return frame_is_intra_only(&cpi->common) || cpi->refresh_alt_ref_frame || - (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref); + (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref) || + vp9_is_upper_layer_key_frame(cpi); } static INLINE int get_token_alloc(int mb_rows, int mb_cols) { diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index bd6984161..1f995c9e7 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -1740,8 +1740,8 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { twopass->gf_bits = gf_bits; } if (i == 1 || - (!rc->source_alt_ref_pending && - cpi->common.frame_type != KEY_FRAME)) { + (!rc->source_alt_ref_pending && cpi->common.frame_type != KEY_FRAME && + !vp9_is_upper_layer_key_frame(cpi))) { // Calculate the per frame bit target for this frame. vp9_rc_set_frame_target(cpi, gf_bits); } @@ -2303,11 +2303,16 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) { this_frame_copy = this_frame; find_next_key_frame(cpi, &this_frame_copy); // Don't place key frame in any enhancement layers in spatial svc - if (cpi->use_svc && cpi->svc.number_temporal_layers == 1 && - cpi->svc.spatial_layer_id > 0) { - cm->frame_type = INTER_FRAME; + if (cpi->use_svc && cpi->svc.number_temporal_layers == 1) { + lc->is_key_frame = 1; + if (cpi->svc.spatial_layer_id > 0) { + cm->frame_type = INTER_FRAME; + } } } else { + if (cpi->use_svc && cpi->svc.number_temporal_layers == 1) { + lc->is_key_frame = 0; + } cm->frame_type = INTER_FRAME; } @@ -2405,9 +2410,11 @@ void vp9_twopass_postencode_update(VP9_COMP *cpi) { cpi->twopass.bits_left = MAX(cpi->twopass.bits_left, 0); #ifdef LONG_TERM_VBR_CORRECTION - if (cpi->common.frame_type != KEY_FRAME) { + if (cpi->common.frame_type != KEY_FRAME && + !vp9_is_upper_layer_key_frame(cpi)) { #else - if (cpi->common.frame_type == KEY_FRAME) { + if (cpi->common.frame_type == KEY_FRAME || + vp9_is_upper_layer_key_frame(cpi)) { // For key frames kf_group_bits already had the target bits subtracted out. // So now update to the correct value based on the actual bits used. cpi->twopass.kf_group_bits += cpi->rc.this_frame_target - bits_used; diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index 6ebd9f3fa..b123bfdcb 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -807,7 +807,7 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi, int active_worst_quality = cpi->twopass.active_worst_quality; int q; - if (frame_is_intra_only(cm)) { + if (frame_is_intra_only(cm) || vp9_is_upper_layer_key_frame(cpi)) { #if !CONFIG_MULTIPLE_ARF // Handle the special case for key frames forced when we have75 reached // the maximum key frame interval. Here force the Q to a range @@ -928,7 +928,8 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi, vp9_clear_system_state(); // Limit Q range for the adaptive loop. - if (cm->frame_type == KEY_FRAME && !rc->this_key_frame_forced) { + if ((cm->frame_type == KEY_FRAME || vp9_is_upper_layer_key_frame(cpi)) && + !rc->this_key_frame_forced) { qdelta = vp9_compute_qdelta_by_rate(&cpi->rc, cm->frame_type, active_worst_quality, 2.0); } else if (!rc->is_src_frame_alt_ref && diff --git a/vp9/encoder/vp9_svc_layercontext.c b/vp9/encoder/vp9_svc_layercontext.c index 2379f35b5..5342447d6 100644 --- a/vp9/encoder/vp9_svc_layercontext.c +++ b/vp9/encoder/vp9_svc_layercontext.c @@ -220,3 +220,16 @@ void vp9_inc_frame_in_layer(SVC *svc) { : &svc->layer_context[svc->spatial_layer_id]; ++lc->current_video_frame_in_layer; } + +int vp9_is_upper_layer_key_frame(const struct VP9_COMP *const cpi) { + int is_upper_layer_key_frame = 0; + + if (cpi->use_svc && cpi->svc.number_temporal_layers == 1 && + cpi->svc.spatial_layer_id > 0) { + if (cpi->svc.layer_context[cpi->svc.spatial_layer_id].is_key_frame) { + is_upper_layer_key_frame = 1; + } + } + + return is_upper_layer_key_frame; +} diff --git a/vp9/encoder/vp9_svc_layercontext.h b/vp9/encoder/vp9_svc_layercontext.h index 2abed3055..74d9c1c0d 100644 --- a/vp9/encoder/vp9_svc_layercontext.h +++ b/vp9/encoder/vp9_svc_layercontext.h @@ -30,6 +30,7 @@ typedef struct { struct twopass_rc twopass; struct vpx_fixed_buf rc_twopass_stats_in; unsigned int current_video_frame_in_layer; + int is_key_frame; } LAYER_CONTEXT; typedef struct { @@ -73,6 +74,9 @@ void vp9_init_second_pass_spatial_svc(struct VP9_COMP *cpi); // Increment number of video frames in layer void vp9_inc_frame_in_layer(SVC *svc); +// Check if current layer is key frame in spatial upper layer +int vp9_is_upper_layer_key_frame(const struct VP9_COMP *const cpi); + #ifdef __cplusplus } // extern "C" #endif |