From aa766c573d9ca0a8aecf65facbc087114b1e988a Mon Sep 17 00:00:00 2001 From: Ayoung Sim Date: Wed, 2 Aug 2017 09:31:53 +0900 Subject: [PATCH] media: mfc: create timestamp for buffer batch mode Change-Id: I92027dbd134d70de5b6d1a2ceec7b802849bed24 Signed-off-by: Ayoung Sim --- .../platform/exynos/mfc/s5p_mfc_enc_vb2_ops.c | 16 ++++--- .../media/platform/exynos/mfc/s5p_mfc_irq.c | 42 ++++++++++++++++-- .../media/platform/exynos/mfc/s5p_mfc_nal_q.c | 44 +++++++++++++++++-- .../media/platform/exynos/mfc/s5p_mfc_qos.c | 8 ++-- .../media/platform/exynos/mfc/s5p_mfc_qos.h | 1 + 5 files changed, 95 insertions(+), 16 deletions(-) diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_enc_vb2_ops.c b/drivers/media/platform/exynos/mfc/s5p_mfc_enc_vb2_ops.c index 44a178b83823..757e77d66240 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_enc_vb2_ops.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_enc_vb2_ops.c @@ -156,6 +156,9 @@ static int s5p_mfc_enc_buf_init(struct vb2_buffer *vb) if (IS_BUFFER_BATCH_MODE(ctx)) { int count = 0; + ctx->framerate = ctx->num_bufs_in_vb * ENC_DEFAULT_CAM_FPS; + mfc_debug(3, "framerate: %ld\n", ctx->framerate); + count = s5p_mfc_bufcon_get_daddr(ctx, buf, dmabuf, i); if (count != ctx->num_bufs_in_vb) { mfc_err_ctx("invalid buffer count %d != num_bufs_in_vb %d\n", @@ -404,16 +407,17 @@ static void s5p_mfc_enc_buf_queue(struct vb2_buffer *vb) s5p_mfc_add_tail_buf(&ctx->buf_queue_lock, &ctx->dst_buf_queue, buf); } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { s5p_mfc_add_tail_buf(&ctx->buf_queue_lock, &ctx->src_buf_queue, buf); + + mfc_debug(7, "framerate: %ld, timestamp: %lld\n", + ctx->framerate, buf->vb.vb2_buf.timestamp); + mfc_debug(7, "qos ratio: %d\n", ctx->qos_ratio); + + s5p_mfc_qos_update_last_framerate(ctx, buf->vb.vb2_buf.timestamp); + s5p_mfc_qos_update_framerate(ctx); } else { mfc_err_ctx("unsupported buffer type (%d)\n", vq->type); } - mfc_debug(7, "timestamp: %lld\n", buf->vb.vb2_buf.timestamp); - mfc_debug(7, "qos ratio: %d\n", ctx->qos_ratio); - - s5p_mfc_qos_update_last_framerate(ctx, buf->vb.vb2_buf.timestamp); - s5p_mfc_qos_update_framerate(ctx); - if (s5p_mfc_enc_ctx_ready(ctx)) { s5p_mfc_set_bit(ctx->num, &dev->work_bits); } diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_irq.c b/drivers/media/platform/exynos/mfc/s5p_mfc_irq.c index 21eaf54f00ba..4e04919021c2 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_irq.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_irq.c @@ -757,6 +757,40 @@ static void mfc_enc_res_change(struct s5p_mfc_ctx *ctx) } } +static void mfc_handle_stream_copy_timestamp(struct s5p_mfc_ctx *ctx, struct s5p_mfc_buf *src_mb) +{ + struct s5p_mfc_dev *dev; + struct s5p_mfc_buf *dst_mb; + u64 interval; + u64 start_timestamp; + u64 new_timestamp; + + if (!ctx) { + mfc_err_dev("no mfc context to run\n"); + return; + } + + dev = ctx->dev; + if (!dev) { + mfc_err_dev("no device to run\n"); + return; + } + + start_timestamp = src_mb->vb.vb2_buf.timestamp; + interval = NSEC_PER_SEC / (ctx->framerate / 1000); + mfc_debug(3, "%ldfps, start timestamp: %lld, base interval: %lld\n", + ctx->framerate / 1000, start_timestamp, interval); + + new_timestamp = start_timestamp + (interval * src_mb->done_index); + mfc_debug(3, "new timestamp: %lld, interval: %lld\n", + new_timestamp, interval * src_mb->done_index); + + /* Get the destination buffer */ + dst_mb = s5p_mfc_get_buf(&ctx->buf_queue_lock, &ctx->dst_buf_queue, MFC_BUF_NO_TOUCH_USED); + if (dst_mb) + dst_mb->vb.vb2_buf.timestamp = new_timestamp; +} + static void mfc_handle_stream_input(struct s5p_mfc_ctx *ctx, int slice_type) { struct s5p_mfc_raw_info *raw; @@ -792,6 +826,8 @@ static void mfc_handle_stream_input(struct s5p_mfc_ctx *ctx, int slice_type) &ctx->src_ctrls[index]) < 0) mfc_err_ctx("failed in recover_buf_ctrls_val\n"); + mfc_handle_stream_copy_timestamp(ctx, src_mb); + /* last image in a buffer container */ if (src_mb->done_index == ctx->num_bufs_in_vb) { src_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock, @@ -955,9 +991,6 @@ static int mfc_handle_stream(struct s5p_mfc_ctx *ctx) ctx->sequence++; - /* handle destination buffer */ - mfc_handle_stream_output(ctx, slice_type, strm_size); - if (enc->in_slice) { if (s5p_mfc_is_queue_count_same(&ctx->buf_queue_lock, &ctx->dst_buf_queue, 0)) { s5p_mfc_clear_bit(ctx->num, &dev->work_bits); @@ -968,6 +1001,9 @@ static int mfc_handle_stream(struct s5p_mfc_ctx *ctx) /* handle source buffer */ mfc_handle_stream_input(ctx, slice_type); + /* handle destination buffer */ + mfc_handle_stream_output(ctx, slice_type, strm_size); + if (IS_BUFFER_BATCH_MODE(ctx)) return 0; diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_nal_q.c b/drivers/media/platform/exynos/mfc/s5p_mfc_nal_q.c index 62d358e29782..f4b6503c295f 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_nal_q.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_nal_q.c @@ -799,6 +799,40 @@ static void mfc_nal_q_get_enc_frame_buffer(struct s5p_mfc_ctx *ctx, mfc_debug(2, "NAL Q: recon c addr: 0x%08lx\n", enc_recon_c_addr); } +static void mfc_nal_q_handle_stream_copy_timestamp(struct s5p_mfc_ctx *ctx, struct s5p_mfc_buf *src_mb) +{ + struct s5p_mfc_dev *dev; + struct s5p_mfc_buf *dst_mb; + u64 interval; + u64 start_timestamp; + u64 new_timestamp; + + if (!ctx) { + mfc_err_dev("NAL Q: no mfc context to run\n"); + return; + } + + dev = ctx->dev; + if (!dev) { + mfc_err_dev("NAL Q: no device to run\n"); + return; + } + + start_timestamp = src_mb->vb.vb2_buf.timestamp; + interval = NSEC_PER_SEC / (ctx->framerate / 1000); + mfc_debug(3, "NAL Q: %ldfps, start timestamp: %lld, base interval: %lld\n", + ctx->framerate / 1000, start_timestamp, interval); + + new_timestamp = start_timestamp + (interval * src_mb->done_index); + mfc_debug(3, "NAL Q: new timestamp: %lld, interval: %lld\n", + new_timestamp, interval * src_mb->done_index); + + /* Get the destination buffer */ + dst_mb = s5p_mfc_get_buf(&ctx->buf_queue_lock, &ctx->dst_buf_nal_queue, MFC_BUF_NO_TOUCH_USED); + if (dst_mb) + dst_mb->vb.vb2_buf.timestamp = new_timestamp; +} + static void mfc_nal_q_handle_stream_input(struct s5p_mfc_ctx *ctx, int slice_type, unsigned int strm_size, EncoderOutputStr *pOutStr) { @@ -827,6 +861,8 @@ static void mfc_nal_q_handle_stream_input(struct s5p_mfc_ctx *ctx, int slice_typ if (src_mb) { src_mb->done_index++; mfc_debug(4, "batch buf done_index: %d\n", src_mb->done_index); + + mfc_nal_q_handle_stream_copy_timestamp(ctx, src_mb); } else { src_mb = s5p_mfc_find_first_buf(&ctx->buf_queue_lock, &ctx->src_buf_nal_queue, enc_addr[0], ctx->num_bufs_in_vb); @@ -834,6 +870,8 @@ static void mfc_nal_q_handle_stream_input(struct s5p_mfc_ctx *ctx, int slice_typ src_mb->done_index++; mfc_debug(4, "batch buf done_index: %d\n", src_mb->done_index); + mfc_nal_q_handle_stream_copy_timestamp(ctx, src_mb); + /* last image in a buffer container */ if (src_mb->done_index == ctx->num_bufs_in_vb) { src_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock, @@ -932,6 +970,9 @@ static void mfc_nal_q_handle_stream(struct s5p_mfc_ctx *ctx, EncoderOutputStr *p ctx->sequence++; + /* handle input buffer */ + mfc_nal_q_handle_stream_input(ctx, slice_type, strm_size, pOutStr); + /* handle output buffer */ if (strm_size > 0) { /* at least one more dest. buffers exist always */ @@ -982,9 +1023,6 @@ static void mfc_nal_q_handle_stream(struct s5p_mfc_ctx *ctx, EncoderOutputStr *p vb2_buffer_done(&dst_mb->vb.vb2_buf, VB2_BUF_STATE_ERROR); } - /* handle input buffer */ - mfc_nal_q_handle_stream_input(ctx, slice_type, strm_size, pOutStr); - mfc_debug_leave(); return; diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_qos.c b/drivers/media/platform/exynos/mfc/s5p_mfc_qos.c index 6a41dd1f2a2a..b9dabbbe2b5e 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_qos.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_qos.c @@ -614,7 +614,7 @@ static int mfc_qos_get_interval(struct list_head *head, struct list_head *entry) return (prev_interval < next_interval ? prev_interval : next_interval); } -static int mfc_qos_dec_add_timestamp(struct s5p_mfc_ctx *ctx, +static int mfc_qos_add_timestamp(struct s5p_mfc_ctx *ctx, struct timeval *time, struct list_head *head) { int replace_entry = 0; @@ -661,7 +661,7 @@ static unsigned long mfc_qos_get_fps_by_timestamp(struct s5p_mfc_ctx *ctx, struc } if (list_empty(&ctx->ts_list)) { - mfc_qos_dec_add_timestamp(ctx, time, &ctx->ts_list); + mfc_qos_add_timestamp(ctx, time, &ctx->ts_list); return mfc_qos_get_framerate_by_interval(0); } else { found = 0; @@ -673,14 +673,14 @@ static unsigned long mfc_qos_get_fps_by_timestamp(struct s5p_mfc_ctx *ctx, struc break; } else if (time_diff > 0) { /* Add this after temp_ts */ - mfc_qos_dec_add_timestamp(ctx, time, &temp_ts->list); + mfc_qos_add_timestamp(ctx, time, &temp_ts->list); found = 1; break; } } if (!found) /* Add this at first entry */ - mfc_qos_dec_add_timestamp(ctx, time, &ctx->ts_list); + mfc_qos_add_timestamp(ctx, time, &ctx->ts_list); } list_for_each_entry(temp_ts, &ctx->ts_list, list) { diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_qos.h b/drivers/media/platform/exynos/mfc/s5p_mfc_qos.h index 521af8968225..61f3b03c3858 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_qos.h +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_qos.h @@ -18,6 +18,7 @@ #define MFC_MAX_FPS (480000) #define DEC_DEFAULT_FPS (240000) #define ENC_DEFAULT_FPS (240000) +#define ENC_DEFAULT_CAM_FPS (60000) #define MB_COUNT_PER_UHD_FRAME 32400 #define MAX_FPS_PER_UHD_FRAME 120 -- 2.20.1