diff --git a/src/gallium/frontends/va/config.c b/src/gallium/frontends/va/config.c index 9abf9af832b..868e568a1a3 100644 --- a/src/gallium/frontends/va/config.c +++ b/src/gallium/frontends/va/config.c @@ -544,6 +544,17 @@ vlVaGetConfigAttributes(VADriverContextP ctx, VAProfile profile, VAEntrypoint en value = ir_support; } break; + case VAConfigAttribEncROI: + { + int roi_support = pscreen->get_video_param(pscreen, ProfileToPipe(profile), + PIPE_VIDEO_ENTRYPOINT_ENCODE, + PIPE_VIDEO_CAP_ENC_ROI); + if (roi_support <= 0) + value = VA_ATTRIB_NOT_SUPPORTED; + else + value = roi_support; + } 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 abcfec06233..9172980bc77 100644 --- a/src/gallium/frontends/va/picture.c +++ b/src/gallium/frontends/va/picture.c @@ -718,6 +718,56 @@ handleVAEncMiscParameterTypeRIR(vlVaContext *context, VAEncMiscParameterBuffer * return status; } +static VAStatus +handleVAEncMiscParameterTypeROI(vlVaContext *context, VAEncMiscParameterBuffer *misc) +{ + VAStatus status = VA_STATUS_SUCCESS; + struct pipe_enc_roi *proi= NULL; + switch (u_reduce_video_profile(context->templat.profile)) { + case PIPE_VIDEO_FORMAT_MPEG4_AVC: + proi = &context->desc.h264enc.roi; + break; + case PIPE_VIDEO_FORMAT_HEVC: + proi = &context->desc.h265enc.roi; + break; +#if VA_CHECK_VERSION(1, 16, 0) + case PIPE_VIDEO_FORMAT_AV1: + proi = &context->desc.av1enc.roi; + break; +#endif + default: + break; + }; + + if (proi) { + VAEncMiscParameterBufferROI *roi = (VAEncMiscParameterBufferROI *)misc->data; + /* do not support priority type, and the maximum region is 32 */ + if ((roi->num_roi > 0 && roi->roi_flags.bits.roi_value_is_qp_delta == 0) + || roi->num_roi > PIPE_ENC_ROI_REGION_NUM_MAX) + status = VA_STATUS_ERROR_FLAG_NOT_SUPPORTED; + else { + uint32_t i; + VAEncROI *src = roi->roi; + + proi->num = roi->num_roi; + for (i = 0; i < roi->num_roi; i++) { + proi->region[i].valid = true; + proi->region[i].x = src->roi_rectangle.x; + proi->region[i].y = src->roi_rectangle.y; + proi->region[i].width = src->roi_rectangle.width; + proi->region[i].height = src->roi_rectangle.height; + proi->region[i].qp_value = (int32_t)CLAMP(src->roi_value, roi->min_delta_qp, roi->max_delta_qp); + src++; + } + + for (; i < PIPE_ENC_ROI_REGION_NUM_MAX; i++) + proi->region[i].valid = false; + } + } + + return status; +} + static VAStatus handleVAEncMiscParameterBufferType(vlVaContext *context, vlVaBuffer *buf) { @@ -758,6 +808,10 @@ handleVAEncMiscParameterBufferType(vlVaContext *context, vlVaBuffer *buf) vaStatus = handleVAEncMiscParameterTypeMaxSliceSize(context, misc); break; + case VAEncMiscParameterTypeROI: + vaStatus = handleVAEncMiscParameterTypeROI(context, misc); + break; + default: break; } diff --git a/src/gallium/include/pipe/p_video_enums.h b/src/gallium/include/pipe/p_video_enums.h index cfc1f74e6f6..8c03fe74755 100644 --- a/src/gallium/include/pipe/p_video_enums.h +++ b/src/gallium/include/pipe/p_video_enums.h @@ -157,6 +157,10 @@ enum pipe_video_cap crop and partial decode support */ PIPE_VIDEO_CAP_ROI_CROP_DEC = 48, + /* + * Encoding Region Of Interest feature + */ + PIPE_VIDEO_CAP_ENC_ROI = 49, }; enum pipe_video_h264_enc_dbk_filter_mode_flags diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h index 67f41c0a3df..0945db18e8f 100644 --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -48,6 +48,7 @@ extern "C" { #define PIPE_DEFAULT_FRAME_RATE_NUM 30 #define PIPE_DEFAULT_INTRA_IDR_PERIOD 30 #define PIPE_H2645_EXTENDED_SAR 255 +#define PIPE_ENC_ROI_REGION_NUM_MAX 32 #define PIPE_DEFAULT_DECODER_FEEDBACK_TIMEOUT_NS 1000000000 /* @@ -449,6 +450,32 @@ enum INTRA_REFRESH_MODE_UNIT_COLUMNS, }; +/* All the values are in pixels, driver converts it into + * different units for different codecs, for example: h264 + * is in 16x16 block, hevc/av1 is in 64x64 block. + * x, y means the location of region start, width/height defines + * the region size; the qp value carries the qp_delta. + */ +struct pipe_enc_region_in_roi +{ + bool valid; + int32_t qp_value; + unsigned int x, y; + unsigned int width, height; +}; +/* It does not support prioirty only qp_delta. + * The priority is implied by the region sequence number. + * Region 0 is most significant one, and region 1 is less + * significant, and lesser significant when region number + * grows. It allows region overlapping, and lower + * priority region would be overwritten by the higher one. + */ +struct pipe_enc_roi +{ + unsigned int num; + struct pipe_enc_region_in_roi region[PIPE_ENC_ROI_REGION_NUM_MAX]; +}; + struct pipe_h264_enc_rate_control { enum pipe_h2645_enc_rate_control_method rate_ctrl_method; @@ -625,6 +652,7 @@ struct pipe_h264_enc_picture_desc unsigned gop_size; struct pipe_enc_quality_modes quality_modes; struct pipe_enc_intra_refresh intra_refresh; + struct pipe_enc_roi roi; bool not_referenced; bool is_ltr; @@ -819,6 +847,7 @@ struct pipe_h265_enc_picture_desc unsigned pic_order_cnt_type; struct pipe_enc_quality_modes quality_modes; struct pipe_enc_intra_refresh intra_refresh; + struct pipe_enc_roi roi; unsigned num_ref_idx_l0_active_minus1; unsigned num_ref_idx_l1_active_minus1; unsigned ref_idx_l0_list[PIPE_H265_MAX_REFERENCES]; @@ -964,6 +993,7 @@ struct pipe_av1_enc_picture_desc }; struct pipe_enc_quality_modes quality_modes; struct pipe_enc_intra_refresh intra_refresh; + struct pipe_enc_roi roi; uint32_t num_tiles_in_pic; /* [1, 32], */ uint32_t tile_rows; uint32_t tile_cols; @@ -1936,6 +1966,42 @@ struct pipe_enc_feedback_metadata unsigned int average_frame_qp; }; +union pipe_enc_cap_roi { + struct { + /** + * The number of ROI regions supported, 0 if ROI is not supported + */ + uint32_t num_roi_regions : 8; + /** + * A flag indicates whether ROI priority is supported + * + * roi_rc_priority_support equal to 1 specifies the underlying driver supports + * ROI priority when VAConfigAttribRateControl != VA_RC_CQP, user can use roi_value + * in #VAEncROI to set ROI priority. roi_rc_priority_support equal to 0 specifies + * the underlying driver doesn't support ROI priority. + * + * User should ignore roi_rc_priority_support when VAConfigAttribRateControl == VA_RC_CQP + * because ROI delta QP is always required when VAConfigAttribRateControl == VA_RC_CQP. + */ + uint32_t roi_rc_priority_support : 1; + /** + * A flag indicates whether ROI delta QP is supported + * + * roi_rc_qp_delta_support equal to 1 specifies the underlying driver supports + * ROI delta QP when VAConfigAttribRateControl != VA_RC_CQP, user can use roi_value + * in #VAEncROI to set ROI delta QP. roi_rc_qp_delta_support equal to 0 specifies + * the underlying driver doesn't support ROI delta QP. + * + * User should ignore roi_rc_qp_delta_support when VAConfigAttribRateControl == VA_RC_CQP + * because ROI delta QP is always required when VAConfigAttribRateControl == VA_RC_CQP. + */ + uint32_t roi_rc_qp_delta_support : 1; + uint32_t reserved : 22; + + } bits; + uint32_t value; +}; + #ifdef __cplusplus } #endif