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

Commit 3c52f31b authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: vidc: update input tag implementation"

parents c1081b07 5592aeb5
Loading
Loading
Loading
Loading
+10 −38
Original line number Diff line number Diff line
@@ -368,7 +368,6 @@ EXPORT_SYMBOL(msm_vidc_release_buffer);
int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b)
{
	struct msm_vidc_inst *inst = instance;
	struct msm_vidc_client_data *client_data = NULL;
	int rc = 0;
	unsigned int i = 0;
	struct buf_queue *q = NULL;
@@ -407,16 +406,15 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b)
	}

	if (b->type == INPUT_MPLANE) {
		client_data = msm_comm_store_client_data(inst,
			b->m.planes[0].reserved[MSM_VIDC_INPUT_TAG_1]);
		if (!client_data) {
			s_vpr_e(inst->sid,
				"%s: failed to store client data\n", __func__);
		rc = msm_comm_store_input_tag(&inst->etb_data, b->index,
				b->m.planes[0].reserved[MSM_VIDC_INPUT_TAG_1],
				0, inst->sid);
		if (rc) {
			s_vpr_e(inst->sid, "Failed to store input tag");
			return -EINVAL;
		}
		msm_comm_store_input_tag(&inst->etb_data, b->index,
			client_data->id, 0, inst->sid);
	}

	/*
	 * set perf mode for image session buffers so that
	 * they will be processed quickly
@@ -447,8 +445,6 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b)
	int rc = 0;
	unsigned int i = 0;
	struct buf_queue *q = NULL;
	u32 input_tag = 0, input_tag2 = 0;
	bool remove;

	if (!inst || !b || !valid_v4l2_buffer(b, inst)) {
		d_vpr_e("%s: invalid params, %pK %pK\n",
@@ -479,34 +475,15 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b)
		b->m.planes[i].reserved[MSM_VIDC_DATA_OFFSET] =
					b->m.planes[i].data_offset;
	}
	/**
	 * Flush handling:
	 * Don't fetch tag - if flush issued at input/output port.
	 * Fetch tag - if atleast 1 ebd received after flush. (Flush_done
	 * event may be notified to userspace even before client
	 * dequeus all buffers at FBD, to avoid this race condition
	 * fetch tag atleast 1 ETB is successfully processed after flush)
	 */
	if (b->type == OUTPUT_MPLANE && !inst->in_flush &&
			!inst->out_flush && inst->clk_data.buffer_counter) {
	if (b->type == OUTPUT_MPLANE) {
		rc = msm_comm_fetch_input_tag(&inst->fbd_data, b->index,
				&input_tag, &input_tag2, inst->sid);
				&b->m.planes[0].reserved[MSM_VIDC_INPUT_TAG_1],
				&b->m.planes[0].reserved[MSM_VIDC_INPUT_TAG_2],
				inst->sid);
		if (rc) {
			s_vpr_e(inst->sid, "Failed to fetch input tag");
			return -EINVAL;
		}
		/**
		 * During flush input_tag & input_tag2 will be zero.
		 * Check before retrieving client data
		 */
		if (input_tag) {
			remove = !(b->flags & V4L2_BUF_FLAG_END_OF_SUBFRAME) &&
					!(b->flags & V4L2_BUF_FLAG_CODECCONFIG);
			msm_comm_fetch_client_data(inst, remove,
				input_tag, input_tag2,
				&b->m.planes[0].reserved[MSM_VIDC_INPUT_TAG_1],
				&b->m.planes[0].reserved[MSM_VIDC_INPUT_TAG_2]);
		}
	}

	return rc;
@@ -1481,7 +1458,6 @@ void *msm_vidc_open(int core_id, int session_type)
	INIT_MSM_VIDC_LIST(&inst->cvpbufs);
	INIT_MSM_VIDC_LIST(&inst->refbufs);
	INIT_MSM_VIDC_LIST(&inst->eosbufs);
	INIT_MSM_VIDC_LIST(&inst->client_data);
	INIT_MSM_VIDC_LIST(&inst->etb_data);
	INIT_MSM_VIDC_LIST(&inst->fbd_data);
	INIT_MSM_VIDC_LIST(&inst->window_data);
@@ -1599,7 +1575,6 @@ void *msm_vidc_open(int core_id, int session_type)
	DEINIT_MSM_VIDC_LIST(&inst->registeredbufs);
	DEINIT_MSM_VIDC_LIST(&inst->eosbufs);
	DEINIT_MSM_VIDC_LIST(&inst->input_crs);
	DEINIT_MSM_VIDC_LIST(&inst->client_data);
	DEINIT_MSM_VIDC_LIST(&inst->etb_data);
	DEINIT_MSM_VIDC_LIST(&inst->fbd_data);
	DEINIT_MSM_VIDC_LIST(&inst->window_data);
@@ -1669,8 +1644,6 @@ static void msm_vidc_cleanup_instance(struct msm_vidc_inst *inst)
	if (msm_comm_release_input_tag(inst))
		s_vpr_e(inst->sid, "Failed to release input_tag buffers\n");

	msm_comm_release_client_data(inst, true);

	msm_comm_release_window_data(inst);

	msm_comm_release_eos_buffers(inst);
@@ -1727,7 +1700,6 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst)
	DEINIT_MSM_VIDC_LIST(&inst->registeredbufs);
	DEINIT_MSM_VIDC_LIST(&inst->eosbufs);
	DEINIT_MSM_VIDC_LIST(&inst->input_crs);
	DEINIT_MSM_VIDC_LIST(&inst->client_data);
	DEINIT_MSM_VIDC_LIST(&inst->etb_data);
	DEINIT_MSM_VIDC_LIST(&inst->fbd_data);
	DEINIT_MSM_VIDC_LIST(&inst->window_data);
+12 −110
Original line number Diff line number Diff line
@@ -2101,7 +2101,6 @@ static void handle_session_flush(enum hal_command_response cmd, void *data)

	if (flush_type == HAL_FLUSH_ALL) {
		msm_comm_clear_window_data(inst);
		msm_comm_release_client_data(inst, false);
		inst->clk_data.buffer_counter = 0;
	}

@@ -2570,6 +2569,7 @@ static void handle_fbd(enum hal_command_response cmd, void *data)
	u64 time_usec = 0;
	u32 planes[VIDEO_MAX_PLANES] = {0};
	struct v4l2_format *f;
	int rc = 0;

	if (!response) {
		d_vpr_e("Invalid response from vidc_hal\n");
@@ -2633,8 +2633,11 @@ static void handle_fbd(enum hal_command_response cmd, void *data)

	vb->timestamp = (time_usec * NSEC_PER_USEC);

	msm_comm_store_input_tag(&inst->fbd_data, vb->index,
		fill_buf_done->input_tag, fill_buf_done->input_tag2, inst->sid);
	rc = msm_comm_store_input_tag(&inst->fbd_data, vb->index,
			fill_buf_done->input_tag,
			fill_buf_done->input_tag2, inst->sid);
	if (rc)
		s_vpr_e(inst->sid, "Failed to store input tag");

	if (inst->session_type == MSM_VIDC_ENCODER) {
		if (inst->max_filled_len < fill_buf_done->filled_len1)
@@ -7138,120 +7141,16 @@ bool kref_get_mbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf)
	return ret;
}

struct msm_vidc_client_data *msm_comm_store_client_data(
	struct msm_vidc_inst *inst, u32 itag)
{
	struct msm_vidc_client_data *data = NULL, *temp = NULL;

	if (!inst) {
		d_vpr_e("%s: invalid params\n", __func__);
		return NULL;
	}

	mutex_lock(&inst->client_data.lock);
	list_for_each_entry(temp, &inst->client_data.list, list) {
		if (!temp->id) {
			data = temp;
			break;
		}
	}
	if (!data) {
		data = kzalloc(sizeof(*data), GFP_KERNEL);
		if (!data) {
			s_vpr_e(inst->sid, "%s: No memory avilable", __func__);
			goto exit;
		}
		INIT_LIST_HEAD(&data->list);
		list_add_tail(&data->list, &inst->client_data.list);
	}

	/**
	 * Special handling, if etb_counter reaches to 2^32 - 1,
	 * then start next value from 1 not 0.
	 */
	if (!inst->etb_counter)
		inst->etb_counter = 1;

	data->id =  inst->etb_counter++;
	data->input_tag = itag;

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

	return data;
}

void msm_comm_fetch_client_data(struct msm_vidc_inst *inst, bool remove,
	u32 itag, u32 itag2, u32 *otag, u32 *otag2)
{
	struct msm_vidc_client_data *temp, *next;
	bool found_itag = false, found_itag2 = false;

	if (!inst || !otag || !otag2) {
		d_vpr_e("%s: invalid params %pK %x %x\n",
			__func__, inst, otag, otag2);
		return;
	}
	/**
	 * Some interlace clips, both BF & TF is available in single ETB buffer.
	 * In that case, firmware copies same input_tag value to both input_tag
	 * and input_tag2 at FBD.
	 */
	if (!itag2 || itag == itag2)
		found_itag2 = true;
	mutex_lock(&inst->client_data.lock);
	list_for_each_entry_safe(temp, next, &inst->client_data.list, list) {
		if (temp->id == itag) {
			*otag = temp->input_tag;
			found_itag = true;
			if (remove)
				temp->id = 0;
		} else if (!found_itag2 && temp->id == itag2) {
			*otag2 = temp->input_tag;
			found_itag2 = true;
			if (remove)
				temp->id = 0;
		}
		if (found_itag && found_itag2)
			break;
	}
	mutex_unlock(&inst->client_data.lock);

	if (!found_itag || !found_itag2) {
		s_vpr_e(inst->sid, "%s: client data not found - %u, %u\n",
			__func__, itag, itag2);
	}
}

void msm_comm_release_client_data(struct msm_vidc_inst *inst, bool remove)
{
	struct msm_vidc_client_data *temp, *next;

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

	mutex_lock(&inst->client_data.lock);
	list_for_each_entry_safe(temp, next, &inst->client_data.list, list) {
		temp->id = 0;
		if (remove) {
			list_del(&temp->list);
			kfree(temp);
		}
	}
	mutex_unlock(&inst->client_data.lock);
}

void msm_comm_store_input_tag(struct msm_vidc_list *data_list,
int msm_comm_store_input_tag(struct msm_vidc_list *data_list,
		u32 index, u32 itag, u32 itag2, u32 sid)
{
	struct msm_vidc_buf_data *pdata = NULL;
	bool found = false;
	int rc = 0;

	if (!data_list) {
		s_vpr_e(sid, "%s: invalid params\n", __func__);
		return;
		return -EINVAL;
	}

	mutex_lock(&data_list->lock);
@@ -7268,6 +7167,7 @@ void msm_comm_store_input_tag(struct msm_vidc_list *data_list,
		pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
		if (!pdata)  {
			s_vpr_e(sid, "%s: malloc failure.\n", __func__);
			rc = -ENOMEM;
			goto exit;
		}
		pdata->index = index;
@@ -7278,6 +7178,8 @@ void msm_comm_store_input_tag(struct msm_vidc_list *data_list,

exit:
	mutex_unlock(&data_list->lock);

	return rc;
}

int msm_comm_fetch_input_tag(struct msm_vidc_list *data_list,
+1 −6
Original line number Diff line number Diff line
@@ -342,16 +342,11 @@ void print_vb2_buffer(const char *str, struct msm_vidc_inst *inst,
		struct vb2_buffer *vb2);
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_input_tag(struct msm_vidc_list *data_list,
int msm_comm_store_input_tag(struct msm_vidc_list *data_list,
		u32 index, u32 itag, u32 itag2, u32 sid);
int msm_comm_fetch_input_tag(struct msm_vidc_list *data_list,
		u32 index, u32 *itag, u32 *itag2, u32 sid);
int msm_comm_release_input_tag(struct msm_vidc_inst *inst);
struct msm_vidc_client_data *msm_comm_store_client_data(
	struct msm_vidc_inst *inst, u32 itag);
void msm_comm_fetch_client_data(struct msm_vidc_inst *inst, bool remove,
	u32 itag, u32 itag2, u32 *mdata, u32 *mtarget);
void msm_comm_release_client_data(struct msm_vidc_inst *inst, bool remove);
int msm_comm_qbufs_batch(struct msm_vidc_inst *inst,
		struct msm_vidc_buffer *mbuf);
int msm_comm_qbuf_decode_batch(struct msm_vidc_inst *inst,
+0 −7
Original line number Diff line number Diff line
@@ -213,12 +213,6 @@ struct msm_vidc_window_data {
	u32 etb_count;
};

struct msm_vidc_client_data {
	struct list_head list;
	u32 id;
	u32 input_tag;
};

struct msm_vidc_common_data {
	char key[128];
	int value;
@@ -541,7 +535,6 @@ struct msm_vidc_inst {
	enum multi_stream stream_output_mode;
	struct v4l2_ctrl **ctrls;
	u32 num_ctrls;
	u32 etb_counter;
	int bit_depth;
	struct kref kref;
	bool in_flush;