diff options
author | Sreerenj Balachandran <sreerenj.balachandran@intel.com> | 2020-03-04 17:15:29 -0900 |
---|---|---|
committer | Sreerenj Balachandran <sreerenj.balachandran@intel.com> | 2020-03-04 17:15:29 -0900 |
commit | db9517f6e04c96241fafcc3005d2c2d64c0345d5 (patch) | |
tree | f71dcca25f334f5a0a5d460297faeecdf34e4eba | |
parent | 355f16bdb32965425b274aa082c1334b0edd5992 (diff) |
SoftwareBRC+SVCVP9_SVC_and_SoftwareBRC
-rw-r--r-- | gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 5 | ||||
-rw-r--r-- | gst-libs/gst/vaapi/vp9_ratectrl.c | 67 | ||||
-rw-r--r-- | gst-libs/gst/vaapi/vp9_ratectrl.h | 2 |
3 files changed, 66 insertions, 8 deletions
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index f6d3366b..5a6c6247 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -29,7 +29,9 @@ #include "gstvaapicodedbufferproxy_priv.h" #include "gstvaapisurface.h" #include "gstvaapifilter.h" + #include "vp9_ratectrl.h" +#include "vp9_svc_layercontext.h" #define DEBUG 1 #include "gstvaapidebug.h" @@ -915,6 +917,9 @@ software_brc_init_comp (GstVaapiEncoder * base_encoder, VP9_COMP *cpi) cpi->refresh_golden_frame = 0; cpi->refresh_last_frame = 1; + if (encoder->k_svc) + cpi->use_svc = 1; + } static void diff --git a/gst-libs/gst/vaapi/vp9_ratectrl.c b/gst-libs/gst/vaapi/vp9_ratectrl.c index c2d24076..621c9e7c 100644 --- a/gst-libs/gst/vaapi/vp9_ratectrl.c +++ b/gst-libs/gst/vaapi/vp9_ratectrl.c @@ -455,13 +455,18 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) { // configuration change has a large change in avg_frame_bandwidth. // Also reset buffer level to optimal level. if (cm->current_video_frame > 0) { - if (rc->avg_frame_bandwidth > (3 * rc->last_avg_frame_bandwidth >> 1) || - rc->avg_frame_bandwidth < (rc->last_avg_frame_bandwidth >> 1)) { - rc->rc_1_frame = 0; - rc->rc_2_frame = 0; - rc->bits_off_target = rc->optimal_buffer_level; - rc->buffer_level = rc->optimal_buffer_level; - } + + if (cpi->use_svc) { + vp9_svc_check_reset_layer_rc_flag(cpi); + } else { + if (rc->avg_frame_bandwidth > (3 * rc->last_avg_frame_bandwidth >> 1) || + rc->avg_frame_bandwidth < (rc->last_avg_frame_bandwidth >> 1)) { + rc->rc_1_frame = 0; + rc->rc_2_frame = 0; + rc->bits_off_target = rc->optimal_buffer_level; + rc->buffer_level = rc->optimal_buffer_level; + } + } } } @@ -1839,6 +1844,54 @@ void vp9_rc_get_one_pass_cbr_params(VP9_COMP *cpi) { if (cm->show_frame) update_buffer_level_preencode(cpi); } +void vp9_rc_get_svc_params(VP9_COMP *cpi) { + VP9_COMMON *const cm = &cpi->common; + RATE_CONTROL *const rc = &cpi->rc; + SVC *const svc = &cpi->svc; + int target = rc->avg_frame_bandwidth; + int layer = LAYER_IDS_TO_IDX(svc->spatial_layer_id, svc->temporal_layer_id, + svc->number_temporal_layers); + if (svc->first_spatial_layer_to_encode) + svc->layer_context[svc->temporal_layer_id].is_key_frame = 0; + // Periodic key frames is based on the super-frame counter + // (svc.current_superframe), also only base spatial layer is key frame. + // Key frame is set for any of the following: very first frame, frame flags + // indicates key, superframe counter hits key frequencey, or (non-intra) sync + // flag is set for spatial layer 0. + if ((cm->current_video_frame == 0 && !svc->previous_frame_is_intra_only) || + (cpi->frame_flags & FRAMEFLAGS_KEY) || + (cpi->oxcf.auto_key && + (svc->current_superframe % cpi->oxcf.key_freq == 0) && + !svc->previous_frame_is_intra_only && svc->spatial_layer_id == 0) || + (svc->spatial_layer_sync[0] == 1 && svc->spatial_layer_id == 0)) { + cm->frame_type = KEY_FRAME; + + rc->source_alt_ref_active = 0; + if (is_one_pass_cbr_svc(cpi)) { + if (cm->current_video_frame > 0) vp9_svc_reset_temporal_layers(cpi, 1); + layer = LAYER_IDS_TO_IDX(svc->spatial_layer_id, svc->temporal_layer_id, + svc->number_temporal_layers); + svc->layer_context[layer].is_key_frame = 1; + cpi->ref_frame_flags &= (~VP9_LAST_FLAG & ~VP9_GOLD_FLAG & ~VP9_ALT_FLAG); + // Assumption here is that LAST_FRAME is being updated for a keyframe. + // Thus no change in update flags. + target = calc_iframe_target_size_one_pass_cbr(cpi); + } + } else { + cm->frame_type = INTER_FRAME; + if (is_one_pass_cbr_svc(cpi)) { + LAYER_CONTEXT *lc = &svc->layer_context[layer]; + // Add condition current_video_frame > 0 for the case where first frame + // is intra only followed by overlay/copy frame. In this case we don't + // want to reset is_key_frame to 0 on overlay/copy frame. + lc->is_key_frame = + (svc->spatial_layer_id == 0 && cm->current_video_frame > 0) + ? 0 + : svc->layer_context[svc->temporal_layer_id].is_key_frame; + target = calc_pframe_target_size_one_pass_cbr(cpi); + } + } + void vp9_set_size_dependent_vars(struct VP9_COMP *cpi, int *q, int *bottom_index, int *top_index) { diff --git a/gst-libs/gst/vaapi/vp9_ratectrl.h b/gst-libs/gst/vaapi/vp9_ratectrl.h index 10234a2f..e78a5292 100644 --- a/gst-libs/gst/vaapi/vp9_ratectrl.h +++ b/gst-libs/gst/vaapi/vp9_ratectrl.h @@ -487,7 +487,7 @@ int vp9_rc_get_default_max_gf_interval(double framerate, int min_gf_interval); // Functions to set parameters for encoding before the actual // encode_frame_to_data_rate() function. void vp9_rc_get_one_pass_cbr_params(struct VP9_COMP *cpi); -//void vp9_rc_get_svc_params(struct VP9_COMP *cpi); +void vp9_rc_get_svc_params(struct VP9_COMP *cpi); // Post encode update of the rate control parameters based // on bytes used |