Loading msm/vidc/hfi_packetization.c +2 −6 Original line number Diff line number Diff line Loading @@ -632,12 +632,10 @@ int create_pkt_cmd_session_etb_decoder( pkt->time_stamp_hi = upper_32_bits(input_frame->timestamp); pkt->time_stamp_lo = lower_32_bits(input_frame->timestamp); pkt->flags = input_frame->flags; pkt->mark_target = input_frame->mark_target; pkt->mark_data = input_frame->mark_data; 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", Loading Loading @@ -667,12 +665,10 @@ int create_pkt_cmd_session_etb_encoder( pkt->time_stamp_hi = upper_32_bits(input_frame->timestamp); pkt->time_stamp_lo = lower_32_bits(input_frame->timestamp); pkt->flags = input_frame->flags; pkt->mark_target = input_frame->mark_target; pkt->mark_data = input_frame->mark_data; 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; Loading msm/vidc/hfi_response_handler.c +4 −8 Original line number Diff line number Diff line Loading @@ -780,7 +780,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, Loading Loading @@ -857,13 +857,11 @@ static int hfi_process_session_ftb_done( 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 = 0; data_done.output_done.input_tag = pkt->input_tag; data_done.output_done.timestamp_hi = pkt->time_stamp_hi; data_done.output_done.timestamp_lo = pkt->time_stamp_lo; data_done.output_done.flags1 = pkt->flags; data_done.output_done.mark_target = pkt->mark_target; data_done.output_done.mark_data = pkt->mark_data; data_done.output_done.stats = pkt->stats; data_done.output_done.offset1 = pkt->offset; data_done.output_done.alloc_len1 = pkt->alloc_len; Loading Loading @@ -892,15 +890,12 @@ static int hfi_process_session_ftb_done( 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 = 0; data_done.output_done.stream_id = pkt->stream_id; data_done.output_done.view_id = pkt->view_id; data_done.output_done.timestamp_hi = pkt->time_stamp_hi; data_done.output_done.timestamp_lo = pkt->time_stamp_lo; data_done.output_done.flags1 = pkt->flags; data_done.output_done.mark_target = pkt->mark_target; data_done.output_done.mark_data = pkt->mark_data; data_done.output_done.stats = pkt->stats; data_done.output_done.alloc_len1 = pkt->alloc_len; data_done.output_done.filled_len1 = pkt->filled_len; Loading @@ -909,7 +904,8 @@ 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_tag2 = pkt->input_tag2; 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 = Loading msm/vidc/msm_vidc.c +49 −12 Original line number Diff line number Diff line Loading @@ -329,6 +329,7 @@ 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; Loading Loading @@ -365,10 +366,17 @@ 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 == INPUT_MPLANE) { msm_comm_store_mark_data(&inst->etb_data, b->index, b->m.planes[0].reserved[3], b->m.planes[0].reserved[4]); if (b->type == INPUT_MPLANE) { client_data = msm_comm_store_client_data(inst, b->m.planes[0].reserved[3]); if (!client_data) { dprintk(VIDC_ERR, "%s: %x: failed to store client data\n", __func__, hash32_ptr(inst->session)); return -EINVAL; } msm_comm_store_input_tag(&inst->etb_data, b->index, client_data->id, 0); } q = msm_comm_get_vb2q(inst, b->type); Loading @@ -394,6 +402,8 @@ 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)) { dprintk(VIDC_ERR, "%s: invalid params, inst %pK\n", Loading Loading @@ -422,13 +432,35 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) b->m.planes[i].reserved[0] = b->m.planes[i].m.fd; b->m.planes[i].reserved[1] = b->m.planes[i].data_offset; } if (inst->session_type == MSM_VIDC_DECODER && b->type == OUTPUT_MPLANE) { msm_comm_fetch_mark_data(&inst->fbd_data, b->index, /** * 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) { rc = msm_comm_fetch_input_tag(&inst->fbd_data, b->index, &input_tag, &input_tag2); if (rc) { dprintk(VIDC_ERR, "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[3], &b->m.planes[0].reserved[4]); } } return rc; } Loading Loading @@ -1553,6 +1585,7 @@ 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); Loading Loading @@ -1668,6 +1701,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->client_data); DEINIT_MSM_VIDC_LIST(&inst->etb_data); DEINIT_MSM_VIDC_LIST(&inst->fbd_data); DEINIT_MSM_VIDC_LIST(&inst->window_data); Loading Loading @@ -1738,9 +1772,11 @@ 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)) if (msm_comm_release_input_tag(inst)) dprintk(VIDC_ERR, "Failed to release mark_data buffers\n"); "Failed to release input_tag buffers\n"); msm_comm_release_client_data(inst); msm_comm_release_window_data(inst); Loading Loading @@ -1802,6 +1838,7 @@ 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->client_data); DEINIT_MSM_VIDC_LIST(&inst->etb_data); DEINIT_MSM_VIDC_LIST(&inst->fbd_data); DEINIT_MSM_VIDC_LIST(&inst->window_data); Loading msm/vidc/msm_vidc_common.c +138 −27 Original line number Diff line number Diff line Loading @@ -2120,8 +2120,10 @@ static void handle_session_flush(enum hal_command_response cmd, void *data) goto exit; } if (flush_type == HAL_FLUSH_ALL) if (flush_type == HAL_FLUSH_ALL) { msm_comm_release_window_data(inst); msm_comm_release_client_data(inst); } dprintk(VIDC_HIGH, "Notify flush complete, flush_type: %x\n", flush_type); Loading Loading @@ -2653,10 +2655,9 @@ 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); } msm_comm_store_input_tag(&inst->fbd_data, vb->index, fill_buf_done->input_tag, fill_buf_done->input_tag2); if (inst->session_type == MSM_VIDC_ENCODER) { msm_comm_store_filled_length(&inst->fbd_data, vb->index, fill_buf_done->filled_len1); Loading @@ -2677,6 +2678,8 @@ static void handle_fbd(enum hal_command_response cmd, void *data) mbuf->vvb.flags |= V4L2_BUF_FLAG_KEYFRAME; if (fill_buf_done->flags1 & HAL_BUFFERFLAG_DATACORRUPT) mbuf->vvb.flags |= V4L2_BUF_FLAG_DATA_CORRUPT; if (fill_buf_done->flags1 & HAL_BUFFERFLAG_ENDOFSUBFRAME) mbuf->vvb.flags |= V4L2_BUF_FLAG_END_OF_SUBFRAME; switch (fill_buf_done->picture_type) { case HFI_PICTURE_TYPE_P: mbuf->vvb.flags |= V4L2_BUF_FLAG_PFRAME; Loading Loading @@ -4039,7 +4042,7 @@ 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.input_tag = 0; data.buffer_type = HAL_BUFFER_INPUT; data.filled_len = 0; data.offset = 0; Loading Loading @@ -4186,6 +4189,7 @@ static void populate_frame_data(struct vidc_frame_data *data, struct v4l2_format *f = NULL; struct vb2_buffer *vb; struct vb2_v4l2_buffer *vbuf; u32 itag = 0, itag2 = 0; if (!inst || !mbuf || !data) { dprintk(VIDC_ERR, "%s: invalid params %pK %pK %pK\n", Loading @@ -4203,7 +4207,7 @@ 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; data->input_tag = 0; if (vb->type == INPUT_MPLANE) { data->buffer_type = HAL_BUFFER_INPUT; Loading @@ -4216,10 +4220,10 @@ static void populate_frame_data(struct vidc_frame_data *data, if (vbuf->flags & V4L2_BUF_FLAG_CODECCONFIG) data->flags |= HAL_BUFFERFLAG_CODECCONFIG; if (inst->session_type == MSM_VIDC_DECODER) { msm_comm_fetch_mark_data(&inst->etb_data, vb->index, &data->mark_data, &data->mark_target); } msm_comm_fetch_input_tag(&inst->etb_data, vb->index, &itag, &itag2); data->input_tag = itag; f = &inst->fmts[INPUT_PORT].v4l2_fmt; } else if (vb->type == OUTPUT_MPLANE) { data->buffer_type = msm_comm_get_hal_output_buffer(inst); Loading Loading @@ -6961,6 +6965,110 @@ 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; if (!inst) { dprintk(VIDC_ERR, "%s: invalid params %pK %un", __func__, inst, itag); return NULL; } mutex_lock(&inst->client_data.lock); data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) { dprintk(VIDC_ERR, "No memory left to allocate tag data"); goto exit; } /** * 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; INIT_LIST_HEAD(&data->list); data->id = inst->etb_counter++; data->input_tag = itag; list_add_tail(&data->list, &inst->client_data.list); 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) { dprintk(VIDC_ERR, "%s: invalid params %pK %x %x\n", __func__, inst, otag, otag2); return; } 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; if (remove) { list_del(&temp->list); kfree(temp); } found_itag = true; /** * Some interlace clips, both BF & TP 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; break; } } else if (temp->id == itag2) { *otag2 = temp->input_tag; found_itag2 = true; if (remove) { list_del(&temp->list); kfree(temp); } } if (found_itag && found_itag2) break; } mutex_unlock(&inst->client_data.lock); if (!found_itag || !found_itag2) { dprintk(VIDC_ERR, "%s: %x: client data not found - %u, %u\n", __func__, hash32_ptr(inst->session), itag, itag2); } } void msm_comm_release_client_data(struct msm_vidc_inst *inst) { struct msm_vidc_client_data *temp, *next; if (!inst) { dprintk(VIDC_ERR, "%s: invalid params %pK\n", __func__, inst); return; } mutex_lock(&inst->client_data.lock); list_for_each_entry_safe(temp, next, &inst->client_data.list, list) { list_del(&temp->list); kfree(temp); } mutex_unlock(&inst->client_data.lock); } void msm_comm_store_filled_length(struct msm_vidc_list *data_list, u32 index, u32 filled_length) { Loading Loading @@ -7018,8 +7126,8 @@ void msm_comm_fetch_filled_length(struct msm_vidc_list *data_list, mutex_unlock(&data_list->lock); } void msm_comm_store_mark_data(struct msm_vidc_list *data_list, u32 index, u32 mark_data, u32 mark_target) void msm_comm_store_input_tag(struct msm_vidc_list *data_list, u32 index, u32 itag, u32 itag2) { struct msm_vidc_buf_data *pdata = NULL; bool found = false; Loading @@ -7033,8 +7141,8 @@ void msm_comm_store_mark_data(struct msm_vidc_list *data_list, 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; pdata->input_tag = itag; pdata->input_tag2 = itag2; found = true; break; } Loading @@ -7047,8 +7155,8 @@ void msm_comm_store_mark_data(struct msm_vidc_list *data_list, goto exit; } pdata->index = index; pdata->mark_data = mark_data; pdata->mark_target = mark_target; pdata->input_tag = itag; pdata->input_tag2 = itag2; list_add_tail(&pdata->list, &data_list->list); } Loading @@ -7056,32 +7164,35 @@ void msm_comm_store_mark_data(struct msm_vidc_list *data_list, 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) int msm_comm_fetch_input_tag(struct msm_vidc_list *data_list, u32 index, u32 *itag, u32 *itag2) { struct msm_vidc_buf_data *pdata = NULL; int rc = 0; if (!data_list || !mark_data || !mark_target) { if (!data_list || !itag || !itag2) { dprintk(VIDC_ERR, "%s: invalid params %pK %pK %pK\n", __func__, data_list, mark_data, mark_target); return; __func__, data_list, itag, itag2); return -EINVAL; } *mark_data = *mark_target = 0; *itag = *itag2 = 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; *itag = pdata->input_tag; *itag2 = pdata->input_tag2; /* clear after fetch */ pdata->mark_data = pdata->mark_target = 0; pdata->input_tag = pdata->input_tag2 = 0; break; } } mutex_unlock(&data_list->lock); return rc; } int msm_comm_release_mark_data(struct msm_vidc_inst *inst) int msm_comm_release_input_tag(struct msm_vidc_inst *inst) { struct msm_vidc_buf_data *pdata, *next; Loading msm/vidc/msm_vidc_common.h +10 −5 Original line number Diff line number Diff line Loading @@ -295,11 +295,16 @@ void msm_comm_store_filled_length(struct msm_vidc_list *data_list, u32 index, u32 filled_length); void msm_comm_fetch_filled_length(struct msm_vidc_list *data_list, u32 index, u32 *filled_length); 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); void msm_comm_store_input_tag(struct msm_vidc_list *data_list, u32 index, u32 itag, u32 itag2); int msm_comm_fetch_input_tag(struct msm_vidc_list *data_list, u32 index, u32 *itag, u32 *itag2); 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); 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, Loading Loading
msm/vidc/hfi_packetization.c +2 −6 Original line number Diff line number Diff line Loading @@ -632,12 +632,10 @@ int create_pkt_cmd_session_etb_decoder( pkt->time_stamp_hi = upper_32_bits(input_frame->timestamp); pkt->time_stamp_lo = lower_32_bits(input_frame->timestamp); pkt->flags = input_frame->flags; pkt->mark_target = input_frame->mark_target; pkt->mark_data = input_frame->mark_data; 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", Loading Loading @@ -667,12 +665,10 @@ int create_pkt_cmd_session_etb_encoder( pkt->time_stamp_hi = upper_32_bits(input_frame->timestamp); pkt->time_stamp_lo = lower_32_bits(input_frame->timestamp); pkt->flags = input_frame->flags; pkt->mark_target = input_frame->mark_target; pkt->mark_data = input_frame->mark_data; 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; Loading
msm/vidc/hfi_response_handler.c +4 −8 Original line number Diff line number Diff line Loading @@ -780,7 +780,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, Loading Loading @@ -857,13 +857,11 @@ static int hfi_process_session_ftb_done( 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 = 0; data_done.output_done.input_tag = pkt->input_tag; data_done.output_done.timestamp_hi = pkt->time_stamp_hi; data_done.output_done.timestamp_lo = pkt->time_stamp_lo; data_done.output_done.flags1 = pkt->flags; data_done.output_done.mark_target = pkt->mark_target; data_done.output_done.mark_data = pkt->mark_data; data_done.output_done.stats = pkt->stats; data_done.output_done.offset1 = pkt->offset; data_done.output_done.alloc_len1 = pkt->alloc_len; Loading Loading @@ -892,15 +890,12 @@ static int hfi_process_session_ftb_done( 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 = 0; data_done.output_done.stream_id = pkt->stream_id; data_done.output_done.view_id = pkt->view_id; data_done.output_done.timestamp_hi = pkt->time_stamp_hi; data_done.output_done.timestamp_lo = pkt->time_stamp_lo; data_done.output_done.flags1 = pkt->flags; data_done.output_done.mark_target = pkt->mark_target; data_done.output_done.mark_data = pkt->mark_data; data_done.output_done.stats = pkt->stats; data_done.output_done.alloc_len1 = pkt->alloc_len; data_done.output_done.filled_len1 = pkt->filled_len; Loading @@ -909,7 +904,8 @@ 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_tag2 = pkt->input_tag2; 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 = Loading
msm/vidc/msm_vidc.c +49 −12 Original line number Diff line number Diff line Loading @@ -329,6 +329,7 @@ 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; Loading Loading @@ -365,10 +366,17 @@ 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 == INPUT_MPLANE) { msm_comm_store_mark_data(&inst->etb_data, b->index, b->m.planes[0].reserved[3], b->m.planes[0].reserved[4]); if (b->type == INPUT_MPLANE) { client_data = msm_comm_store_client_data(inst, b->m.planes[0].reserved[3]); if (!client_data) { dprintk(VIDC_ERR, "%s: %x: failed to store client data\n", __func__, hash32_ptr(inst->session)); return -EINVAL; } msm_comm_store_input_tag(&inst->etb_data, b->index, client_data->id, 0); } q = msm_comm_get_vb2q(inst, b->type); Loading @@ -394,6 +402,8 @@ 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)) { dprintk(VIDC_ERR, "%s: invalid params, inst %pK\n", Loading Loading @@ -422,13 +432,35 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) b->m.planes[i].reserved[0] = b->m.planes[i].m.fd; b->m.planes[i].reserved[1] = b->m.planes[i].data_offset; } if (inst->session_type == MSM_VIDC_DECODER && b->type == OUTPUT_MPLANE) { msm_comm_fetch_mark_data(&inst->fbd_data, b->index, /** * 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) { rc = msm_comm_fetch_input_tag(&inst->fbd_data, b->index, &input_tag, &input_tag2); if (rc) { dprintk(VIDC_ERR, "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[3], &b->m.planes[0].reserved[4]); } } return rc; } Loading Loading @@ -1553,6 +1585,7 @@ 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); Loading Loading @@ -1668,6 +1701,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->client_data); DEINIT_MSM_VIDC_LIST(&inst->etb_data); DEINIT_MSM_VIDC_LIST(&inst->fbd_data); DEINIT_MSM_VIDC_LIST(&inst->window_data); Loading Loading @@ -1738,9 +1772,11 @@ 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)) if (msm_comm_release_input_tag(inst)) dprintk(VIDC_ERR, "Failed to release mark_data buffers\n"); "Failed to release input_tag buffers\n"); msm_comm_release_client_data(inst); msm_comm_release_window_data(inst); Loading Loading @@ -1802,6 +1838,7 @@ 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->client_data); DEINIT_MSM_VIDC_LIST(&inst->etb_data); DEINIT_MSM_VIDC_LIST(&inst->fbd_data); DEINIT_MSM_VIDC_LIST(&inst->window_data); Loading
msm/vidc/msm_vidc_common.c +138 −27 Original line number Diff line number Diff line Loading @@ -2120,8 +2120,10 @@ static void handle_session_flush(enum hal_command_response cmd, void *data) goto exit; } if (flush_type == HAL_FLUSH_ALL) if (flush_type == HAL_FLUSH_ALL) { msm_comm_release_window_data(inst); msm_comm_release_client_data(inst); } dprintk(VIDC_HIGH, "Notify flush complete, flush_type: %x\n", flush_type); Loading Loading @@ -2653,10 +2655,9 @@ 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); } msm_comm_store_input_tag(&inst->fbd_data, vb->index, fill_buf_done->input_tag, fill_buf_done->input_tag2); if (inst->session_type == MSM_VIDC_ENCODER) { msm_comm_store_filled_length(&inst->fbd_data, vb->index, fill_buf_done->filled_len1); Loading @@ -2677,6 +2678,8 @@ static void handle_fbd(enum hal_command_response cmd, void *data) mbuf->vvb.flags |= V4L2_BUF_FLAG_KEYFRAME; if (fill_buf_done->flags1 & HAL_BUFFERFLAG_DATACORRUPT) mbuf->vvb.flags |= V4L2_BUF_FLAG_DATA_CORRUPT; if (fill_buf_done->flags1 & HAL_BUFFERFLAG_ENDOFSUBFRAME) mbuf->vvb.flags |= V4L2_BUF_FLAG_END_OF_SUBFRAME; switch (fill_buf_done->picture_type) { case HFI_PICTURE_TYPE_P: mbuf->vvb.flags |= V4L2_BUF_FLAG_PFRAME; Loading Loading @@ -4039,7 +4042,7 @@ 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.input_tag = 0; data.buffer_type = HAL_BUFFER_INPUT; data.filled_len = 0; data.offset = 0; Loading Loading @@ -4186,6 +4189,7 @@ static void populate_frame_data(struct vidc_frame_data *data, struct v4l2_format *f = NULL; struct vb2_buffer *vb; struct vb2_v4l2_buffer *vbuf; u32 itag = 0, itag2 = 0; if (!inst || !mbuf || !data) { dprintk(VIDC_ERR, "%s: invalid params %pK %pK %pK\n", Loading @@ -4203,7 +4207,7 @@ 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; data->input_tag = 0; if (vb->type == INPUT_MPLANE) { data->buffer_type = HAL_BUFFER_INPUT; Loading @@ -4216,10 +4220,10 @@ static void populate_frame_data(struct vidc_frame_data *data, if (vbuf->flags & V4L2_BUF_FLAG_CODECCONFIG) data->flags |= HAL_BUFFERFLAG_CODECCONFIG; if (inst->session_type == MSM_VIDC_DECODER) { msm_comm_fetch_mark_data(&inst->etb_data, vb->index, &data->mark_data, &data->mark_target); } msm_comm_fetch_input_tag(&inst->etb_data, vb->index, &itag, &itag2); data->input_tag = itag; f = &inst->fmts[INPUT_PORT].v4l2_fmt; } else if (vb->type == OUTPUT_MPLANE) { data->buffer_type = msm_comm_get_hal_output_buffer(inst); Loading Loading @@ -6961,6 +6965,110 @@ 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; if (!inst) { dprintk(VIDC_ERR, "%s: invalid params %pK %un", __func__, inst, itag); return NULL; } mutex_lock(&inst->client_data.lock); data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) { dprintk(VIDC_ERR, "No memory left to allocate tag data"); goto exit; } /** * 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; INIT_LIST_HEAD(&data->list); data->id = inst->etb_counter++; data->input_tag = itag; list_add_tail(&data->list, &inst->client_data.list); 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) { dprintk(VIDC_ERR, "%s: invalid params %pK %x %x\n", __func__, inst, otag, otag2); return; } 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; if (remove) { list_del(&temp->list); kfree(temp); } found_itag = true; /** * Some interlace clips, both BF & TP 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; break; } } else if (temp->id == itag2) { *otag2 = temp->input_tag; found_itag2 = true; if (remove) { list_del(&temp->list); kfree(temp); } } if (found_itag && found_itag2) break; } mutex_unlock(&inst->client_data.lock); if (!found_itag || !found_itag2) { dprintk(VIDC_ERR, "%s: %x: client data not found - %u, %u\n", __func__, hash32_ptr(inst->session), itag, itag2); } } void msm_comm_release_client_data(struct msm_vidc_inst *inst) { struct msm_vidc_client_data *temp, *next; if (!inst) { dprintk(VIDC_ERR, "%s: invalid params %pK\n", __func__, inst); return; } mutex_lock(&inst->client_data.lock); list_for_each_entry_safe(temp, next, &inst->client_data.list, list) { list_del(&temp->list); kfree(temp); } mutex_unlock(&inst->client_data.lock); } void msm_comm_store_filled_length(struct msm_vidc_list *data_list, u32 index, u32 filled_length) { Loading Loading @@ -7018,8 +7126,8 @@ void msm_comm_fetch_filled_length(struct msm_vidc_list *data_list, mutex_unlock(&data_list->lock); } void msm_comm_store_mark_data(struct msm_vidc_list *data_list, u32 index, u32 mark_data, u32 mark_target) void msm_comm_store_input_tag(struct msm_vidc_list *data_list, u32 index, u32 itag, u32 itag2) { struct msm_vidc_buf_data *pdata = NULL; bool found = false; Loading @@ -7033,8 +7141,8 @@ void msm_comm_store_mark_data(struct msm_vidc_list *data_list, 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; pdata->input_tag = itag; pdata->input_tag2 = itag2; found = true; break; } Loading @@ -7047,8 +7155,8 @@ void msm_comm_store_mark_data(struct msm_vidc_list *data_list, goto exit; } pdata->index = index; pdata->mark_data = mark_data; pdata->mark_target = mark_target; pdata->input_tag = itag; pdata->input_tag2 = itag2; list_add_tail(&pdata->list, &data_list->list); } Loading @@ -7056,32 +7164,35 @@ void msm_comm_store_mark_data(struct msm_vidc_list *data_list, 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) int msm_comm_fetch_input_tag(struct msm_vidc_list *data_list, u32 index, u32 *itag, u32 *itag2) { struct msm_vidc_buf_data *pdata = NULL; int rc = 0; if (!data_list || !mark_data || !mark_target) { if (!data_list || !itag || !itag2) { dprintk(VIDC_ERR, "%s: invalid params %pK %pK %pK\n", __func__, data_list, mark_data, mark_target); return; __func__, data_list, itag, itag2); return -EINVAL; } *mark_data = *mark_target = 0; *itag = *itag2 = 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; *itag = pdata->input_tag; *itag2 = pdata->input_tag2; /* clear after fetch */ pdata->mark_data = pdata->mark_target = 0; pdata->input_tag = pdata->input_tag2 = 0; break; } } mutex_unlock(&data_list->lock); return rc; } int msm_comm_release_mark_data(struct msm_vidc_inst *inst) int msm_comm_release_input_tag(struct msm_vidc_inst *inst) { struct msm_vidc_buf_data *pdata, *next; Loading
msm/vidc/msm_vidc_common.h +10 −5 Original line number Diff line number Diff line Loading @@ -295,11 +295,16 @@ void msm_comm_store_filled_length(struct msm_vidc_list *data_list, u32 index, u32 filled_length); void msm_comm_fetch_filled_length(struct msm_vidc_list *data_list, u32 index, u32 *filled_length); 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); void msm_comm_store_input_tag(struct msm_vidc_list *data_list, u32 index, u32 itag, u32 itag2); int msm_comm_fetch_input_tag(struct msm_vidc_list *data_list, u32 index, u32 *itag, u32 *itag2); 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); 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, Loading