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

Commit 551a2222 authored by Qiwei Liu's avatar Qiwei Liu
Browse files

msm: vidc: enable mark_data feature



Use v4l2_buffer.m.planes[0].reserved[3,4] to pass
mark_data and mark_target with userspace.
Use 2 lists to store and pass mark_data between
v4l2_buffer and HFI.

CRs-fixed: 2099825
Change-Id: I2102b80a81041a6283061bcf320de9a21b373156
Signed-off-by: default avatarQiwei Liu <qiweil@codeaurora.org>
parent aad73aa4
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -510,6 +510,12 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b)
		msm_comm_update_input_cr(inst, b->index, cr);
	}

	if (inst->session_type == MSM_VIDC_DECODER &&
			b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
		msm_comm_store_mark_data(&inst->etb_data, b->index,
			b->m.planes[0].reserved[3], b->m.planes[0].reserved[4]);
	}

	q = msm_comm_get_vb2q(inst, b->type);
	if (!q) {
		dprintk(VIDC_ERR,
@@ -562,6 +568,13 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b)
		b->m.planes[i].reserved[1] = b->m.planes[i].data_offset;
	}

	if (inst->session_type == MSM_VIDC_DECODER &&
			b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
		msm_comm_fetch_mark_data(&inst->fbd_data, b->index,
			&b->m.planes[0].reserved[3],
			&b->m.planes[0].reserved[4]);
	}

	return rc;
}
EXPORT_SYMBOL(msm_vidc_dqbuf);
@@ -1566,6 +1579,8 @@ void *msm_vidc_open(int core_id, int session_type)
	INIT_MSM_VIDC_LIST(&inst->registeredbufs);
	INIT_MSM_VIDC_LIST(&inst->reconbufs);
	INIT_MSM_VIDC_LIST(&inst->eosbufs);
	INIT_MSM_VIDC_LIST(&inst->etb_data);
	INIT_MSM_VIDC_LIST(&inst->fbd_data);

	kref_init(&inst->kref);

@@ -1673,6 +1688,8 @@ void *msm_vidc_open(int core_id, int session_type)
	DEINIT_MSM_VIDC_LIST(&inst->eosbufs);
	DEINIT_MSM_VIDC_LIST(&inst->freqs);
	DEINIT_MSM_VIDC_LIST(&inst->input_crs);
	DEINIT_MSM_VIDC_LIST(&inst->etb_data);
	DEINIT_MSM_VIDC_LIST(&inst->fbd_data);

	kfree(inst);
	inst = NULL;
@@ -1716,6 +1733,10 @@ static void msm_vidc_cleanup_instance(struct msm_vidc_inst *inst)
		dprintk(VIDC_ERR,
			"Failed to release persist buffers\n");

	if (msm_comm_release_mark_data(inst))
		dprintk(VIDC_ERR,
			"Failed to release mark_data buffers\n");

	/*
	 * At this point all buffes should be with driver
	 * irrespective of scenario
@@ -1771,6 +1792,8 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst)
	DEINIT_MSM_VIDC_LIST(&inst->eosbufs);
	DEINIT_MSM_VIDC_LIST(&inst->freqs);
	DEINIT_MSM_VIDC_LIST(&inst->input_crs);
	DEINIT_MSM_VIDC_LIST(&inst->etb_data);
	DEINIT_MSM_VIDC_LIST(&inst->fbd_data);

	mutex_destroy(&inst->sync_lock);
	mutex_destroy(&inst->bufq[CAPTURE_PORT].lock);
+99 −10
Original line number Diff line number Diff line
@@ -2569,6 +2569,11 @@ static void handle_fbd(enum hal_command_response cmd, void *data)
	}
	vb->timestamp = (time_usec * NSEC_PER_USEC);

	if (inst->session_type == MSM_VIDC_DECODER) {
		msm_comm_store_mark_data(&inst->fbd_data, vb->index,
			fill_buf_done->mark_data, fill_buf_done->mark_target);
	}

	extra_idx = EXTRADATA_IDX(inst->bufq[CAPTURE_PORT].num_planes);
	if (extra_idx && extra_idx < VIDEO_MAX_PLANES)
		vb->planes[extra_idx].bytesused = vb->planes[extra_idx].length;
@@ -3955,9 +3960,6 @@ static void populate_frame_data(struct vidc_frame_data *data,
	data->clnt_data = data->device_addr;

	if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
		bool pic_decoding_mode = msm_comm_g_ctrl_for_id(inst,
				V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE);

		data->buffer_type = HAL_BUFFER_INPUT;
		data->filled_len = vb->planes[0].bytesused;
		data->offset = vb->planes[0].data_offset;
@@ -3974,13 +3976,10 @@ static void populate_frame_data(struct vidc_frame_data *data,
		if (vbuf->flags & V4L2_QCOM_BUF_TIMESTAMP_INVALID)
			data->timestamp = LLONG_MAX;

		/* XXX: This is a dirty hack necessitated by the firmware,
		 * which refuses to issue FBDs for non I-frames in Picture Type
		 * Decoding mode, unless we pass in non-zero value in mark_data
		 * and mark_target.
		 */
		data->mark_data = data->mark_target =
			pic_decoding_mode ? 0xdeadbeef : 0;
		if (inst->session_type == MSM_VIDC_DECODER) {
			msm_comm_fetch_mark_data(&inst->etb_data, vb->index,
				&data->mark_data, &data->mark_target);
		}

	} else if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
		data->buffer_type = msm_comm_get_hal_output_buffer(inst);
@@ -6610,3 +6609,93 @@ bool kref_get_mbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf)
	return ret;
}

void msm_comm_store_mark_data(struct msm_vidc_list *data_list,
		u32 index, u32 mark_data, u32 mark_target)
{
	struct msm_vidc_buf_data *pdata = NULL;
	bool found = false;

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

	mutex_lock(&data_list->lock);
	list_for_each_entry(pdata, &data_list->list, list) {
		if (pdata->index == index) {
			pdata->mark_data = mark_data;
			pdata->mark_target = mark_target;
			found = true;
			break;
		}
	}

	if (!found) {
		pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
		if (!pdata)  {
			dprintk(VIDC_WARN, "%s: malloc failure.\n", __func__);
			goto exit;
		}
		pdata->index = index;
		pdata->mark_data = mark_data;
		pdata->mark_target = mark_target;
		list_add_tail(&pdata->list, &data_list->list);
	}

exit:
	mutex_unlock(&data_list->lock);
}

void msm_comm_fetch_mark_data(struct msm_vidc_list *data_list,
		u32 index, u32 *mark_data, u32 *mark_target)
{
	struct msm_vidc_buf_data *pdata = NULL;

	if (!data_list || !mark_data || !mark_target) {
		dprintk(VIDC_ERR, "%s: invalid params %pK %pK %pK\n",
			__func__, data_list, mark_data, mark_target);
		return;
	}

	*mark_data = *mark_target = 0;
	mutex_lock(&data_list->lock);
	list_for_each_entry(pdata, &data_list->list, list) {
		if (pdata->index == index) {
			*mark_data = pdata->mark_data;
			*mark_target = pdata->mark_target;
			/* clear after fetch */
			pdata->mark_data = pdata->mark_target = 0;
			break;
		}
	}
	mutex_unlock(&data_list->lock);
}

int msm_comm_release_mark_data(struct msm_vidc_inst *inst)
{
	struct msm_vidc_buf_data *pdata, *next;

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

	mutex_lock(&inst->etb_data.lock);
	list_for_each_entry_safe(pdata, next, &inst->etb_data.list, list) {
		list_del(&pdata->list);
		kfree(pdata);
	}
	mutex_unlock(&inst->etb_data.lock);

	mutex_lock(&inst->fbd_data.lock);
	list_for_each_entry_safe(pdata, next, &inst->fbd_data.list, list) {
		list_del(&pdata->list);
		kfree(pdata);
	}
	mutex_unlock(&inst->fbd_data.lock);

	return 0;
}
+5 −0
Original line number Diff line number Diff line
@@ -154,5 +154,10 @@ void print_v4l2_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst,
		struct v4l2_buffer *v4l2);
void kref_put_mbuf(struct msm_vidc_buffer *mbuf);
bool kref_get_mbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf);
void msm_comm_store_mark_data(struct msm_vidc_list *data_list,
		u32 index, u32 mark_data, u32 mark_target);
void msm_comm_fetch_mark_data(struct msm_vidc_list *data_list,
		u32 index, u32 *mark_data, u32 *mark_target);
int msm_comm_release_mark_data(struct msm_vidc_inst *inst);

#endif
+9 −0
Original line number Diff line number Diff line
@@ -175,6 +175,13 @@ struct msm_vidc_csc_coeff {
	u32 *vpe_csc_custom_limit_coeff;
};

struct msm_vidc_buf_data {
	struct list_head list;
	u32 index;
	u32 mark_data;
	u32 mark_target;
};

struct msm_vidc_common_data {
	char key[128];
	int value;
@@ -349,6 +356,8 @@ struct msm_vidc_inst {
	struct msm_vidc_list reconbufs;
	struct msm_vidc_list eosbufs;
	struct msm_vidc_list registeredbufs;
	struct msm_vidc_list etb_data;
	struct msm_vidc_list fbd_data;
	struct buffer_requirements buff_req;
	struct smem_client *mem_client;
	struct v4l2_ctrl_handler ctrl_handler;