diff options
author | Sreerenj Balachandran <sreerenj.balachandran@intel.com> | 2016-08-09 15:53:47 +0300 |
---|---|---|
committer | Sreerenj Balachandran <sreerenj.balachandran@intel.com> | 2016-08-09 15:53:47 +0300 |
commit | e1a4f29a0487341f5c6841e31c286d9ba5e87a89 (patch) | |
tree | af188f7846a44a6ddcea4650c50c7af94acab2c0 | |
parent | f182b8be2ba05965e6d31a4d380d6563b9b53a77 (diff) |
encoder: VP9: Add CBR encoding supportvp9_enc_cbr
https://bugzilla.gnome.org/show_bug.cgi?id=749950
-rw-r--r-- | gst-libs/gst/vaapi/gstvaapiencoder_vp9.c | 101 | ||||
-rw-r--r-- | gst-libs/gst/vaapi/gstvaapiencoder_vp9.h | 4 |
2 files changed, 102 insertions, 3 deletions
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c index 6006f682..01b0d6ed 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c @@ -39,7 +39,8 @@ /* Supported set of VA rate controls, within this implementation */ #define SUPPORTED_RATECONTROLS \ - (GST_VAAPI_RATECONTROL_MASK (CQP)) + (GST_VAAPI_RATECONTROL_MASK (CQP) | \ + GST_VAAPI_RATECONTROL_MASK (CBR)) /* Supported set of tuning options, within this implementation */ #define SUPPORTED_TUNE_OPTIONS \ @@ -56,6 +57,9 @@ #define MAX_FRAME_WIDTH 4096 #define MAX_FRAME_HEIGHT 4096 +/* Default CPB length (in milliseconds) */ +#define DEFAULT_CPB_LENGTH 1500 + typedef enum { GST_VAAPI_ENCODER_VP9_REF_PIC_MODE_0 = 0, @@ -101,8 +105,47 @@ struct _GstVaapiEncoderVP9 guint frame_num; GstVaapiSurfaceProxy *ref_list[GST_VP9_REF_FRAMES]; /* reference list */ guint ref_list_idx; /* next free slot in ref_list */ + + /* Bitrate contral parameters, CPB = Coded Picture Buffer */ + guint bitrate_bits; // bitrate (bits) + guint cpb_length; // length of CPB buffer (ms) }; +/* Estimates a good enough bitrate if none was supplied */ +static void +ensure_bitrate (GstVaapiEncoderVP9 * encoder) +{ + GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); + guint bitrate; + + switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) { + case GST_VAAPI_RATECONTROL_CBR: + case GST_VAAPI_RATECONTROL_VBR: + if (!base_encoder->bitrate) { + /* Fixme: Provide better estimation */ + /* Using a 1/6 compression ratio */ + /* 12 bits per pixel fro yuv420 */ + base_encoder->bitrate = + (GST_VAAPI_ENCODER_WIDTH (encoder) * + GST_VAAPI_ENCODER_HEIGHT (encoder) * 12 / 6) * + GST_VAAPI_ENCODER_FPS_N (encoder) / + GST_VAAPI_ENCODER_FPS_D (encoder) / 1000; + GST_INFO ("target bitrate computed to %u kbps", base_encoder->bitrate); + } + + bitrate = (base_encoder->bitrate * 1000); + if (bitrate != encoder->bitrate_bits) { + GST_DEBUG ("HRD bitrate: %u bits/sec", bitrate); + encoder->bitrate_bits = bitrate; + } + + break; + default: + base_encoder->bitrate = 0; + break; + } +} + /* Derives the profile that suits best to the configuration */ static GstVaapiEncoderStatus ensure_profile (GstVaapiEncoderVP9 * encoder) @@ -110,6 +153,9 @@ ensure_profile (GstVaapiEncoderVP9 * encoder) /* Always start from "simple" profile for maximum compatibility */ encoder->profile = GST_VAAPI_PROFILE_VP9_0; + /* Ensure bitrate if not set already */ + ensure_bitrate (encoder); + return GST_VAAPI_ENCODER_STATUS_SUCCESS; } @@ -183,6 +229,7 @@ fill_sequence (GstVaapiEncoderVP9 * encoder, GstVaapiEncSequence * sequence) seq_param->kf_max_dist = base_encoder->keyframe_period; seq_param->intra_period = base_encoder->keyframe_period; + seq_param->bits_per_second = encoder->bitrate_bits; return TRUE; } @@ -212,6 +259,37 @@ error: return FALSE; } +static gboolean +ensure_misc_params (GstVaapiEncoderVP9 * encoder, GstVaapiEncPicture * picture) +{ + GstVaapiEncMiscParam *misc = NULL; + VAEncMiscParameterRateControl *rate_control; + + /* RateControl params */ + if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR || + GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_VBR) { + + misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder); + g_assert (misc); + if (!misc) + return FALSE; + + rate_control = misc->data; + memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl)); + rate_control->bits_per_second = encoder->bitrate_bits; + rate_control->target_percentage = 70; + rate_control->window_size = encoder->cpb_length; + rate_control->initial_qp = encoder->yac_qi; + rate_control->min_qp = 1; /* Fixme: provide user control */ + rate_control->basic_unit_size = 0; + + gst_vaapi_enc_picture_add_misc_param (picture, misc); + gst_vaapi_codec_object_replace (&misc, NULL); + } + + return TRUE; +} + static void get_ref_indices (guint ref_pic_mode, guint ref_list_idx, guint * last_idx, guint * gf_idx, guint * arf_idx, guint8 * refresh_frame_flags) @@ -356,6 +434,8 @@ gst_vaapi_encoder_vp9_encode (GstVaapiEncoder * base_encoder, if (!ensure_sequence (encoder, picture)) goto error; + if (!ensure_misc_params (encoder, picture)) + goto error; if (!ensure_picture (encoder, picture, codedbuf, reconstruct)) goto error; if (!gst_vaapi_enc_picture_encode (picture)) @@ -432,10 +512,11 @@ gst_vaapi_encoder_vp9_init (GstVaapiEncoder * base_encoder) encoder->loop_filter_level = DEFAULT_LOOP_FILTER_LEVEL; encoder->sharpness_level = DEFAULT_SHARPNESS_LEVEL; encoder->yac_qi = DEFAULT_YAC_QINDEX; + encoder->bitrate_bits = 0; + encoder->cpb_length = DEFAULT_CPB_LENGTH; memset (encoder->ref_list, 0, G_N_ELEMENTS (encoder->ref_list)); encoder->ref_list_idx = 0; - return TRUE; } @@ -463,6 +544,9 @@ gst_vaapi_encoder_vp9_set_property (GstVaapiEncoder * base_encoder, case GST_VAAPI_ENCODER_VP9_PROP_REF_PIC_MODE: encoder->ref_pic_mode = g_value_get_enum (value); break; + case GST_VAAPI_ENCODER_VP9_PROP_CPB_LENGTH: + encoder->cpb_length = g_value_get_uint (value); + break; default: return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER; } @@ -548,6 +632,19 @@ gst_vaapi_encoder_vp9_get_default_properties (void) gst_vaapi_encoder_vp9_ref_pic_mode_type (), GST_VAAPI_ENCODER_VP9_REF_PIC_MODE_0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoderVP9:cpb-length: + * + * The size of the Coded Picture Buffer , which means + * the window size in milliseconds. + * + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_VP9_PROP_CPB_LENGTH, + g_param_spec_uint ("cpb-length", + "CPB Length", "Length of the CPB_buffer/window_size in milliseconds", + 1, 10000, DEFAULT_CPB_LENGTH, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); return props; diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h index 2ddcbd40..7967a980 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.h @@ -38,6 +38,7 @@ typedef struct _GstVaapiEncoderVP9 GstVaapiEncoderVP9; * @GST_VAAPI_ENCODER_VP9_PROP_LOOP_SHARPNESS_LEVEL: Sharpness Level(uint). * @GST_VAAPI_ENCODER_VP9_PROP_YAC_Q_INDEX: Quantization table index for luma AC * @GST_VAAPI_ENCODER_VP9_PROP_REF_PIC_MODE: Reference picute selection modes + * @GST_VAAPI_ENCODER_VP9_PROP_CPB_LENGTH:Length of CPB buffer in milliseconds * * The set of VP9 encoder specific configurable properties. */ @@ -45,7 +46,8 @@ typedef enum { GST_VAAPI_ENCODER_VP9_PROP_LOOP_FILTER_LEVEL = -1, GST_VAAPI_ENCODER_VP9_PROP_SHARPNESS_LEVEL = -2, GST_VAAPI_ENCODER_VP9_PROP_YAC_Q_INDEX = -3, - GST_VAAPI_ENCODER_VP9_PROP_REF_PIC_MODE = -4 + GST_VAAPI_ENCODER_VP9_PROP_REF_PIC_MODE = -4, + GST_VAAPI_ENCODER_VP9_PROP_CPB_LENGTH = -5 } GstVaapiEncoderVP9Prop; GstVaapiEncoder * |