diff --git a/drivers/mxc/vpu_malone/Makefile b/drivers/mxc/vpu_malone/Makefile index fec4d43b361f..a30f8ee81dda 100644 --- a/drivers/mxc/vpu_malone/Makefile +++ b/drivers/mxc/vpu_malone/Makefile @@ -11,7 +11,6 @@ vpu-malone-objs = vpu_b0.o \ vpu_rpc.o \ insert_startcode.o \ vpu_debug_log.o \ - vpu_ts.o \ vpu_mu.o \ vpu_pm.o diff --git a/drivers/mxc/vpu_malone/mediasys_types.h b/drivers/mxc/vpu_malone/mediasys_types.h index b2c531694a8c..e6007e821dac 100644 --- a/drivers/mxc/vpu_malone/mediasys_types.h +++ b/drivers/mxc/vpu_malone/mediasys_types.h @@ -174,6 +174,7 @@ typedef enum { VID_API_CMD_DBG_DUMP_LOG = 0x1F, /* Begin Encode CMDs */ VID_API_CMD_YUV_READY = 0x20, + VID_API_CMD_TS = 0x21, VID_API_CMD_FIRM_RESET = 0x40, @@ -684,8 +685,13 @@ typedef struct { u_int32 uFWOffset; u_int32 uMaxDecoderStreams; MediaIPFW_Video_DbgLogDesc DbgLogDesc; - MediaIPFW_Video_FrameBuffer StreamFrameBuffer[VID_API_NUM_STREAMS]; - MediaIPFW_Video_FrameBuffer StreamDCPBuffer[VID_API_NUM_STREAMS]; + union { + struct { + MediaIPFW_Video_FrameBuffer StreamFrameBuffer[VID_API_NUM_STREAMS]; + MediaIPFW_Video_FrameBuffer StreamDCPBuffer[VID_API_NUM_STREAMS]; + }; + BUFFER_DESCRIPTOR_TYPE StreamApiCmdBufferDesc[VID_API_NUM_STREAMS]; + }; MediaIPFW_Video_UData UDataBuffer[VID_API_NUM_STREAMS]; MediaIPFW_Video_BufDesc DebugBufferDesc; MediaIPFW_Video_BufDesc EngAccessBufferDesc[VID_API_NUM_STREAMS]; diff --git a/drivers/mxc/vpu_malone/vpu_b0.c b/drivers/mxc/vpu_malone/vpu_b0.c index 46397058e6d3..b780c1f411fb 100644 --- a/drivers/mxc/vpu_malone/vpu_b0.c +++ b/drivers/mxc/vpu_malone/vpu_b0.c @@ -45,12 +45,18 @@ #include "vpu_b0.h" #include "insert_startcode.h" #include "vpu_debug_log.h" -#include "vpu_ts.h" #include "vpu_pm.h" #include "vpu_mu.h" +#ifndef TSM_TIMESTAMP_NONE +#define TSM_TIMESTAMP_NONE -1L +#endif +#ifndef TSM_TS_IS_VALID +#define TSM_TS_IS_VALID(ts) ((ts) >= 0) +#endif + unsigned int vpu_dbg_level_decoder = LVL_WARN; -static int vpu_frm_depth = INVALID_FRAME_DEPTH; +static int vpu_frm_depth = VPU_FRAME_DEPTH_DEFAULT; static int vpu_log_depth = DEFAULT_LOG_DEPTH; static int vpu_max_bufsize = MAX_BUFFER_SIZE; static int vpu_frmdbg_ena = DEFAULT_FRMDBG_ENABLE; @@ -59,9 +65,6 @@ static int vpu_frmdbg_raw = 1; static int vpu_dbe_num = 1; static int vpu_frmcrcdump_ena; static int stream_buffer_threshold = 0x10000; -static int tsm_mode = MODE_AI; -static int tsm_buffer_size = 1024; -static int tsm_use_consumed_length = 1; static int precheck_show_bytes; static int vpu_show_perf_ena; static int vpu_show_perf_idx = (1 << VPU_MAX_NUM_STREAMS) - 1; @@ -133,6 +136,7 @@ static char *cmd2str[] = { "VID_API_CMD_DBG_STOP_LOG", "VID_API_CMD_DBG_DUMP_LOG", "VID_API_CMD_YUV_READY", /*0x20*/ + "VID_API_CMD_TS", }; static char *event2str[] = { @@ -279,7 +283,7 @@ static void count_cmd(struct vpu_statistic *statistic, u32 cmdid) if (cmdid < ARRAY_SIZE(cmd2str)) statistic->cmd[cmdid]++; else - statistic->cmd[VID_API_CMD_YUV_READY + 1]++; + statistic->cmd[VID_API_CMD_TS + 1]++; statistic->current_cmd = cmdid; ktime_get_raw_ts64(&statistic->ts_cmd); } @@ -1528,7 +1532,8 @@ static void vpu_dec_receive_ts(struct vpu_ctx *ctx, int size) { struct vb2_v4l2_buffer *vbuf; - TSM_TIMESTAMP input_ts; + s64 input_ts; + u32 data[3]; if (!ctx || !vb) return; @@ -1548,31 +1553,25 @@ static void vpu_dec_receive_ts(struct vpu_ctx *ctx, if (TSM_TS_IS_VALID(input_ts) && input_ts > ctx->output_ts) ctx->output_ts = input_ts; - if (down_interruptible(&ctx->tsm_lock)) { - vpu_err("%s() get tsm lock fail\n", __func__); - return; - } - if (is_codec_config_data(vb) && !TSM_TS_IS_VALID(input_ts)) { vpu_dbg(LVL_BIT_TS, "[INPUT TS]codec data\n"); ctx->extra_size += size; - up(&ctx->tsm_lock); return; } - if (ctx->tsm_sync_flag) { - vpu_dbg(LVL_BIT_TS, "resyncTSManager\n"); - resyncTSManager(ctx->tsm, input_ts, tsm_mode); - ctx->tsm_sync_flag = false; - } size += ctx->extra_size; ctx->extra_size = 0; 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->str_index, size, ctx->total_ts_bytes); - up(&ctx->tsm_lock); + + if (input_ts < 0) { + data[0] = (u32)-1; + data[1] = 0; + } else { + data[0] = input_ts / NSEC_PER_SEC; + data[1] = input_ts % NSEC_PER_SEC; + } + data[2] = size; + v4l2_vpu_send_cmd(ctx, ctx->str_index, VID_API_CMD_TS, 3, data); } static int v4l2_ioctl_qbuf(struct file *file, @@ -1618,74 +1617,6 @@ static int v4l2_ioctl_qbuf(struct file *file, return ret; } -static void vpu_dec_send_ts(struct vpu_ctx *ctx, struct v4l2_buffer *buf) -{ - TSM_TIMESTAMP ts; - struct timespec64 ts64; - - if (down_interruptible(&ctx->tsm_lock)) { - vpu_err("%s() get tsm lock fail\n", __func__); - return; - } - - ts = TSManagerSend2(ctx->tsm, NULL); - if (TSM_TS_IS_VALID(ts) && ts < ctx->capture_ts) { - vpu_dbg(LVL_BIT_TS, "revise timestamp: %32lld -> %32lld\n", - ts, ctx->capture_ts); - ts = ctx->capture_ts; - } - vpu_dbg(LVL_BIT_TS, "[OUTPUT TS]%32lld (%lld)\n", - ts, getTSManagerFrameInterval(ctx->tsm)); - ts64 = ns_to_timespec64(ts); - buf->timestamp.tv_sec = ts64.tv_sec; - buf->timestamp.tv_usec = ts64.tv_nsec / NSEC_PER_USEC; - buf->flags |= V4L2_BUF_FLAG_TIMESTAMP_COPY; - - up(&ctx->tsm_lock); - - if (TSM_TS_IS_VALID(ts)) - ctx->capture_ts = ts; -} - -static void vpu_dec_valid_ts(struct vpu_ctx *ctx, - u32 consumed_pic_bytesused, - struct vb2_data_req *p_data_req) -{ - WARN_ON(!ctx || !ctx->tsm); - - if (down_interruptible(&ctx->tsm_lock)) { - vpu_err("%s() get tsm lock fail\n", __func__); - return; - } - - vpu_dbg(LVL_BIT_FRAME_BYTES, "[%d]Valid bytes : %8d / %16ld\n", - ctx->str_index, consumed_pic_bytesused, - ctx->total_consumed_bytes); - TSManagerValid2(ctx->tsm, - consumed_pic_bytesused, - p_data_req ? p_data_req->vb2_buf : NULL); - - up(&ctx->tsm_lock); -} - -static void vpu_dec_skip_ts(struct vpu_ctx *ctx) -{ - TSM_TIMESTAMP ts; - - WARN_ON(!ctx || !ctx->tsm); - - if (down_interruptible(&ctx->tsm_lock)) { - vpu_err("%s() get tsm lock fail\n", __func__); - return; - } - - ts = TSManagerSend2(ctx->tsm, NULL); - - up(&ctx->tsm_lock); - - vpu_dbg(LVL_BIT_TS, "[SKIP TS]%32lld\n", ts); -} - static int v4l2_ioctl_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf @@ -1719,8 +1650,6 @@ static int v4l2_ioctl_dqbuf(struct file *file, if (!V4L2_TYPE_IS_OUTPUT(buf->type) && is_10bit_format(ctx)) buf->reserved = 1; - if (!V4L2_TYPE_IS_OUTPUT(buf->type)) - vpu_dec_send_ts(ctx, buf); if (V4L2_TYPE_IS_OUTPUT(buf->type)) buf->flags &= ~V4L2_NXP_BUF_MASK_FLAGS; @@ -1967,32 +1896,6 @@ static int vpu_dec_v4l2_ioctl_g_parm(struct file *file, void *fh, return 0; } -static void vpu_dec_set_tsm_frame_rate(struct vpu_ctx *ctx) -{ - u32 numerator; - u32 denominator; - - WARN_ON(!ctx || !ctx->tsm); - - if (down_interruptible(&ctx->tsm_lock)) { - vpu_err("%s() get tsm lock fail\n", __func__); - return; - } - numerator = ctx->fixed_frame_interval.numerator; - denominator = ctx->fixed_frame_interval.denominator; - if (numerator && denominator) { - setTSManagerFrameRate(ctx->tsm, denominator, numerator); - goto exit; - } - - numerator = ctx->frame_interval.numerator; - denominator = ctx->frame_interval.denominator; - if (numerator && denominator) - setTSManagerFrameRate(ctx->tsm, denominator, numerator); -exit: - up(&ctx->tsm_lock); -} - static int vpu_dec_v4l2_ioctl_s_parm(struct file *file, void *fh, struct v4l2_streamparm *parm) { @@ -2012,7 +1915,6 @@ static int vpu_dec_v4l2_ioctl_s_parm(struct file *file, void *fh, parm->parm.capture.timeperframe.numerator / gcd; ctx->fixed_frame_interval.denominator = parm->parm.capture.timeperframe.denominator / gcd; - vpu_dec_set_tsm_frame_rate(ctx); mutex_unlock(&ctx->instance_mutex); return 0; @@ -2128,8 +2030,8 @@ static struct v4l2_ctrl_config vpu_custom_s_cfg[] = { .id = V4L2_CID_USER_FRAME_DEPTH, .name = "frame depth ctrl", .type = V4L2_CTRL_TYPE_INTEGER, - .min = -1, - .max = 999, + .min = 1, + .max = VPU_FRAME_DEPTH_MAX, .step = 1, }, { @@ -2497,6 +2399,8 @@ static void update_wptr(struct vpu_ctx *ctx, length = (wptr + size - pStrBufDesc->wptr) % size; ctx->total_write_bytes += length; + vpu_dbg(LVL_BIT_FRAME_BYTES, "[%d]receive bytes : %8d / %16ld\n", + ctx->str_index, length, ctx->total_write_bytes); vpu_dbg(LVL_BIT_WPTR, "ctx[%d] wptr : 0x%08x -> 0x%08x\n", ctx->str_index, pStrBufDesc->wptr, wptr); pStrBufDesc->wptr = wptr; @@ -2776,6 +2680,8 @@ static void vpu_dec_send_cmd(struct vpu_dev *dev, u32 idx, u32 cmdid, { WARN_ON(!dev || idx >= VPU_MAX_NUM_STREAMS); + if (!rpc_check_is_ready(&dev->shared_mem, idx)) + vpu_err("[%d] is not ready\n", idx); mutex_lock(&dev->cmd_mutex); rpc_send_cmd_buf(&dev->shared_mem, idx, cmdid, cmdnum, local_cmddata); mb(); @@ -3014,7 +2920,6 @@ static int send_start_cmd(struct vpu_ctx *ctx) pStrBufDesc->start = ctx->stream_buffer.dma_phy; pStrBufDesc->end = ctx->stream_buffer.dma_phy + ctx->stream_buffer.dma_size; pStrBufDesc->LWM = 0x01; - ctx->pre_pic_end_addr = pStrBufDesc->start; ctx->beginning = pStrBufDesc->start; pSharedInterface->pStreamBuffDesc[ctx->str_index][uStrBufIdx] = @@ -3046,7 +2951,6 @@ static int send_start_cmd(struct vpu_ctx *ctx) v4l2_vpu_send_cmd(ctx, ctx->str_index, VID_API_CMD_START, 0, NULL); ctx->firmware_stopped = false; - ctx->tsm_sync_flag = true; ctx->first_data_flag = true; vpu_calculate_performance(ctx, 0xff, "send start cmd"); @@ -3358,8 +3262,6 @@ static void fill_stream_buffer_info(struct vpu_ctx *ctx) buffer_info->stream_buffer_threshold = frame_threshold[idx]; else buffer_info->stream_buffer_threshold = 0; - - buffer_info->stream_pic_input_count = ctx->frm_total_num; } static void set_pic_end_flag(struct vpu_ctx *ctx) @@ -3386,9 +3288,6 @@ static bool vpu_dec_stream_is_ready(struct vpu_ctx *ctx) if (ctx->fifo_low) return true; - if (ctx->tsm_sync_flag) - return true; - pStrBufDesc = get_str_buffer_desc(ctx); stream_size = got_used_space(pStrBufDesc->wptr, pStrBufDesc->rptr, @@ -3402,15 +3301,11 @@ static bool vpu_dec_stream_is_ready(struct vpu_ctx *ctx) /* *frame depth need to be set by user and then the condition works */ - if (vpu_frm_depth != INVALID_FRAME_DEPTH && - ctx->stream_input_mode == FRAME_LVL) { - if ((getTSManagerPreBufferCnt(ctx->tsm)) >= vpu_frm_depth) + if (vpu_frm_depth > 0 && ctx->stream_input_mode == FRAME_LVL) { + if (ctx->frm_dec_delay >= vpu_frm_depth) return false; } - if ((getTSManagerPreBufferCnt(ctx->tsm)) >= (tsm_buffer_size * 9 / 10)) - return false; - if (ctx->ts_threshold > 0 && TSM_TS_IS_VALID(ctx->output_ts) && TSM_TS_IS_VALID(ctx->capture_ts)) { @@ -3569,11 +3464,14 @@ static void report_buffer_done(struct vpu_ctx *ctx, void *frame_info) u_int32 *FrameInfo = (u_int32 *)frame_info; u_int32 fs_id = FrameInfo[0x0]; uint32_t stride = FrameInfo[3]; + s64 timestamp = ((s32)FrameInfo[9] * NSEC_PER_SEC) + FrameInfo[10]; bool b10BitFormat = is_10bit_format(ctx); int buffer_id; vpu_dbg(LVL_BIT_FUNC, "%s() fs_id=%d, ulFsLumaBase[0]=%x, stride=%d, b10BitFormat=%d, ctx->seqinfo.uBitDepthLuma=%d\n", __func__, fs_id, FrameInfo[1], stride, b10BitFormat, ctx->seqinfo.uBitDepthLuma); + vpu_dbg(LVL_BIT_TS, "[OUTPUT TS]%32lld\n", timestamp); + ctx->capture_ts = timestamp; v4l2_update_stream_addr(ctx, 0); buffer_id = find_buffer_id(ctx, FrameInfo[1]); @@ -3590,7 +3488,6 @@ static void report_buffer_done(struct vpu_ctx *ctx, void *frame_info) set_data_req_status(p_data_req, FRAME_SKIP); up(&This->drv_q_lock); - vpu_dec_skip_ts(ctx); send_skip_event(ctx); ctx->frm_dis_delay--; return; @@ -3613,6 +3510,7 @@ static void report_buffer_done(struct vpu_ctx *ctx, void *frame_info) if (p_data_req->vb2_buf) { p_data_req->vb2_buf->planes[0].bytesused = This->sizeimage[0]; p_data_req->vb2_buf->planes[1].bytesused = This->sizeimage[1]; + p_data_req->vb2_buf->timestamp = timestamp; if (p_data_req->vb2_buf->state == VB2_BUF_STATE_ACTIVE) vb2_buffer_done(p_data_req->vb2_buf, VB2_BUF_STATE_DONE); @@ -3733,69 +3631,6 @@ static void add_buffer_to_queue(struct queue_data *q_data, struct vb2_data_req * data_req->queued = true; } -static u32 correct_consumed_length(struct vpu_ctx *ctx, - u32 consumed_pic_bytesused) -{ - long total_read_bytes; - long delta; - u32 circle_count; - u32 stream_size; - pSTREAM_BUFFER_DESCRIPTOR_TYPE pStrBufDesc; - - pStrBufDesc = get_str_buffer_desc(ctx); - stream_size = got_used_space(pStrBufDesc->wptr, - pStrBufDesc->rptr, - pStrBufDesc->start, - pStrBufDesc->end); - total_read_bytes = ctx->total_write_bytes - stream_size; - delta = total_read_bytes - ctx->total_consumed_bytes; - if (delta < ctx->stream_buffer.dma_size) - return consumed_pic_bytesused; - - circle_count = delta / ctx->stream_buffer.dma_size; - vpu_dbg(LVL_BIT_FRAME_BYTES, - "ctx[%d] cross over %d circles\n", - ctx->str_index, circle_count); - - consumed_pic_bytesused += ctx->stream_buffer.dma_size * circle_count; - ctx->total_consumed_bytes += ctx->stream_buffer.dma_size * circle_count; - - return consumed_pic_bytesused; -} - -static u32 get_consumed_pic_bytesused(struct vpu_ctx *ctx, - u32 pic_start_addr, - u32 pic_end_addr) -{ - u32 consumed_pic_bytesused; - u32 pic_size; - - consumed_pic_bytesused = pic_end_addr + - + ctx->stream_buffer.dma_size - - ctx->pre_pic_end_addr; - consumed_pic_bytesused %= ctx->stream_buffer.dma_size; - pic_size = pic_end_addr + ctx->stream_buffer.dma_size - pic_start_addr; - pic_size %= ctx->stream_buffer.dma_size; - - ctx->total_consumed_bytes += consumed_pic_bytesused; - consumed_pic_bytesused = correct_consumed_length(ctx, - consumed_pic_bytesused); - - vpu_dbg(LVL_BIT_PIC_ADDR, "<0x%08x 0x%08x>, %8d, %8d\n", - pic_start_addr, pic_end_addr, pic_size, consumed_pic_bytesused); - if (consumed_pic_bytesused < pic_size) - vpu_err("ErrorAddr:[%d] Start(0x%x), End(0x%x), preEnd(0x%x)\n", - ctx->str_index, - pic_start_addr, - pic_end_addr, - ctx->pre_pic_end_addr); - - - ctx->pre_pic_end_addr = pic_end_addr; - - return consumed_pic_bytesused; -} - static int parse_frame_interval_from_seqinfo(struct vpu_ctx *ctx, MediaIPFW_Video_SeqInfo *seq_info) { @@ -3814,10 +3649,6 @@ static int parse_frame_interval_from_seqinfo(struct vpu_ctx *ctx, ctx->frame_interval.numerator /= gcd; ctx->frame_interval.denominator /= gcd; - mutex_lock(&ctx->instance_mutex); - vpu_dec_set_tsm_frame_rate(ctx); - mutex_unlock(&ctx->instance_mutex); - return 0; } @@ -4326,12 +4157,11 @@ static void vpu_api_event_handler(struct vpu_ctx *ctx, u_int32 uStrIdx, u_int32 int buffer_id; u_int32 uDecFrmId = event_data[7]; u_int32 uPicStartAddr = event_data[10]; - u_int32 uPicEndAddr = event_data[12]; struct queue_data *This = &ctx->q_data[V4L2_DST]; u_int32 uDpbmcCrc; size_t wr_size; - u32 consumed_pic_bytesused = 0; struct vb2_data_req *p_data_req = NULL; + u32 consumed_count = event_data[13]; if (This->vdec_std == VPU_VIDEO_HEVC) uDpbmcCrc = pPerfDcpInfo->uDBEDpbCRC[0]; @@ -4351,20 +4181,10 @@ static void vpu_api_event_handler(struct vpu_ctx *ctx, u_int32 uStrIdx, u_int32 event_data[0], uPicStartAddr, pQMeterInfo, pPicInfo, pDispInfo, pPerfInfo, pPerfDcpInfo); - down(&ctx->q_data[V4L2_SRC].drv_q_lock); - if (tsm_use_consumed_length) - consumed_pic_bytesused = get_consumed_pic_bytesused(ctx, - uPicStartAddr, - uPicEndAddr); - up(&ctx->q_data[V4L2_SRC].drv_q_lock); - buffer_id = find_buffer_id(ctx, event_data[0]); if (buffer_id == -1) { vpu_err("error: %s() ctx[%d] not find buffer id: %d, addr: 0x%x\n", __func__, ctx->str_index, uDecFrmId, event_data[0]); - vpu_dec_valid_ts(ctx, - consumed_pic_bytesused, - NULL); break; } @@ -4375,18 +4195,20 @@ static void vpu_api_event_handler(struct vpu_ctx *ctx, u_int32 uStrIdx, u_int32 else p_data_req->bfield = true; - vpu_dec_valid_ts(ctx, consumed_pic_bytesused, p_data_req); This->process_count++; - } if (ctx->statistic.event[VID_API_EVENT_PIC_DECODED] == 1) vpu_calculate_performance(ctx, uEvent, "first decoded"); else vpu_calculate_performance(ctx, uEvent, NULL); - ctx->frm_dec_delay--; + if (ctx->frm_dec_delay >= consumed_count) + ctx->frm_dec_delay -= consumed_count; + else + ctx->frm_dec_delay = 0; ctx->fifo_low = false; ctx->frame_decoded = true; v4l2_update_stream_addr(ctx, 0); + } break; case VID_API_EVENT_SEQ_HDR_FOUND: { MediaIPFW_Video_SeqInfo *pSeqInfo = (MediaIPFW_Video_SeqInfo *)dev->shared_mem.seq_mem_vir; @@ -4522,10 +4344,8 @@ static void vpu_api_event_handler(struct vpu_ctx *ctx, u_int32 uStrIdx, u_int32 vpu_dbg(LVL_INFO, "warning: normal release and previous status %s, frame not for display, queue the buffer to list again\n", bufstat[p_data_req->status]); - if (p_data_req->status == FRAME_DECODED) { - vpu_dec_skip_ts(ctx); + if (p_data_req->status == FRAME_DECODED) send_skip_event(ctx); - } } if (p_data_req->status != FRAME_ALLOC) { set_data_req_status(p_data_req, FRAME_RELEASE); @@ -4607,20 +4427,14 @@ static void vpu_api_event_handler(struct vpu_ctx *ctx, u_int32 uStrIdx, u_int32 queue->qbuf_count, queue->dqbuf_count); vpu_dbg(LVL_BIT_FRAME_BYTES, - "[%d]total bytes: %ld, %ld, %ld, %ld\n", + "[%d]total bytes: %ld, %ld\n", ctx->str_index, ctx->total_qbuf_bytes, - ctx->total_ts_bytes, - ctx->total_write_bytes, - ctx->total_consumed_bytes); + ctx->total_write_bytes); update_wptr(ctx, pStrBufDesc, pStrBufDesc->rptr); - ctx->pre_pic_end_addr = pStrBufDesc->rptr; ctx->beginning = pStrBufDesc->rptr; ctx->total_qbuf_bytes = 0; ctx->total_write_bytes = 0; - ctx->total_consumed_bytes = 0; - ctx->total_ts_bytes = 0; - ctx->tsm_sync_flag = true; up(&queue->drv_q_lock); ctx->frm_dis_delay = 0; @@ -5438,7 +5252,7 @@ static ssize_t show_instance_command_info(struct device *dev, statistic = &ctx->statistic; num += scnprintf(buf + num, PAGE_SIZE - num, "command number:\n"); - for (i = VID_API_CMD_NULL; i < VID_API_CMD_YUV_READY + 1; i++) { + for (i = VID_API_CMD_NULL; i < VID_API_CMD_TS + 1; i++) { size = scnprintf(buf + num, PAGE_SIZE - num, "\t%40s(%2d):%16ld\n", cmd2str[i], i, statistic->cmd[i]); @@ -5446,7 +5260,7 @@ static ssize_t show_instance_command_info(struct device *dev, } num += scnprintf(buf + num, PAGE_SIZE - num, "\t%40s :%16ld\n", - "UNKNOWN COMMAND", statistic->cmd[VID_API_CMD_YUV_READY + 1]); + "UNKNOWN COMMAND", statistic->cmd[VID_API_CMD_TS + 1]); num += scnprintf(buf + num, PAGE_SIZE - num, "current command:\n"); num += scnprintf(buf + num, PAGE_SIZE - num, @@ -5572,9 +5386,6 @@ static ssize_t show_instance_buffer_info(struct device *dev, num += scnprintf(buf + num, PAGE_SIZE - num, "\t%40s:%16d\n", "total frame number", ctx->frm_total_num); - num += scnprintf(buf + num, PAGE_SIZE - num, - "\t%40s:%16d\n", "timestamp delay frame", - getTSManagerPreBufferCnt(ctx->tsm)); num += scnprintf(buf + num, PAGE_SIZE - num, "\t%40s:%16lld\n", "timestamp threshold(ms)", ctx->ts_threshold); @@ -6159,12 +5970,6 @@ static int v4l2_open(struct file *filp) ctx->quantization = V4L2_QUANTIZATION_LIM_RANGE; INIT_LIST_HEAD(&ctx->cmd_q); INIT_LIST_HEAD(&ctx->perf_q); - ctx->tsm = createTSManager(tsm_buffer_size); - if (!ctx->tsm) - goto err_create_tsm; - sema_init(&ctx->tsm_lock, 1); - resyncTSManager(ctx->tsm, 0, tsm_mode); - ctx->tsm_sync_flag = false; ctx->output_ts = TSM_TIMESTAMP_NONE; ctx->capture_ts = TSM_TIMESTAMP_NONE; create_instance_file(ctx); @@ -6201,6 +6006,7 @@ static int v4l2_open(struct file *filp) create_fwlog_file(ctx->dev); create_dbglog_file(ctx->dev); mutex_unlock(&dev->dev_mutex); + rpc_init_instance(&dev->shared_mem, ctx->str_index); rpc_set_stream_cfg_value(dev->shared_mem.pSharedInterface, ctx->str_index, vpu_dbe_num); init_vpu_buffer(ctx); @@ -6218,10 +6024,6 @@ err_firmware_load: if (vpu_frmcrcdump_ena) close_crc_file(ctx); err_open_crc: - if (ctx->tsm) - destroyTSManager(ctx->tsm); - ctx->tsm = NULL; -err_create_tsm: remove_instance_file(ctx); dev->ctx[idx] = NULL; err_init_kfifo: @@ -6315,10 +6117,6 @@ static int v4l2_release(struct file *filp) if (ctx->instance_wq) destroy_workqueue(ctx->instance_wq); - if (ctx->tsm) { - destroyTSManager(ctx->tsm); - ctx->tsm = NULL; - } if (vpu_frmcrcdump_ena) close_crc_file(ctx); ctrls_delete_decoder(ctx); @@ -7039,12 +6837,6 @@ module_param(vpu_frmcrcdump_ena, int, 0644); MODULE_PARM_DESC(vpu_frmcrcdump_ena, "enable frame crc dump(0-1)"); module_param(stream_buffer_threshold, int, 0644); MODULE_PARM_DESC(stream_buffer_threshold, "stream buffer threshold"); -module_param(tsm_mode, int, 0644); -MODULE_PARM_DESC(tsm_mode, "timestamp manager mode(0 : ai, 1 : fifo)"); -module_param(tsm_buffer_size, int, 0644); -MODULE_PARM_DESC(tsm_buffer_size, "timestamp manager buffer size"); -module_param(tsm_use_consumed_length, int, 0644); -MODULE_PARM_DESC(tsm_use_consumed_length, "timestamp manager use consumed length"); module_param(precheck_show_bytes, int, 0644); MODULE_PARM_DESC(precheck_show_bytes, "show the beginning of content"); module_param(vpu_show_perf_ena, int, 0644); diff --git a/drivers/mxc/vpu_malone/vpu_b0.h b/drivers/mxc/vpu_malone/vpu_b0.h index 83f1e5c06484..3d7ca75c5746 100644 --- a/drivers/mxc/vpu_malone/vpu_b0.h +++ b/drivers/mxc/vpu_malone/vpu_b0.h @@ -68,7 +68,8 @@ extern unsigned int vpu_dbg_level_decoder; #define VPU_DISABLE_BITS (0x7) #define V4L2_PIX_FMT_NV12_10BIT v4l2_fourcc('N', 'T', '1', '2') /* Y/CbCr 4:2:0 for 10bit */ -#define INVALID_FRAME_DEPTH -1 +#define VPU_FRAME_DEPTH_MAX 512 +#define VPU_FRAME_DEPTH_DEFAULT 256 #define DECODER_NODE_NUMBER 12 // use /dev/video12 as vpu decoder #define DEFAULT_LOG_DEPTH 20 #define DEFAULT_FRMDBG_ENABLE 0 @@ -342,7 +343,7 @@ struct vpu_dev { }; struct vpu_statistic { - unsigned long cmd[VID_API_CMD_YUV_READY + 2]; + unsigned long cmd[VID_API_CMD_TS + 2]; unsigned long event[VID_API_EVENT_DEC_CFG_INFO + 2]; unsigned long current_cmd; unsigned long current_event; @@ -462,15 +463,9 @@ struct vpu_ctx { int frm_dec_delay; int frm_total_num; - void *tsm; - bool tsm_sync_flag; - u32 pre_pic_end_addr; long total_qbuf_bytes; long total_write_bytes; - long total_consumed_bytes; - long total_ts_bytes; u32 extra_size; - struct semaphore tsm_lock; s64 output_ts; s64 capture_ts; s64 ts_threshold; diff --git a/drivers/mxc/vpu_malone/vpu_rpc.c b/drivers/mxc/vpu_malone/vpu_rpc.c index 7057b12b0cb8..17858802ed23 100644 --- a/drivers/mxc/vpu_malone/vpu_rpc.c +++ b/drivers/mxc/vpu_malone/vpu_rpc.c @@ -54,6 +54,7 @@ #include #include +#include #include "vpu_rpc.h" void rpc_init_shared_memory(struct shared_addr *This, @@ -331,6 +332,7 @@ void rpc_send_cmd_buf(struct shared_addr *This, { pDEC_RPC_HOST_IFACE pSharedInterface = (pDEC_RPC_HOST_IFACE)This->shared_mem_vir; MediaIPFW_Video_BufDesc *pCmdDesc = &pSharedInterface->StreamCmdBufferDesc; + BUFFER_DESCRIPTOR_TYPE *desc = NULL; u_int32 *cmddata; u_int32 i; u_int32 *cmdword = (u_int32 *)(This->cmd_mem_vir+pCmdDesc->uWrPtr - pCmdDesc->uStart); @@ -358,6 +360,12 @@ void rpc_send_cmd_buf(struct shared_addr *This, *cmddata = local_cmddata[i]; rpc_update_cmd_buffer_ptr(pCmdDesc); } + if (cmdid != VID_API_CMD_FIRM_RESET) { + desc = &pSharedInterface->StreamApiCmdBufferDesc[idx]; + desc->wptr++; + if (desc->wptr >= desc->end) + desc->wptr = desc->start; + } } u_int32 rpc_MediaIPFW_Video_message_check(struct shared_addr *This) @@ -424,3 +432,56 @@ void rpc_receive_msg_buf(struct shared_addr *This, struct event_msg *msg) rpc_update_msg_buffer_ptr(pMsgDesc); } } + +static bool check_is_ready(struct shared_addr *This, u32 idx) +{ + pDEC_RPC_HOST_IFACE pSharedInterface = NULL; + BUFFER_DESCRIPTOR_TYPE *desc = NULL; + u32 size; + u32 rptr; + u32 wptr; + u32 used; + + if (!This || !This->shared_mem_vir || idx >= VID_API_NUM_STREAMS) + return false; + pSharedInterface = This->shared_mem_vir; + desc = &pSharedInterface->StreamApiCmdBufferDesc[idx]; + size = desc->end - desc->start; + rptr = desc->rptr; + wptr = desc->wptr; + used = (wptr + size - rptr) % size; + if (!size || used < size / 2) + return true; + + return false; +} + +bool rpc_check_is_ready(struct shared_addr *This, u32 idx) +{ + u32 cnt = 0; + + if (!This || !This->shared_mem_vir || idx >= VID_API_NUM_STREAMS) + return false; + while (!check_is_ready(This, idx)) { + if (cnt > 30) + return false; + mdelay(1); + cnt++; + } + + return true; +} + +void rpc_init_instance(struct shared_addr *This, u32 idx) +{ + pDEC_RPC_HOST_IFACE pSharedInterface = NULL; + BUFFER_DESCRIPTOR_TYPE *desc = NULL; + + if (!This || !This->shared_mem_vir || idx >= VID_API_NUM_STREAMS) + return; + pSharedInterface = This->shared_mem_vir; + desc = &pSharedInterface->StreamApiCmdBufferDesc[idx]; + desc->wptr = desc->rptr; + if (desc->wptr >= desc->end) + desc->wptr = desc->start; +} diff --git a/drivers/mxc/vpu_malone/vpu_rpc.h b/drivers/mxc/vpu_malone/vpu_rpc.h index 661746fb7acd..0c98a14adc6f 100644 --- a/drivers/mxc/vpu_malone/vpu_rpc.h +++ b/drivers/mxc/vpu_malone/vpu_rpc.h @@ -118,5 +118,7 @@ void rpc_send_cmd_buf(struct shared_addr *This, u_int32 *local_cmddata); void rpc_receive_msg_buf(struct shared_addr *This, struct event_msg *msg); u_int32 rpc_MediaIPFW_Video_message_check(struct shared_addr *This); +bool rpc_check_is_ready(struct shared_addr *This, u32 idx); +void rpc_init_instance(struct shared_addr *This, u32 idx); #endif diff --git a/drivers/mxc/vpu_malone/vpu_ts.c b/drivers/mxc/vpu_malone/vpu_ts.c deleted file mode 100644 index c45ab9cbae3c..000000000000 --- a/drivers/mxc/vpu_malone/vpu_ts.c +++ /dev/null @@ -1,612 +0,0 @@ -/* - * Copyright 2018-2019 NXP - */ - -/* - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -/* - * Module Name: TimeStamp.c - * - * Description: include TimeStamp stratege for VPU / SW video decoder plugin - * - * Portability: This code is written for Linux OS and Gstreamer - */ - -#include -#include - -#include "vpu_ts.h" - -int debug_level; - -static void tsm_free_received_entry(TSMRecivedCtl *rctl, - TSMReceivedEntry *entry) -{ - entry->next = rctl->free; - rctl->free = entry; -} - - -static TSMReceivedEntry *tsm_new_received_entry(TSMRecivedCtl *rctl) -{ - TSMReceivedEntry *ret = NULL; - - if (rctl->free) { - ret = rctl->free; - rctl->free = ret->next; - } else { - TSMReceivedEntryMemory *p = kzalloc(sizeof(TSMReceivedEntryMemory), GFP_KERNEL); - - if (p) { - int i; - - for (i = 1; i < TSM_RECEIVED_NUNBER; i++) { - TSMReceivedEntry *e = &p->entrys[i]; - - tsm_free_received_entry(rctl, e); - }; - p->next = rctl->memory; - rctl->memory = p; - ret = p->entrys; - } - } - return ret; -} - - -void TSManagerReceive2(void *handle, TSM_TIMESTAMP timestamp, int size) -{ -#define CLEAR_TSM_RENTRY(entry)\ - do { \ - (entry)->used = 0; \ - (entry)->next = NULL; \ - } while (0) - TSManager *tsm = (TSManager *) handle; - - TSM_VERBOSE("receive2 %u:%02u:%02u.%09u size %d\n", - TSM_TIME_H(timestamp), - TSM_TIME_M(timestamp), - TSM_TIME_S(timestamp), - TSM_TIME_NS(timestamp), - size); - - if (tsm) { - if (size > 0) { - TSMRecivedCtl *rctl = &tsm->rctl; - TSMReceivedEntry *e = tsm_new_received_entry(rctl); - - if (e) { - CLEAR_TSM_RENTRY(e); - e->ts = timestamp; - e->size = size; - if (rctl->tail) { - rctl->tail->next = e; - rctl->tail = e; - } else - rctl->head = rctl->tail = e; - } - rctl->cnt++; - } else - TSManagerReceive(handle, timestamp); - } -} - - -static TSM_TIMESTAMP TSManagerGetLastTimeStamp(TSMRecivedCtl *rctl, - int size, int use) -{ - TSM_TIMESTAMP ts = TSM_TIMESTAMP_NONE; - TSMReceivedEntry *e; - - while ((size > 0) && (e = rctl->head)) { - if (TSM_TS_IS_VALID(e->ts)) - ts = ((e->used) ? (TSM_TIMESTAMP_NONE) : (e->ts)); - - TSM_VERBOSE("ts get: %u:%02u:%02u.%09u\n", - TSM_TIME_H(ts), - TSM_TIME_M(ts), - TSM_TIME_S(ts), - TSM_TIME_NS(ts)); - - if (use) - e->used = 1; - if (size >= e->size) { - rctl->head = e->next; - if (rctl->head == NULL) - rctl->tail = NULL; - size -= e->size; - rctl->cnt--; - tsm_free_received_entry(rctl, e); - } else { - e->size -= size; - size = 0; - } - } - return ts; -} - - -void TSManagerFlush2(void *handle, int size) -{ - TSManager *tsm = (TSManager *) handle; - - if (tsm) - TSManagerGetLastTimeStamp(&tsm->rctl, size, 0); -} - - -/*====================================================================================== -FUNCTION: mfw_gst_receive_ts - -DESCRIPTION: Check timestamp and do frame dropping if enabled - -ARGUMENTS PASSED: pTimeStamp_Object - TimeStamp Manager to handle related timestamp - timestamp - time stamp of the input buffer which has video data. -RETURN VALUE: None -PRE-CONDITIONS: None -POST-CONDITIONS: None -IMPORTANT NOTES: None -=======================================================================================*/ -static void _TSManagerReceive(void *handle, TSM_TIMESTAMP timestamp, void *key) -{ - TSManager *tsm = (TSManager *) handle; - - if (tsm) { - if (TSM_TS_IS_VALID(timestamp) && (tsm->rx_cnt)) - tsm->valid_ts_received = 1; - tsm->rx_cnt++; - if (tsm->cnt < tsm->ts_buf_size - 1) { - tsm->cnt++; - if (tsm->mode == MODE_AI) { - if (TSM_TS_IS_VALID(timestamp)) { - if (tsm->first_rx) { - tsm->last_ts_received = timestamp; - tsm->first_rx = 0; - } else { - if (tsm->suspicious_ts) { - if (timestamp >= tsm->suspicious_ts) - tsm->last_ts_received = timestamp; - tsm->suspicious_ts = 0; - } - if ((timestamp > tsm->last_ts_received) - && (timestamp - tsm->last_ts_received > tsm->discont_threshold)) { - tsm->suspicious_ts = timestamp; - timestamp = TSM_TIMESTAMP_NONE; - } - } - } - - if (TSM_TS_IS_VALID(timestamp)) { // && (TSM_ABS(timestamp, tsm->last_ts_sent)ts_buf[tsm->rx].ts = timestamp; - tsm->ts_buf[tsm->rx].age = tsm->age + TSM_PLUS_AGE(tsm); - tsm->ts_buf[tsm->rx].key = key; - tsm->last_ts_received = timestamp; -#ifdef DEBUG - //printf("age should %lld %lld\n", tsm->age, tsm->ts_buf[tsm->rx].age); - //printf("++++++ distance = %d tx=%d, rx=%d, invalid count=%d\n", TSM_DISTANCE(tsm), tsm->tx, tsm->rx,tsm->invalid_ts_count); -#endif - tsm->rx = ((tsm->rx + 1) % tsm->ts_buf_size); - } else - tsm->invalid_ts_count++; - } else if (tsm->mode == MODE_FIFO) { - tsm->ts_buf[tsm->rx].ts = timestamp; - tsm->rx = ((tsm->rx + 1) % tsm->ts_buf_size); - } - TSM_LOG("++Receive %d:%u:%02u:%02u.%09u, invalid:%d, size:%d key %p\n", - tsm->rx_cnt, - TSM_TIME_H(timestamp), - TSM_TIME_M(timestamp), - TSM_TIME_S(timestamp), - TSM_TIME_NS(timestamp), - tsm->invalid_ts_count, - tsm->cnt, - key); - } else - TSM_ERROR("Too many timestamps recieved!! (cnt=%d)\n", tsm->cnt); - } -} - -void TSManagerValid2(void *handle, int size, void *key) -{ - TSManager *tsm = (TSManager *) handle; - - TSM_VERBOSE("valid2 size %d\n", size); - - if (tsm) { - TSM_TIMESTAMP ts; - - ts = TSManagerGetLastTimeStamp(&tsm->rctl, size, 1); - TSM_VERBOSE("TSManagerGetLastTimeStamp: %u:%02u:%02u.%09u\n", - TSM_TIME_H(ts), - TSM_TIME_M(ts), - TSM_TIME_S(ts), - TSM_TIME_NS(ts)); - _TSManagerReceive(tsm, ts, key); - } -} - -void TSManagerReceive(void *handle, TSM_TIMESTAMP timestamp) -{ - _TSManagerReceive(handle, timestamp, TSM_KEY_NONE); -} - - -/*====================================================================================== -FUNCTION: TSManagerSend - -DESCRIPTION: Check timestamp and do frame dropping if enabled - -ARGUMENTS PASSED: pTimeStamp_Object - TimeStamp Manager to handle related timestamp - ptimestamp - returned timestamp to use at render - -RETURN VALUE: None -PRE-CONDITIONS: None -POST-CONDITIONS: None -IMPORTANT NOTES: None -=======================================================================================*/ -static TSM_TIMESTAMP _TSManagerSend2(void *handle, void *key, int send) -{ - TSManager *tsm = (TSManager *) handle; - int i; - int index = -1; - int isValidTs = 0; - TSM_TIMESTAMP ts0 = 0, tstmp = TSM_TIMESTAMP_NONE; - unsigned long long age = 0; - TSM_TIMESTAMP half_interval; - - if (tsm == NULL) - return tstmp; - - i = tsm->tx; - half_interval = TSM_ADAPTIVE_INTERVAL (tsm) >> 1; - - if (tsm) { - if (send) - tsm->tx_cnt++; - else { - tsm->cnt++; - tsm->invalid_ts_count++; - } - if (tsm->cnt > 0) { - if (send) - tsm->cnt--; - - if (tsm->mode == MODE_AI) { - if (tsm->first_tx == 0) - tstmp = tsm->last_ts_sent + TSM_ADAPTIVE_INTERVAL(tsm); - else - tstmp = tsm->last_ts_sent; - - while (i != tsm->rx) { - if (index >= 0) { - if (tsm->ts_buf[i].ts < ts0) { - ts0 = tsm->ts_buf[i].ts; - age = tsm->ts_buf[i].age; - index = i; - } - } else { - ts0 = tsm->ts_buf[i].ts; - age = tsm->ts_buf[i].age; - index = i; - } - if ((TSM_KEY_IS_VALID(key)) && (key == tsm->ts_buf[i].key)) - break; - i = ((i + 1) % tsm->ts_buf_size); - } - if (index >= 0) { - if ((tsm->invalid_ts_count) && (ts0 >= ((tstmp) + half_interval)) - && (age > tsm->age)) { - /* use calculated ts0 */ - if (send) - tsm->invalid_ts_count--; - } else { - if (send) { - if (index != tsm->tx) - tsm->ts_buf[index] = tsm->ts_buf[tsm->tx]; - - tsm->tx = ((tsm->tx + 1) % tsm->ts_buf_size); - } -#if 0 - if (ts0 >= ((tstmp) + half_interval)) - tstmp = tstmp; - else - tstmp = ts0; -#else - tstmp = ts0; -#endif - isValidTs = 1; - } - } else { - if (send) - tsm->invalid_ts_count--; - } - - if (tsm->first_tx == 0) { - if (tstmp > tsm->last_ts_sent) - ts0 = (tstmp - tsm->last_ts_sent); - else { - ts0 = 0; - //reset the timestamp to last frame only when new frames's timestamp is earlier than one frame. - if (tstmp + TSM_ADAPTIVE_INTERVAL(tsm) * 3 / 2 < tsm->last_ts_sent) - tstmp = tsm->last_ts_sent; - } - - if (ts0 > TSM_ADAPTIVE_INTERVAL(tsm) * 3 / 2) { - TSM_WARNING("Jitter1:%u:%02u:%02u.%09u %u:%02u:%02u.%09u\n", - TSM_TIME_H(ts0), - TSM_TIME_M(ts0), - TSM_TIME_S(ts0), - TSM_TIME_NS(ts0), - TSM_TIME_H(TSM_ADAPTIVE_INTERVAL(tsm) * 3 / 2), - TSM_TIME_M(TSM_ADAPTIVE_INTERVAL(tsm) * 3 / 2), - TSM_TIME_S(TSM_ADAPTIVE_INTERVAL(tsm) * 3 / 2), - TSM_TIME_NS(TSM_ADAPTIVE_INTERVAL(tsm) * 3 / 2)); - } else if (ts0 == 0) - TSM_WARNING("Jitter:%u:%02u:%02u.%09u\n", - TSM_TIME_H(ts0), - TSM_TIME_M(ts0), - TSM_TIME_S(ts0), - TSM_TIME_NS(ts0)); - - if (send) { - if (isValidTs && ts0 > TSM_ADAPTIVE_INTERVAL(tsm) * 2) - ts0 = TSM_ADAPTIVE_INTERVAL(tsm) * 2; - if ((ts0 <= TSM_ADAPTIVE_INTERVAL(tsm) * 2) || (tsm->big_cnt > 3)) { - tsm->big_cnt = 0; - tsm->dur_history_total -= - tsm->dur_history_buf[tsm->dur_history_tx]; - tsm->dur_history_buf[tsm->dur_history_tx] = ts0; - tsm->dur_history_tx = - ((tsm->dur_history_tx + 1) % TSM_HISTORY_SIZE); - tsm->dur_history_total += ts0; - } else - tsm->big_cnt++; - } - } - if (send) { - tsm->last_ts_sent = tstmp; - tsm->age++; - tsm->first_tx = 0; - } - } else if (tsm->mode == MODE_FIFO) { - tstmp = tsm->ts_buf[tsm->tx].ts; - if (send) - tsm->tx = ((tsm->tx + 1) % tsm->ts_buf_size); - - ts0 = tstmp - tsm->last_ts_sent; - if (send) - tsm->last_ts_sent = tstmp; - } - - if (send) { - TSM_LOG("--Send %d:%u:%02u:%02u.%09u, int:%u:%02u:%02u.%09u, avg:%u:%02u:%02u.%09u inkey %p\n", - tsm->tx_cnt, - TSM_TIME_H(tstmp), - TSM_TIME_M(tstmp), - TSM_TIME_S(tstmp), - TSM_TIME_NS(tstmp), - TSM_TIME_H(ts0), - TSM_TIME_M(ts0), - TSM_TIME_S(ts0), - TSM_TIME_NS(ts0), - TSM_TIME_H(TSM_ADAPTIVE_INTERVAL(tsm)), - TSM_TIME_M(TSM_ADAPTIVE_INTERVAL(tsm)), - TSM_TIME_S(TSM_ADAPTIVE_INTERVAL(tsm)), - TSM_TIME_NS(TSM_ADAPTIVE_INTERVAL(tsm)), - key); - } - } else { - if (tsm->valid_ts_received == 0) { - if (tsm->first_tx) - tstmp = tsm->last_ts_sent; - else - tstmp = tsm->last_ts_sent + TSM_ADAPTIVE_INTERVAL(tsm); - - if (send) { - tsm->first_tx = 0; - tsm->last_ts_sent = tstmp; - } - } - TSM_ERROR("Too many timestamps send!!\n"); - } - if (send == 0) { - tsm->cnt--; - tsm->invalid_ts_count--; - } - } - - return tstmp; -} - - -TSM_TIMESTAMP TSManagerSend2(void *handle, void *key) -{ - return _TSManagerSend2(handle, key, 1); -} - - -TSM_TIMESTAMP TSManagerQuery2(void *handle, void *key) -{ - return _TSManagerSend2(handle, key, 0); -} - - -TSM_TIMESTAMP TSManagerSend(void *handle) -{ - return TSManagerSend2(handle, TSM_KEY_NONE); -} - - -TSM_TIMESTAMP TSManagerQuery(void *handle) -{ - return TSManagerQuery2(handle, TSM_KEY_NONE); -} - - -void resyncTSManager(void *handle, TSM_TIMESTAMP synctime, TSMGR_MODE mode) -{ - TSManager *tsm = (TSManager *) handle; - - if (tsm) { - TSMRecivedCtl *rctl = &tsm->rctl; - TSMReceivedEntry *e = rctl->head; - - while ((e = rctl->head)) { - rctl->head = e->next; - tsm_free_received_entry(rctl, e); - }; - rctl->cnt = 0; - - rctl->tail = NULL; - - tsm->first_tx = 1; - tsm->first_rx = 1; - tsm->suspicious_ts = 0; - - if (TSM_TS_IS_VALID(synctime)) - tsm->last_ts_sent = synctime; - - tsm->tx = tsm->rx = 0; - tsm->invalid_ts_count = 0; - tsm->mode = mode; - tsm->age = 0; - tsm->rx_cnt = tsm->tx_cnt = tsm->cnt = 0; - tsm->valid_ts_received = 0; - tsm->big_cnt = 0; - } -} - - -/*====================================================================================== -FUNCTION: mfw_gst_init_ts - -DESCRIPTION: alloc and initialize timestamp strcture - -ARGUMENTS PASSED: ppTimeStamp_Object - pointer of TimeStamp Manager to handle related timestamp - -RETURN VALUE: TimeStamp structure pointer -PRE-CONDITIONS: None -POST-CONDITIONS: None -IMPORTANT NOTES: None -=======================================================================================*/ -void *createTSManager(int ts_buf_size) -{ - TSManager *tsm = (TSManager *) kzalloc(sizeof(TSManager), GFP_KERNEL); - - if (tsm) { - memset(tsm, 0, sizeof(TSManager)); - if (ts_buf_size <= 0) - ts_buf_size = TSM_DEFAULT_TS_BUFFER_SIZE; - - tsm->ts_buf_size = ts_buf_size; - tsm->ts_buf = kzalloc(sizeof(TSMControl) * ts_buf_size, GFP_KERNEL); - - if (tsm->ts_buf == NULL) - goto fail; - - resyncTSManager(tsm, (TSM_TIMESTAMP) 0, MODE_AI); - - tsm->dur_history_tx = 0; - TSM_BUFFER_SET(tsm->dur_history_buf, TSM_DEFAULT_INTERVAL, - TSM_HISTORY_SIZE); - tsm->dur_history_total = TSM_DEFAULT_INTERVAL << TSM_HISTORY_POWER; - - tsm->discont_threshold = 10000000000LL; // 10s - } - return tsm; -fail: - if (tsm) { - if (tsm->ts_buf) - kfree(tsm->ts_buf); - kfree(tsm); - tsm = NULL; - } - return tsm; -} - - -void destroyTSManager(void *handle) -{ - TSManager *tsm = (TSManager *) handle; - - if (tsm) { - TSMRecivedCtl *rctl = &tsm->rctl; - TSMReceivedEntryMemory *rmem; - - if (tsm->ts_buf) - kfree(tsm->ts_buf); - - while ((rmem = rctl->memory)) { - rctl->memory = rmem->next; - kfree(rmem); - } - kfree(tsm); - tsm = NULL; - } -} - - -void setTSManagerFrameRate(void *handle, int fps_n, int fps_d) -//void setTSManagerFrameRate(void * handle, float framerate) -{ - TSManager *tsm = (TSManager *) handle; - TSM_TIMESTAMP ts; - - if ((fps_n > 0) && (fps_d > 0) && (fps_n / fps_d <= 80)) - ts = TSM_SECOND * fps_d / fps_n; - else - ts = TSM_DEFAULT_INTERVAL; - // TSM_TIMESTAMP ts = TSM_SECOND / framerate; - - if (tsm) { - TSM_BUFFER_SET(tsm->dur_history_buf, ts, TSM_HISTORY_SIZE); - tsm->dur_history_total = (ts << TSM_HISTORY_POWER); - TSM_LOG("Set frame intrval:%u:%02u:%02u.%09u\n", - TSM_TIME_H(ts), - TSM_TIME_M(ts), - TSM_TIME_S(ts), - TSM_TIME_NS(ts)); - } -} - -TSM_TIMESTAMP getTSManagerFrameInterval(void *handle) -{ - TSManager *tsm = (TSManager *) handle; - TSM_TIMESTAMP ts = 0; - - if (tsm) - ts = TSM_ADAPTIVE_INTERVAL(tsm); - - return ts; -} - - -TSM_TIMESTAMP getTSManagerPosition(void *handle) -{ - TSManager *tsm = (TSManager *) handle; - TSM_TIMESTAMP ts = 0; - - if (tsm) - ts = tsm->last_ts_sent; - - return ts; -} - - -int getTSManagerPreBufferCnt(void *handle) -{ - int i = 0; - TSManager *tsm = (TSManager *) handle; - - if (tsm) - i = tsm->rctl.cnt; - - return i; -} diff --git a/drivers/mxc/vpu_malone/vpu_ts.h b/drivers/mxc/vpu_malone/vpu_ts.h deleted file mode 100644 index 956310f4919f..000000000000 --- a/drivers/mxc/vpu_malone/vpu_ts.h +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright 2018-2019 NXP - */ - -/* - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -/* - * Module Name: TimeStamp.h - * - * Description: include TimeStamp stratege for VPU / SW video decoder plugin - * - * Portability: This code is written for Linux OS and Gstreamer - */ - -#ifndef _TIMESTAMP_H_ -#define _TIMESTAMP_H_ - - -/** - * GST_CLOCK_TIME_NONE: - * - * Constant to define an undefined clock time. - */ - -typedef long long TSM_TIMESTAMP; - -typedef enum { - MODE_AI, - MODE_FIFO, -} TSMGR_MODE; - -#define TSM_TIMESTAMP_NONE ((long long)(-1)) -#define TSM_KEY_NONE ((void *)0) - -enum { - DEBUG_LEVEL_ERROR = 1, - DEBUG_LEVEL_WARNING, - DEBUG_LEVEL_LOG, - DEBUG_LEVEL_VERBOSE, -}; - -#define TSM_MESSAGE(level, fmt, ...) \ - do { \ - if (debug_level >= (level)) { \ - pr_info("TSM:"fmt, ##__VA_ARGS__); \ - } \ - } while (0) - -#define TSM_ERROR(...) TSM_MESSAGE(DEBUG_LEVEL_ERROR, ##__VA_ARGS__) -#define TSM_WARNING(...) TSM_MESSAGE(DEBUG_LEVEL_WARNING, ##__VA_ARGS__) -#define TSM_LOG(...) TSM_MESSAGE(DEBUG_LEVEL_LOG, ##__VA_ARGS__) -#define TSM_VERBOSE(...) TSM_MESSAGE(DEBUG_LEVEL_VERBOSE, ##__VA_ARGS__) - -#define TSM_HISTORY_POWER 5 -#define TSM_HISTORY_SIZE (1 << TSM_HISTORY_POWER) -#define TSM_ADAPTIVE_INTERVAL(tsm) \ - (tsm->dur_history_total >> TSM_HISTORY_POWER) - -#define TSM_SECOND ((TSM_TIMESTAMP)1000000000) -#define TSM_DEFAULT_INTERVAL (TSM_SECOND/30) -#define TSM_DEFAULT_TS_BUFFER_SIZE (128) - -#define TSM_TS_IS_VALID(ts) \ - ((ts) != TSM_TIMESTAMP_NONE) - -#define TSM_KEY_IS_VALID(key) \ - ((key) != TSM_KEY_NONE) - -#define TSM_DISTANCE(tsm)\ - (((tsm->rx) >= (tsm->tx))?((tsm->rx)-(tsm->tx)):(tsm->ts_buf_size-(tsm->tx)+(tsm->rx))) - -#define TSM_PLUS_AGE(tsm)\ - (TSM_DISTANCE(tsm)+tsm->invalid_ts_count+2) - -#define TSM_ABS(ts0, ts1)\ - (((ts0) > (ts1))?((ts0)-(ts1)):((ts1)-(ts0))) - -#define TSM_TIME_H(t) \ - (TSM_TS_IS_VALID(t) ? \ - (unsigned int) (((TSM_TIMESTAMP)(t)) / (TSM_SECOND * 60 * 60)) : 99) -#define TSM_TIME_M(t) \ - (TSM_TS_IS_VALID(t) ? \ - (unsigned int) ((((TSM_TIMESTAMP)(t)) / (TSM_SECOND * 60)) % 60) : 99) -#define TSM_TIME_S(t) \ - (TSM_TS_IS_VALID(t) ? \ - (unsigned int) ((((TSM_TIMESTAMP)(t)) / TSM_SECOND) % 60) : 99) -#define TSM_TIME_NS(t) \ - (TSM_TS_IS_VALID(t) ? \ - (unsigned int) (((TSM_TIMESTAMP)(t)) % TSM_SECOND) : 999999999) - -#define TSM_BUFFER_SET(buf, value, size) \ - do { \ - int i; \ - for (i = 0; i < (size); i++) { \ - (buf)[i] = (value); \ - } \ - } while (0) - -#define TSM_RECEIVED_NUNBER 512 - -typedef struct { - TSM_TIMESTAMP ts; - unsigned long long age; - void *key; -} TSMControl; - -typedef struct _TSMReceivedEntry { - TSM_TIMESTAMP ts; - struct _TSMReceivedEntry *next; - unsigned int used:1; - int size; -} TSMReceivedEntry; - -typedef struct _TSMReceivedEntryMemory { - struct _TSMReceivedEntryMemory *next; - TSMReceivedEntry entrys[TSM_RECEIVED_NUNBER]; -} TSMReceivedEntryMemory; - -typedef struct { - TSMReceivedEntry *head; - TSMReceivedEntry *tail; - TSMReceivedEntry *free; - TSMReceivedEntryMemory *memory; - int cnt; -} TSMRecivedCtl; - -typedef struct _TSManager { - int first_tx; - int first_rx; - int rx; //timestamps received - int tx; //timestamps transferred - TSM_TIMESTAMP last_ts_sent; //last time stamp sent - TSM_TIMESTAMP last_ts_received; - TSM_TIMESTAMP suspicious_ts; - - TSM_TIMESTAMP discont_threshold; - - unsigned int invalid_ts_count; - TSMGR_MODE mode; - int ts_buf_size; - int dur_history_tx; - TSM_TIMESTAMP dur_history_total; - TSM_TIMESTAMP dur_history_buf[TSM_HISTORY_SIZE]; - TSMControl *ts_buf; - unsigned long long age; - int tx_cnt; - int rx_cnt; - int cnt; - unsigned int valid_ts_received:1; - int big_cnt; - - TSMRecivedCtl rctl; -} TSManager; - -/** - * GST_CLOCK_TIME_IS_VALID: - * @time: clock time to validate - * - * Tests if a given #GstClockTime represents a valid defined time. - */ - -/*! - * This function receive timestamp into timestamp manager. - * - * @param handle handle of timestamp manager. - * - * @param timestamp timestamp received - * - * @return - */ -void TSManagerReceive(void *handle, TSM_TIMESTAMP timestamp); -void TSManagerReceive2(void *handle, TSM_TIMESTAMP timestamp, int size); -void TSManagerFlush2(void *handle, int size); -void TSManagerValid2(void *handle, int size, void *key); -/*! - * This function send the timestamp for next output frame. - * - * @param handle handle of timestamp manager. - * - * @return timestamp for next output frame. - */ -TSM_TIMESTAMP TSManagerSend(void *handle); -TSM_TIMESTAMP TSManagerSend2(void *handle, void *key); -TSM_TIMESTAMP TSManagerQuery2(void *handle, void *key); -TSM_TIMESTAMP TSManagerQuery(void *handle); -/*! - * This function resync timestamp handler when reset and seek - * - * @param handle handle of timestamp manager. - * - * @param synctime the postion time needed to set, if value invalid, position keeps original - * - * @param mode playing mode (AI or FIFO) - * - * @return - */ -void resyncTSManager(void *handle, TSM_TIMESTAMP synctime, TSMGR_MODE mode); -/*! - * This function create and reset timestamp handler - * - * @param ts_buf_size time stamp queue buffer size - * - * @return - */ -void *createTSManager(int ts_buf_size); -/*! - * This function destroy timestamp handler - * - * @param handle handle of timestamp manager. - * - * @return - */ -void destroyTSManager(void *handle); -/*! - * This function set history buffer frame interval by fps_n and fps_d - * - * @param handle handle of timestamp manager. - * - * @param framerate the framerate to be set - * - * @return - */ -void setTSManagerFrameRate(void *handle, int fps_n, int fps_d); -// void setTSManagerFrameRate(void * handle, float framerate); -/*! - * This function set the current calculated Frame Interval - * - * @param handle handle of timestamp manager. - * - * @return - */ -TSM_TIMESTAMP getTSManagerFrameInterval(void *handle); -/*! - * This function get the current time stamp postion - * - * @param handle handle of timestamp manager. - * - * @return - */ -TSM_TIMESTAMP getTSManagerPosition(void *handle); -int getTSManagerPreBufferCnt(void *handle); - - -#endif /*_TIMESTAMP_H_ */