frontends/va: Separate QP for I/P/B frames

For H264/HEVC this needs to calculate init_qp + slice_qp_delta.

Reviewed-by: Ruijing Dong <ruijing.dong@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27558>
This commit is contained in:
David Rosca 2024-02-12 20:45:33 +01:00 committed by Marge Bot
parent c69f76170e
commit 8c9445896f
4 changed files with 45 additions and 17 deletions

View file

@ -221,17 +221,6 @@ VAStatus vlVaHandleVAEncPictureParameterBufferTypeAV1(vlVaDriver *drv, vlVaConte
PIPE_USAGE_STAGING, coded_buf->size);
context->coded_buf = coded_buf;
for (i = 0; i < ARRAY_SIZE(context->desc.av1enc.rc); i++) {
context->desc.av1enc.rc[i].qp = av1->base_qindex ? av1->base_qindex : 60;
/* Distinguishes from the default params set for these values and app specific params passed down */
context->desc.av1enc.rc[i].app_requested_initial_qp = (av1->base_qindex != 0);
context->desc.av1enc.rc[i].min_qp = av1->min_base_qindex ? av1->min_base_qindex : 1;
context->desc.av1enc.rc[i].max_qp = av1->max_base_qindex ? av1->max_base_qindex : 255;
/* Distinguishes from the default params set for these values and app specific params passed down */
context->desc.av1enc.rc[i].app_requested_qp_range =
((context->desc.av1enc.rc[i].max_qp != AV1_MAX_QP_DEFAULT) || (context->desc.av1enc.rc[i].min_qp != AV1_MIN_QP_DEFAULT));
}
/* these frame types will need to be seen as force type */
switch(av1->picture_flags.bits.frame_type)
{
@ -249,6 +238,22 @@ VAStatus vlVaHandleVAEncPictureParameterBufferTypeAV1(vlVaDriver *drv, vlVaConte
break;
};
for (i = 0; i < ARRAY_SIZE(context->desc.av1enc.rc); i++) {
unsigned qindex = av1->base_qindex ? av1->base_qindex : 60;
if (context->desc.av1enc.frame_type == PIPE_AV1_ENC_FRAME_TYPE_KEY ||
context->desc.av1enc.frame_type == PIPE_AV1_ENC_FRAME_TYPE_INTRA_ONLY)
context->desc.av1enc.rc[i].qp = qindex;
else
context->desc.av1enc.rc[i].qp_inter = qindex;
/* Distinguishes from the default params set for these values and app specific params passed down */
context->desc.av1enc.rc[i].app_requested_initial_qp = (av1->base_qindex != 0);
context->desc.av1enc.rc[i].min_qp = av1->min_base_qindex ? av1->min_base_qindex : 1;
context->desc.av1enc.rc[i].max_qp = av1->max_base_qindex ? av1->max_base_qindex : 255;
/* Distinguishes from the default params set for these values and app specific params passed down */
context->desc.av1enc.rc[i].app_requested_qp_range =
((context->desc.av1enc.rc[i].max_qp != AV1_MAX_QP_DEFAULT) || (context->desc.av1enc.rc[i].min_qp != AV1_MIN_QP_DEFAULT));
}
if (context->desc.av1enc.frame_type == FRAME_TYPE_KEY_FRAME)
context->desc.av1enc.last_key_frame_num = context->desc.av1enc.frame_num;

View file

@ -84,9 +84,7 @@ vlVaHandleVAEncPictureParameterBufferTypeH264(vlVaDriver *drv, vlVaContext *cont
context->desc.h264enc.num_slice_descriptors = 0;
memset(&context->desc.h264enc.slices_descriptors, 0, sizeof(context->desc.h264enc.slices_descriptors));
context->desc.h264enc.quant_i_frames = h264->pic_init_qp;
context->desc.h264enc.quant_b_frames = h264->pic_init_qp;
context->desc.h264enc.quant_p_frames = h264->pic_init_qp;
context->desc.h264enc.init_qp = h264->pic_init_qp;
context->desc.h264enc.gop_cnt++;
if (context->desc.h264enc.gop_cnt == context->desc.h264enc.gop_size)
context->desc.h264enc.gop_cnt = 0;
@ -109,6 +107,7 @@ VAStatus
vlVaHandleVAEncSliceParameterBufferTypeH264(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
{
VAEncSliceParameterBufferH264 *h264;
unsigned slice_qp;
h264 = buf->data;
memset(&context->desc.h264enc.ref_idx_l0_list, VA_INVALID_ID, sizeof(context->desc.h264enc.ref_idx_l0_list));
@ -144,12 +143,16 @@ vlVaHandleVAEncSliceParameterBufferTypeH264(vlVaDriver *drv, vlVaContext *contex
slice_descriptor.macroblock_address = h264->macroblock_address;
slice_descriptor.num_macroblocks = h264->num_macroblocks;
slice_qp = context->desc.h264enc.init_qp + h264->slice_qp_delta;
if ((h264->slice_type == 1) || (h264->slice_type == 6)) {
context->desc.h264enc.picture_type = PIPE_H2645_ENC_PICTURE_TYPE_B;
slice_descriptor.slice_type = PIPE_H264_SLICE_TYPE_B;
context->desc.h264enc.quant_b_frames = slice_qp;
} else if ((h264->slice_type == 0) || (h264->slice_type == 5)) {
context->desc.h264enc.picture_type = PIPE_H2645_ENC_PICTURE_TYPE_P;
slice_descriptor.slice_type = PIPE_H264_SLICE_TYPE_P;
context->desc.h264enc.quant_p_frames = slice_qp;
} else if ((h264->slice_type == 2) || (h264->slice_type == 7)) {
if (context->desc.h264enc.picture_type == PIPE_H2645_ENC_PICTURE_TYPE_IDR) {
if (slice_descriptor.macroblock_address == 0) {
@ -161,6 +164,7 @@ vlVaHandleVAEncSliceParameterBufferTypeH264(vlVaDriver *drv, vlVaContext *contex
context->desc.h264enc.picture_type = PIPE_H2645_ENC_PICTURE_TYPE_I;
slice_descriptor.slice_type = PIPE_H264_SLICE_TYPE_I;
}
context->desc.h264enc.quant_i_frames = slice_qp;
} else {
context->desc.h264enc.picture_type = PIPE_H2645_ENC_PICTURE_TYPE_SKIP;
}

View file

@ -63,9 +63,7 @@ vlVaHandleVAEncPictureParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContext *cont
context->coded_buf = coded_buf;
context->desc.h265enc.pic.log2_parallel_merge_level_minus2 = h265->log2_parallel_merge_level_minus2;
context->desc.h265enc.pic.nal_unit_type = h265->nal_unit_type;
context->desc.h265enc.rc.quant_i_frames = h265->pic_init_qp;
context->desc.h265enc.rc.quant_p_frames = h265->pic_init_qp;
context->desc.h265enc.rc.quant_b_frames = h265->pic_init_qp;
context->desc.h265enc.rc.init_qp = h265->pic_init_qp;
switch(h265->pic_fields.bits.coding_type) {
case 1:
@ -106,6 +104,7 @@ VAStatus
vlVaHandleVAEncSliceParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
{
VAEncSliceParameterBufferHEVC *h265;
unsigned slice_qp;
h265 = buf->data;
memset(&context->desc.h265enc.ref_idx_l0_list, VA_INVALID_ID, sizeof(context->desc.h265enc.ref_idx_l0_list));
@ -136,6 +135,23 @@ vlVaHandleVAEncSliceParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContext *contex
context->desc.h265enc.slice.slice_deblocking_filter_disabled_flag = h265->slice_fields.bits.slice_deblocking_filter_disabled_flag;
context->desc.h265enc.slice.slice_loop_filter_across_slices_enabled_flag = h265->slice_fields.bits.slice_loop_filter_across_slices_enabled_flag;
slice_qp = context->desc.h265enc.rc.init_qp + h265->slice_qp_delta;
switch (context->desc.h265enc.picture_type) {
case PIPE_H2645_ENC_PICTURE_TYPE_I:
case PIPE_H2645_ENC_PICTURE_TYPE_IDR:
context->desc.h265enc.rc.quant_i_frames = slice_qp;
break;
case PIPE_H2645_ENC_PICTURE_TYPE_P:
context->desc.h265enc.rc.quant_p_frames = slice_qp;
break;
case PIPE_H2645_ENC_PICTURE_TYPE_B:
context->desc.h265enc.rc.quant_b_frames = slice_qp;
break;
default:
break;
}
/* Handle the slice control parameters */
struct h265_slice_descriptor slice_descriptor;
memset(&slice_descriptor, 0, sizeof(slice_descriptor));

View file

@ -631,6 +631,7 @@ struct pipe_h264_enc_picture_desc
unsigned intra_idr_period;
unsigned ip_period;
unsigned init_qp;
unsigned quant_i_frames;
unsigned quant_p_frames;
unsigned quant_b_frames;
@ -814,6 +815,7 @@ struct pipe_h265_enc_rate_control
unsigned peak_bitrate;
unsigned frame_rate_num;
unsigned frame_rate_den;
unsigned init_qp;
unsigned quant_i_frames;
unsigned quant_p_frames;
unsigned quant_b_frames;
@ -892,6 +894,7 @@ struct pipe_av1_enc_rate_control
unsigned enforce_hrd;
unsigned max_au_size;
unsigned qp; /* Initial QP */
unsigned qp_inter;
unsigned max_qp;
unsigned min_qp;
bool app_requested_qp_range;