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

Commit 92f0730e authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: vidc: Fix individual QP types and QP range control"

parents 7cedb987 9106c03d
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -701,10 +701,6 @@ static inline void copy_cap_prop(
		out->capability_type = get_hal_cap_type(in->capability_type);
		out->min = in->min;
		out->max = in->max;
		if (in->capability_type == HFI_CAPABILITY_I_FRAME_QP ||
			in->capability_type == HFI_CAPABILITY_P_FRAME_QP ||
			in->capability_type == HFI_CAPABILITY_B_FRAME_QP)
			++out->max;
		out->step_size = in->step_size;
	}
}
+66 −45
Original line number Diff line number Diff line
@@ -24,7 +24,12 @@
#define QP_ENABLE_I 0x1
#define QP_ENABLE_P 0x2
#define QP_ENABLE_B 0x4
#define INVALID_QP -1
#define MIN_QP 0
#define MAX_QP 0x33
#define MAX_QP_PACKED 0x333333
#define DEFAULT_MIN_QP 0xA
#define DEFAULT_MIN_QP_PACKED 0xA0A0A
#define DEFAULT_MAX_QP_PACKED 0x2C2C2C
#define MAX_INTRA_REFRESH_MBS ((7680 * 4320) >> 8)
#define MAX_LTR_FRAME_COUNT 10
#define MAX_NUM_B_FRAMES 1
@@ -88,9 +93,9 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = {
		.id = V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP,
		.name = "HEVC I Frame Quantization",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.minimum = INVALID_QP,
		.maximum = INVALID_QP,
		.default_value = INVALID_QP,
		.minimum = MIN_QP,
		.maximum = MAX_QP,
		.default_value = DEFAULT_MIN_QP,
		.step = 1,
		.menu_skip_mask = 0,
		.qmenu = NULL,
@@ -99,9 +104,9 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = {
		.id = V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP,
		.name = "HEVC P Frame Quantization",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.minimum = INVALID_QP,
		.maximum = INVALID_QP,
		.default_value = INVALID_QP,
		.minimum = MIN_QP,
		.maximum = MAX_QP,
		.default_value = DEFAULT_MIN_QP,
		.step = 1,
		.menu_skip_mask = 0,
		.qmenu = NULL,
@@ -110,9 +115,9 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = {
		.id = V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP,
		.name = "HEVC B Frame Quantization",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.minimum = INVALID_QP,
		.maximum = INVALID_QP,
		.default_value = INVALID_QP,
		.minimum = MIN_QP,
		.maximum = MAX_QP,
		.default_value = DEFAULT_MIN_QP,
		.step = 1,
		.menu_skip_mask = 0,
		.qmenu = NULL,
@@ -121,9 +126,9 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = {
		.id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
		.name = "HEVC Quantization Range Minimum",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.minimum = INVALID_QP,
		.maximum = INVALID_QP,
		.default_value = INVALID_QP,
		.minimum = MIN_QP,
		.maximum = MAX_QP_PACKED,
		.default_value = DEFAULT_MIN_QP_PACKED,
		.step = 1,
		.menu_skip_mask = 0,
		.qmenu = NULL,
@@ -132,9 +137,9 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = {
		.id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP,
		.name = "HEVC Quantization Range Maximum",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.minimum = INVALID_QP,
		.maximum = INVALID_QP,
		.default_value = INVALID_QP,
		.minimum = MIN_QP,
		.maximum = MAX_QP_PACKED,
		.default_value = DEFAULT_MAX_QP_PACKED,
		.step = 1,
		.menu_skip_mask = 0,
		.qmenu = NULL,
@@ -1726,20 +1731,19 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
		if ((ctrl->val & 0xff) < i_qp->minimum ||
			((ctrl->val >> 8) & 0xff) < p_qp->minimum ||
			((ctrl->val >> 16) & 0xff) < b_qp->minimum ||
			(ctrl->val & 0xff) >= i_qp->maximum ||
			((ctrl->val >> 8) & 0xff) >= p_qp->maximum ||
			(inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_VP8 &&
			((ctrl->val >> 16) & 0xff) >= b_qp->maximum)) {
			(ctrl->val & 0xff) > i_qp->maximum ||
			((ctrl->val >> 8) & 0xff) > p_qp->maximum ||
			((ctrl->val >> 16) & 0xff) > b_qp->maximum) {
			dprintk(VIDC_ERR, "Invalid QP %#x\n", ctrl->val);
			return -EINVAL;
		}
		if (ctrl->id == V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP)
			inst->client_set_ctrls |= CLIENT_SET_MIN_QP;
		else
			inst->client_set_ctrls |= CLIENT_SET_MAX_QP;
		break;
	case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP:
		i_qp = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP);
		if ((ctrl->val & 0xff) >= i_qp->maximum) {
			dprintk(VIDC_ERR, "Invalid QP %#x\n", ctrl->val);
			return -EINVAL;
		}
		inst->client_set_ctrls |= CLIENT_SET_I_QP;
		if (inst->state == MSM_VIDC_START_DONE) {
			rc = msm_venc_set_dyn_qp(inst, ctrl);
			if (rc)
@@ -1748,6 +1752,12 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
					__func__);
		}
		break;
	case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP:
		inst->client_set_ctrls |= CLIENT_SET_P_QP;
		break;
	case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP:
		inst->client_set_ctrls |= CLIENT_SET_B_QP;
		break;
	case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER:
		if (inst->state == MSM_VIDC_START_DONE) {
			rc = msm_venc_set_hp_layer(inst);
@@ -1759,8 +1769,6 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
		break;
	case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER:
	case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE:
	case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP:
	case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP:
	case V4L2_CID_MPEG_VIDEO_B_FRAMES:
	case V4L2_CID_ROTATE:
	case V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT:
@@ -2294,6 +2302,7 @@ int msm_venc_set_frame_qp(struct msm_vidc_inst *inst)
	hdev = inst->core->device;

	qp.layer_id = MSM_VIDC_ALL_LAYER_ID;
	qp.enable = 0;
	qp.enable = QP_ENABLE_I | QP_ENABLE_P | QP_ENABLE_B;

	i_qp = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP);
@@ -2301,37 +2310,38 @@ int msm_venc_set_frame_qp(struct msm_vidc_inst *inst)
	b_qp = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP);
	rc_enable = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE);

	/*
	 * When RC is ON:
	 *   Enable QP types which have been set by client.
	 * When RC is OFF:
	 *   I_QP value must be set by client.
	 *   If other QP value is invalid, then, assign I_QP value to it.
	 */
	if (rc_enable->val) {
		if (i_qp->val >= i_qp->default_value ||
			i_qp->val < i_qp->minimum)
			qp.enable &= (!QP_ENABLE_I);
		if (p_qp->val >= p_qp->default_value ||
			p_qp->val < p_qp->minimum)
			qp.enable &= (!QP_ENABLE_P);
		if (b_qp->val >= b_qp->default_value ||
			b_qp->val < b_qp->minimum)
			qp.enable &= (!QP_ENABLE_B);

		if (!(qp.enable & 0x7))
		if (!(inst->client_set_ctrls & CLIENT_SET_I_QP))
			qp.enable &= ~QP_ENABLE_I;
		if (!(inst->client_set_ctrls & CLIENT_SET_P_QP))
			qp.enable &= ~QP_ENABLE_P;
		if (!(inst->client_set_ctrls & CLIENT_SET_B_QP))
			qp.enable &= ~QP_ENABLE_B;

		if (!qp.enable)
			return 0;
	} else {
		if (i_qp->val >= i_qp->default_value ||
			i_qp->val < i_qp->minimum) {
		if (!(inst->client_set_ctrls & CLIENT_SET_I_QP)) {
			dprintk(VIDC_WARN,
				"%s: Client value is not valid\n", __func__);
			return -EINVAL;
		}
		if (p_qp->val >= p_qp->default_value ||
			p_qp->val < p_qp->minimum)
		if (!(inst->client_set_ctrls & CLIENT_SET_P_QP))
			p_qp->val = i_qp->val;
		if (b_qp->val >= b_qp->default_value ||
			b_qp->val < b_qp->minimum)
		if (!(inst->client_set_ctrls & CLIENT_SET_B_QP))
			b_qp->val = i_qp->val;
	}

	/* B frame QP is not supported for VP8. */
	if (inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_VP8)
		qp.enable &= (!QP_ENABLE_B);
		qp.enable &= ~QP_ENABLE_B;

	qp.qp_packed = i_qp->val | p_qp->val << 8 | b_qp->val << 16;

@@ -2358,6 +2368,13 @@ int msm_venc_set_qp_range(struct msm_vidc_inst *inst)
	}
	hdev = inst->core->device;

	if (!(inst->client_set_ctrls & CLIENT_SET_MIN_QP) &&
		!(inst->client_set_ctrls & CLIENT_SET_MAX_QP)) {
		dprintk(VIDC_DBG,
			"%s: Client didn't set QP range.\n", __func__);
		return 0;
	}

	qp_range.min_qp.layer_id = MSM_VIDC_ALL_LAYER_ID;
	qp_range.max_qp.layer_id = MSM_VIDC_ALL_LAYER_ID;

@@ -3178,6 +3195,10 @@ int msm_venc_set_dyn_qp(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
	qp.enable = QP_ENABLE_I | QP_ENABLE_P | QP_ENABLE_B;
	qp.layer_id = MSM_VIDC_ALL_LAYER_ID;

	/* B frame QP is not supported for VP8. */
	if (inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_VP8)
		qp.enable &= ~QP_ENABLE_B;

	dprintk(VIDC_DBG, "%s: %#x\n", __func__,
		ctrl->val);
	rc = call_hfi_op(hdev, session_set_property, inst->session,
+1 −1
Original line number Diff line number Diff line
@@ -1313,7 +1313,7 @@ static int msm_vidc_comm_update_ctrl(struct msm_vidc_inst *inst,
	if (ctrl) {
		v4l2_ctrl_modify_range(ctrl, capability->min,
				capability->max, ctrl->step,
				capability->max);
				ctrl->default_value);
		dprintk(VIDC_DBG,
			"%s: Updated Range = %lld --> %lld Def value = %lld\n",
			ctrl->name, ctrl->minimum, ctrl->maximum,
+8 −0
Original line number Diff line number Diff line
@@ -38,6 +38,14 @@ enum load_calc_quirks {
	LOAD_CALC_IGNORE_NON_REALTIME_LOAD = 1 << 2,
};

enum client_set_controls {
	CLIENT_SET_I_QP = 0x1,
	CLIENT_SET_P_QP = 0x2,
	CLIENT_SET_B_QP = 0x4,
	CLIENT_SET_MIN_QP = 0x8,
	CLIENT_SET_MAX_QP = 0x10,
};

static inline bool is_turbo_session(struct msm_vidc_inst *inst)
{
	return !!(inst->flags & VIDC_TURBO);
+1 −0
Original line number Diff line number Diff line
@@ -493,6 +493,7 @@ struct msm_vidc_inst {
	u32 frame_quality;
	u32 rc_type;
	u32 hybrid_hp;
	u32 client_set_ctrls;
	struct internal_buf *dpb_extra_binfo;
	struct msm_vidc_codec_data *codec_data;
	struct hal_hdr10_pq_sei hdr10_sei_params;