Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0799e92c authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: vidc: Fix masking of QP values for different codecs in driver"

parents 81de7e7c 2c6f6601
Loading
Loading
Loading
Loading
+385 −5
Original line number Diff line number Diff line
@@ -468,7 +468,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = {
	},
	{
		.id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP,
		.name = "I Frame Quantization",
		.name = "H264 I Frame Quantization",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.minimum = 1,
		.maximum = 51,
@@ -479,7 +479,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = {
	},
	{
		.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP,
		.name = "P Frame Quantization",
		.name = "H264 P Frame Quantization",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.minimum = 1,
		.maximum = 51,
@@ -490,7 +490,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = {
	},
	{
		.id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP,
		.name = "B Frame Quantization",
		.name = "H264 B Frame Quantization",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.minimum = 1,
		.maximum = 51,
@@ -499,6 +499,61 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = {
		.menu_skip_mask = 0,
		.qmenu = NULL,
	},
	{
		.id = V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP,
		.name = "H263 I Frame Quantization",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.minimum = 1,
		.maximum = 31,
		.default_value = I_FRAME_QP,
		.step = 1,
		.menu_skip_mask = 0,
		.qmenu = NULL,
	},
	{
		.id = V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP,
		.name = "H263 P Frame Quantization",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.minimum = 1,
		.maximum = 31,
		.default_value = P_FRAME_QP,
		.step = 1,
		.menu_skip_mask = 0,
		.qmenu = NULL,
	},
	{
		.id = V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP,
		.name = "H263 B Frame Quantization",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.minimum = 1,
		.maximum = 31,
		.default_value = B_FRAME_QP,
		.step = 1,
		.menu_skip_mask = 0,
		.qmenu = NULL,
	},
	{
		.id = V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP,
		.name = "VPX I Frame Quantization",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.minimum = 0,
		.maximum = 127,
		.default_value = I_FRAME_QP,
		.step = 1,
		.menu_skip_mask = 0,
		.qmenu = NULL,
	},
	{
		.id = V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP,
		.name = "VPX P Frame Quantization",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.minimum = 0,
		.maximum = 127,
		.default_value = P_FRAME_QP,
		.step = 1,
		.menu_skip_mask = 0,
		.qmenu = NULL,
	},
	{
		.id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP,
		.name = "H264 Minimum QP",
@@ -521,6 +576,24 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = {
		.menu_skip_mask = 0,
		.qmenu = NULL,
	},
	{
		.id = V4L2_CID_MPEG_VIDEO_VPX_MIN_QP,
		.name = "VPX Minimum QP",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.minimum = 0,
		.maximum = 127,
		.default_value = 0,
		.step = 1,
	},
	{
		.id = V4L2_CID_MPEG_VIDEO_VPX_MAX_QP,
		.name = "VPX Maximum QP",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.minimum = 0,
		.maximum = 127,
		.default_value = 127,
		.step = 1,
	},
	{
		.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP,
		.name = "VP8 Minimum QP",
@@ -539,6 +612,24 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = {
		.default_value = 128,
		.step = 1,
	},
	{
		.id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP,
		.name = "MPEG4 Minimum QP",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.minimum = 1,
		.maximum = 31,
		.default_value = 1,
		.step = 1,
	},
	{
		.id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP,
		.name = "MPEG4 Maximum QP",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.minimum = 1,
		.maximum = 31,
		.default_value = 31,
		.step = 1,
	},
	{
		.id = V4L2_CID_MPEG_VIDEO_MIN_QP_PACKED,
		.name = "H264 Minimum QP PACKED",
@@ -939,6 +1030,36 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = {
		.default_value = 0,
		.step = 0,
	},
	{
		.id = V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_I_FRAME_QP,
		.name = "Iframe initial QP",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.minimum = 1,
		.maximum = 127,
		.default_value = 1,
		.step = 1,
		.qmenu = NULL,
	},
	{
		.id = V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_P_FRAME_QP,
		.name = "Pframe initial QP",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.minimum = 1,
		.maximum = 127,
		.default_value = 1,
		.step = 1,
		.qmenu = NULL,
	},
	{
		.id = V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_B_FRAME_QP,
		.name = "Bframe initial QP",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.minimum = 1,
		.maximum = 127,
		.default_value = 1,
		.step = 1,
		.qmenu = NULL,
	},
	{
		.id = V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP,
		.name = "Iframe initial QP",
@@ -1122,7 +1243,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = {
		.name = "Set frame level QP",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.minimum = 1,
		.maximum = 51,
		.maximum = 127,
		.default_value = 1,
		.step = 1,
		.qmenu = NULL,
@@ -2230,6 +2351,9 @@ unknown_value:
	return -EINVAL;
}

static int msm_venc_validate_qp_value(struct msm_vidc_inst *inst,
					struct v4l2_ctrl *ctrl);

static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
{
	int rc = 0;
@@ -2649,6 +2773,81 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
		pdata = &quantization;
		break;
	}
	case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP: {
		struct v4l2_ctrl *qpp, *qpb;

		qpp = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP);
		qpb = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP);

		property_id = HAL_PARAM_VENC_SESSION_QP;
		quantization.qpi = ctrl->val;
		quantization.qpp = qpp->val;
		quantization.qpb = qpb->val;
		quantization.layer_id = 0;

		pdata = &quantization;
		break;
	}
	case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP: {
		struct v4l2_ctrl *qpi, *qpb;

		qpi = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP);
		qpb = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP);

		property_id = HAL_PARAM_VENC_SESSION_QP;
		quantization.qpp = ctrl->val;
		quantization.qpi = qpi->val;
		quantization.qpb = qpb->val;
		quantization.layer_id = 0;

		pdata = &quantization;
		break;
	}
	case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP: {
		struct v4l2_ctrl *qpi, *qpp;

		qpi = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP);
		qpp = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP);

		property_id = HAL_PARAM_VENC_SESSION_QP;
		quantization.qpb = ctrl->val;
		quantization.qpi = qpi->val;
		quantization.qpp = qpp->val;
		quantization.layer_id = 0;

		pdata = &quantization;
		break;
	}
	case V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP: {
		struct v4l2_ctrl *qpp;

		qpp = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP);

		property_id = HAL_PARAM_VENC_SESSION_QP;
		quantization.qpi = ctrl->val;
		quantization.qpp = qpp->val;
		/* Bframes are not supported for VPX */
		quantization.qpb = 0;
		quantization.layer_id = 0;

		pdata = &quantization;
		break;
	}
	case V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP: {
		struct v4l2_ctrl *qpi;

		qpi = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP);

		property_id = HAL_PARAM_VENC_SESSION_QP;
		quantization.qpp = ctrl->val;
		quantization.qpi = qpi->val;
		/* Bframes are not supported for VPX */
		quantization.qpb = 0;
		quantization.layer_id = 0;

		pdata = &quantization;
		break;
	}
	case V4L2_CID_MPEG_VIDEO_H264_MIN_QP: {
		struct v4l2_ctrl *qp_max;

@@ -2689,8 +2888,85 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
		pdata = &qp_range;
		break;
	}
	case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP: {
		struct v4l2_ctrl *qp_max;

		qp_max = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP);
		if (ctrl->val >= qp_max->val) {
			dprintk(VIDC_ERR,
					"Bad range: Min QP (%d) > Max QP(%d)\n",
					ctrl->val, qp_max->val);
			rc = -ERANGE;
			break;
		}

		property_id = HAL_PARAM_VENC_SESSION_QP_RANGE;
		qp_range.layer_id = 0;
		qp_range.max_qp = qp_max->val;
		qp_range.min_qp = ctrl->val;

		pdata = &qp_range;
		break;
	}
	case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP: {
		struct v4l2_ctrl *qp_min;

		qp_min = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP);
		if (ctrl->val <= qp_min->val) {
			dprintk(VIDC_ERR,
					"Bad range: Max QP (%d) < Min QP(%d)\n",
					ctrl->val, qp_min->val);
			rc = -ERANGE;
			break;
		}

		property_id = HAL_PARAM_VENC_SESSION_QP_RANGE;
		qp_range.layer_id = 0;
		qp_range.max_qp = ctrl->val;
		qp_range.min_qp = qp_min->val;

		pdata = &qp_range;
		break;
	}
	case V4L2_CID_MPEG_VIDEO_VPX_MIN_QP: {
		struct v4l2_ctrl *qp_max;

		qp_max = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_VPX_MAX_QP);
		if (ctrl->val >= qp_max->val) {
			dprintk(VIDC_ERR,
					"Bad range: Min QP (%d) > Max QP(%d)\n",
					ctrl->val, qp_max->val);
			rc = -ERANGE;
			break;
		}
		property_id = HAL_PARAM_VENC_SESSION_QP_RANGE;
		qp_range.layer_id = 0;
		qp_range.max_qp = qp_max->val;
		qp_range.min_qp = ctrl->val;
		pdata = &qp_range;
		break;
	}
	case V4L2_CID_MPEG_VIDEO_VPX_MAX_QP: {
		struct v4l2_ctrl *qp_min;

		qp_min = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_VPX_MIN_QP);
		if (ctrl->val <= qp_min->val) {
			dprintk(VIDC_ERR,
					"Bad range: Max QP (%d) < Min QP(%d)\n",
					ctrl->val, qp_min->val);
			rc = -ERANGE;
			break;
		}
		property_id = HAL_PARAM_VENC_SESSION_QP_RANGE;
		qp_range.layer_id = 0;
		qp_range.max_qp = ctrl->val;
		qp_range.min_qp = qp_min->val;
		pdata = &qp_range;
		break;
	}
	case V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP: {
		struct v4l2_ctrl *qp_max;

		qp_max = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP);
		property_id = HAL_PARAM_VENC_SESSION_QP_RANGE;
		qp_range.layer_id = 0;
@@ -2701,6 +2977,7 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
	}
	case V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP: {
		struct v4l2_ctrl *qp_min;

		qp_min = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP);
		property_id = HAL_PARAM_VENC_SESSION_QP_RANGE;
		qp_range.layer_id = 0;
@@ -3222,6 +3499,14 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
		pdata = &baselayerid;
		break;
	case V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP:
		/* Sanity check for the QP boundaries as we are using
		 * same control to set dynamic QP for all the codecs
		 */
		rc = msm_venc_validate_qp_value(inst, ctrl);
		if (rc) {
			dprintk(VIDC_ERR, "Invalid QP Config QP Range\n");
			break;
		}
		property_id = HAL_CONFIG_VENC_FRAME_QP;
		frameqp = ctrl->val;
		pdata = &frameqp;
@@ -3380,7 +3665,6 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
	}

	v4l2_ctrl_lock(ctrl);
#undef TRY_GET_CTRL

	if (!rc && property_id) {
		dprintk(VIDC_DBG, "Control: HAL property=%x,ctrl_value=%d\n",
@@ -3393,6 +3677,59 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
	return rc;
}

static int msm_venc_validate_qp_value(struct msm_vidc_inst *inst,
					struct v4l2_ctrl *ctrl)
{
	int rc = 0, min, max;
	struct v4l2_ctrl *temp_ctrl = NULL;
	int qp_value = ctrl->val;

#define VALIDATE_BOUNDARIES(__min, __max, __val) ({\
	int __rc = __val >= __min && \
			__val <= __max; \
	if (!__rc) \
		dprintk(VIDC_ERR, "QP beyond range: min(%d) max(%d) val(%d)", \
				__min, __max, __val); \
	__rc; \
})

	switch (inst->fmts[CAPTURE_PORT].fourcc) {
	case V4L2_PIX_FMT_VP8:
		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_VPX_MAX_QP);
		max = temp_ctrl->maximum;
		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_VPX_MIN_QP);
		min = temp_ctrl->minimum;
		if (!VALIDATE_BOUNDARIES(min, max, qp_value))
			rc = -EINVAL;
		break;
	case V4L2_PIX_FMT_H263:
	case V4L2_PIX_FMT_MPEG4:
		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP);
		max = temp_ctrl->maximum;
		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP);
		min = temp_ctrl->minimum;
		if (!VALIDATE_BOUNDARIES(min, max, qp_value))
			rc = -EINVAL;
		break;
	case V4L2_PIX_FMT_H264:
	case V4L2_PIX_FMT_HEVC:
		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_MAX_QP);
		max = temp_ctrl->maximum;
		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_MIN_QP);
		min = temp_ctrl->minimum;
		if (!VALIDATE_BOUNDARIES(min, max, qp_value))
			rc = -EINVAL;
		break;
	default:
		dprintk(VIDC_ERR, "%s Invalid Codec\n", __func__);
		return -EINVAL;
	}
	return rc;
#undef VALIDATE_BOUNDARIES
}

#undef TRY_GET_CTRL

static int try_set_ext_ctrl(struct msm_vidc_inst *inst,
	struct v4l2_ext_controls *ctrl)
{
@@ -3408,6 +3745,7 @@ static int try_set_ext_ctrl(struct msm_vidc_inst *inst,
	struct hal_aspect_ratio sar;
	struct hal_bitrate bitrate;
	struct hal_frame_size blur_res;
	struct v4l2_ctrl *temp_ctrl;

	if (!inst || !inst->core || !inst->core->device || !ctrl) {
		dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
@@ -3470,6 +3808,48 @@ static int try_set_ext_ctrl(struct msm_vidc_inst *inst,
			property_id = HAL_PARAM_VENC_ENABLE_INITIAL_QP;
			pdata = &quant;
			break;
		case V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_I_FRAME_QP:
			/* Sanity check for the QP boundaries as we are using
			 * same control to set Initial QP for all the codecs
			 */
			temp_ctrl->id =
				V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_I_FRAME_QP;
			temp_ctrl->val = control[i].value;
			rc = msm_venc_validate_qp_value(inst, temp_ctrl);
			if (rc) {
				dprintk(VIDC_ERR, "Invalid Initial I QP\n");
				break;
			}
			quant.qpi = control[i].value;
			property_id = HAL_PARAM_VENC_ENABLE_INITIAL_QP;
			pdata = &quant;
			break;
		case V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_P_FRAME_QP:
			temp_ctrl->id =
				V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_P_FRAME_QP;
			temp_ctrl->val = control[i].value;
			rc = msm_venc_validate_qp_value(inst, temp_ctrl);
			if (rc) {
				dprintk(VIDC_ERR, "Invalid Initial P QP\n");
				break;
			}
			quant.qpp = control[i].value;
			property_id = HAL_PARAM_VENC_ENABLE_INITIAL_QP;
			pdata = &quant;
			break;
		case V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_B_FRAME_QP:
			temp_ctrl->id =
				V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_B_FRAME_QP;
			temp_ctrl->val = control[i].value;
			rc = msm_venc_validate_qp_value(inst, temp_ctrl);
			if (rc) {
				dprintk(VIDC_ERR, "Invalid Initial B QP\n");
				break;
			}
			quant.qpb = control[i].value;
			property_id = HAL_PARAM_VENC_ENABLE_INITIAL_QP;
			pdata = &quant;
			break;
		case V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE:
			search_range.i_frame.x_subsampled = control[i].value;
			property_id = HAL_PARAM_VENC_SEARCH_RANGE;
+12 −4
Original line number Diff line number Diff line
@@ -927,9 +927,9 @@ enum v4l2_mpeg_vidc_video_mvc_layout {
	V4L2_MPEG_VIDC_VIDEO_MVC_SEQUENTIAL = 0,
	V4L2_MPEG_VIDC_VIDEO_MVC_TOP_BOTTOM = 1
};

#define V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP (V4L2_CID_MPEG_MSM_VIDC_BASE + 44)
#define V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP (V4L2_CID_MPEG_MSM_VIDC_BASE + 45)

#define V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR \
		(V4L2_CID_MPEG_MSM_VIDC_BASE + 46)

@@ -969,13 +969,13 @@ enum vl42_mpeg_vidc_video_enable_initial_qp {
	V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP_BFRAME = 0x4,
};

#define V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP \
#define V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_I_FRAME_QP \
		(V4L2_CID_MPEG_MSM_VIDC_BASE + 54)

#define V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP \
#define V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_P_FRAME_QP \
		(V4L2_CID_MPEG_MSM_VIDC_BASE + 55)

#define V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP \
#define V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_B_FRAME_QP \
		(V4L2_CID_MPEG_MSM_VIDC_BASE + 56)

#define V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE \
@@ -1211,6 +1211,14 @@ enum v4l2_mpeg_vidc_video_venc_iframesize_type {
	V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_UNLIMITED,
};

#define V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP \
		(V4L2_CID_MPEG_MSM_VIDC_BASE + 99)
#define V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP \
		(V4L2_CID_MPEG_MSM_VIDC_BASE + 100)
#define V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP \
		(V4L2_CID_MPEG_MSM_VIDC_BASE + 101)


/*  Camera class control IDs */

#define V4L2_CID_CAMERA_CLASS_BASE 	(V4L2_CTRL_CLASS_CAMERA | 0x900)