瀏覽代碼

video: driver: Add support to deduce min, max, frame qp values

Add support to deduce min, max, frame qp values from client set
controls and set the same to video firmware.

Change-Id: Id94e781cc0c8afdf0e9e00562bdaea32db04fd74
Signed-off-by: Akshata Sahukar <[email protected]>
Akshata Sahukar 4 年之前
父節點
當前提交
0b21038c27

+ 90 - 69
driver/platform/waipio/src/msm_vidc_waipio.c

@@ -23,6 +23,10 @@
 #define MIN_CHROMA_QP_OFFSET    -12
 #define MIN_CHROMA_QP_OFFSET    -12
 #define MAX_CHROMA_QP_OFFSET    0
 #define MAX_CHROMA_QP_OFFSET    0
 #define MAX_BITRATE             220000000
 #define MAX_BITRATE             220000000
+#define MIN_QP_10BIT            -12
+#define MIN_QP_8BIT             0
+#define MAX_QP                  51
+#define DEFAULT_QP              20
 
 
 #define UBWC_CONFIG(mc, ml, hbb, bs1, bs2, bs3, bsp) \
 #define UBWC_CONFIG(mc, ml, hbb, bs1, bs2, bs3, bsp) \
 {	\
 {	\
@@ -115,7 +119,18 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
 		MSM_VIDC_FMT_NV12C,
 		MSM_VIDC_FMT_NV12C,
 		BIT(MSM_VIDC_FMT_NV12) | BIT(MSM_VIDC_FMT_NV21) | BIT(MSM_VIDC_FMT_NV12C),
 		BIT(MSM_VIDC_FMT_NV12) | BIT(MSM_VIDC_FMT_NV21) | BIT(MSM_VIDC_FMT_NV12C),
 		MSM_VIDC_FMT_NV12C},
 		MSM_VIDC_FMT_NV12C},
-	{PIX_FMTS, ENC|DEC, HEVC,
+	{PIX_FMTS, ENC, HEVC,
+		MSM_VIDC_FMT_NV12,
+		MSM_VIDC_FMT_TP10C,
+		BIT(MSM_VIDC_FMT_NV12) | BIT(MSM_VIDC_FMT_NV21) | BIT(MSM_VIDC_FMT_NV12C ) |
+		BIT(MSM_VIDC_FMT_P010) | BIT(MSM_VIDC_FMT_TP10C),
+		MSM_VIDC_FMT_NV12C,
+		0, 0,
+		CAP_FLAG_ROOT,
+		{0},
+		{PROFILE, MIN_FRAME_QP, MAX_FRAME_QP, I_FRAME_QP}},
+
+	{PIX_FMTS, DEC, HEVC,
 		MSM_VIDC_FMT_NV12,
 		MSM_VIDC_FMT_NV12,
 		MSM_VIDC_FMT_TP10C,
 		MSM_VIDC_FMT_TP10C,
 		BIT(MSM_VIDC_FMT_NV12) | BIT(MSM_VIDC_FMT_NV21) | BIT(MSM_VIDC_FMT_NV12C ) |
 		BIT(MSM_VIDC_FMT_NV12) | BIT(MSM_VIDC_FMT_NV21) | BIT(MSM_VIDC_FMT_NV12C ) |
@@ -294,7 +309,7 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
 		V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
 		V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
 		HFI_PROP_RATE_CONTROL,
 		HFI_PROP_RATE_CONTROL,
 		CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
 		CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
-		{0}, {LTR_COUNT, IR_RANDOM, TIME_DELTA_BASED_RC},
+		{0}, {LTR_COUNT, IR_RANDOM, TIME_DELTA_BASED_RC, I_FRAME_QP},
 		msm_vidc_adjust_bitrate_mode, msm_vidc_set_u32_enum},
 		msm_vidc_adjust_bitrate_mode, msm_vidc_set_u32_enum},
 
 
 	{LOSSLESS, ENC, HEVC,
 	{LOSSLESS, ENC, HEVC,
@@ -441,68 +456,85 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
 		0, 1000, 500, 0,
 		0, 1000, 500, 0,
 		V4L2_CID_MPEG_VIDEO_VBV_DELAY},
 		V4L2_CID_MPEG_VIDEO_VBV_DELAY},
 
 
-	// TODO: QP for 10 bits and review QP caps
+	{MIN_FRAME_QP, ENC, H264,
+		MIN_QP_8BIT, MAX_QP, 1, MIN_QP_8BIT,
+		V4L2_CID_MPEG_VIDEO_H264_MIN_QP,
+		HFI_PROP_MIN_QP_PACKED,
+		CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT,
+		{0}, {0},
+		NULL, msm_vidc_set_min_qp},
 
 
 	{MIN_FRAME_QP, ENC, HEVC,
 	{MIN_FRAME_QP, ENC, HEVC,
-		0, 51, 1, 20,
+		MIN_QP_10BIT, MAX_QP, 1, MIN_QP_10BIT,
 		V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
 		V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
 		HFI_PROP_MIN_QP_PACKED,
 		HFI_PROP_MIN_QP_PACKED,
-		CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT},
-
-	{MIN_FRAME_QP, ENC, H264,
-		0, 51, 1, 20,
-		V4L2_CID_MPEG_VIDEO_H264_MIN_QP,
-		HFI_PROP_MIN_QP_PACKED,
-		CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT},
+		CAP_FLAG_OUTPUT_PORT,
+		{PIX_FMTS}, {0},
+		msm_vidc_adjust_hevc_min_qp, msm_vidc_set_min_qp},
 
 
 	{I_FRAME_MIN_QP, ENC, H264,
 	{I_FRAME_MIN_QP, ENC, H264,
-		0, 51, 1, 20,
-		V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP,
-		HFI_PROP_MIN_QP_PACKED,
-		CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT},
+		MIN_QP_8BIT, MAX_QP, 1, MIN_QP_8BIT,
+		V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP},
+
+	{I_FRAME_MIN_QP, ENC, HEVC,
+		MIN_QP_10BIT, MAX_QP, 1, MIN_QP_10BIT,
+		V4L2_CID_MPEG_VIDC_HEVC_I_FRAME_MIN_QP},
 
 
 	{P_FRAME_MIN_QP, ENC, H264,
 	{P_FRAME_MIN_QP, ENC, H264,
-		0, 51, 1, 20,
-		V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP,
-		HFI_PROP_MIN_QP_PACKED,
-		CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT},
+		MIN_QP_8BIT, MAX_QP, 1, MIN_QP_8BIT,
+		V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP},
 
 
-	// confirm codec
-	{B_FRAME_MIN_QP, ENC, HEVC|H264,
-		0, 51, 1, 20,
-		V4L2_CID_MPEG_VIDC_B_FRAME_MIN_QP,
-		HFI_PROP_MIN_QP_PACKED,
-		CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT},
+	{P_FRAME_MIN_QP, ENC, HEVC,
+		MIN_QP_10BIT, MAX_QP, 1, MIN_QP_10BIT,
+		V4L2_CID_MPEG_VIDC_HEVC_P_FRAME_MIN_QP},
+
+	{B_FRAME_MIN_QP, ENC, H264,
+		MIN_QP_8BIT, MAX_QP, 1, MIN_QP_8BIT,
+		V4L2_CID_MPEG_VIDC_B_FRAME_MIN_QP},
+
+	{B_FRAME_MIN_QP, ENC, HEVC,
+		MIN_QP_10BIT, MAX_QP, 1, MIN_QP_10BIT,
+		V4L2_CID_MPEG_VIDC_B_FRAME_MIN_QP},
 
 
 	{MAX_FRAME_QP, ENC, H264,
 	{MAX_FRAME_QP, ENC, H264,
-		0, 51, 1, 20,
+		MIN_QP_8BIT, MAX_QP, 1, MAX_QP,
 		V4L2_CID_MPEG_VIDEO_H264_MAX_QP,
 		V4L2_CID_MPEG_VIDEO_H264_MAX_QP,
 		HFI_PROP_MAX_QP_PACKED,
 		HFI_PROP_MAX_QP_PACKED,
-		CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT},
+		CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT,
+		{0}, {0},
+		NULL, msm_vidc_set_min_qp},
 
 
 	{MAX_FRAME_QP, ENC, HEVC,
 	{MAX_FRAME_QP, ENC, HEVC,
-		0, 51, 1, 20,
+		MIN_QP_10BIT, MAX_QP, 1, MAX_QP,
 		V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP,
 		V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP,
 		HFI_PROP_MAX_QP_PACKED,
 		HFI_PROP_MAX_QP_PACKED,
-		CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT},
+		CAP_FLAG_OUTPUT_PORT,
+		{PIX_FMTS}, {0},
+		msm_vidc_adjust_hevc_max_qp, msm_vidc_set_min_qp},
 
 
 	{I_FRAME_MAX_QP, ENC, H264,
 	{I_FRAME_MAX_QP, ENC, H264,
-		0, 51, 1, 20,
-		V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP,
-		HFI_PROP_MAX_QP_PACKED,
-		CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT},
+		MIN_QP_8BIT, MAX_QP, 1, MAX_QP,
+		V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP},
+
+	{I_FRAME_MAX_QP, ENC, HEVC,
+		MIN_QP_10BIT, MAX_QP, 1, MAX_QP,
+		V4L2_CID_MPEG_VIDC_HEVC_I_FRAME_MAX_QP},
 
 
 	{P_FRAME_MAX_QP, ENC, H264,
 	{P_FRAME_MAX_QP, ENC, H264,
-		0, 51, 1, 20,
-		V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP,
-		HFI_PROP_MAX_QP_PACKED,
-		CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT},
+		MIN_QP_8BIT, MAX_QP, 1, MAX_QP,
+		V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP},
 
 
-	{B_FRAME_MAX_QP, ENC, HEVC|H264,
-		0, 51, 1, 20,
-		V4L2_CID_MPEG_VIDC_B_FRAME_MAX_QP,
-		HFI_PROP_MAX_QP_PACKED,
-		CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT},
+	{P_FRAME_MAX_QP, ENC, HEVC,
+		MIN_QP_10BIT, MAX_QP, 1, MAX_QP,
+		V4L2_CID_MPEG_VIDC_HEVC_P_FRAME_MAX_QP},
+
+	{B_FRAME_MAX_QP, ENC, H264,
+		MIN_QP_8BIT, MAX_QP, 1, MAX_QP,
+		V4L2_CID_MPEG_VIDC_B_FRAME_MAX_QP},
+
+	{B_FRAME_MAX_QP, ENC, HEVC,
+		MIN_QP_10BIT, MAX_QP, 1, MAX_QP,
+		V4L2_CID_MPEG_VIDC_B_FRAME_MAX_QP},
 
 
 	{HEVC_HIER_QP, ENC, HEVC,
 	{HEVC_HIER_QP, ENC, HEVC,
 		V4L2_MPEG_MSM_VIDC_DISABLE, V4L2_MPEG_MSM_VIDC_ENABLE,
 		V4L2_MPEG_MSM_VIDC_DISABLE, V4L2_MPEG_MSM_VIDC_ENABLE,
@@ -511,50 +543,39 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
 		HFI_PROP_QP_PACKED,
 		HFI_PROP_QP_PACKED,
 		CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT},
 		CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT},
 
 
-	/*
-	 * HEVC I_MIN_QP, I_MAX_QP, P_MIN_QP, P_MAX_QP, B_MIN_QP, B_MAX_QP are missing
-	 */
 	{I_FRAME_QP, ENC, HEVC,
 	{I_FRAME_QP, ENC, HEVC,
-		0, 51, 1, 10,
+		MIN_QP_10BIT, MAX_QP, 1, DEFAULT_QP,
 		V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP,
 		V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP,
 		HFI_PROP_QP_PACKED,
 		HFI_PROP_QP_PACKED,
-		CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT},
+		CAP_FLAG_OUTPUT_PORT,
+		{PIX_FMTS, BITRATE_MODE}, {0},
+		msm_vidc_adjust_hevc_frame_qp, msm_vidc_set_frame_qp},
 
 
 	{I_FRAME_QP, ENC, H264,
 	{I_FRAME_QP, ENC, H264,
-		0, 51, 1, 10,
+		MIN_QP_8BIT, MAX_QP, 1, DEFAULT_QP,
 		V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP,
 		V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP,
 		HFI_PROP_QP_PACKED,
 		HFI_PROP_QP_PACKED,
-		CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT},
-
-	{I_FRAME_QP, ENC, VP9, 0, 127, 1, 20},
+		CAP_FLAG_OUTPUT_PORT,
+		{BITRATE_MODE}, {0},
+		NULL, msm_vidc_set_frame_qp},
 
 
 	{P_FRAME_QP, ENC, HEVC,
 	{P_FRAME_QP, ENC, HEVC,
-		0, 51, 1, 20,
-		V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP,
-		HFI_PROP_QP_PACKED,
-		CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT},
+		MIN_QP_10BIT, MAX_QP, 1, DEFAULT_QP,
+		V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP},
 
 
 	{P_FRAME_QP, ENC, H264,
 	{P_FRAME_QP, ENC, H264,
-		0, 51, 1, 20,
-		V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP,
-		HFI_PROP_QP_PACKED,
-		CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT},
+		MIN_QP_8BIT, MAX_QP, 1, DEFAULT_QP,
+		V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP},
 
 
 	{P_FRAME_QP, ENC, VP9, 0, 127, 1, 40},
 	{P_FRAME_QP, ENC, VP9, 0, 127, 1, 40},
 
 
 	{B_FRAME_QP, ENC, HEVC,
 	{B_FRAME_QP, ENC, HEVC,
-		0, 51, 1, 20,
-		V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP,
-		HFI_PROP_QP_PACKED,
-		CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT},
+		MIN_QP_10BIT, MAX_QP, 1, DEFAULT_QP,
+		V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP},
 
 
 	{B_FRAME_QP, ENC, H264,
 	{B_FRAME_QP, ENC, H264,
-		0, 51, 1, 20,
-		V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP,
-		HFI_PROP_QP_PACKED,
-		CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT},
-
-	{B_FRAME_QP, ENC, VP9, 0, 127, 1, 40},
+		MIN_QP_8BIT, MAX_QP, 1, DEFAULT_QP,
+		V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP},
 
 
 	{L0_QP, ENC, HEVC,
 	{L0_QP, ENC, HEVC,
 		0, 51, 1, 20,
 		0, 51, 1, 20,

+ 9 - 0
driver/vidc/inc/msm_vidc_control.h

@@ -28,12 +28,21 @@ int msm_vidc_adjust_mark_ltr(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_ir_random(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_ir_random(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_delta_based_rc(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_delta_based_rc(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_transform_8x8(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_transform_8x8(void *instance, struct v4l2_ctrl *ctrl);
+int msm_vidc_adjust_hevc_min_qp(void *instance, struct v4l2_ctrl *ctrl);
+int msm_vidc_adjust_hevc_max_qp(void *instance, struct v4l2_ctrl *ctrl);
+int msm_vidc_adjust_hevc_frame_qp(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_v4l2_properties(struct msm_vidc_inst *inst);
 int msm_vidc_adjust_v4l2_properties(struct msm_vidc_inst *inst);
 
 
 int msm_vidc_set_header_mode(void *instance,
 int msm_vidc_set_header_mode(void *instance,
 	enum msm_vidc_inst_capability_type cap_id);
 	enum msm_vidc_inst_capability_type cap_id);
 int msm_vidc_set_deblock_mode(void *instance,
 int msm_vidc_set_deblock_mode(void *instance,
 	enum msm_vidc_inst_capability_type cap_id);
 	enum msm_vidc_inst_capability_type cap_id);
+int msm_vidc_set_min_qp(void *instance,
+	enum msm_vidc_inst_capability_type cap_id);
+int msm_vidc_set_max_qp(void *instance,
+	enum msm_vidc_inst_capability_type cap_id);
+int msm_vidc_set_frame_qp(void *instance,
+	enum msm_vidc_inst_capability_type cap_id);
 int msm_vidc_set_u32(void *instance,
 int msm_vidc_set_u32(void *instance,
 	enum msm_vidc_inst_capability_type cap_id);
 	enum msm_vidc_inst_capability_type cap_id);
 int msm_vidc_set_u32_enum(void *instance,
 int msm_vidc_set_u32_enum(void *instance,

+ 270 - 8
driver/vidc/src/msm_vidc_control.c

@@ -11,6 +11,11 @@
 #include "msm_vidc_internal.h"
 #include "msm_vidc_internal.h"
 #include "msm_vidc_driver.h"
 #include "msm_vidc_driver.h"
 
 
+#define CAP_TO_8BIT_QP(a) {          \
+	if ((a) < 0)                 \
+		(a) = 0;             \
+}
+
 static bool is_priv_ctrl(u32 id)
 static bool is_priv_ctrl(u32 id)
 {
 {
 	if (IS_PRIV_CTRL(id))
 	if (IS_PRIV_CTRL(id))
@@ -191,6 +196,14 @@ static const char *msm_vidc_get_priv_ctrl_name(u32 sid, u32 control_id)
 		return "Encoder QP Metadata";
 		return "Encoder QP Metadata";
 	case V4L2_CID_MPEG_VIDC_MIN_BITSTREAM_SIZE_OVERWRITE:
 	case V4L2_CID_MPEG_VIDC_MIN_BITSTREAM_SIZE_OVERWRITE:
 		return "Bitstream Size Overwrite";
 		return "Bitstream Size Overwrite";
+	case V4L2_CID_MPEG_VIDC_HEVC_I_FRAME_MIN_QP:
+		return "HEVC I Frame Min QP";
+	case V4L2_CID_MPEG_VIDC_HEVC_P_FRAME_MIN_QP:
+		return "HEVC P Frame Min QP";
+	case V4L2_CID_MPEG_VIDC_HEVC_I_FRAME_MAX_QP:
+		return "HEVC I Frame Max QP";
+	case V4L2_CID_MPEG_VIDC_HEVC_P_FRAME_MAX_QP:
+		return "HEVC P Frame Max QP";
 	default:
 	default:
 		s_vpr_e(sid, "%s: ctrl name not available for ctrl id %#x\n",
 		s_vpr_e(sid, "%s: ctrl name not available for ctrl id %#x\n",
 			__func__, control_id);
 			__func__, control_id);
@@ -337,14 +350,54 @@ static int msm_vidc_get_parent_value(struct msm_vidc_inst* inst,
 			*value = inst->capabilities->cap[parent].value;
 			*value = inst->capabilities->cap[parent].value;
 	} else {
 	} else {
 		s_vpr_e(inst->sid,
 		s_vpr_e(inst->sid,
-			"%s: missing parent %d, please correct database\n",
-			func, parent);
+			"%s: missing parent %d for cap %d, please correct database\n",
+			func, parent, cap);
 		rc = -EINVAL;
 		rc = -EINVAL;
 	}
 	}
 
 
 	return rc;
 	return rc;
 }
 }
 
 
+static int msm_vidc_adjust_hevc_qp(struct msm_vidc_inst *inst,
+	enum msm_vidc_inst_capability_type cap_id)
+{
+	struct msm_vidc_inst_capability *capability;
+	s32 pix_fmt = -1;
+
+	capability = inst->capabilities;
+
+	if (inst->codec != MSM_VIDC_HEVC) {
+		s_vpr_e(inst->sid,
+			"%s: incorrect entry in database for cap %d. fix the database\n",
+			__func__, cap_id);
+		return -EINVAL;
+	}
+
+	if (msm_vidc_get_parent_value(inst, cap_id,
+		PIX_FMTS, &pix_fmt, __func__))
+		return -EINVAL;
+
+	if (pix_fmt == MSM_VIDC_FMT_P010 || pix_fmt == MSM_VIDC_FMT_TP10C)
+		goto exit;
+
+	CAP_TO_8BIT_QP(capability->cap[cap_id].value);
+	if (cap_id == MIN_FRAME_QP) {
+		CAP_TO_8BIT_QP(capability->cap[I_FRAME_MIN_QP].value);
+		CAP_TO_8BIT_QP(capability->cap[P_FRAME_MIN_QP].value);
+		CAP_TO_8BIT_QP(capability->cap[B_FRAME_MIN_QP].value);
+	} else if (cap_id == MAX_FRAME_QP) {
+		CAP_TO_8BIT_QP(capability->cap[I_FRAME_MAX_QP].value);
+		CAP_TO_8BIT_QP(capability->cap[P_FRAME_MAX_QP].value);
+		CAP_TO_8BIT_QP(capability->cap[B_FRAME_MAX_QP].value);
+	} else if (cap_id == I_FRAME_QP) {
+		CAP_TO_8BIT_QP(capability->cap[P_FRAME_QP].value);
+		CAP_TO_8BIT_QP(capability->cap[B_FRAME_QP].value);
+	}
+
+exit:
+	return 0;
+}
+
 static int msm_vidc_adjust_property(struct msm_vidc_inst *inst,
 static int msm_vidc_adjust_property(struct msm_vidc_inst *inst,
 	enum msm_vidc_inst_capability_type cap_id)
 	enum msm_vidc_inst_capability_type cap_id)
 {
 {
@@ -1015,6 +1068,57 @@ int msm_vidc_adjust_transform_8x8(void *instance, struct v4l2_ctrl *ctrl)
 	return 0;
 	return 0;
 }
 }
 
 
+int msm_vidc_adjust_hevc_min_qp(void *instance, struct v4l2_ctrl *ctrl)
+{
+	int rc = 0;
+	struct msm_vidc_inst_capability *capability;
+	struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
+
+	if (!inst || !inst->capabilities) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	capability = inst->capabilities;
+
+	rc = msm_vidc_adjust_hevc_qp(inst, MIN_FRAME_QP);
+
+	return rc;
+}
+
+int msm_vidc_adjust_hevc_max_qp(void *instance, struct v4l2_ctrl *ctrl)
+{
+	int rc = 0;
+	struct msm_vidc_inst_capability *capability;
+	struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
+
+	if (!inst || !inst->capabilities) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	capability = inst->capabilities;
+
+	rc = msm_vidc_adjust_hevc_qp(inst, MAX_FRAME_QP);
+
+	return rc;
+}
+
+int msm_vidc_adjust_hevc_frame_qp(void *instance, struct v4l2_ctrl *ctrl)
+{
+	int rc = 0;
+	struct msm_vidc_inst_capability *capability;
+	struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
+
+	if (!inst || !inst->capabilities) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	capability = inst->capabilities;
+
+	rc = msm_vidc_adjust_hevc_qp(inst, I_FRAME_QP);
+
+	return rc;
+}
+
 /*
 /*
  * Loop over instance capabilities with CAP_FLAG_ROOT
  * Loop over instance capabilities with CAP_FLAG_ROOT
  * and call adjust function, where
  * and call adjust function, where
@@ -1114,7 +1218,7 @@ int msm_vidc_set_deblock_mode(void *instance,
 	int rc = 0;
 	int rc = 0;
 	struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
 	struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
 	s32 alpha = 0, beta = 0;
 	s32 alpha = 0, beta = 0;
-	u32 lf_mode, hfi_value = 0, lf_offset = 12;
+	u32 lf_mode, hfi_value = 0, lf_offset = 6;
 	struct msm_vidc_inst_capability *capability;
 	struct msm_vidc_inst_capability *capability;
 
 
 	if (!inst || !inst->capabilities) {
 	if (!inst || !inst->capabilities) {
@@ -1127,11 +1231,6 @@ int msm_vidc_set_deblock_mode(void *instance,
 	if (rc)
 	if (rc)
 		return -EINVAL;
 		return -EINVAL;
 
 
-	/*
-	 * TODO: Revisit once s32 packing problem is fixed in hfi interface.
-	 * For now, using offset value as 6 to shift alpha, beta ranges
-	 * to (0 to 12) from (-6 to 6)
-	 */
 	beta = inst->capabilities->cap[LF_BETA].value + lf_offset;
 	beta = inst->capabilities->cap[LF_BETA].value + lf_offset;
 	alpha = inst->capabilities->cap[LF_ALPHA].value + lf_offset;
 	alpha = inst->capabilities->cap[LF_ALPHA].value + lf_offset;
 
 
@@ -1165,6 +1264,169 @@ int msm_vidc_set_use_and_mark_ltr(void *instance,
 	return rc;
 	return rc;
 }
 }
 
 
+int msm_vidc_set_min_qp(void *instance,
+	enum msm_vidc_inst_capability_type cap_id)
+{
+	int rc = 0;
+	struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
+	struct msm_vidc_inst_capability *capability;
+	s32 i_frame_qp = 0, p_frame_qp = 0, b_frame_qp = 0, min_qp_enable = 0;
+	u32 i_qp_enable = 0, p_qp_enable = 0, b_qp_enable = 0;
+	u32 client_qp_enable = 0, hfi_value = 0, offset = 0;
+
+	if (!inst || !inst->capabilities) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	capability = inst->capabilities;
+
+	min_qp_enable =
+		capability->cap[MIN_FRAME_QP].flags & CAP_FLAG_CLIENT_SET;
+
+	i_qp_enable = min_qp_enable ||
+		capability->cap[I_FRAME_MIN_QP].flags & CAP_FLAG_CLIENT_SET;
+	p_qp_enable = min_qp_enable ||
+		capability->cap[P_FRAME_MIN_QP].flags & CAP_FLAG_CLIENT_SET;
+	b_qp_enable = min_qp_enable ||
+		capability->cap[B_FRAME_MIN_QP].flags & CAP_FLAG_CLIENT_SET;
+
+	client_qp_enable = i_qp_enable | p_qp_enable << 1 | b_qp_enable << 2;
+	if (!client_qp_enable)
+		return 0;
+
+	if (is_10bit_colorformat(capability->cap[PIX_FMTS].value))
+		offset = 12;
+
+	/*
+	 * I_FRAME_MIN_QP, P_FRAME_MIN_QP, B_FRAME_MIN_QP,
+	 * MIN_FRAME_QP caps have default value as MIN_QP_10BIT values.
+	 * Hence, if client sets either one among MIN_FRAME_QP
+	 * and (I_FRAME_MIN_QP or P_FRAME_MIN_QP or B_FRAME_MIN_QP),
+	 * max of both caps will result into client set value.
+	 */
+	i_frame_qp = max(capability->cap[I_FRAME_MIN_QP].value,
+			capability->cap[MIN_FRAME_QP].value) + offset;
+	p_frame_qp = max(capability->cap[P_FRAME_MIN_QP].value,
+			capability->cap[MIN_FRAME_QP].value) + offset;
+	b_frame_qp = max(capability->cap[B_FRAME_MIN_QP].value,
+			capability->cap[MIN_FRAME_QP].value) + offset;
+
+	hfi_value = i_frame_qp | p_frame_qp << 8 | b_frame_qp << 16 |
+		client_qp_enable << 24;
+	rc = msm_vidc_packetize_control(inst, cap_id, HFI_PAYLOAD_32_PACKED,
+		&hfi_value, sizeof(u32), __func__);
+
+	return rc;
+}
+
+int msm_vidc_set_max_qp(void *instance,
+	enum msm_vidc_inst_capability_type cap_id)
+{
+	int rc = 0;
+	struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
+	struct msm_vidc_inst_capability *capability;
+	s32 i_frame_qp = 0, p_frame_qp = 0, b_frame_qp = 0, max_qp_enable = 0;
+	u32 i_qp_enable = 0, p_qp_enable = 0, b_qp_enable = 0;
+	u32 client_qp_enable = 0, hfi_value = 0, offset = 0;
+
+	if (!inst || !inst->capabilities) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	capability = inst->capabilities;
+
+	max_qp_enable =
+		capability->cap[MAX_FRAME_QP].flags & CAP_FLAG_CLIENT_SET;
+
+	i_qp_enable = max_qp_enable ||
+		capability->cap[I_FRAME_MIN_QP].flags & CAP_FLAG_CLIENT_SET;
+	p_qp_enable = max_qp_enable ||
+		capability->cap[P_FRAME_MIN_QP].flags & CAP_FLAG_CLIENT_SET;
+	b_qp_enable = max_qp_enable ||
+		capability->cap[B_FRAME_MIN_QP].flags & CAP_FLAG_CLIENT_SET;
+
+	client_qp_enable = i_qp_enable | p_qp_enable << 1 | b_qp_enable << 2;
+	if (!client_qp_enable)
+		return 0;
+
+	if (is_10bit_colorformat(capability->cap[PIX_FMTS].value))
+		offset = 12;
+
+	/*
+	 * I_FRAME_MAX_QP, P_FRAME_MAX_QP, B_FRAME_MAX_QP,
+	 * MAX_FRAME_QP caps have default value as MAX_QP values.
+	 * Hence, if client sets either one among MAX_FRAME_QP
+	 * and (I_FRAME_MAX_QP or P_FRAME_MAX_QP or B_FRAME_MAX_QP),
+	 * min of both caps will result into client set value.
+	 */
+	i_frame_qp = min(capability->cap[I_FRAME_MAX_QP].value,
+			capability->cap[MAX_FRAME_QP].value) + offset;
+	p_frame_qp = min(capability->cap[P_FRAME_MAX_QP].value,
+			capability->cap[MAX_FRAME_QP].value) + offset;
+	b_frame_qp = min(capability->cap[B_FRAME_MAX_QP].value,
+			capability->cap[MAX_FRAME_QP].value) + offset;
+
+	hfi_value = i_frame_qp | p_frame_qp << 8 | b_frame_qp << 16 |
+		client_qp_enable << 24;
+	rc = msm_vidc_packetize_control(inst, cap_id, HFI_PAYLOAD_32_PACKED,
+		&hfi_value, sizeof(u32), __func__);
+
+	return rc;
+}
+
+int msm_vidc_set_frame_qp(void *instance,
+	enum msm_vidc_inst_capability_type cap_id)
+{
+	int rc = 0;
+	struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
+	struct msm_vidc_inst_capability *capab;
+	s32 i_frame_qp = 0, p_frame_qp = 0, b_frame_qp = 0;
+	u32 i_qp_enable = 0, p_qp_enable = 0, b_qp_enable = 0;
+	u32 client_qp_enable = 0, hfi_value = 0, offset = 0;
+	s32 rc_type = -1;
+
+	if (!inst || !inst->capabilities) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	capab = inst->capabilities;
+
+	if (msm_vidc_get_parent_value(inst, I_FRAME_QP,
+		BITRATE_MODE, &rc_type, __func__))
+		return -EINVAL;
+
+	if (rc_type == HFI_RC_OFF) {
+		/* Mandatorily set for rc off case */
+		i_qp_enable = p_qp_enable = b_qp_enable = 1;
+	} else {
+		/* Set only if client has set for NON rc off case */
+		i_qp_enable =
+			capab->cap[I_FRAME_QP].flags & CAP_FLAG_CLIENT_SET;
+		p_qp_enable =
+			capab->cap[P_FRAME_QP].flags & CAP_FLAG_CLIENT_SET;
+		b_qp_enable =
+			capab->cap[B_FRAME_QP].flags & CAP_FLAG_CLIENT_SET;
+	}
+
+	client_qp_enable = i_qp_enable | p_qp_enable << 1 | b_qp_enable << 2;
+	if (!client_qp_enable)
+		return 0;
+
+	if (is_10bit_colorformat(capab->cap[PIX_FMTS].value))
+		offset = 12;
+
+	i_frame_qp = capab->cap[I_FRAME_QP].value + offset;
+	p_frame_qp = capab->cap[P_FRAME_QP].value + offset;
+	b_frame_qp = capab->cap[B_FRAME_QP].value + offset;
+
+	hfi_value = i_frame_qp | p_frame_qp << 8 | b_frame_qp << 16 |
+		client_qp_enable << 24;
+	rc = msm_vidc_packetize_control(inst, cap_id, HFI_PAYLOAD_32_PACKED,
+		&hfi_value, sizeof(u32), __func__);
+
+	return rc;
+}
+
 /* TODO
 /* TODO
 int msm_vidc_set_flip(void *instance,
 int msm_vidc_set_flip(void *instance,
 	enum msm_vidc_inst_capability_type cap_id)
 	enum msm_vidc_inst_capability_type cap_id)

+ 10 - 0
include/uapi/vidc/media/v4l2_vidc_extensions.h

@@ -106,6 +106,16 @@ enum v4l2_mpeg_vidc_blur_types {
 #define V4L2_CID_MPEG_VIDC_MIN_BITSTREAM_SIZE_OVERWRITE                       \
 #define V4L2_CID_MPEG_VIDC_MIN_BITSTREAM_SIZE_OVERWRITE                       \
 	(V4L2_CID_MPEG_VIDC_BASE + 0x23)
 	(V4L2_CID_MPEG_VIDC_BASE + 0x23)
 
 
+/* Deprecate below controls once they are available in upstream */
+#define V4L2_CID_MPEG_VIDC_HEVC_I_FRAME_MIN_QP                               \
+	(V4L2_CID_MPEG_VIDC_BASE + 0x24)
+#define V4L2_CID_MPEG_VIDC_HEVC_P_FRAME_MIN_QP                               \
+	(V4L2_CID_MPEG_VIDC_BASE + 0x25)
+#define V4L2_CID_MPEG_VIDC_HEVC_I_FRAME_MAX_QP                               \
+	(V4L2_CID_MPEG_VIDC_BASE + 0x26)
+#define V4L2_CID_MPEG_VIDC_HEVC_P_FRAME_MAX_QP                               \
+	(V4L2_CID_MPEG_VIDC_BASE + 0x27)
+
 enum v4l2_mpeg_vidc_metapayload_header_flags {
 enum v4l2_mpeg_vidc_metapayload_header_flags {
 	METADATA_FLAGS_NONE             = 0,
 	METADATA_FLAGS_NONE             = 0,
 	METADATA_FLAGS_TOP_FIELD        = (1 << 0),
 	METADATA_FLAGS_TOP_FIELD        = (1 << 0),