diff --git a/src/gallium/drivers/radeonsi/si_get.c b/src/gallium/drivers/radeonsi/si_get.c index d6dc407f084..46b74f8f068 100644 --- a/src/gallium/drivers/radeonsi/si_get.c +++ b/src/gallium/drivers/radeonsi/si_get.c @@ -618,6 +618,11 @@ static int si_get_video_param(struct pipe_screen *screen, enum pipe_video_profil return 4; else return 0; + case PIPE_VIDEO_CAP_ENC_QUALITY_LEVEL: + if (sscreen->info.family >= CHIP_RAVEN) + return 32; + else + return 0; default: return 0; } diff --git a/src/gallium/frontends/va/config.c b/src/gallium/frontends/va/config.c index b07a110b6ec..ae13e624861 100644 --- a/src/gallium/frontends/va/config.c +++ b/src/gallium/frontends/va/config.c @@ -207,6 +207,18 @@ vlVaGetConfigAttributes(VADriverContextP ctx, VAProfile profile, VAEntrypoint en else value = supportedSliceStructuresFlagSet; } break; + case VAConfigAttribEncQualityRange: + { + /* + * this quality range provides different options within the range; and it isn't strictly + * faster when higher value used. + * 0, not used; 1, default value; others are using vlVaQualityBits for different modes. + */ + int quality_range = pscreen->get_video_param(pscreen, ProfileToPipe(profile), + PIPE_VIDEO_ENTRYPOINT_ENCODE, + PIPE_VIDEO_CAP_ENC_QUALITY_LEVEL); + value = quality_range ? quality_range : VA_ATTRIB_NOT_SUPPORTED; + } break; default: value = VA_ATTRIB_NOT_SUPPORTED; break; diff --git a/src/gallium/frontends/va/picture.c b/src/gallium/frontends/va/picture.c index 5f443d5c3f8..422cd7914a1 100644 --- a/src/gallium/frontends/va/picture.c +++ b/src/gallium/frontends/va/picture.c @@ -113,6 +113,52 @@ vlVaGetReferenceFrame(vlVaDriver *drv, VASurfaceID surface_id, else *ref_frame = NULL; } +/* + * in->quality = 0; without any settings, it is using speed preset + * and no preencode and no vbaq. It is the fastest setting. + * in->quality = 1; suggested setting, with balanced preset, and + * preencode and vbaq + * in->quality = others; it is the customized setting + * with valid bit (bit #0) set to "1" + * for example: + * + * 0x3 (balance preset, no pre-encoding, no vbaq) + * 0x13 (balanced preset, no pre-encoding, vbaq) + * 0x13 (balanced preset, no pre-encoding, vbaq) + * 0x9 (speed preset, pre-encoding, no vbaq) + * 0x19 (speed preset, pre-encoding, vbaq) + * + * The quality value has to be treated as a combination + * of preset mode, pre-encoding and vbaq settings. + * The quality and speed could be vary according to + * different settings, + */ +void +vlVaHandleVAEncMiscParameterTypeQualityLevel(struct pipe_enc_quality_modes *p, vlVaQualityBits *in) +{ + if (!in->quality) { + p->level = 0; + p->preset_mode = PRESET_MODE_SPEED; + p->pre_encode_mode = PREENCODING_MODE_DISABLE; + p->vbaq_mode = VBAQ_DISABLE; + + return; + } + + if (p->level != in->quality) { + if (in->quality == 1) { + p->preset_mode = PRESET_MODE_BALANCE; + p->pre_encode_mode = PREENCODING_MODE_DEFAULT; + p->vbaq_mode = VBAQ_AUTO; + } else { + p->preset_mode = in->preset_mode > PRESET_MODE_QUALITY + ? PRESET_MODE_QUALITY : in->preset_mode; + p->pre_encode_mode = in->pre_encode_mode; + p->vbaq_mode = in->vbaq_mode; + } + } + p->level = in->quality; +} static VAStatus handlePictureParameterBuffer(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) @@ -456,6 +502,27 @@ handleVAEncSequenceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vl return status; } +static VAStatus +handleVAEncMiscParameterTypeQualityLevel(vlVaContext *context, VAEncMiscParameterBuffer *misc) +{ + VAStatus status = VA_STATUS_SUCCESS; + + switch (u_reduce_video_profile(context->templat.profile)) { + case PIPE_VIDEO_FORMAT_MPEG4_AVC: + status = vlVaHandleVAEncMiscParameterTypeQualityLevelH264(context, misc); + break; + + case PIPE_VIDEO_FORMAT_HEVC: + status = vlVaHandleVAEncMiscParameterTypeQualityLevelHEVC(context, misc); + break; + + default: + break; + } + + return status; +} + static VAStatus handleVAEncMiscParameterBufferType(vlVaContext *context, vlVaBuffer *buf) { @@ -476,6 +543,10 @@ handleVAEncMiscParameterBufferType(vlVaContext *context, vlVaBuffer *buf) vaStatus = handleVAEncMiscParameterTypeTemporalLayer(context, misc); break; + case VAEncMiscParameterTypeQualityLevel: + vaStatus = handleVAEncMiscParameterTypeQualityLevel(context, misc); + break; + default: break; } diff --git a/src/gallium/frontends/va/picture_h264.c b/src/gallium/frontends/va/picture_h264.c old mode 100755 new mode 100644 diff --git a/src/gallium/frontends/va/picture_h264_enc.c b/src/gallium/frontends/va/picture_h264_enc.c index af190f4f4e9..a02ed9439ab 100644 --- a/src/gallium/frontends/va/picture_h264_enc.c +++ b/src/gallium/frontends/va/picture_h264_enc.c @@ -247,6 +247,16 @@ vlVaHandleVAEncMiscParameterTypeTemporalLayerH264(vlVaContext *context, VAEncMis return VA_STATUS_SUCCESS; } +VAStatus +vlVaHandleVAEncMiscParameterTypeQualityLevelH264(vlVaContext *context, VAEncMiscParameterBuffer *misc) +{ + VAEncMiscParameterBufferQualityLevel *ql = (VAEncMiscParameterBufferQualityLevel *)misc->data; + vlVaHandleVAEncMiscParameterTypeQualityLevel(&context->desc.h264enc.quality_modes, + (vlVaQualityBits *)&ql->quality_level); + + return VA_STATUS_SUCCESS; +} + void getEncParamPresetH264(vlVaContext *context) { //motion estimation preset diff --git a/src/gallium/frontends/va/picture_hevc_enc.c b/src/gallium/frontends/va/picture_hevc_enc.c index f5f044aca21..9fb28ee3a5c 100644 --- a/src/gallium/frontends/va/picture_hevc_enc.c +++ b/src/gallium/frontends/va/picture_hevc_enc.c @@ -197,6 +197,16 @@ vlVaHandleVAEncMiscParameterTypeFrameRateHEVC(vlVaContext *context, VAEncMiscPar return VA_STATUS_SUCCESS; } +VAStatus +vlVaHandleVAEncMiscParameterTypeQualityLevelHEVC(vlVaContext *context, VAEncMiscParameterBuffer *misc) +{ + VAEncMiscParameterBufferQualityLevel *ql = (VAEncMiscParameterBufferQualityLevel *)misc->data; + vlVaHandleVAEncMiscParameterTypeQualityLevel(&context->desc.h265enc.quality_modes, + (vlVaQualityBits *)&ql->quality_level); + + return VA_STATUS_SUCCESS; +} + static void profile_tier(struct vl_rbsp *rbsp) { vl_rbsp_u(rbsp, 2); /* general_profile_space */ diff --git a/src/gallium/frontends/va/surface.c b/src/gallium/frontends/va/surface.c old mode 100755 new mode 100644 diff --git a/src/gallium/frontends/va/va_private.h b/src/gallium/frontends/va/va_private.h old mode 100755 new mode 100644 index 15222ac4d73..42f61c9b8a4 --- a/src/gallium/frontends/va/va_private.h +++ b/src/gallium/frontends/va/va_private.h @@ -67,6 +67,16 @@ #define SOS (8 + 4 * 2) #define MAX_MJPEG_SLICE_HEADER_SIZE (SOI + DQT + DHT + DRI + SOF + SOS) +#define PRESET_MODE_SPEED (0) +#define PRESET_MODE_BALANCE (1) +#define PRESET_MODE_QUALITY (2) + +#define PREENCODING_MODE_DISABLE (0) +#define PREENCODING_MODE_DEFAULT (1) + +#define VBAQ_DISABLE (0) +#define VBAQ_AUTO (1) + static inline enum pipe_video_chroma_format ChromaToPipe(int format) { @@ -342,6 +352,19 @@ typedef struct { enum pipe_format encoder_format; } vlVaSurface; +typedef struct { + union { + unsigned int quality; + struct { + unsigned int valid_setting: 1; + unsigned int preset_mode: 2; + unsigned int pre_encode_mode: 1; + unsigned int vbaq_mode: 1; + unsigned int reservered: 27; + }; + }; +} vlVaQualityBits; + // Public functions: VAStatus VA_DRIVER_INIT_FUNC(VADriverContextP ctx); @@ -467,16 +490,19 @@ void vlVaHandlePictureParameterBufferAV1(vlVaDriver *drv, vlVaContext *context, void vlVaHandleSliceParameterBufferAV1(vlVaContext *context, vlVaBuffer *buf, unsigned int num); void getEncParamPresetH264(vlVaContext *context); void getEncParamPresetH265(vlVaContext *context); +void vlVaHandleVAEncMiscParameterTypeQualityLevel(struct pipe_enc_quality_modes *p, vlVaQualityBits *in); VAStatus vlVaHandleVAEncPictureParameterBufferTypeH264(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf); VAStatus vlVaHandleVAEncSliceParameterBufferTypeH264(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf); VAStatus vlVaHandleVAEncSequenceParameterBufferTypeH264(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf); VAStatus vlVaHandleVAEncMiscParameterTypeRateControlH264(vlVaContext *context, VAEncMiscParameterBuffer *buf); VAStatus vlVaHandleVAEncMiscParameterTypeFrameRateH264(vlVaContext *context, VAEncMiscParameterBuffer *buf); VAStatus vlVaHandleVAEncMiscParameterTypeTemporalLayerH264(vlVaContext *context, VAEncMiscParameterBuffer *buf); +VAStatus vlVaHandleVAEncMiscParameterTypeQualityLevelH264(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); VAStatus vlVaHandleVAEncMiscParameterTypeRateControlHEVC(vlVaContext *context, VAEncMiscParameterBuffer *buf); VAStatus vlVaHandleVAEncMiscParameterTypeFrameRateHEVC(vlVaContext *context, VAEncMiscParameterBuffer *buf); VAStatus vlVaHandleVAEncPackedHeaderDataBufferTypeHEVC(vlVaContext *context, vlVaBuffer *buf); +VAStatus vlVaHandleVAEncMiscParameterTypeQualityLevelHEVC(vlVaContext *context, VAEncMiscParameterBuffer *buf); #endif //VA_PRIVATE_H diff --git a/src/gallium/include/pipe/p_video_enums.h b/src/gallium/include/pipe/p_video_enums.h index 7d157364479..7589fb5ea0b 100644 --- a/src/gallium/include/pipe/p_video_enums.h +++ b/src/gallium/include/pipe/p_video_enums.h @@ -105,6 +105,7 @@ enum pipe_video_cap PIPE_VIDEO_CAP_VPP_MAX_OUTPUT_HEIGHT = 23, PIPE_VIDEO_CAP_VPP_MIN_OUTPUT_WIDTH = 24, PIPE_VIDEO_CAP_VPP_MIN_OUTPUT_HEIGHT = 25, + PIPE_VIDEO_CAP_ENC_QUALITY_LEVEL = 26, }; /* To be used with PIPE_VIDEO_CAP_VPP_ORIENTATION_MODES and for VPP state*/ diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h index 1a95dfb39d4..7948e62a5ba 100755 --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -362,6 +362,14 @@ struct pipe_h264_picture_desc void *priv; }; +struct pipe_enc_quality_modes +{ + unsigned int level; + unsigned int preset_mode; + unsigned int pre_encode_mode; + unsigned int vbaq_mode; +}; + struct pipe_h264_enc_rate_control { enum pipe_h2645_enc_rate_control_method rate_ctrl_method; @@ -440,6 +448,7 @@ struct pipe_h264_enc_picture_desc unsigned gop_size; unsigned ref_pic_mode; unsigned num_temporal_layers; + struct pipe_enc_quality_modes quality_modes; bool not_referenced; bool enable_vui; @@ -531,6 +540,7 @@ struct pipe_h265_enc_picture_desc unsigned pic_order_cnt_type; unsigned ref_idx_l0; unsigned ref_idx_l1; + struct pipe_enc_quality_modes quality_modes; bool not_referenced; struct hash_table *frame_idx; };