venus: Add support for min/max qp range.
authorViswanath Boma <quic_vboma@quicinc.com>
Thu, 23 Mar 2023 09:10:52 +0000 (14:40 +0530)
committerHans Verkuil <hverkuil-cisco@xs4all.nl>
Wed, 12 Apr 2023 07:35:44 +0000 (09:35 +0200)
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 <quic_vboma@quicinc.com>
Signed-off-by: Vikash Garodia <quic_vgarodia@quicinc.com>
Signed-off-by: Stanimir Varbanov <stanimir.k.varbanov@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
drivers/media/platform/qcom/venus/hfi_cmds.c
drivers/media/platform/qcom/venus/hfi_helper.h
drivers/media/platform/qcom/venus/venc.c

index 930b743..bc3f8ff 100644 (file)
@@ -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:
index d2d6719..105792a 100644 (file)
 #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
index 6d61614..8d80033 100644 (file)
@@ -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;