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

Commit 5ba3fb1b authored by Maheshwar Ajja's avatar Maheshwar Ajja
Browse files

msm: vidc: Correct buffer counts for secondary output mode



The buffer counts in driver are not proper if client enables
multi stream secondary output mode resulting in video failures.
Correct the buffer counts to resolve the failures.

Change-Id: Ia3707f858c58db6bd3ca1176c98f9c529cc5b181
Signed-off-by: default avatarMaheshwar Ajja <majja@codeaurora.org>
parent a60934ca
Loading
Loading
Loading
Loading
+35 −32
Original line number Diff line number Diff line
@@ -799,6 +799,7 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst)
	inst->capability.secure_output2_threshold.max = 0;
	inst->buffer_mode_set[OUTPUT_PORT] = HAL_BUFFER_MODE_STATIC;
	inst->buffer_mode_set[CAPTURE_PORT] = HAL_BUFFER_MODE_DYNAMIC;
	inst->stream_output_mode = HAL_VIDEO_DECODER_PRIMARY;
	/* To start with, both ports are 1 plane each */
	inst->bufq[OUTPUT_PORT].num_planes = 1;
	inst->bufq[CAPTURE_PORT].num_planes = 1;
@@ -1082,20 +1083,31 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
			rc = call_hfi_op(hdev, session_set_property, (void *)
				inst->session, HAL_PARAM_VDEC_MULTI_STREAM,
				pdata);
			if (rc)
			if (rc) {
				dprintk(VIDC_ERR,
					"Failed:Disabling OUTPUT2 port : %d\n",
					rc);

			bufreq_out2 = get_buff_req_buffer(inst,
					HAL_BUFFER_OUTPUT2);
			if (!bufreq_out2)
				break;
			}
			/*
			 * If stream output mode was secondary earlier then
			 * populate output bufreqs with output2 bufreqs
			 */
			if (is_secondary_output_mode(inst)) {
				msm_comm_copy_bufreqs(inst, HAL_BUFFER_OUTPUT2,
					HAL_BUFFER_OUTPUT);
				msm_comm_copy_bufreqs(inst,
					HAL_BUFFER_EXTRADATA_OUTPUT2,
					HAL_BUFFER_EXTRADATA_OUTPUT);
			}

			bufreq_out2->buffer_count_min =
				bufreq_out2->buffer_count_min_host =
				bufreq_out2->buffer_count_actual = 0;
			/* reset output2 buffer requirements */
			msm_comm_reset_bufreqs(inst, HAL_BUFFER_OUTPUT2);
			msm_comm_reset_bufreqs(inst,
				HAL_BUFFER_EXTRADATA_OUTPUT2);

			msm_comm_set_stream_output_mode(inst,
				HAL_VIDEO_DECODER_PRIMARY);
			break;
		case V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY:
			switch (inst->bit_depth) {
@@ -1158,23 +1170,25 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
				frame_sz.height);
			rc = call_hfi_op(hdev, session_set_property, (void *)
				inst->session, HAL_PARAM_FRAME_SIZE, pdata);
			if (rc)
			if (rc) {
				dprintk(VIDC_ERR,
					"Failed setting OUTPUT2 size : %d\n",
					rc);
			/* Populate output2 bufreqs with output bufreqs */
			bufreq = get_buff_req_buffer(inst, HAL_BUFFER_OUTPUT);
			if (!bufreq)
				break;
			}

			/* Populate output2 bufreqs with output bufreqs */
			msm_comm_copy_bufreqs(inst, HAL_BUFFER_OUTPUT,
				HAL_BUFFER_OUTPUT2);
			msm_comm_copy_bufreqs(inst,
				HAL_BUFFER_EXTRADATA_OUTPUT,
				HAL_BUFFER_EXTRADATA_OUTPUT2);

			bufreq_out2 = get_buff_req_buffer(inst,
						HAL_BUFFER_OUTPUT2);
			if (!bufreq_out2)
				break;

			memcpy(bufreq_out2, bufreq,
				sizeof(struct hal_buffer_requirements));
			bufreq_out2->buffer_type = HAL_BUFFER_OUTPUT2;
			rc = msm_comm_set_buffer_count(inst,
				bufreq_out2->buffer_count_min_host,
				bufreq_out2->buffer_count_actual,
@@ -1182,23 +1196,11 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
			if (rc) {
				dprintk(VIDC_ERR,
					"%s: Failed to set opb buffer count to FW\n");
				return -EINVAL;
			}
			/* Do the same for extradata but no set is required */
			bufreq = get_buff_req_buffer(inst,
					HAL_BUFFER_EXTRADATA_OUTPUT);
			if (!bufreq)
				break;

			bufreq_out2 = get_buff_req_buffer(inst,
					HAL_BUFFER_EXTRADATA_OUTPUT2);
			if (!bufreq_out2)
				break;
			}

			memcpy(bufreq_out2, bufreq,
				sizeof(struct hal_buffer_requirements));
			bufreq_out2->buffer_type =
				HAL_BUFFER_EXTRADATA_OUTPUT2;
			msm_comm_set_stream_output_mode(inst,
				HAL_VIDEO_DECODER_SECONDARY);
			break;
		default:
			dprintk(VIDC_ERR,
@@ -1292,8 +1294,9 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)

	if (!rc && property_id) {
		dprintk(VIDC_DBG,
			"Control: Name = %s, ID = 0x%x Value = %d\n",
				ctrl->name, ctrl->id, ctrl->val);
			"Control: %x : Name = %s, ID = 0x%x Value = %d\n",
			hash32_ptr(inst->session), ctrl->name,
			ctrl->id, ctrl->val);
		rc = call_hfi_op(hdev, session_set_property, (void *)
				inst->session, property_id, pdata);
	}
+3 −2
Original line number Diff line number Diff line
@@ -2136,8 +2136,9 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)

	if (!rc && property_id) {
		dprintk(VIDC_DBG,
			"Control: Name = %s, ID = 0x%x Value = %d\n",
				ctrl->name, ctrl->id, ctrl->val);
			"Control: %x : Name = %s, ID = 0x%x Value = %d\n",
			hash32_ptr(inst->session), ctrl->name,
			ctrl->id, ctrl->val);
		rc = call_hfi_op(hdev, session_set_property,
				(void *)inst->session, property_id, pdata);
	}
+4 −0
Original line number Diff line number Diff line
@@ -1631,6 +1631,8 @@ static int try_get_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
			return -EINVAL;
		}
		ctrl->val = bufreq->buffer_count_min_host;
		dprintk(VIDC_DBG, "g_min: %x : hal_buffer %d min buffers %d\n",
			hash32_ptr(inst->session), buffer_type, ctrl->val);
		break;
	case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT:
		bufreq = get_buff_req_buffer(inst, HAL_BUFFER_INPUT);
@@ -1651,6 +1653,8 @@ static int try_get_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
				MIN_NUM_OUTPUT_BUFFERS_VP9;

		ctrl->val = bufreq->buffer_count_min_host;
		dprintk(VIDC_DBG, "g_min: %x : hal_buffer %d min buffers %d\n",
			hash32_ptr(inst->session), HAL_BUFFER_INPUT, ctrl->val);
		break;
	case V4L2_CID_MPEG_VIDC_VIDEO_TME_PAYLOAD_VERSION:
		ctrl->val = inst->capability.tme_version;
+105 −9
Original line number Diff line number Diff line
@@ -707,16 +707,46 @@ int msm_comm_ctrl_deinit(struct msm_vidc_inst *inst)
	return 0;
}

int msm_comm_set_stream_output_mode(struct msm_vidc_inst *inst,
		enum multi_stream mode)
{
	if (!inst) {
		dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
		return -EINVAL;
	}

	if (!is_decode_session(inst)) {
		dprintk(VIDC_DBG, "%s: not a decode session %x\n",
			__func__, hash32_ptr(inst->session));
		return -EINVAL;
	}

	if (mode == HAL_VIDEO_DECODER_SECONDARY)
		inst->stream_output_mode = HAL_VIDEO_DECODER_SECONDARY;
	else
		inst->stream_output_mode = HAL_VIDEO_DECODER_PRIMARY;

	return 0;
}

enum multi_stream msm_comm_get_stream_output_mode(struct msm_vidc_inst *inst)
{
	switch (msm_comm_g_ctrl_for_id(inst,
				V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE)) {
		case V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY:
			return HAL_VIDEO_DECODER_SECONDARY;
		case V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_PRIMARY:
		default:
	if (!inst) {
		dprintk(VIDC_ERR, "%s: invalid params, return default mode\n",
			__func__);
		return HAL_VIDEO_DECODER_PRIMARY;
	}

	if (!is_decode_session(inst)) {
		dprintk(VIDC_DBG, "%s: not a decode session %x\n",
			__func__, hash32_ptr(inst->session));
		return HAL_VIDEO_DECODER_PRIMARY;
	}

	if (inst->stream_output_mode == HAL_VIDEO_DECODER_SECONDARY)
		return HAL_VIDEO_DECODER_SECONDARY;
	else
		return HAL_VIDEO_DECODER_PRIMARY;
}

static int msm_comm_get_mbs_per_sec(struct msm_vidc_inst *inst)
@@ -1741,6 +1771,9 @@ static void handle_event_change(enum hal_command_response cmd, void *data)
		bufreq->buffer_count_min_host = bufreq->buffer_count_min +
							extra_buff_count;
	}
	dprintk(VIDC_DBG, "%s: buffer[%d] count: min %d min_host %d\n",
		__func__, bufreq->buffer_type, bufreq->buffer_count_min,
		bufreq->buffer_count_min_host);

	mutex_unlock(&inst->lock);

@@ -3096,6 +3129,11 @@ static int msm_comm_init_buffer_count(struct msm_vidc_inst *inst)
	bufreq->buffer_count_min_host = bufreq->buffer_count_actual =
				bufreq->buffer_count_min + extra_buff_count;

	dprintk(VIDC_DBG, "%s: %x : input min %d min_host %d actual %d\n",
		__func__, hash32_ptr(inst->session),
		bufreq->buffer_count_min, bufreq->buffer_count_min_host,
		bufreq->buffer_count_actual);

	rc = msm_comm_set_buffer_count(inst,
			bufreq->buffer_count_min_host,
			bufreq->buffer_count_actual, HAL_BUFFER_INPUT);
@@ -3125,6 +3163,11 @@ static int msm_comm_init_buffer_count(struct msm_vidc_inst *inst)
	bufreq->buffer_count_min_host = bufreq->buffer_count_actual =
		bufreq->buffer_count_min + extra_buff_count;

	dprintk(VIDC_DBG, "%s: %x : output min %d min_host %d actual %d\n",
		__func__, hash32_ptr(inst->session),
		bufreq->buffer_count_min, bufreq->buffer_count_min_host,
		bufreq->buffer_count_actual);

	rc = msm_comm_set_buffer_count(inst,
		bufreq->buffer_count_min_host,
		bufreq->buffer_count_actual, HAL_BUFFER_OUTPUT);
@@ -3473,6 +3516,58 @@ static int get_flipped_state(int present_state,
	return flipped_state;
}

int msm_comm_reset_bufreqs(struct msm_vidc_inst *inst, enum hal_buffer buf_type)
{
	struct hal_buffer_requirements *bufreqs;

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

	bufreqs = get_buff_req_buffer(inst, buf_type);
	if (!bufreqs) {
		dprintk(VIDC_ERR, "%s: invalid buf type %d\n",
			__func__, buf_type);
		return -EINVAL;
	}
	bufreqs->buffer_size = bufreqs->buffer_region_size =
	bufreqs->buffer_count_min = bufreqs->buffer_count_min_host =
	bufreqs->buffer_count_actual = bufreqs->contiguous =
	bufreqs->buffer_alignment = 0;

	return 0;
}

int msm_comm_copy_bufreqs(struct msm_vidc_inst *inst, enum hal_buffer src_type,
		enum hal_buffer dst_type)
{
	struct hal_buffer_requirements *src_bufreqs;
	struct hal_buffer_requirements *dst_bufreqs;

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

	src_bufreqs = get_buff_req_buffer(inst, src_type);
	dst_bufreqs = get_buff_req_buffer(inst, dst_type);
	if (!src_bufreqs || !dst_bufreqs) {
		dprintk(VIDC_ERR, "%s: invalid buf type: src %d dst %d\n",
			__func__, src_type, dst_type);
		return -EINVAL;
	}
	dst_bufreqs->buffer_size = src_bufreqs->buffer_size;
	dst_bufreqs->buffer_region_size = src_bufreqs->buffer_region_size;
	dst_bufreqs->buffer_count_min = src_bufreqs->buffer_count_min;
	dst_bufreqs->buffer_count_min_host = src_bufreqs->buffer_count_min_host;
	dst_bufreqs->buffer_count_actual = src_bufreqs->buffer_count_actual;
	dst_bufreqs->contiguous = src_bufreqs->contiguous;
	dst_bufreqs->buffer_alignment = src_bufreqs->buffer_alignment;

	return 0;
}

struct hal_buffer_requirements *get_buff_req_buffer(
		struct msm_vidc_inst *inst, enum hal_buffer buffer_type)
{
@@ -4824,8 +4919,9 @@ int msm_comm_set_buffer_count(struct msm_vidc_inst *inst,
	buf_count.buffer_type = type;
	buf_count.buffer_count_actual = act_count;
	buf_count.buffer_count_min_host = host_count;
	dprintk(VIDC_DBG, "%s : Act count = %d Host count = %d\n",
		__func__, act_count, host_count);
	dprintk(VIDC_DBG, "%s: %x : hal_buffer %d min_host %d actual %d\n",
		__func__, hash32_ptr(inst->session), type,
		host_count, act_count);
	rc = call_hfi_op(hdev, session_set_property,
		inst->session, HAL_PARAM_BUFFER_COUNT_ACTUAL, &buf_count);
	if (rc)
+16 −0
Original line number Diff line number Diff line
@@ -69,6 +69,16 @@ static inline bool is_encode_session(struct msm_vidc_inst *inst)
	return inst->session_type == MSM_VIDC_ENCODER;
}

static inline bool is_primary_output_mode(struct msm_vidc_inst *inst)
{
	return inst->stream_output_mode == HAL_VIDEO_DECODER_PRIMARY;
}

static inline bool is_secondary_output_mode(struct msm_vidc_inst *inst)
{
	return inst->stream_output_mode == HAL_VIDEO_DECODER_SECONDARY;
}

static inline int msm_comm_g_ctrl(struct msm_vidc_inst *inst,
		struct v4l2_control *ctrl)
{
@@ -128,6 +138,10 @@ int msm_comm_force_cleanup(struct msm_vidc_inst *inst);
int msm_comm_suspend(int core_id);
enum hal_extradata_id msm_comm_get_hal_extradata_index(
	enum v4l2_mpeg_vidc_extradata index);
int msm_comm_reset_bufreqs(struct msm_vidc_inst *inst,
	enum hal_buffer buf_type);
int msm_comm_copy_bufreqs(struct msm_vidc_inst *inst,
	enum hal_buffer src_type, enum hal_buffer dst_type);
struct hal_buffer_requirements *get_buff_req_buffer(
			struct msm_vidc_inst *inst, u32 buffer_type);
#define IS_PRIV_CTRL(idx) (\
@@ -138,6 +152,8 @@ int msm_comm_kill_session(struct msm_vidc_inst *inst);
void msm_comm_generate_session_error(struct msm_vidc_inst *inst);
void msm_comm_generate_sys_error(struct msm_vidc_inst *inst);
enum multi_stream msm_comm_get_stream_output_mode(struct msm_vidc_inst *inst);
int msm_comm_set_stream_output_mode(struct msm_vidc_inst *inst,
		enum multi_stream mode);
enum hal_buffer msm_comm_get_hal_output_buffer(struct msm_vidc_inst *inst);
int msm_comm_smem_alloc(struct msm_vidc_inst *inst, size_t size, u32 align,
		u32 flags, enum hal_buffer buffer_type, int map_kernel,
Loading