summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSreerenj Balachandran <sreerenj.balachandran@intel.com>2020-03-04 17:15:29 -0900
committerSreerenj Balachandran <sreerenj.balachandran@intel.com>2020-03-04 17:15:29 -0900
commitdb9517f6e04c96241fafcc3005d2c2d64c0345d5 (patch)
treef71dcca25f334f5a0a5d460297faeecdf34e4eba
parent355f16bdb32965425b274aa082c1334b0edd5992 (diff)
-rw-r--r--gst-libs/gst/vaapi/gstvaapiencoder_vp9.c5
-rw-r--r--gst-libs/gst/vaapi/vp9_ratectrl.c67
-rw-r--r--gst-libs/gst/vaapi/vp9_ratectrl.h2
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