}
static void vpu_dec_receive_ts(struct vpu_ctx *ctx,
- struct v4l2_buffer *buf,
+ struct vb2_buffer *vb,
int size)
{
+ struct vb2_v4l2_buffer *vbuf;
TSM_TIMESTAMP input_ts;
- if (buf->flags & V4L2_NXP_BUF_FLAG_TIMESTAMP_INVALID) {
+ if (!ctx || !vb)
+ return;
+
+ vbuf = to_vb2_v4l2_buffer(vb);
+ if (vbuf->flags & V4L2_NXP_BUF_FLAG_TIMESTAMP_INVALID) {
vpu_dbg(LVL_BIT_TS, "[INPUT TS]Invalid timestamp, drop it\n");
return;
}
- input_ts = timeval_to_ns(&buf->timestamp);
+ input_ts = vb->timestamp;
if (input_ts < 0)
input_ts = TSM_TIMESTAMP_NONE;
- vpu_dbg(LVL_BIT_TS, "[INPUT TS]%32lld\n", input_ts);
if (ctx->tsm_sync_flag) {
+ vpu_dbg(LVL_BIT_TS, "resyncTSManager\n");
resyncTSManager(ctx->tsm, input_ts, tsm_mode);
ctx->tsm_sync_flag = false;
}
+ vpu_dbg(LVL_BIT_TS, "[INPUT TS]%32lld\n", input_ts);
TSManagerReceive2(ctx->tsm, input_ts, size);
ctx->total_ts_bytes += size;
vpu_dbg(LVL_BIT_FRAME_BYTES, "[%d]receive bytes : %8d / %16ld\n",
ctx->total_qbuf_bytes);
q_data = &ctx->q_data[V4L2_SRC];
- vpu_dec_receive_ts(ctx, buf, buf->m.planes[0].bytesused);
v4l2_update_stream_addr(ctx, 0);
} else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
q_data = &ctx->q_data[V4L2_DST];
buffer = kzalloc(SCODE_SIZE, GFP_KERNEL); //for eos data
if (!buffer) {
vpu_dbg(LVL_ERR, "error: eos buffer alloc fail\n");
- return -1;
+ return 0;
}
atomic64_add(SCODE_SIZE, &ctx->statistic.total_alloc_size);
plbuffer = (uint32_t *)buffer;
pbbuffer = (uint8_t *)(ctx->stream_buffer.dma_virt + wptr - start);
else {
vpu_dbg(LVL_ERR, "error: return wptr(0x%x), start(0x%x) is not valid\n", wptr, start);
- return -1;
+ goto error;
}
// Word align
int i;
if (end%4 != 0) {
vpu_dbg(LVL_ERR, "end address of stream not aligned by 4 bytes !\n");
- return -1;
+ goto error;
}
pad_bytes = 4 - (((u_int64)pbbuffer)%4);
for (i = 0; i < pad_bytes; i++)
} else {
/* all other standards do not support the frame flush mechanism so just return */
vpu_dbg(LVL_WARN, "warning: format(%d) not support frame flush mechanism !\n", q_data->vdec_std);
- return 0;
+ goto error;
}
}
plbuffer[0] = last;
vpu_dbg(LVL_INFO, "%s() done type (%d) MCX address virt=%p, phy=0x%x, index=%d\n",
__func__, eScodeType, pStrBufDesc, dev->shared_mem.pSharedInterface->pStreamBuffDesc[ctx->str_index][uStrBufIdx], ctx->str_index);
return pad_bytes;
+error:
+ kfree(buffer);
+ atomic64_sub(SCODE_SIZE, &ctx->statistic.total_alloc_size);
+ return 0;
}
static int add_scode(struct vpu_ctx *ctx, u_int32 uStrBufIdx, VPU_PADDING_SCODE_TYPE eScodeType, bool bUpdateWr)
size = add_scode_vpu(ctx, uStrBufIdx, eScodeType, bUpdateWr);
if (size > 0)
set_pic_end_flag(ctx);
+ else
+ size = 0;
mutex_unlock(&ctx->instance_mutex);
return size;
}
MU_SendMessage(ctx->dev->mu_base_virtaddr, 0, COMMAND);
}
-static void transfer_buffer_to_firmware(struct vpu_ctx *ctx, void *input_buffer, uint32_t buffer_size, uint32_t vdec_std)
+static u32 transfer_buffer_to_firmware(struct vpu_ctx *ctx,
+ void *input_buffer,
+ uint32_t buffer_size,
+ uint32_t vdec_std)
{
pSTREAM_BUFFER_DESCRIPTOR_TYPE pStrBufDesc;
u_int32 uStrBufIdx = 0; //set to be default 0, FIX_ME later
if (ctx->stream_buffer.dma_size < buffer_size + MIN_SPACE) {
vpu_dbg(LVL_ERR, "circular buffer size is set too small\n");
- return;
+ return 0;
}
if (!ctx->start_code_bypass)
length = insert_scode_4_seq(ctx, input_buffer, ctx->stream_buffer.dma_virt, vdec_std, buffer_size);
pCodecPara = (MediaIPFW_Video_CodecParams *)ctx->dev->shared_mem.codec_mem_vir;
if (ctx->b_dis_reorder) {
/* set the shared memory space control with this */
- add_scode(ctx, 0, BUFFLUSH_PADDING_TYPE, true);
+ length += add_scode(ctx, 0, BUFFLUSH_PADDING_TYPE, true);
record_log_info(ctx, LOG_PADDING, 0, 0);
pCodecPara[ctx->str_index].uDispImm = 1;
} else {
ctx->frm_dec_delay = 1;
ctx->frm_total_num = 1;
fill_stream_buffer_info(ctx);
+
+ return length;
}
static void v4l2_transfer_buffer_to_firmware(struct queue_data *This, struct vb2_buffer *vb)
struct vb2_data_req *p_data_req;
void *data_mapped;
uint32_t buffer_size = vb->planes[0].bytesused;
+ u32 frame_bytes;
int ret;
data_mapped = (void *)vb2_plane_vaddr(vb, 0);
vpu_dbg(LVL_ERR, "alloc vpu buffer fail\n");
return;
}
- transfer_buffer_to_firmware(ctx, data_mapped, buffer_size, This->vdec_std);
+ frame_bytes = transfer_buffer_to_firmware(ctx,
+ data_mapped,
+ buffer_size,
+ This->vdec_std);
#ifdef HANDLE_EOS
if (vb->planes[0].bytesused < vb->planes[0].length)
vpu_dbg(LVL_INFO, "v4l2_transfer_buffer_to_firmware - set stream_feed_complete - DEBUG 1\n");
v4l2_vpu_send_cmd(ctx, ctx->str_index, VID_API_CMD_START, 0, NULL);
p_data_req = list_first_entry(&This->drv_q,
typeof(*p_data_req), list);
+ vpu_dec_receive_ts(ctx, p_data_req->vb2_buf, frame_bytes);
list_del(&p_data_req->list);
p_data_req->queued = false;
if (p_data_req->vb2_buf)
uint32_t start;
uint32_t end;
void *wptr_virt;
- uint32_t ret = 1;
u_int32 length = 0;
vpu_dbg(LVL_BIT_FUNC, "enter %s\n", __func__);
vpu_dbg(LVL_BIT_FUNC, "update address virt=%p, phy=0x%x, index=%d\n",
pStrBufDesc, dev->shared_mem.pSharedInterface->pStreamBuffDesc[ctx->str_index][uStrBufIdx], ctx->str_index);
- return ret;
+ return length + buffer_size;
}
+
static int update_stream_addr_vpu(struct vpu_ctx *ctx, void *input_buffer, uint32_t buffer_size, uint32_t uStrBufIdx)
{
int size = 0;
struct queue_data *This = &ctx->q_data[V4L2_SRC];
void *input_buffer;
uint32_t buffer_size;
+ u32 frame_bytes;
down(&This->drv_q_lock);
while (!list_empty(&This->drv_q)) {
buffer_size = p_data_req->vb2_buf->planes[0].bytesused;
input_buffer = (void *)vb2_plane_vaddr(p_data_req->vb2_buf, 0);
- if (!update_stream_addr_vpu(ctx, input_buffer, buffer_size, uStrBufIdx)) {
+ frame_bytes = update_stream_addr_vpu(ctx,
+ input_buffer,
+ buffer_size,
+ uStrBufIdx);
+ if (!frame_bytes) {
up(&This->drv_q_lock);
vpu_dbg(LVL_INFO, " %s no space to write\n", __func__);
return;
if (ctx->b_dis_reorder) {
/* frame successfully written into the stream buffer if in special low latency mode
mark that this frame should be flushed for decode immediately */
- add_scode(ctx, 0, BUFFLUSH_PADDING_TYPE, true);
+ frame_bytes += add_scode(ctx,
+ 0,
+ BUFFLUSH_PADDING_TYPE,
+ true);
record_log_info(ctx, LOG_PADDING, 0, 0);
}
ctx->frm_dec_delay++;
if (buffer_size < p_data_req->vb2_buf->planes[0].length)
vpu_dbg(LVL_INFO, "v4l2_transfer_buffer_to_firmware - set stream_feed_complete - DEBUG 2\n");
#endif
+ vpu_dec_receive_ts(ctx, p_data_req->vb2_buf, frame_bytes);
list_del(&p_data_req->list);
p_data_req->queued = false;
if (p_data_req->vb2_buf)