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

Commit cc207104 authored by Praneeth Paladugu's avatar Praneeth Paladugu Committed by Umesh Pandey
Browse files

msm: vidc: Add support for buffer tags and sub-frame info



   1) Clients send input_tag and output_tag through buffer
      reserved fields. Driver needs to pass them to FW and
      when FW returns them back, send them to client.
   2) Convey sub-frame information to client from FW.

Change-Id: Ia92bca933d18a7795ba17eea9178a4c5de49157b
Signed-off-by: default avatarPraneeth Paladugu <ppaladug@codeaurora.org>
Signed-off-by: default avatarUmesh Pandey <umeshp@codeaurora.org>
parent 26424f74
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -806,7 +806,7 @@ int create_pkt_cmd_session_etb_decoder(
	pkt->offset = input_frame->offset;
	pkt->alloc_len = input_frame->alloc_len;
	pkt->filled_len = input_frame->filled_len;
	pkt->input_tag = input_frame->clnt_data;
	pkt->input_tag = input_frame->input_tag;
	pkt->packet_buffer = (u32)input_frame->device_addr;

	trace_msm_v4l2_vidc_buffer_event_start("ETB",
@@ -841,7 +841,7 @@ int create_pkt_cmd_session_etb_encoder(
	pkt->offset = input_frame->offset;
	pkt->alloc_len = input_frame->alloc_len;
	pkt->filled_len = input_frame->filled_len;
	pkt->input_tag = input_frame->clnt_data;
	pkt->input_tag = input_frame->input_tag;
	pkt->packet_buffer = (u32)input_frame->device_addr;
	pkt->extra_data_buffer = (u32)input_frame->extradata_addr;

@@ -877,6 +877,7 @@ int create_pkt_cmd_session_ftb(struct hfi_cmd_session_fill_buffer_packet *pkt,
		return -EINVAL;

	pkt->packet_buffer = (u32)output_frame->device_addr;
	pkt->output_tag = output_frame->output_tag;
	pkt->extra_data_buffer = (u32)output_frame->extradata_addr;
	pkt->alloc_len = output_frame->alloc_len;
	pkt->filled_len = output_frame->filled_len;
+23 −2
Original line number Diff line number Diff line
@@ -115,6 +115,7 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
	struct hfi_pic_struct *pic_struct;
	struct hfi_buffer_requirements *buf_req;
	struct hfi_index_extradata_input_crop_payload *crop_info;
	struct hfi_dpb_counts *dpb_counts;
	u32 entropy_mode = 0;
	u8 *data_ptr;
	int prop_id;
@@ -215,6 +216,23 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
				data_ptr +=
					sizeof(struct hfi_pic_struct);
				break;
			case HFI_PROPERTY_PARAM_VDEC_DPB_COUNTS:
				data_ptr = data_ptr + sizeof(u32);
				dpb_counts = (struct hfi_dpb_counts *) data_ptr;
				event_notify.max_dpb_count =
					dpb_counts->max_dpb_count;
				event_notify.max_ref_count =
					dpb_counts->max_ref_count;
				event_notify.max_dec_buffering =
					dpb_counts->max_dec_buffering;
				dprintk(VIDC_DBG,
					"DPB Counts: dpb %d ref %d buff %d\n",
						dpb_counts->max_dpb_count,
						dpb_counts->max_ref_count,
						dpb_counts->max_dec_buffering);
				data_ptr +=
					sizeof(struct hfi_pic_struct);
				break;
			case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE:
				data_ptr = data_ptr + sizeof(u32);
				colour_info =
@@ -312,6 +330,7 @@ static int hfi_process_evt_release_buffer_ref(u32 device_id,
	event_notify.hal_event_type = HAL_EVENT_RELEASE_BUFFER_REFERENCE;
	event_notify.packet_buffer = data->packet_buffer;
	event_notify.extra_data_buffer = data->extra_data_buffer;
	event_notify.output_tag = data->output_tag;

	info->response_type = HAL_SESSION_EVENT_CHANGE;
	info->response.event = event_notify;
@@ -1358,7 +1377,7 @@ static int hfi_process_session_etb_done(u32 device_id,
	data_done.session_id = (void *)(uintptr_t)pkt->session_id;
	data_done.status = hfi_map_err_status(pkt->error_type);
	data_done.size = sizeof(struct msm_vidc_cb_data_done);
	data_done.clnt_data = pkt->input_tag;
	data_done.input_done.input_tag = pkt->input_tag;
	data_done.input_done.recon_stats.buffer_index =
		pkt->ubwc_cr_stats.frame_index;
	memcpy(&data_done.input_done.recon_stats.ubwc_stats_info,
@@ -1490,7 +1509,9 @@ static int hfi_process_session_ftb_done(
		data_done.output_done.frame_height = pkt->frame_height;
		data_done.output_done.start_x_coord = pkt->start_x_coord;
		data_done.output_done.start_y_coord = pkt->start_y_coord;
		data_done.output_done.input_tag1 = pkt->input_tag;
		data_done.output_done.input_tag = pkt->input_tag;
		data_done.output_done.input_tag1 = pkt->input_tag2;
		data_done.output_done.output_tag = pkt->output_tag;
		data_done.output_done.picture_type = pkt->picture_type;
		data_done.output_done.packet_buffer1 = pkt->packet_buffer;
		data_done.output_done.extra_data_buffer =
+17 −0
Original line number Diff line number Diff line
@@ -495,6 +495,7 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b)
	struct msm_vidc_inst *inst = instance;
	int rc = 0, i = 0;
	struct buf_queue *q = NULL;
	struct vidc_tag_data tag_data;
	u32 cr = 0;

	if (!inst || !inst->core || !b || !valid_v4l2_buffer(b, inst)) {
@@ -523,6 +524,12 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b)
			b->m.planes[0].reserved[3], b->m.planes[0].reserved[4]);
	}

	tag_data.index = b->index;
	tag_data.type = b->type;
	tag_data.input_tag = b->m.planes[0].reserved[5];
	tag_data.output_tag = b->m.planes[0].reserved[6];
	msm_comm_store_tags(inst, &tag_data);

	q = msm_comm_get_vb2q(inst, b->type);
	if (!q) {
		dprintk(VIDC_ERR,
@@ -545,6 +552,7 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b)
	struct msm_vidc_inst *inst = instance;
	int rc = 0, i = 0;
	struct buf_queue *q = NULL;
	struct vidc_tag_data tag_data;

	if (!inst || !b || !valid_v4l2_buffer(b, inst)) {
		dprintk(VIDC_ERR, "%s: invalid params, inst %pK\n",
@@ -582,6 +590,13 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b)
			&b->m.planes[0].reserved[4]);
	}

	tag_data.index = b->index;
	tag_data.type = b->type;

	msm_comm_fetch_tags(inst, &tag_data);
	b->m.planes[0].reserved[5] = tag_data.input_tag;
	b->m.planes[0].reserved[6] = tag_data.output_tag;

	return rc;
}
EXPORT_SYMBOL(msm_vidc_dqbuf);
@@ -1618,6 +1633,7 @@ void *msm_vidc_open(int core_id, int session_type)
	INIT_MSM_VIDC_LIST(&inst->scratchbufs);
	INIT_MSM_VIDC_LIST(&inst->freqs);
	INIT_MSM_VIDC_LIST(&inst->input_crs);
	INIT_MSM_VIDC_LIST(&inst->buffer_tags);
	INIT_MSM_VIDC_LIST(&inst->persistbufs);
	INIT_MSM_VIDC_LIST(&inst->pending_getpropq);
	INIT_MSM_VIDC_LIST(&inst->outputbufs);
@@ -1734,6 +1750,7 @@ 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->buffer_tags);
	DEINIT_MSM_VIDC_LIST(&inst->etb_data);
	DEINIT_MSM_VIDC_LIST(&inst->fbd_data);

+120 −4
Original line number Diff line number Diff line
@@ -1586,7 +1586,7 @@ static void handle_session_init_done(enum hal_command_response cmd, void *data)
}

static void msm_vidc_queue_rbr_event(struct msm_vidc_inst *inst,
		int fd, u32 offset)
		int fd, u32 offset, u32 output_tag)
{
	struct v4l2_event buf_event = {0};
	u32 *ptr;
@@ -1595,6 +1595,7 @@ static void msm_vidc_queue_rbr_event(struct msm_vidc_inst *inst,
	ptr = (u32 *)buf_event.u.data;
	ptr[0] = fd;
	ptr[1] = offset;
	ptr[2] = output_tag;

	v4l2_event_queue_fh(&inst->event_handler, &buf_event);
}
@@ -1643,6 +1644,7 @@ static void handle_event_change(enum hal_command_response cmd, void *data)
		planes[0] = event_notify->packet_buffer;
		planes[1] = event_notify->extra_data_buffer;
		mbuf = msm_comm_get_buffer_using_device_planes(inst, planes);
		mbuf->output_tag = event_notify->output_tag;
		if (!mbuf || !kref_get_mbuf(inst, mbuf)) {
			dprintk(VIDC_ERR,
				"%s: data_addr %x, extradata_addr %x not found\n",
@@ -1709,6 +1711,9 @@ static void handle_event_change(enum hal_command_response cmd, void *data)
	ptr[10] = msm_comm_get_v4l2_level(
		inst->fmts[OUTPUT_PORT].fourcc,
		event_notify->level);
	ptr[11] = event_notify->max_dpb_count;
	ptr[12] = event_notify->max_ref_count;
	ptr[13] = event_notify->max_dec_buffering;

	dprintk(VIDC_DBG,
		"Event payload: height = %d width = %d profile = %d level = %d\n",
@@ -2375,6 +2380,7 @@ static void handle_ebd(enum hal_command_response cmd, void *data)
	struct msm_vidc_inst *inst;
	struct vidc_hal_ebd *empty_buf_done;
	struct vb2_v4l2_buffer *vbuf;
	struct vidc_tag_data tag_data;
	u32 planes[VIDEO_MAX_PLANES] = {0};
	u32 extra_idx = 0, i;

@@ -2455,6 +2461,14 @@ static void handle_ebd(enum hal_command_response cmd, void *data)
	}
	mutex_unlock(&inst->registeredbufs.lock);

	tag_data.index = vb->index;
	tag_data.input_tag = empty_buf_done->input_tag;
	tag_data.output_tag = empty_buf_done->output_tag;
	tag_data.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;

	msm_comm_store_tags(inst, &tag_data);


	update_recon_stats(inst, &empty_buf_done->recon_stats);
	msm_vidc_clear_freq_entry(inst, mbuf->smem[0].device_addr);
	/*
@@ -2520,6 +2534,7 @@ static void handle_fbd(enum hal_command_response cmd, void *data)
	struct vb2_buffer *vb, *vb2;
	struct vidc_hal_fbd *fill_buf_done;
	struct vb2_v4l2_buffer *vbuf;
	struct vidc_tag_data tag_data;
	enum hal_buffer buffer_type;
	u64 time_usec = 0;
	u32 planes[VIDEO_MAX_PLANES] = {0};
@@ -2603,6 +2618,13 @@ static void handle_fbd(enum hal_command_response cmd, void *data)
			fill_buf_done->mark_data, fill_buf_done->mark_target);
	}

	tag_data.index = vb->index;
	tag_data.input_tag = fill_buf_done->input_tag;
	tag_data.output_tag = fill_buf_done->output_tag;
	tag_data.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;

	msm_comm_store_tags(inst, &tag_data);

	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;
@@ -2623,6 +2645,8 @@ static void handle_fbd(enum hal_command_response cmd, void *data)
		mbuf->vvb.flags |= V4L2_QCOM_BUF_FLAG_DECODEONLY;
	if (fill_buf_done->flags1 & HAL_BUFFERFLAG_DATACORRUPT)
		mbuf->vvb.flags |= V4L2_QCOM_BUF_DATA_CORRUPT;
	if (fill_buf_done->flags1 & HAL_BUFFERFLAG_ENDOFSUBFRAME)
		mbuf->vvb.flags |= V4L2_QCOM_BUF_END_OF_SUBFRAME;
	switch (fill_buf_done->picture_type) {
	case HAL_PICTURE_IDR:
		mbuf->vvb.flags |= V4L2_QCOM_BUF_FLAG_IDRFRAME;
@@ -3824,7 +3848,6 @@ int msm_vidc_send_pending_eos_buffers(struct msm_vidc_inst *inst)
	list_for_each_entry_safe(binfo, temp, &inst->eosbufs.list, list) {
		data.alloc_len = binfo->smem.size;
		data.device_addr = binfo->smem.device_addr;
		data.clnt_data = data.device_addr;
		data.buffer_type = HAL_BUFFER_INPUT;
		data.filled_len = 0;
		data.offset = 0;
@@ -3976,6 +3999,7 @@ static void populate_frame_data(struct vidc_frame_data *data,
	int extra_idx;
	struct vb2_buffer *vb;
	struct vb2_v4l2_buffer *vbuf;
	struct vidc_tag_data tag_data;

	if (!inst || !mbuf || !data) {
		dprintk(VIDC_ERR, "%s: invalid params %pK %pK %pK\n",
@@ -3993,7 +4017,6 @@ static void populate_frame_data(struct vidc_frame_data *data,
	data->device_addr = mbuf->smem[0].device_addr;
	data->timestamp = time_usec;
	data->flags = 0;
	data->clnt_data = data->device_addr;

	if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
		data->buffer_type = HAL_BUFFER_INPUT;
@@ -4021,6 +4044,14 @@ static void populate_frame_data(struct vidc_frame_data *data,
		data->buffer_type = msm_comm_get_hal_output_buffer(inst);
	}

	tag_data.index = vb->index;
	tag_data.type = vb->type;

	msm_comm_fetch_tags(inst, &tag_data);
	data->input_tag = tag_data.input_tag;
	data->output_tag = tag_data.output_tag;


	extra_idx = EXTRADATA_IDX(vb->num_planes);
	if (extra_idx && extra_idx < VIDEO_MAX_PLANES) {
		data->extradata_addr = mbuf->smem[extra_idx].device_addr;
@@ -6605,7 +6636,8 @@ void handle_release_buffer_reference(struct msm_vidc_inst *inst,
		/* send RBR event to client */
		msm_vidc_queue_rbr_event(inst,
			mbuf->vvb.vb2_buf.planes[0].m.fd,
			mbuf->vvb.vb2_buf.planes[0].data_offset);
			mbuf->vvb.vb2_buf.planes[0].data_offset,
			mbuf->output_tag);

		/* clear RBR_PENDING flag */
		mbuf->flags &= ~MSM_VIDC_FLAG_RBR_PENDING;
@@ -6742,6 +6774,90 @@ bool kref_get_mbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf)
	return ret;
}

void msm_comm_free_buffer_tags(struct msm_vidc_inst *inst)
{
	struct vidc_tag_data *temp, *next;

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

	mutex_lock(&inst->buffer_tags.lock);
	list_for_each_entry_safe(temp, next, &inst->buffer_tags.list, list) {
		list_del(&temp->list);
		kfree(temp);
	}
	INIT_LIST_HEAD(&inst->buffer_tags.list);
	mutex_unlock(&inst->buffer_tags.lock);
}

void msm_comm_store_tags(struct msm_vidc_inst *inst,
	struct vidc_tag_data *tag_data)
{

	struct vidc_tag_data *temp, *next;
	struct vidc_tag_data *pdata = NULL;
	bool found = false;

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


	mutex_lock(&inst->buffer_tags.lock);
	list_for_each_entry_safe(temp, next, &inst->buffer_tags.list, list) {
		if (temp->index == tag_data->index &&
				temp->type == tag_data->type) {
			temp->input_tag = tag_data->input_tag;
			temp->output_tag = tag_data->output_tag;
			found = true;
			break;
		}
	}

	if (!found) {
		pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
		if (!pdata)  {
			dprintk(VIDC_WARN, "%s: malloc failure.\n", __func__);
			goto exit;
		}
		pdata->input_tag = tag_data->input_tag;
		pdata->output_tag = tag_data->output_tag;
		pdata->index = tag_data->index;
		pdata->type = tag_data->type;
		list_add_tail(&pdata->list, &inst->buffer_tags.list);
	}

exit:
	mutex_unlock(&inst->buffer_tags.lock);
}

void msm_comm_fetch_tags(struct msm_vidc_inst *inst,
	struct vidc_tag_data *tag_data)
{
	struct vidc_tag_data *temp, *next;

	if (!inst || !tag_data) {
		dprintk(VIDC_ERR, "%s: invalid params %pK %pK\n",
				__func__, inst, tag_data);
		return;
	}
	mutex_lock(&inst->buffer_tags.lock);
	list_for_each_entry_safe(temp, next, &inst->buffer_tags.list, list) {
		if (temp->index == tag_data->index &&
				temp->type == tag_data->type) {
			tag_data->input_tag = temp->input_tag;
			tag_data->output_tag = temp->output_tag;
			break;
		}
	}
	mutex_unlock(&inst->buffer_tags.lock);
}

void msm_comm_store_mark_data(struct msm_vidc_list *data_list,
		u32 index, u32 mark_data, u32 mark_target)
{
+6 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -150,6 +150,11 @@ bool msm_comm_compare_device_plane(struct msm_vidc_buffer *mbuf,
		u32 *planes, u32 i);
bool msm_comm_compare_device_planes(struct msm_vidc_buffer *mbuf,
		u32 *planes);
void msm_comm_store_tags(struct msm_vidc_inst *inst,
		struct vidc_tag_data *tag_data);
void msm_comm_fetch_tags(struct msm_vidc_inst *inst,
		struct vidc_tag_data *tag_data);
void msm_comm_free_buffer_tags(struct msm_vidc_inst *inst);
int msm_comm_qbuf_cache_operations(struct msm_vidc_inst *inst,
		struct v4l2_buffer *b);
int msm_comm_dqbuf_cache_operations(struct msm_vidc_inst *inst,
Loading