mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-11 07:03:09 -04:00
msm: vidc: update input tag implementation
In qbuf (input) store input_tag to etb_data list and send it to firmware in etb. Firmware will return input_tag in ftb_done, store it in fbd_data list and return the same when client does dqbuf (output). Change-Id: I3589e5a3017cac49000fc64191f9f756bc4011f4 Signed-off-by: Govindaraj Rajagopal <grajagop@codeaurora.org>
This commit is contained in:
parent
666c906d4e
commit
455cd2b148
4 changed files with 23 additions and 163 deletions
|
|
@ -363,7 +363,6 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev,
|
|||
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;
|
||||
|
|
@ -402,16 +401,15 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev,
|
|||
}
|
||||
|
||||
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
|
||||
|
|
@ -442,8 +440,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",
|
||||
|
|
@ -474,36 +470,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->session_type == MSM_VIDC_ENCODER ||
|
||||
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;
|
||||
|
|
@ -1470,7 +1445,6 @@ void *msm_vidc_open(int core_id, int session_type)
|
|||
INIT_MSM_VIDC_LIST(&inst->registeredbufs);
|
||||
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);
|
||||
|
|
@ -1575,7 +1549,6 @@ fail_bufq_capture:
|
|||
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);
|
||||
|
|
@ -1645,8 +1618,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);
|
||||
|
|
@ -1702,7 +1673,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);
|
||||
|
|
|
|||
|
|
@ -2042,7 +2042,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;
|
||||
}
|
||||
|
||||
|
|
@ -2511,6 +2510,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");
|
||||
|
|
@ -2574,8 +2574,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)
|
||||
|
|
@ -6783,120 +6786,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);
|
||||
|
|
@ -6913,6 +6812,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;
|
||||
|
|
@ -6923,6 +6823,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,
|
||||
|
|
|
|||
|
|
@ -308,16 +308,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,
|
||||
|
|
|
|||
|
|
@ -204,12 +204,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;
|
||||
|
|
@ -530,7 +524,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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue