mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 09:28:07 +02:00
frontends/va: change to per-layer rate control
Allows for each layer in a Scalable Video Coding (SVC) video to have its own rate control setting, when encoding H.264. Signed-off-by: Thong Thai <thong.thai@amd.com> Reviewed-by: Boyuan Zhang <Boyuan.Zhang@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11850>
This commit is contained in:
parent
c2695823fd
commit
856e2b7529
2 changed files with 59 additions and 32 deletions
|
|
@ -316,7 +316,7 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width,
|
|||
if (config->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) {
|
||||
switch (u_reduce_video_profile(context->templat.profile)) {
|
||||
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
|
||||
context->desc.h264enc.rate_ctrl.rate_ctrl_method = config->rc;
|
||||
context->desc.h264enc.rate_ctrl[0].rate_ctrl_method = config->rc;
|
||||
context->desc.h264enc.frame_idx = util_hash_table_create_ptr_keys();
|
||||
break;
|
||||
case PIPE_VIDEO_FORMAT_HEVC:
|
||||
|
|
|
|||
|
|
@ -124,8 +124,8 @@ vlVaHandleVAEncSequenceParameterBufferTypeH264(vlVaDriver *drv, vlVaContext *con
|
|||
if (context->gop_coeff > VL_VA_ENC_GOP_COEFF)
|
||||
context->gop_coeff = VL_VA_ENC_GOP_COEFF;
|
||||
context->desc.h264enc.gop_size = h264->intra_idr_period * context->gop_coeff;
|
||||
context->desc.h264enc.rate_ctrl.frame_rate_num = h264->time_scale / 2;
|
||||
context->desc.h264enc.rate_ctrl.frame_rate_den = h264->num_units_in_tick;
|
||||
context->desc.h264enc.rate_ctrl[0].frame_rate_num = h264->time_scale / 2;
|
||||
context->desc.h264enc.rate_ctrl[0].frame_rate_den = h264->num_units_in_tick;
|
||||
context->desc.h264enc.pic_order_cnt_type = h264->seq_fields.bits.pic_order_cnt_type;
|
||||
|
||||
if (h264->frame_cropping_flag) {
|
||||
|
|
@ -141,17 +141,32 @@ vlVaHandleVAEncSequenceParameterBufferTypeH264(vlVaDriver *drv, vlVaContext *con
|
|||
VAStatus
|
||||
vlVaHandleVAEncMiscParameterTypeRateControlH264(vlVaContext *context, VAEncMiscParameterBuffer *misc)
|
||||
{
|
||||
unsigned temporal_id;
|
||||
VAEncMiscParameterRateControl *rc = (VAEncMiscParameterRateControl *)misc->data;
|
||||
if (context->desc.h264enc.rate_ctrl.rate_ctrl_method ==
|
||||
PIPE_H2645_ENC_RATE_CONTROL_METHOD_CONSTANT)
|
||||
context->desc.h264enc.rate_ctrl.target_bitrate = rc->bits_per_second;
|
||||
|
||||
temporal_id = context->desc.h264enc.rate_ctrl[0].rate_ctrl_method !=
|
||||
PIPE_H2645_ENC_RATE_CONTROL_METHOD_DISABLE ?
|
||||
rc->rc_flags.bits.temporal_id :
|
||||
0;
|
||||
|
||||
if (context->desc.h264enc.rate_ctrl[0].rate_ctrl_method ==
|
||||
PIPE_H2645_ENC_RATE_CONTROL_METHOD_CONSTANT)
|
||||
context->desc.h264enc.rate_ctrl[temporal_id].target_bitrate =
|
||||
rc->bits_per_second;
|
||||
else
|
||||
context->desc.h264enc.rate_ctrl.target_bitrate = rc->bits_per_second * (rc->target_percentage / 100.0);
|
||||
context->desc.h264enc.rate_ctrl.peak_bitrate = rc->bits_per_second;
|
||||
if (context->desc.h264enc.rate_ctrl.target_bitrate < 2000000)
|
||||
context->desc.h264enc.rate_ctrl.vbv_buffer_size = MIN2((context->desc.h264enc.rate_ctrl.target_bitrate * 2.75), 2000000);
|
||||
context->desc.h264enc.rate_ctrl[temporal_id].target_bitrate =
|
||||
rc->bits_per_second * (rc->target_percentage / 100.0);
|
||||
|
||||
if (temporal_id >= context->desc.h264enc.num_temporal_layers)
|
||||
return VA_STATUS_ERROR_INVALID_PARAMETER;
|
||||
|
||||
context->desc.h264enc.rate_ctrl[temporal_id].peak_bitrate = rc->bits_per_second;
|
||||
if (context->desc.h264enc.rate_ctrl[temporal_id].target_bitrate < 2000000)
|
||||
context->desc.h264enc.rate_ctrl[temporal_id].vbv_buffer_size =
|
||||
MIN2((context->desc.h264enc.rate_ctrl[0].target_bitrate * 2.75), 2000000);
|
||||
else
|
||||
context->desc.h264enc.rate_ctrl.vbv_buffer_size = context->desc.h264enc.rate_ctrl.target_bitrate;
|
||||
context->desc.h264enc.rate_ctrl[temporal_id].vbv_buffer_size =
|
||||
context->desc.h264enc.rate_ctrl[0].target_bitrate;
|
||||
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -159,14 +174,26 @@ vlVaHandleVAEncMiscParameterTypeRateControlH264(vlVaContext *context, VAEncMiscP
|
|||
VAStatus
|
||||
vlVaHandleVAEncMiscParameterTypeFrameRateH264(vlVaContext *context, VAEncMiscParameterBuffer *misc)
|
||||
{
|
||||
unsigned temporal_id;
|
||||
VAEncMiscParameterFrameRate *fr = (VAEncMiscParameterFrameRate *)misc->data;
|
||||
|
||||
temporal_id = context->desc.h264enc.rate_ctrl[0].rate_ctrl_method !=
|
||||
PIPE_H2645_ENC_RATE_CONTROL_METHOD_DISABLE ?
|
||||
fr->framerate_flags.bits.temporal_id :
|
||||
0;
|
||||
|
||||
if (context->desc.h264enc.num_temporal_layers > 0 &&
|
||||
temporal_id >= context->desc.h264enc.num_temporal_layers)
|
||||
return VA_STATUS_ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (fr->framerate & 0xffff0000) {
|
||||
context->desc.h264enc.rate_ctrl.frame_rate_num = fr->framerate & 0xffff;
|
||||
context->desc.h264enc.rate_ctrl.frame_rate_den = fr->framerate >> 16 & 0xffff;
|
||||
context->desc.h264enc.rate_ctrl[temporal_id].frame_rate_num = fr->framerate & 0xffff;
|
||||
context->desc.h264enc.rate_ctrl[temporal_id].frame_rate_den = fr->framerate >> 16 & 0xffff;
|
||||
} else {
|
||||
context->desc.h264enc.rate_ctrl.frame_rate_num = fr->framerate;
|
||||
context->desc.h264enc.rate_ctrl.frame_rate_den = 1;
|
||||
context->desc.h264enc.rate_ctrl[temporal_id].frame_rate_num = fr->framerate;
|
||||
context->desc.h264enc.rate_ctrl[temporal_id].frame_rate_den = 1;
|
||||
}
|
||||
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -196,25 +223,25 @@ void getEncParamPresetH264(vlVaContext *context)
|
|||
context->desc.h264enc.pic_ctrl.enc_constraint_set_flags = 0x00000040;
|
||||
|
||||
//rate control
|
||||
context->desc.h264enc.rate_ctrl.vbv_buffer_size = 20000000;
|
||||
context->desc.h264enc.rate_ctrl.vbv_buf_lv = 48;
|
||||
context->desc.h264enc.rate_ctrl.fill_data_enable = 1;
|
||||
context->desc.h264enc.rate_ctrl.enforce_hrd = 1;
|
||||
context->desc.h264enc.rate_ctrl[0].vbv_buffer_size = 20000000;
|
||||
context->desc.h264enc.rate_ctrl[0].vbv_buf_lv = 48;
|
||||
context->desc.h264enc.rate_ctrl[0].fill_data_enable = 1;
|
||||
context->desc.h264enc.rate_ctrl[0].enforce_hrd = 1;
|
||||
context->desc.h264enc.enable_vui = false;
|
||||
if (context->desc.h264enc.rate_ctrl.frame_rate_num == 0 ||
|
||||
context->desc.h264enc.rate_ctrl.frame_rate_den == 0) {
|
||||
context->desc.h264enc.rate_ctrl.frame_rate_num = 30;
|
||||
context->desc.h264enc.rate_ctrl.frame_rate_den = 1;
|
||||
if (context->desc.h264enc.rate_ctrl[0].frame_rate_num == 0 ||
|
||||
context->desc.h264enc.rate_ctrl[0].frame_rate_den == 0) {
|
||||
context->desc.h264enc.rate_ctrl[0].frame_rate_num = 30;
|
||||
context->desc.h264enc.rate_ctrl[0].frame_rate_den = 1;
|
||||
}
|
||||
context->desc.h264enc.rate_ctrl.target_bits_picture =
|
||||
context->desc.h264enc.rate_ctrl.target_bitrate *
|
||||
((float)context->desc.h264enc.rate_ctrl.frame_rate_den /
|
||||
context->desc.h264enc.rate_ctrl.frame_rate_num);
|
||||
context->desc.h264enc.rate_ctrl.peak_bits_picture_integer =
|
||||
context->desc.h264enc.rate_ctrl.peak_bitrate *
|
||||
((float)context->desc.h264enc.rate_ctrl.frame_rate_den /
|
||||
context->desc.h264enc.rate_ctrl.frame_rate_num);
|
||||
context->desc.h264enc.rate_ctrl[0].target_bits_picture =
|
||||
context->desc.h264enc.rate_ctrl[0].target_bitrate *
|
||||
((float)context->desc.h264enc.rate_ctrl[0].frame_rate_den /
|
||||
context->desc.h264enc.rate_ctrl[0].frame_rate_num);
|
||||
context->desc.h264enc.rate_ctrl[0].peak_bits_picture_integer =
|
||||
context->desc.h264enc.rate_ctrl[0].peak_bitrate *
|
||||
((float)context->desc.h264enc.rate_ctrl[0].frame_rate_den /
|
||||
context->desc.h264enc.rate_ctrl[0].frame_rate_num);
|
||||
|
||||
context->desc.h264enc.rate_ctrl.peak_bits_picture_fraction = 0;
|
||||
context->desc.h264enc.rate_ctrl[0].peak_bits_picture_fraction = 0;
|
||||
context->desc.h264enc.ref_pic_mode = 0x00000201;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue