mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 08:58:02 +02:00
frontends/va: add max_frame_size into rate control
why: max au size and per picture rate control data structure need to follow the input how: have max_frame_size as the input to rate control also re-calculate other rate control related params Signed-off-by: Ruijing Dong <ruijing.dong@amd.com> Reviewed-by: Sil Vilerino <sivileri@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18534>
This commit is contained in:
parent
6646ae2576
commit
3c8937d363
9 changed files with 95 additions and 8 deletions
|
|
@ -52,6 +52,20 @@ static void radeon_vcn_enc_quality_modes(struct radeon_encoder *enc,
|
|||
p->vbaq_mode = in->vbaq_mode ? RENCODE_VBAQ_AUTO : RENCODE_VBAQ_NONE;
|
||||
}
|
||||
|
||||
static uint32_t radeon_vcn_per_frame_integer(uint32_t bitrate, uint32_t den, uint32_t num)
|
||||
{
|
||||
uint64_t rate_den = (uint64_t)bitrate * (uint64_t)den;
|
||||
|
||||
return (uint32_t)(rate_den/num);
|
||||
}
|
||||
|
||||
static uint32_t radeon_vcn_per_frame_frac(uint32_t bitrate, uint32_t den, uint32_t num)
|
||||
{
|
||||
uint64_t rate_den = (uint64_t)bitrate * (uint64_t)den;
|
||||
uint64_t remainder = rate_den % num;
|
||||
|
||||
return (uint32_t)((remainder << 32) / num);
|
||||
}
|
||||
static void radeon_vcn_enc_get_param(struct radeon_encoder *enc, struct pipe_picture_desc *picture)
|
||||
{
|
||||
if (u_reduce_video_profile(picture->profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) {
|
||||
|
|
@ -80,18 +94,24 @@ static void radeon_vcn_enc_get_param(struct radeon_encoder *enc, struct pipe_pic
|
|||
}
|
||||
enc->enc_pic.num_temporal_layers = pic->num_temporal_layers ? pic->num_temporal_layers : 1;
|
||||
enc->enc_pic.temporal_id = 0;
|
||||
for (int i = 0; i < enc->enc_pic.num_temporal_layers; i++)
|
||||
{
|
||||
for (int i = 0; i < enc->enc_pic.num_temporal_layers; i++) {
|
||||
enc->enc_pic.rc_layer_init[i].target_bit_rate = pic->rate_ctrl[i].target_bitrate;
|
||||
enc->enc_pic.rc_layer_init[i].peak_bit_rate = pic->rate_ctrl[i].peak_bitrate;
|
||||
enc->enc_pic.rc_layer_init[i].frame_rate_num = pic->rate_ctrl[i].frame_rate_num;
|
||||
enc->enc_pic.rc_layer_init[i].frame_rate_den = pic->rate_ctrl[i].frame_rate_den;
|
||||
enc->enc_pic.rc_layer_init[i].vbv_buffer_size = pic->rate_ctrl[i].vbv_buffer_size;
|
||||
enc->enc_pic.rc_layer_init[i].avg_target_bits_per_picture = pic->rate_ctrl[i].target_bits_picture;
|
||||
enc->enc_pic.rc_layer_init[i].avg_target_bits_per_picture =
|
||||
radeon_vcn_per_frame_integer(pic->rate_ctrl[i].target_bitrate,
|
||||
pic->rate_ctrl[i].frame_rate_den,
|
||||
pic->rate_ctrl[i].frame_rate_num);
|
||||
enc->enc_pic.rc_layer_init[i].peak_bits_per_picture_integer =
|
||||
pic->rate_ctrl[i].peak_bits_picture_integer;
|
||||
radeon_vcn_per_frame_integer(pic->rate_ctrl[i].peak_bitrate,
|
||||
pic->rate_ctrl[i].frame_rate_den,
|
||||
pic->rate_ctrl[i].frame_rate_num);
|
||||
enc->enc_pic.rc_layer_init[i].peak_bits_per_picture_fractional =
|
||||
pic->rate_ctrl[i].peak_bits_picture_fraction;
|
||||
radeon_vcn_per_frame_frac(pic->rate_ctrl[i].peak_bitrate,
|
||||
pic->rate_ctrl[i].frame_rate_den,
|
||||
pic->rate_ctrl[i].frame_rate_num);
|
||||
}
|
||||
enc->enc_pic.rc_session_init.vbv_buffer_level = pic->rate_ctrl[0].vbv_buf_lv;
|
||||
enc->enc_pic.rc_per_pic.qp = pic->quant_i_frames;
|
||||
|
|
@ -125,6 +145,7 @@ static void radeon_vcn_enc_get_param(struct radeon_encoder *enc, struct pipe_pic
|
|||
else
|
||||
enc->enc_pic.spec_misc.cabac_enable = false;
|
||||
|
||||
enc->enc_pic.rc_per_pic.max_au_size = pic->rate_ctrl[0].max_au_size;
|
||||
enc->enc_pic.spec_misc.cabac_init_idc = enc->enc_pic.spec_misc.cabac_enable ? pic->pic_ctrl.enc_cabac_init_idc : 0;
|
||||
|
||||
} else if (u_reduce_video_profile(picture->profile) == PIPE_VIDEO_FORMAT_HEVC) {
|
||||
|
|
@ -212,10 +233,18 @@ static void radeon_vcn_enc_get_param(struct radeon_encoder *enc, struct pipe_pic
|
|||
enc->enc_pic.rc_layer_init[0].frame_rate_num = pic->rc.frame_rate_num;
|
||||
enc->enc_pic.rc_layer_init[0].frame_rate_den = pic->rc.frame_rate_den;
|
||||
enc->enc_pic.rc_layer_init[0].vbv_buffer_size = pic->rc.vbv_buffer_size;
|
||||
enc->enc_pic.rc_layer_init[0].avg_target_bits_per_picture = pic->rc.target_bits_picture;
|
||||
enc->enc_pic.rc_layer_init[0].peak_bits_per_picture_integer = pic->rc.peak_bits_picture_integer;
|
||||
enc->enc_pic.rc_layer_init[0].avg_target_bits_per_picture =
|
||||
radeon_vcn_per_frame_integer(pic->rc.target_bitrate,
|
||||
pic->rc.frame_rate_den,
|
||||
pic->rc.frame_rate_num);
|
||||
enc->enc_pic.rc_layer_init[0].peak_bits_per_picture_integer =
|
||||
radeon_vcn_per_frame_integer(pic->rc.peak_bitrate,
|
||||
pic->rc.frame_rate_den,
|
||||
pic->rc.frame_rate_num);
|
||||
enc->enc_pic.rc_layer_init[0].peak_bits_per_picture_fractional =
|
||||
pic->rc.peak_bits_picture_fraction;
|
||||
radeon_vcn_per_frame_frac(pic->rc.peak_bitrate,
|
||||
pic->rc.frame_rate_den,
|
||||
pic->rc.frame_rate_num);
|
||||
enc->enc_pic.rc_session_init.vbv_buffer_level = pic->rc.vbv_buf_lv;
|
||||
enc->enc_pic.rc_per_pic.qp = pic->rc.quant_i_frames;
|
||||
enc->enc_pic.rc_per_pic.min_qp_app = 0;
|
||||
|
|
@ -240,6 +269,7 @@ static void radeon_vcn_enc_get_param(struct radeon_encoder *enc, struct pipe_pic
|
|||
default:
|
||||
enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_NONE;
|
||||
}
|
||||
enc->enc_pic.rc_per_pic.max_au_size = pic->rc.max_au_size;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -623,6 +623,8 @@ static int si_get_video_param(struct pipe_screen *screen, enum pipe_video_profil
|
|||
return 32;
|
||||
else
|
||||
return 0;
|
||||
case PIPE_VIDEO_CAP_ENC_SUPPORTS_MAX_FRAME_SIZE:
|
||||
return (sscreen->info.family >= CHIP_RAVEN) ? 1 : 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -219,6 +219,16 @@ vlVaGetConfigAttributes(VADriverContextP ctx, VAProfile profile, VAEntrypoint en
|
|||
PIPE_VIDEO_CAP_ENC_QUALITY_LEVEL);
|
||||
value = quality_range ? quality_range : VA_ATTRIB_NOT_SUPPORTED;
|
||||
} break;
|
||||
case VAConfigAttribMaxFrameSize:
|
||||
{
|
||||
/* Max Frame Size can be used to control picture level frame size.
|
||||
* This frame size is in bits.
|
||||
*/
|
||||
value = pscreen->get_video_param(pscreen, ProfileToPipe(profile),
|
||||
PIPE_VIDEO_ENTRYPOINT_ENCODE,
|
||||
PIPE_VIDEO_CAP_ENC_SUPPORTS_MAX_FRAME_SIZE);
|
||||
value = value ? value : VA_ATTRIB_NOT_SUPPORTED;
|
||||
} break;
|
||||
default:
|
||||
value = VA_ATTRIB_NOT_SUPPORTED;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -523,6 +523,26 @@ handleVAEncMiscParameterTypeQualityLevel(vlVaContext *context, VAEncMiscParamete
|
|||
return status;
|
||||
}
|
||||
|
||||
static VAStatus
|
||||
handleVAEncMiscParameterTypeMaxFrameSize(vlVaContext *context, VAEncMiscParameterBuffer *misc)
|
||||
{
|
||||
VAStatus status = VA_STATUS_SUCCESS;
|
||||
|
||||
switch (u_reduce_video_profile(context->templat.profile)) {
|
||||
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
|
||||
status = vlVaHandleVAEncMiscParameterTypeMaxFrameSizeH264(context, misc);
|
||||
break;
|
||||
|
||||
case PIPE_VIDEO_FORMAT_HEVC:
|
||||
status = vlVaHandleVAEncMiscParameterTypeMaxFrameSizeHEVC(context, misc);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
static VAStatus
|
||||
handleVAEncMiscParameterBufferType(vlVaContext *context, vlVaBuffer *buf)
|
||||
{
|
||||
|
|
@ -547,6 +567,10 @@ handleVAEncMiscParameterBufferType(vlVaContext *context, vlVaBuffer *buf)
|
|||
vaStatus = handleVAEncMiscParameterTypeQualityLevel(context, misc);
|
||||
break;
|
||||
|
||||
case VAEncMiscParameterTypeMaxFrameSize:
|
||||
vaStatus = handleVAEncMiscParameterTypeMaxFrameSize(context, misc);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -259,6 +259,14 @@ vlVaHandleVAEncMiscParameterTypeQualityLevelH264(vlVaContext *context, VAEncMisc
|
|||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VAStatus
|
||||
vlVaHandleVAEncMiscParameterTypeMaxFrameSizeH264(vlVaContext *context, VAEncMiscParameterBuffer *misc)
|
||||
{
|
||||
VAEncMiscParameterBufferMaxFrameSize *ms = (VAEncMiscParameterBufferMaxFrameSize *)misc->data;
|
||||
context->desc.h264enc.rate_ctrl[0].max_au_size = ms->max_frame_size;
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void getEncParamPresetH264(vlVaContext *context)
|
||||
{
|
||||
//rate control
|
||||
|
|
|
|||
|
|
@ -331,6 +331,14 @@ vlVaHandleVAEncPackedHeaderDataBufferTypeHEVC(vlVaContext *context, vlVaBuffer *
|
|||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VAStatus
|
||||
vlVaHandleVAEncMiscParameterTypeMaxFrameSizeHEVC(vlVaContext *context, VAEncMiscParameterBuffer *misc)
|
||||
{
|
||||
VAEncMiscParameterBufferMaxFrameSize *ms = (VAEncMiscParameterBufferMaxFrameSize *)misc->data;
|
||||
context->desc.h265enc.rc.max_au_size = ms->max_frame_size;
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void getEncParamPresetH265(vlVaContext *context)
|
||||
{
|
||||
//rate control
|
||||
|
|
|
|||
|
|
@ -498,6 +498,7 @@ VAStatus vlVaHandleVAEncMiscParameterTypeRateControlH264(vlVaContext *context, V
|
|||
VAStatus vlVaHandleVAEncMiscParameterTypeFrameRateH264(vlVaContext *context, VAEncMiscParameterBuffer *buf);
|
||||
VAStatus vlVaHandleVAEncMiscParameterTypeTemporalLayerH264(vlVaContext *context, VAEncMiscParameterBuffer *buf);
|
||||
VAStatus vlVaHandleVAEncMiscParameterTypeQualityLevelH264(vlVaContext *context, VAEncMiscParameterBuffer *buf);
|
||||
VAStatus vlVaHandleVAEncMiscParameterTypeMaxFrameSizeH264(vlVaContext *context, VAEncMiscParameterBuffer *buf);
|
||||
VAStatus vlVaHandleVAEncPictureParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf);
|
||||
VAStatus vlVaHandleVAEncSliceParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf);
|
||||
VAStatus vlVaHandleVAEncSequenceParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf);
|
||||
|
|
@ -505,4 +506,5 @@ VAStatus vlVaHandleVAEncMiscParameterTypeRateControlHEVC(vlVaContext *context, V
|
|||
VAStatus vlVaHandleVAEncMiscParameterTypeFrameRateHEVC(vlVaContext *context, VAEncMiscParameterBuffer *buf);
|
||||
VAStatus vlVaHandleVAEncPackedHeaderDataBufferTypeHEVC(vlVaContext *context, vlVaBuffer *buf);
|
||||
VAStatus vlVaHandleVAEncMiscParameterTypeQualityLevelHEVC(vlVaContext *context, VAEncMiscParameterBuffer *buf);
|
||||
VAStatus vlVaHandleVAEncMiscParameterTypeMaxFrameSizeHEVC(vlVaContext *context, VAEncMiscParameterBuffer *buf);
|
||||
#endif //VA_PRIVATE_H
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ enum pipe_video_cap
|
|||
all the planes contiguously. This allows for use with some frontends functions that
|
||||
require this like vaDeriveImage */
|
||||
PIPE_VIDEO_SUPPORTS_CONTIGUOUS_PLANES_MAP = 27,
|
||||
PIPE_VIDEO_CAP_ENC_SUPPORTS_MAX_FRAME_SIZE = 28,
|
||||
};
|
||||
|
||||
/* To be used with PIPE_VIDEO_CAP_VPP_ORIENTATION_MODES and for VPP state*/
|
||||
|
|
|
|||
|
|
@ -384,6 +384,7 @@ struct pipe_h264_enc_rate_control
|
|||
unsigned peak_bits_picture_fraction;
|
||||
unsigned fill_data_enable;
|
||||
unsigned enforce_hrd;
|
||||
unsigned max_au_size;
|
||||
};
|
||||
|
||||
struct pipe_h264_enc_motion_estimation
|
||||
|
|
@ -520,6 +521,7 @@ struct pipe_h265_enc_rate_control
|
|||
unsigned peak_bits_picture_fraction;
|
||||
unsigned fill_data_enable;
|
||||
unsigned enforce_hrd;
|
||||
unsigned max_au_size;
|
||||
};
|
||||
|
||||
struct pipe_h265_enc_picture_desc
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue