mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 17:20:36 +00:00
encoder: add bitrate API.
Add gst_vaapi_encoder_set_bitrate() interface to allow the user control the bitrate for encoding. Currently, changing this parameter is only valid before the first frame is encoded. Should the value be modified afterwards, then GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED is returned. https://bugzilla.gnome.org/show_bug.cgi?id=719529
This commit is contained in:
parent
a24c52e4d0
commit
70b3600f11
10 changed files with 70 additions and 29 deletions
|
@ -491,6 +491,39 @@ error_unsupported_rate_control:
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_encoder_set_bitrate:
|
||||
* @encoder: a #GstVaapiEncoder
|
||||
* @bitrate: the requested bitrate (in kbps)
|
||||
*
|
||||
* Notifies the @encoder to use the supplied @bitrate value.
|
||||
*
|
||||
* Note: currently, the bitrate can only be specified before the first
|
||||
* frame is encoded. Afterwards, any change to this parameter is
|
||||
* invalid and @GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED is
|
||||
* returned.
|
||||
*
|
||||
* Return value: a #GstVaapiEncoderStatus
|
||||
*/
|
||||
GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_set_bitrate (GstVaapiEncoder * encoder, guint bitrate)
|
||||
{
|
||||
g_return_val_if_fail (encoder != NULL, 0);
|
||||
|
||||
if (encoder->bitrate != bitrate && encoder->num_codedbuf_queued > 0)
|
||||
goto error_operation_failed;
|
||||
|
||||
encoder->bitrate = bitrate;
|
||||
return GST_VAAPI_ENCODER_STATUS_SUCCESS;
|
||||
|
||||
/* ERRORS */
|
||||
error_operation_failed:
|
||||
{
|
||||
GST_ERROR ("could not change bitrate value after encoding started");
|
||||
return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
/* Base encoder initialization (internal) */
|
||||
static gboolean
|
||||
gst_vaapi_encoder_init (GstVaapiEncoder * encoder, GstVaapiDisplay * display)
|
||||
|
|
|
@ -90,6 +90,9 @@ GstVaapiEncoderStatus
|
|||
gst_vaapi_encoder_set_rate_control (GstVaapiEncoder * encoder,
|
||||
GstVaapiRateControl rate_control);
|
||||
|
||||
GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_set_bitrate (GstVaapiEncoder * encoder, guint bitrate);
|
||||
|
||||
GstVaapiEncoderStatus
|
||||
gst_vaapi_encoder_put_frame (GstVaapiEncoder * encoder,
|
||||
GstVideoCodecFrame * frame);
|
||||
|
|
|
@ -852,6 +852,7 @@ static gboolean
|
|||
fill_va_sequence_param (GstVaapiEncoderH264 * encoder,
|
||||
GstVaapiEncSequence * sequence)
|
||||
{
|
||||
GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
|
||||
VAEncSequenceParameterBufferH264 *seq = sequence->param;
|
||||
guint width_in_mbs, height_in_mbs;
|
||||
|
||||
|
@ -863,8 +864,8 @@ fill_va_sequence_param (GstVaapiEncoderH264 * encoder,
|
|||
seq->level_idc = encoder->level;
|
||||
seq->intra_period = encoder->intra_period;
|
||||
seq->ip_period = 0; // ?
|
||||
if (encoder->bitrate > 0)
|
||||
seq->bits_per_second = encoder->bitrate * 1024;
|
||||
if (base_encoder->bitrate > 0)
|
||||
seq->bits_per_second = base_encoder->bitrate * 1024;
|
||||
else
|
||||
seq->bits_per_second = 0;
|
||||
|
||||
|
@ -912,12 +913,12 @@ fill_va_sequence_param (GstVaapiEncoderH264 * encoder,
|
|||
}
|
||||
|
||||
/*vui not set */
|
||||
seq->vui_parameters_present_flag = (encoder->bitrate > 0 ? TRUE : FALSE);
|
||||
seq->vui_parameters_present_flag = (base_encoder->bitrate > 0 ? TRUE : FALSE);
|
||||
if (seq->vui_parameters_present_flag) {
|
||||
seq->vui_fields.bits.aspect_ratio_info_present_flag = FALSE;
|
||||
seq->vui_fields.bits.bitstream_restriction_flag = FALSE;
|
||||
seq->vui_fields.bits.timing_info_present_flag =
|
||||
(encoder->bitrate > 0 ? TRUE : FALSE);
|
||||
(base_encoder->bitrate > 0 ? TRUE : FALSE);
|
||||
if (seq->vui_fields.bits.timing_info_present_flag) {
|
||||
seq->num_units_in_tick = GST_VAAPI_ENCODER_FPS_D (encoder);
|
||||
seq->time_scale = GST_VAAPI_ENCODER_FPS_N (encoder) * 2;
|
||||
|
@ -1209,6 +1210,7 @@ ensure_slices (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
|
|||
static gboolean
|
||||
ensure_misc (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
|
||||
{
|
||||
GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
|
||||
GstVaapiEncMiscParam *misc = NULL;
|
||||
VAEncMiscParameterHRD *hrd;
|
||||
VAEncMiscParameterRateControl *rate_control;
|
||||
|
@ -1220,9 +1222,9 @@ ensure_misc (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
|
|||
return FALSE;
|
||||
gst_vaapi_enc_picture_add_misc_buffer (picture, misc);
|
||||
hrd = misc->impl;
|
||||
if (encoder->bitrate > 0) {
|
||||
hrd->initial_buffer_fullness = encoder->bitrate * 1024 * 4;
|
||||
hrd->buffer_size = encoder->bitrate * 1024 * 8;
|
||||
if (base_encoder->bitrate > 0) {
|
||||
hrd->initial_buffer_fullness = base_encoder->bitrate * 1024 * 4;
|
||||
hrd->buffer_size = base_encoder->bitrate * 1024 * 8;
|
||||
} else {
|
||||
hrd->initial_buffer_fullness = 0;
|
||||
hrd->buffer_size = 0;
|
||||
|
@ -1239,8 +1241,8 @@ ensure_misc (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
|
|||
gst_vaapi_enc_picture_add_misc_buffer (picture, misc);
|
||||
rate_control = misc->impl;
|
||||
memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl));
|
||||
if (encoder->bitrate)
|
||||
rate_control->bits_per_second = encoder->bitrate * 1024;
|
||||
if (base_encoder->bitrate)
|
||||
rate_control->bits_per_second = base_encoder->bitrate * 1024;
|
||||
else
|
||||
rate_control->bits_per_second = 0;
|
||||
rate_control->target_percentage = 70;
|
||||
|
@ -1257,6 +1259,7 @@ ensure_misc (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
|
|||
gboolean
|
||||
init_encoder_public_attributes (GstVaapiEncoderH264 * encoder)
|
||||
{
|
||||
GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
|
||||
guint width_mbs, height_mbs, total_mbs;
|
||||
|
||||
if (!GST_VAAPI_ENCODER_WIDTH (encoder) ||
|
||||
|
@ -1298,13 +1301,13 @@ init_encoder_public_attributes (GstVaapiEncoderH264 * encoder)
|
|||
GST_VAAPI_RATECONTROL_VBR == GST_VAAPI_ENCODER_RATE_CONTROL (encoder) ||
|
||||
GST_VAAPI_RATECONTROL_VBR_CONSTRAINED ==
|
||||
GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) {
|
||||
if (!encoder->bitrate)
|
||||
encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) *
|
||||
if (!base_encoder->bitrate)
|
||||
base_encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) *
|
||||
GST_VAAPI_ENCODER_HEIGHT (encoder) *
|
||||
GST_VAAPI_ENCODER_FPS_N (encoder) /
|
||||
GST_VAAPI_ENCODER_FPS_D (encoder) / 4 / 1024;
|
||||
} else
|
||||
encoder->bitrate = 0;
|
||||
base_encoder->bitrate = 0;
|
||||
|
||||
if (!encoder->slice_num)
|
||||
encoder->slice_num = GST_VAAPI_ENCODER_H264_DEFAULT_SLICE_NUM;
|
||||
|
@ -1706,7 +1709,6 @@ gst_vaapi_encoder_h264_init (GstVaapiEncoder * base)
|
|||
/* init attributes */
|
||||
encoder->profile = 0;
|
||||
encoder->level = 0;
|
||||
encoder->bitrate = 0;
|
||||
encoder->idr_period = 0;
|
||||
encoder->intra_period = 0;
|
||||
encoder->init_qp = -1;
|
||||
|
|
|
@ -70,7 +70,6 @@ struct _GstVaapiEncoderH264
|
|||
/* public */
|
||||
guint32 profile;
|
||||
guint32 level;
|
||||
guint32 bitrate; /*kbps */
|
||||
guint32 intra_period;
|
||||
guint32 idr_period;
|
||||
guint32 init_qp; /*default 24 */
|
||||
|
|
|
@ -105,6 +105,8 @@ ensure_sampling_desity (GstVaapiEncoderMpeg2 * encoder)
|
|||
static gboolean
|
||||
ensure_public_attributes (GstVaapiEncoderMpeg2 * encoder)
|
||||
{
|
||||
GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
|
||||
|
||||
if (!GST_VAAPI_ENCODER_WIDTH (encoder) ||
|
||||
!GST_VAAPI_ENCODER_HEIGHT (encoder) ||
|
||||
!GST_VAAPI_ENCODER_FPS_N (encoder) ||
|
||||
|
@ -128,13 +130,13 @@ ensure_public_attributes (GstVaapiEncoderMpeg2 * encoder)
|
|||
|
||||
/* default compress ratio 1: (4*8*1.5) */
|
||||
if (GST_VAAPI_RATECONTROL_CBR == GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) {
|
||||
if (!encoder->bitrate)
|
||||
encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) *
|
||||
if (!base_encoder->bitrate)
|
||||
base_encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) *
|
||||
GST_VAAPI_ENCODER_HEIGHT (encoder) *
|
||||
GST_VAAPI_ENCODER_FPS_N (encoder) /
|
||||
GST_VAAPI_ENCODER_FPS_D (encoder) / 4 / 1024;
|
||||
} else
|
||||
encoder->bitrate = 0;
|
||||
base_encoder->bitrate = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -176,6 +178,7 @@ make_profile_and_level_indication (guint32 profile, guint32 level)
|
|||
static gboolean
|
||||
fill_sequence (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncSequence * sequence)
|
||||
{
|
||||
GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
|
||||
VAEncSequenceParameterBufferMPEG2 *seq = sequence->param;
|
||||
|
||||
memset (seq, 0, sizeof (VAEncSequenceParameterBufferMPEG2));
|
||||
|
@ -185,8 +188,8 @@ fill_sequence (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncSequence * sequence)
|
|||
seq->picture_width = GST_VAAPI_ENCODER_WIDTH (encoder);
|
||||
seq->picture_height = GST_VAAPI_ENCODER_HEIGHT (encoder);
|
||||
|
||||
if (encoder->bitrate > 0)
|
||||
seq->bits_per_second = encoder->bitrate * 1024;
|
||||
if (base_encoder->bitrate > 0)
|
||||
seq->bits_per_second = base_encoder->bitrate * 1024;
|
||||
else
|
||||
seq->bits_per_second = 0;
|
||||
|
||||
|
@ -418,6 +421,7 @@ static gboolean
|
|||
set_misc_parameters (GstVaapiEncoderMpeg2 * encoder,
|
||||
GstVaapiEncPicture * picture)
|
||||
{
|
||||
GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
|
||||
GstVaapiEncMiscParam *misc = NULL;
|
||||
VAEncMiscParameterHRD *hrd;
|
||||
VAEncMiscParameterRateControl *rate_control;
|
||||
|
@ -429,9 +433,9 @@ set_misc_parameters (GstVaapiEncoderMpeg2 * encoder,
|
|||
return FALSE;
|
||||
gst_vaapi_enc_picture_add_misc_buffer (picture, misc);
|
||||
hrd = misc->impl;
|
||||
if (encoder->bitrate > 0) {
|
||||
hrd->initial_buffer_fullness = encoder->bitrate * 1024 * 4;
|
||||
hrd->buffer_size = encoder->bitrate * 1024 * 8;
|
||||
if (base_encoder->bitrate > 0) {
|
||||
hrd->initial_buffer_fullness = base_encoder->bitrate * 1024 * 4;
|
||||
hrd->buffer_size = base_encoder->bitrate * 1024 * 8;
|
||||
} else {
|
||||
hrd->initial_buffer_fullness = 0;
|
||||
hrd->buffer_size = 0;
|
||||
|
@ -447,8 +451,8 @@ set_misc_parameters (GstVaapiEncoderMpeg2 * encoder,
|
|||
gst_vaapi_enc_picture_add_misc_buffer (picture, misc);
|
||||
rate_control = misc->impl;
|
||||
memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl));
|
||||
if (encoder->bitrate)
|
||||
rate_control->bits_per_second = encoder->bitrate * 1024;
|
||||
if (base_encoder->bitrate)
|
||||
rate_control->bits_per_second = base_encoder->bitrate * 1024;
|
||||
else
|
||||
rate_control->bits_per_second = 0;
|
||||
rate_control->target_percentage = 70;
|
||||
|
|
|
@ -80,7 +80,6 @@ struct _GstVaapiEncoderMpeg2
|
|||
/* public */
|
||||
guint32 profile;
|
||||
guint32 level;
|
||||
guint32 bitrate; /*kbps */
|
||||
guint32 cqp;
|
||||
guint32 intra_period;
|
||||
guint32 ip_period;
|
||||
|
|
|
@ -98,6 +98,7 @@ struct _GstVaapiEncoder
|
|||
GstVideoInfo video_info;
|
||||
GstVaapiRateControl rate_control;
|
||||
guint32 rate_control_mask;
|
||||
guint bitrate; /* kbps */
|
||||
|
||||
GMutex mutex;
|
||||
GCond surface_free;
|
||||
|
|
|
@ -318,6 +318,10 @@ ensure_encoder (GstVaapiEncode * encode)
|
|||
encode->rate_control);
|
||||
if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
status = gst_vaapi_encoder_set_bitrate (encode->encoder, encode->bitrate);
|
||||
if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -162,7 +162,6 @@ gst_vaapiencode_h264_create_encoder (GstVaapiEncode * base,
|
|||
GstVaapiDisplay * display)
|
||||
{
|
||||
GstVaapiEncodeH264 *const encode = GST_VAAPIENCODE_H264_CAST (base);
|
||||
GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (base);
|
||||
GstVaapiEncoder *base_encoder;
|
||||
GstVaapiEncoderH264 *encoder;
|
||||
|
||||
|
@ -173,7 +172,6 @@ gst_vaapiencode_h264_create_encoder (GstVaapiEncode * base,
|
|||
|
||||
encoder->profile = GST_VAAPI_PROFILE_UNKNOWN;
|
||||
encoder->level = GST_VAAPI_ENCODER_H264_DEFAULT_LEVEL;
|
||||
encoder->bitrate = base_encode->bitrate;
|
||||
encoder->intra_period = encode->intra_period;
|
||||
encoder->init_qp = encode->init_qp;
|
||||
encoder->min_qp = encode->min_qp;
|
||||
|
|
|
@ -153,7 +153,6 @@ gst_vaapiencode_mpeg2_create_encoder (GstVaapiEncode * base,
|
|||
GstVaapiDisplay * display)
|
||||
{
|
||||
GstVaapiEncodeMpeg2 *const encode = GST_VAAPIENCODE_MPEG2_CAST (base);
|
||||
GstVaapiEncode *const base_encode = GST_VAAPIENCODE_CAST (base);
|
||||
GstVaapiEncoder *base_encoder;
|
||||
GstVaapiEncoderMpeg2 *encoder;
|
||||
|
||||
|
@ -164,7 +163,6 @@ gst_vaapiencode_mpeg2_create_encoder (GstVaapiEncode * base,
|
|||
|
||||
encoder->profile = GST_VAAPI_ENCODER_MPEG2_DEFAULT_PROFILE;
|
||||
encoder->level = GST_VAAPI_ENCODER_MPEG2_DEFAULT_LEVEL;
|
||||
encoder->bitrate = base_encode->bitrate;
|
||||
encoder->cqp = encode->quantizer;
|
||||
encoder->intra_period = encode->intra_period;
|
||||
encoder->ip_period = encode->ip_period;
|
||||
|
|
Loading…
Reference in a new issue