media: mfc: create timestamp for buffer batch mode
authorAyoung Sim <a.sim@samsung.com>
Wed, 2 Aug 2017 00:31:53 +0000 (09:31 +0900)
committerCosmin Tanislav <demonsingur@gmail.com>
Mon, 22 Apr 2024 17:22:21 +0000 (20:22 +0300)
Change-Id: I92027dbd134d70de5b6d1a2ceec7b802849bed24
Signed-off-by: Ayoung Sim <a.sim@samsung.com>
drivers/media/platform/exynos/mfc/s5p_mfc_enc_vb2_ops.c
drivers/media/platform/exynos/mfc/s5p_mfc_irq.c
drivers/media/platform/exynos/mfc/s5p_mfc_nal_q.c
drivers/media/platform/exynos/mfc/s5p_mfc_qos.c
drivers/media/platform/exynos/mfc/s5p_mfc_qos.h

index 44a178b83823885f6469e0c0a1354eef839645e6..757e77d6624083bb543e9c9938091d928b7a2de1 100644 (file)
@@ -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);
        }
index 21eaf54f00ba7b8b511ec1f8b1732b5ab69a4302..4e04919021c263e55589163d818fb379ac6b0b00 100644 (file)
@@ -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;
 
index 62d358e29782e042c783e2e0b56fe5fc90213280..f4b6503c295f13583488af8c0a63bac3d11fc924 100644 (file)
@@ -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;
index 6a41dd1f2a2a2e9b3d3641a4cf1e8eea4c119fa2..b9dabbbe2b5e81674a4f87a73c76dbd5c14ad362 100644 (file)
@@ -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) {
index 521af8968225fabacac48c20bb8f26a900cecd59..61f3b03c3858442944a28d1027b92072ab8b1cc7 100644 (file)
@@ -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