From 90655e2e79b4547fbae6bd0ce737db0df93465c4 Mon Sep 17 00:00:00 2001 From: Viswanath Boma Date: Thu, 23 Mar 2023 14:40:52 +0530 Subject: venus: Add support for min/max qp range. Currently QP range set from client is not communicated to video firmware. Add support for the QP range HFI to set the same to firmware. Signed-off-by: Viswanath Boma Signed-off-by: Vikash Garodia Signed-off-by: Stanimir Varbanov Signed-off-by: Hans Verkuil --- drivers/media/platform/qcom/venus/hfi_cmds.c | 23 +++++++++++++++ drivers/media/platform/qcom/venus/hfi_helper.h | 18 +++++++++++ drivers/media/platform/qcom/venus/venc.c | 41 +++++++++++++++++++++----- 3 files changed, 74 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/qcom/venus/hfi_cmds.c b/drivers/media/platform/qcom/venus/hfi_cmds.c index 930b743f225e..bc3f8ff05840 100644 --- a/drivers/media/platform/qcom/venus/hfi_cmds.c +++ b/drivers/media/platform/qcom/venus/hfi_cmds.c @@ -1257,7 +1257,30 @@ pkt_session_set_property_4xx(struct hfi_session_set_property_pkt *pkt, pkt->shdr.hdr.size += sizeof(u32) + sizeof(*tm); break; } + case HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE_V2: { + struct hfi_quantization_range_v2 *in = pdata, *range = prop_data; + u32 min_qp, max_qp; + + min_qp = in->min_qp.qp_packed; + max_qp = in->max_qp.qp_packed; + /* We'll be packing in the qp, so make sure we + * won't be losing data when masking + */ + if (min_qp > 0xff || max_qp > 0xff) + return -ERANGE; + + range->min_qp.layer_id = 0xFF; + range->max_qp.layer_id = 0xFF; + range->min_qp.qp_packed = (min_qp & 0xFF) | ((min_qp & 0xFF) << 8) | + ((min_qp & 0xFF) << 16); + range->max_qp.qp_packed = (max_qp & 0xFF) | ((max_qp & 0xFF) << 8) | + ((max_qp & 0xFF) << 16); + range->min_qp.enable = 7; + range->max_qp.enable = 7; + pkt->shdr.hdr.size += sizeof(u32) + sizeof(*range); + break; + } case HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE: case HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER: case HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE: diff --git a/drivers/media/platform/qcom/venus/hfi_helper.h b/drivers/media/platform/qcom/venus/hfi_helper.h index d2d6719a2ba4..105792a68060 100644 --- a/drivers/media/platform/qcom/venus/hfi_helper.h +++ b/drivers/media/platform/qcom/venus/hfi_helper.h @@ -487,6 +487,11 @@ #define HFI_PROPERTY_PARAM_VENC_SESSION_QP 0x2005006 #define HFI_PROPERTY_PARAM_VENC_MPEG4_AC_PREDICTION 0x2005007 #define HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE 0x2005008 +/* + * Note: HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE_V2 is + * specific to HFI_VERSION_6XX and HFI_VERSION_4XX only + */ +#define HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE_V2 0x2005009 #define HFI_PROPERTY_PARAM_VENC_MPEG4_TIME_RESOLUTION 0x2005009 #define HFI_PROPERTY_PARAM_VENC_MPEG4_SHORT_HEADER 0x200500a #define HFI_PROPERTY_PARAM_VENC_MPEG4_HEADER_EXTENSION 0x200500b @@ -827,6 +832,19 @@ struct hfi_quantization_range { u32 layer_id; }; +struct hfi_quantization_v2 { + u32 qp_packed; + u32 layer_id; + u32 enable; + u32 reserved[3]; +}; + +struct hfi_quantization_range_v2 { + struct hfi_quantization_v2 min_qp; + struct hfi_quantization_v2 max_qp; + u32 reserved[4]; +}; + #define HFI_LTR_MODE_DISABLE 0x0 #define HFI_LTR_MODE_MANUAL 0x1 #define HFI_LTR_MODE_PERIODIC 0x2 diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index 6d61614656a5..8d80033bb612 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -617,6 +617,7 @@ static int venc_set_properties(struct venus_inst *inst) struct hfi_idr_period idrp; struct hfi_quantization quant; struct hfi_quantization_range quant_range; + struct hfi_quantization_range_v2 quant_range_v2; struct hfi_enable en; struct hfi_ltr_mode ltr_mode; struct hfi_intra_refresh intra_refresh = {}; @@ -825,16 +826,40 @@ static int venc_set_properties(struct venus_inst *inst) if (ret) return ret; - ptype = HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE; - if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_HEVC) { - quant_range.min_qp = ctr->hevc_min_qp; - quant_range.max_qp = ctr->hevc_max_qp; + if (inst->core->res->hfi_version == HFI_VERSION_4XX || + inst->core->res->hfi_version == HFI_VERSION_6XX) { + ptype = HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE_V2; + + if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_HEVC) { + quant_range_v2.min_qp.qp_packed = ctr->hevc_min_qp; + quant_range_v2.max_qp.qp_packed = ctr->hevc_max_qp; + } else if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_VP8) { + quant_range_v2.min_qp.qp_packed = ctr->vp8_min_qp; + quant_range_v2.max_qp.qp_packed = ctr->vp8_max_qp; + } else { + quant_range_v2.min_qp.qp_packed = ctr->h264_min_qp; + quant_range_v2.max_qp.qp_packed = ctr->h264_max_qp; + } + + ret = hfi_session_set_property(inst, ptype, &quant_range_v2); } else { - quant_range.min_qp = ctr->h264_min_qp; - quant_range.max_qp = ctr->h264_max_qp; + ptype = HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE; + + if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_HEVC) { + quant_range.min_qp = ctr->hevc_min_qp; + quant_range.max_qp = ctr->hevc_max_qp; + } else if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_VP8) { + quant_range.min_qp = ctr->vp8_min_qp; + quant_range.max_qp = ctr->vp8_max_qp; + } else { + quant_range.min_qp = ctr->h264_min_qp; + quant_range.max_qp = ctr->h264_max_qp; + } + + quant_range.layer_id = 0; + ret = hfi_session_set_property(inst, ptype, &quant_range); } - quant_range.layer_id = 0; - ret = hfi_session_set_property(inst, ptype, &quant_range); + if (ret) return ret; -- cgit