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

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

Merge "msm: vidc: Fix setting codec specific properties"

parents 7839efbd c3d9306e
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -1196,6 +1196,19 @@ int msm_vdec_set_secure_mode(struct msm_vidc_inst *inst)
	hdev = inst->core->device;

	ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_SECURE);

	if (ctrl->val) {
		if (!(inst->fmts[OUTPUT_PORT].fourcc == V4L2_PIX_FMT_HEVC ||
			inst->fmts[OUTPUT_PORT].fourcc == V4L2_PIX_FMT_H264 ||
			inst->fmts[OUTPUT_PORT].fourcc == V4L2_PIX_FMT_VP9 ||
			inst->fmts[OUTPUT_PORT].fourcc == V4L2_PIX_FMT_MPEG2)) {
			dprintk(VIDC_ERR,
				"%s: Secure allowed for HEVC/H264/VP9/MPEG2\n",
				__func__);
			return -EINVAL;
		}
	}

	dprintk(VIDC_DBG, "%s: %#x\n", __func__, ctrl->val);
	rc = call_hfi_op(hdev, session_set_property, inst->session,
		HFI_PROPERTY_PARAM_SECURE_SESSION, &ctrl->val, sizeof(u32));
+169 −27
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@
#define MAX_INTRA_REFRESH_MBS ((7680 * 4320) >> 8)
#define MAX_LTR_FRAME_COUNT 10
#define MAX_NUM_B_FRAMES 1
#define MIN_CBRPLUS_W 1280
#define MIN_CBRPLUS_H 720

#define L_MODE V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY
#define MIN_NUM_ENC_OUTPUT_BUFFERS 4
@@ -1918,6 +1920,16 @@ int msm_venc_set_secure_mode(struct msm_vidc_inst *inst)
	ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_SECURE);
	enable.enable = !!ctrl->val;

	if (enable.enable) {
		if (!(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264 ||
			inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_HEVC)) {
			dprintk(VIDC_ERR,
				"%s: Secure mode only allowed for HEVC/H264\n",
				__func__);
			return -EINVAL;
		}
	}

	dprintk(VIDC_DBG, "%s: %d\n", __func__, enable.enable);
	rc = call_hfi_op(hdev, session_set_property, inst->session,
		HFI_PROPERTY_PARAM_SECURE_SESSION, &enable, sizeof(enable));
@@ -2252,13 +2264,55 @@ int msm_venc_set_rate_control(struct msm_vidc_inst *inst)
{
	int rc = 0;
	struct hfi_device *hdev;
	u32 hfi_rc;
	u32 hfi_rc, codec;
	u32 height, width, mbpf;
	struct hfi_vbv_hrd_buf_size hrd_buf_size;

	if (!inst || !inst->core) {
		dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
		return -EINVAL;
	}

	hdev = inst->core->device;
	inst->clk_data.is_cbr_plus = false;
	codec = inst->fmts[CAPTURE_PORT].fourcc;
	height = inst->prop.height[OUTPUT_PORT];
	width = inst->prop.width[OUTPUT_PORT];
	mbpf = NUM_MBS_PER_FRAME(height, width);

	if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_MBR_VFR)
		inst->rc_type = V4L2_MPEG_VIDEO_BITRATE_MODE_MBR;
	else if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
			   inst->clk_data.low_latency_mode)
		inst->rc_type = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;

	if ((inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR ||
		inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR) &&
		(codec != V4L2_PIX_FMT_VP8)) {
		hrd_buf_size.vbv_hrd_buf_size = 500;
		inst->clk_data.low_latency_mode = true;

		if ((width > MIN_CBRPLUS_W && height > MIN_CBRPLUS_H) ||
			(width > MIN_CBRPLUS_H && height > MIN_CBRPLUS_W) ||
			mbpf > NUM_MBS_PER_FRAME(720, 1280)) {
			hrd_buf_size.vbv_hrd_buf_size = 1000;
			inst->clk_data.is_cbr_plus = true;
		}

		dprintk(VIDC_DBG, "Set hrd_buf_size %d",
				hrd_buf_size.vbv_hrd_buf_size);

		rc = call_hfi_op(hdev, session_set_property,
			(void *)inst->session,
			HFI_PROPERTY_CONFIG_VENC_VBV_HRD_BUF_SIZE,
			(void *)&hrd_buf_size, sizeof(hrd_buf_size));
		if (rc) {
			dprintk(VIDC_ERR, "%s: set HRD_BUF_SIZE %u failed\n",
					__func__,
					hrd_buf_size.vbv_hrd_buf_size);
			inst->clk_data.is_cbr_plus = false;
		}
	}

	switch (inst->rc_type) {
	case RATE_CONTROL_OFF:
@@ -2276,9 +2330,6 @@ int msm_venc_set_rate_control(struct msm_vidc_inst *inst)
	case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR:
		hfi_rc = HFI_RATE_CONTROL_CBR_VFR;
		break;
	case V4L2_MPEG_VIDEO_BITRATE_MODE_MBR_VFR:
		hfi_rc = HFI_RATE_CONTROL_MBR_VFR;
		break;
	case V4L2_MPEG_VIDEO_BITRATE_MODE_CQ:
		hfi_rc = HFI_RATE_CONTROL_CQ;
		break;
@@ -2694,35 +2745,88 @@ int msm_venc_set_slice_control_mode(struct msm_vidc_inst *inst)
	struct v4l2_ctrl *ctrl_t;
	struct hfi_multi_slice_control multi_slice_control;
	int temp = 0;
	u32 mb_per_frame, fps, mbps, bitrate;
	u32 slice_val, slice_mode, max_avg_slicesize;
	u32 rc_mode, output_width, output_height;
	struct v4l2_ctrl *rc_enable;

	if (!inst || !inst->core) {
		dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
		return -EINVAL;
	}
	hdev = inst->core->device;

	if (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_HEVC &&
		inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_H264)
		return 0;

	slice_mode = HFI_MULTI_SLICE_OFF;
	slice_val = 0;

	bitrate = inst->clk_data.bitrate;
	fps = inst->clk_data.frame_rate;
	rc_mode = inst->rc_type;
	rc_enable = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE);
	if (fps > 60 ||
		(rc_enable->val &&
		 rc_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR &&
		 rc_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)) {
		goto set_and_exit;
	}

	output_width = inst->prop.width[OUTPUT_PORT];
	output_height = inst->prop.height[OUTPUT_PORT];

	if (output_height < 128 ||
		(inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_HEVC &&
		 output_width < 384) ||
		(inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_H264 &&
		 output_width < 192)) {
		goto set_and_exit;
	}

	ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE);
	multi_slice_control.multi_slice = HFI_MULTI_SLICE_OFF;
	temp = 0;
	if (ctrl->val == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) {
		temp = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
		multi_slice_control.multi_slice = HFI_MULTI_SLICE_BY_MB_COUNT;
		slice_mode = HFI_MULTI_SLICE_BY_MB_COUNT;
	} else if (ctrl->val == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) {
		temp = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
		multi_slice_control.multi_slice =
			HFI_MULTI_SLICE_BY_BYTE_COUNT;
		slice_mode = HFI_MULTI_SLICE_BY_BYTE_COUNT;
	} else {
		goto set_and_exit;
	}

	multi_slice_control.slice_size = 0;
	if (temp) {
	ctrl_t = get_ctrl(inst, temp);
		multi_slice_control.slice_size = ctrl_t->val;
	slice_val = ctrl_t->val;

	/* Update Slice Config */
	mb_per_frame = NUM_MBS_PER_FRAME(output_height, output_width);
	mbps = NUM_MBS_PER_SEC(output_height, output_width, fps);

	if (slice_mode == HFI_MULTI_SLICE_BY_MB_COUNT) {
		if (output_width <= 4096 || output_height <= 4096 ||
			mb_per_frame <= NUM_MBS_PER_FRAME(4096, 2160) ||
			mbps <= NUM_MBS_PER_SEC(4096, 2160, 60)) {
			slice_val = max(slice_val, mb_per_frame / 10);
		}
	} else {
		if (output_width <= 1920 || output_height <= 1920 ||
			mb_per_frame <= NUM_MBS_PER_FRAME(1088, 1920) ||
			mbps <= NUM_MBS_PER_SEC(1088, 1920, 60)) {
			max_avg_slicesize = ((bitrate / fps) / 8) / 10;
			slice_val = max(slice_val, max_avg_slicesize);
		}
	}

	if (slice_mode == HFI_MULTI_SLICE_OFF) {
		ctrl->val = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
		ctrl_t->val = 0;
	}

set_and_exit:
	multi_slice_control.multi_slice = slice_mode;
	multi_slice_control.slice_size = slice_val;

	hdev = inst->core->device;
	dprintk(VIDC_DBG, "%s: %d %d\n", __func__,
			multi_slice_control.multi_slice,
			multi_slice_control.slice_size);
@@ -2739,7 +2843,8 @@ int msm_venc_set_intra_refresh_mode(struct msm_vidc_inst *inst)
{
	int rc = 0;
	struct hfi_device *hdev;
	struct v4l2_ctrl *ctrl;
	struct v4l2_ctrl *ctrl = NULL;
	struct v4l2_ctrl *rc_mode = NULL;
	struct hfi_intra_refresh intra_refresh;

	if (!inst || !inst->core) {
@@ -2748,6 +2853,11 @@ int msm_venc_set_intra_refresh_mode(struct msm_vidc_inst *inst)
	}
	hdev = inst->core->device;

	rc_mode = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE_MODE);
	if (!(rc_mode->val == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR ||
		rc_mode->val == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR))
		return 0;

	ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM);
	intra_refresh.mbs = 0;
	if (ctrl->val) {
@@ -2791,6 +2901,9 @@ int msm_venc_set_loop_filter_mode(struct msm_vidc_inst *inst)
	}
	hdev = inst->core->device;

	if (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_H264)
		return 0;

	ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE);
	ctrl_a = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA);
	ctrl_b = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA);
@@ -2825,6 +2938,10 @@ int msm_venc_set_sequence_header_mode(struct msm_vidc_inst *inst)
	}
	hdev = inst->core->device;

	if (!(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264 ||
		inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_HEVC))
		return 0;

	ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR);
	if (ctrl->val)
		enable.enable = true;
@@ -2854,6 +2971,10 @@ int msm_venc_set_au_delimiter_mode(struct msm_vidc_inst *inst)
	}
	hdev = inst->core->device;

	if (!(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264 ||
		inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_HEVC))
		return 0;

	ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_AU_DELIMITER);
	enable.enable = !!ctrl->val;

@@ -3096,7 +3217,8 @@ int msm_venc_set_video_signal_info(struct msm_vidc_inst *inst)
	}
	hdev = inst->core->device;

	if (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_H264)
	if (!(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264 ||
		inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_HEVC))
		return 0;

	ctrl_cs = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE);
@@ -3166,8 +3288,8 @@ int msm_venc_set_8x8_transform(struct msm_vidc_inst *inst)
{
	int rc = 0;
	struct hfi_device *hdev;
	struct v4l2_ctrl *ctrl;
	struct v4l2_ctrl *profile;
	struct v4l2_ctrl *ctrl = NULL;
	struct v4l2_ctrl *profile = NULL;
	struct hfi_enable enable;

	if (!inst || !inst->core) {
@@ -3176,17 +3298,13 @@ int msm_venc_set_8x8_transform(struct msm_vidc_inst *inst)
	}
	hdev = inst->core->device;

	if (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_H264 &&
		inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_HEVC)
	if (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_H264)
		return 0;

	if (inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264) {
	profile = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_PROFILE);
		if (profile->val == V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE ||
			profile->val ==
			V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE)
	if (!(profile->val == V4L2_MPEG_VIDEO_H264_PROFILE_HIGH ||
		profile->val == V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH))
		return 0;
	}

	ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM);
	enable.enable = !!ctrl->val;
@@ -3310,6 +3428,10 @@ int msm_venc_set_ltr_mode(struct msm_vidc_inst *inst)
	}
	hdev = inst->core->device;

	if (!(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_HEVC ||
		inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264))
		return 0;

	ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT);
	if (!ctrl->val)
		return 0;
@@ -3344,6 +3466,10 @@ int msm_venc_set_ltr_useframe(struct msm_vidc_inst *inst)
	}
	hdev = inst->core->device;

	if (!(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_HEVC ||
		inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264))
		return 0;

	ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME);
	use_ltr.ref_ltr = ctrl->val;
	use_ltr.use_constrnt = false;
@@ -3371,6 +3497,10 @@ int msm_venc_set_ltr_markframe(struct msm_vidc_inst *inst)
	}
	hdev = inst->core->device;

	if (!(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_HEVC ||
		inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264))
		return 0;

	ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME);
	mark_ltr.mark_frame = ctrl->val;

@@ -3435,6 +3565,10 @@ int msm_venc_set_aspect_ratio(struct msm_vidc_inst *inst)
	}
	hdev = inst->core->device;

	if (!(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264 ||
		inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_HEVC))
		return 0;

	ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH);
	if (!ctrl->val)
		return 0;
@@ -3485,6 +3619,7 @@ int msm_venc_set_blur_resolution(struct msm_vidc_inst *inst)
int msm_venc_set_hdr_info(struct msm_vidc_inst *inst)
{
	int rc = 0;
	struct v4l2_ctrl *profile = NULL;
	struct hfi_device *hdev;

	if (!inst || !inst->core) {
@@ -3493,6 +3628,13 @@ int msm_venc_set_hdr_info(struct msm_vidc_inst *inst)
	}
	hdev = inst->core->device;

	if (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_HEVC)
		return 0;

	profile = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_PROFILE);
	if (profile->val != V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10)
		return 0;

	/* No conversion to HFI needed as both structures are same */
	dprintk(VIDC_DBG, "%s: setting hdr info\n", __func__);
	rc = call_hfi_op(hdev, session_set_property, inst->session,
+0 −66
Original line number Diff line number Diff line
@@ -797,64 +797,6 @@ static inline int msm_vidc_verify_buffer_counts(struct msm_vidc_inst *inst)
	return rc;
}

int msm_vidc_set_internal_config(struct msm_vidc_inst *inst)
{
	int rc = 0;
	u32 rc_mode = RATE_CONTROL_OFF;
	struct hfi_vbv_hdr_buf_size hrd_buf_size;
	struct hfi_enable latency;
	struct hfi_device *hdev;
	u32 codec;
	u32 mbps, fps;
	u32 output_width, output_height;

	if (!inst || !inst->core || !inst->core->device) {
		dprintk(VIDC_WARN, "%s: Invalid parameter\n", __func__);
		return -EINVAL;
	}

	if (inst->session_type != MSM_VIDC_ENCODER)
		return rc;

	hdev = inst->core->device;

	codec = inst->fmts[CAPTURE_PORT].fourcc;
	latency.enable =  msm_comm_g_ctrl_for_id(inst,
			V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE);

	if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_MBR_VFR)
		rc_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_MBR;
	else if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
			   latency.enable == V4L2_MPEG_MSM_VIDC_ENABLE &&
			   codec != V4L2_PIX_FMT_VP8)
		rc_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;

	output_height = inst->prop.height[CAPTURE_PORT];
	output_width = inst->prop.width[CAPTURE_PORT];
	fps = inst->clk_data.frame_rate >> 16;
	mbps = NUM_MBS_PER_SEC(output_height, output_width, fps);
	if ((rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR ||
		 rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR) &&
		(codec != V4L2_PIX_FMT_VP8)) {
		if ((rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR &&
		    mbps <= CBR_MB_LIMIT) ||
		   (rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR &&
		    mbps <= CBR_VFR_MB_LIMIT))
			hrd_buf_size.vbv_hdr_buf_size = 500;
		else
			hrd_buf_size.vbv_hdr_buf_size = 1000;
		dprintk(VIDC_DBG, "Enable hdr_buf_size %d :\n",
				hrd_buf_size.vbv_hdr_buf_size);
		rc = call_hfi_op(hdev, session_set_property,
			(void *)inst->session,
			HFI_PROPERTY_CONFIG_VENC_VBV_HRD_BUF_SIZE,
			(void *)&hrd_buf_size, sizeof(hrd_buf_size));
		inst->clk_data.low_latency_mode = true;
	}

	return rc;
}

static int msm_vidc_set_rotation(struct msm_vidc_inst *inst)
{
	int rc = 0;
@@ -997,14 +939,6 @@ static inline int start_streaming(struct msm_vidc_inst *inst)
		goto fail_start;
	}

	rc = msm_vidc_set_internal_config(inst);
	if (rc) {
		dprintk(VIDC_ERR,
			"Set internal config failed %pK\n", inst);
		goto fail_start;
	}


	/* Decide work mode for current session */
	rc = call_core_op(inst->core, decide_work_mode, inst);
	if (rc) {
+54 −43
Original line number Diff line number Diff line
@@ -1272,6 +1272,7 @@ int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst)
	int rc = 0;
	struct hfi_device *hdev;
	struct hfi_video_work_route pdata;
	bool cbr_plus;

	if (!inst || !inst->core || !inst->core->device) {
		dprintk(VIDC_ERR,
@@ -1281,45 +1282,39 @@ int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst)
	}

	hdev = inst->core->device;

	cbr_plus = inst->clk_data.is_cbr_plus;
	pdata.video_work_route = 4;

	if (inst->session_type == MSM_VIDC_DECODER) {
		if (inst->fmts[OUTPUT_PORT].fourcc == V4L2_PIX_FMT_MPEG2 ||
			inst->pic_struct != MSM_VIDC_PIC_STRUCT_PROGRESSIVE)
			pdata.video_work_route = 1;
	} else if (inst->session_type == MSM_VIDC_ENCODER) {
		u32 slice_mode, rc_mode;
		u32 output_width, output_height, fps, mbps;
		bool cbr_plus;
		u32 slice_mode, output_width, output_height, num_mbs;
		bool is_1080p_above;

		if (inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_VP8) {
			pdata.video_work_route = 1;
			goto decision_done;
		}

		rc_mode = msm_comm_g_ctrl_for_id(inst,
			V4L2_CID_MPEG_VIDEO_BITRATE_MODE);
		slice_mode =  msm_comm_g_ctrl_for_id(inst,
				V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE);
		output_height = inst->prop.height[CAPTURE_PORT];
		output_width = inst->prop.width[CAPTURE_PORT];
		fps = inst->clk_data.frame_rate >> 16;
		mbps = NUM_MBS_PER_SEC(output_height, output_width, fps);
		cbr_plus = ((rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR &&
			mbps > CBR_MB_LIMIT) ||
			(rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR &&
			mbps > CBR_VFR_MB_LIMIT));
		output_height = inst->prop.height[OUTPUT_PORT];
		output_width = inst->prop.width[OUTPUT_PORT];
		num_mbs = NUM_MBS_PER_FRAME(output_height, output_width);

		is_1080p_above =
			((output_height > 1088 && output_width > 1920) ||
			 (output_height > 1920 && output_width > 1088) ||
			 num_mbs > NUM_MBS_PER_FRAME(1088, 1920));

		if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES ||
			((mbps <= NUM_MBS_PER_SEC(1920, 1088, 60)) && !cbr_plus)
			) {
			inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_VP8 ||
			(!is_1080p_above && !cbr_plus)) {
			pdata.video_work_route = 1;
			dprintk(VIDC_DBG, "Configured work route = 1");
		}
	} else {
		return -EINVAL;
	}

decision_done:
	dprintk(VIDC_DBG, "Configurng work route = %u",
			pdata.video_work_route);

	inst->clk_data.work_route = pdata.video_work_route;
	rc = call_hfi_op(hdev, session_set_property,
@@ -1486,6 +1481,7 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst)
	struct hfi_video_work_mode pdata;
	struct hfi_enable latency;
	u32 num_mbs = 0;
	u32 width, height;

	if (!inst || !inst->core || !inst->core->device) {
		dprintk(VIDC_ERR,
@@ -1496,28 +1492,52 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst)

	hdev = inst->core->device;
	pdata.video_work_mode = HFI_WORKMODE_2;
	latency.enable = inst->clk_data.low_latency_mode;

	if (inst->clk_data.low_latency_mode) {
		pdata.video_work_mode = HFI_WORKMODE_1;
		dprintk(VIDC_DBG, "Configured work mode = 1");
	} else if (inst->session_type == MSM_VIDC_DECODER) {
		num_mbs = NUM_MBS_PER_FRAME(
					inst->prop.height[OUTPUT_PORT],
					inst->prop.width[OUTPUT_PORT]);
	if (inst->session_type == MSM_VIDC_DECODER) {
		height = inst->prop.height[CAPTURE_PORT];
		width = inst->prop.width[CAPTURE_PORT];
		num_mbs = NUM_MBS_PER_FRAME(height, width);
		if (inst->fmts[OUTPUT_PORT].fourcc == V4L2_PIX_FMT_MPEG2 ||
			(inst->pic_struct != MSM_VIDC_PIC_STRUCT_PROGRESSIVE) ||
			(num_mbs < NUM_MBS_PER_FRAME(720, 1280)))
			inst->pic_struct != MSM_VIDC_PIC_STRUCT_PROGRESSIVE ||
			inst->clk_data.low_latency_mode ||
			(width < 1280 && height < 720) ||
			(width < 720 && height < 1280) ||
			num_mbs < NUM_MBS_PER_FRAME(720, 1280)) {
			pdata.video_work_mode = HFI_WORKMODE_1;
		}
	} else if (inst->session_type == MSM_VIDC_ENCODER) {
		if (inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_VP8) {
		height = inst->prop.height[OUTPUT_PORT];
		width = inst->prop.width[OUTPUT_PORT];
		num_mbs = NUM_MBS_PER_FRAME(height, width);
		if ((num_mbs >= NUM_MBS_PER_FRAME(2160, 4096) ||
			(width < 4096 && height < 2160) ||
			(width < 2160 && height < 4096)) &&
			(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_VP8 ||
			 inst->clk_data.low_latency_mode)) {
			pdata.video_work_mode = HFI_WORKMODE_1;
			/* For WORK_MODE_1, set Low Latency mode by default */
			inst->clk_data.low_latency_mode = true;
			latency.enable = true;
		}
	} else {
		return -EINVAL;
	}

	dprintk(VIDC_DBG, "Configuring work mode = %u low latency = %u",
			inst->clk_data.work_mode,
			latency.enable);

	rc = call_hfi_op(hdev, session_set_property,
		(void *)inst->session,
		HFI_PROPERTY_PARAM_VENC_LOW_LATENCY_MODE,
		(void *)&latency, sizeof(latency));
	if (rc)
		dprintk(VIDC_WARN,
			" Failed to configure low latency %pK\n", inst);
	else
		inst->clk_data.low_latency_mode = latency.enable;


	inst->clk_data.work_mode = pdata.video_work_mode;
	rc = call_hfi_op(hdev, session_set_property,
			(void *)inst->session, HFI_PROPERTY_PARAM_WORK_MODE,
@@ -1526,15 +1546,6 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst)
		dprintk(VIDC_WARN,
			" Failed to configure Work Mode %pK\n", inst);

	if (inst->clk_data.low_latency_mode &&
		inst->session_type == MSM_VIDC_ENCODER){
		latency.enable = true;
		rc = call_hfi_op(hdev, session_set_property,
			(void *)inst->session,
			HFI_PROPERTY_PARAM_VENC_LOW_LATENCY_MODE,
			(void *)&latency, sizeof(latency));
	}

	return rc;
}

+1 −0
Original line number Diff line number Diff line
@@ -362,6 +362,7 @@ struct clock_data {
	u32 opb_fourcc;
	u32 work_mode;
	bool low_latency_mode;
	bool is_cbr_plus;
	bool turbo_mode;
	u32 work_route;
	u32 dcvs_flags;
Loading