[COMMON] media: mfc: supports drop control
authorAyoung Sim <a.sim@samsung.com>
Wed, 10 Apr 2019 07:39:19 +0000 (16:39 +0900)
committerKim Gunho <gunho.kim@samsung.com>
Fri, 28 Jun 2019 14:45:48 +0000 (23:45 +0900)
When the input interval is lower than set fps,
bit allocation is adjusted by drop control.

Change-Id: Ic628a72c55bc6cb1c69ebe0a07968b4567d65a81
Signed-off-by: Ayoung Sim <a.sim@samsung.com>
drivers/media/platform/exynos/mfc/exynos_mfc_media.h
drivers/media/platform/exynos/mfc/mfc_common.h
drivers/media/platform/exynos/mfc/mfc_data_struct.h
drivers/media/platform/exynos/mfc/mfc_enc_ctrl.c
drivers/media/platform/exynos/mfc/mfc_enc_internal.h
drivers/media/platform/exynos/mfc/mfc_enc_param.c
drivers/media/platform/exynos/mfc/mfc_enc_v4l2.c
drivers/media/platform/exynos/mfc/mfc_qos.c

index 5e93f31c13e12b51ac39dd1db72ad1008dce600b..8c7bd16ab1d037190c83658c6eb0ff1db129ee2e 100644 (file)
@@ -139,6 +139,8 @@ enum v4l2_mpeg_video_hevc_hierarchical_coding_type {
 #define V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_2BIT_CHROMA \
                                        (V4L2_CID_MPEG_MFC_BASE + 28)
 
+#define V4L2_CID_MPEG_VIDEO_DROP_CONTROL                       \
+                                       (V4L2_CID_MPEG_MFC_BASE + 41)
 #define V4L2_CID_MPEG_VIDEO_H264_MVC_VIEW_ID                   \
                                        (V4L2_CID_MPEG_MFC_BASE + 42)
 #define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_STATUS                 \
index 3badb63a55742b4908ff1e9d0a6aedb97e94216f..c387cec69b31899141ab70e0f586b96c5b1adc34 100644 (file)
@@ -55,6 +55,8 @@
 
 #define NUM_MPEG4_LF_BUF       2
 
+#define FRAME_RATE_RESOLUTION  1000
+
 #define DEFAULT_TAG            (0xE05)
 
 #define MFC_NO_INSTANCE_SET    -1
 #define        ENC_SET_STATIC_INFO             (1 << 11)
 #define        ENC_SET_HDR10_PLUS              (1 << 12)
 #define        ENC_SET_VP9_PROFILE_LEVEL       (1 << 13)
+#define        ENC_SET_DROP_CONTROL            (1 << 14)
 
 #define MFC_VER_MAJOR(dev)     ((dev->pdata->ip_ver >> 8) & 0xFF)
 #define MFC_VER_MINOR(dev)     (dev->pdata->ip_ver & 0xFF)
index 6fbb116df3316a77a28e5bcac71b97c0b697b323..97cd24fb1b05e3037a4b9721b5fe50946935fad6 100644 (file)
@@ -1126,10 +1126,10 @@ struct mfc_enc_params {
        u8 pad_cb;
        u8 pad_cr;
 
-       u8 fixed_target_bit;
        u8 rc_mb;               /* H.264: MFCv5, MPEG4/H.263: MFCv6 */
        u8 rc_pvc;
        u8 rc_frame;
+       u8 drop_control;
        u32 rc_bitrate;
        u32 rc_framerate;
        u16 rc_reaction_coeff;
@@ -1150,6 +1150,7 @@ struct mfc_enc_params {
        u8 weighted_enable;
        u8 roi_enable;
        u8 ivf_header_disable;  /* VP8, VP9 */
+       u8 fixed_target_bit;
 
        u32 check_color_range;
        u32 color_range;
@@ -1577,6 +1578,7 @@ struct mfc_ctx {
        struct list_head ts_list;
        int ts_count;
        int ts_is_full;
+       int ts_last_interval;
 
        /* bitrate control for QoS*/
        struct mfc_bitrate bitrate_array[MAX_TIME_INDEX];
index c6cf3d3f1f7225b510b0d7ff480698f216d40d4d..7a99fa1c966e2a8b329858c0f9be8ba47d67d7d7 100644 (file)
@@ -659,6 +659,18 @@ static struct mfc_ctrl_cfg mfc_ctrl_list[] = {
                .flag_mode = MFC_CTRL_MODE_SFR,
                .flag_addr = MFC_REG_E_PARAM_CHANGE,
                .flag_shft = 13,
+       },
+       {       /* sync the timestamp for drop control */
+               .type = MFC_CTRL_TYPE_SET,
+               .id = V4L2_CID_MPEG_VIDEO_DROP_CONTROL,
+               .is_volatile = 1,
+               .mode = MFC_CTRL_MODE_SFR,
+               .addr = MFC_REG_E_RC_FRAME_RATE,
+               .mask = 0x0000FFFF,
+               .shft = 0,
+               .flag_mode = MFC_CTRL_MODE_NONE,
+               .flag_addr = 0,
+               .flag_shft = 0,
        }
 };
 
@@ -1128,6 +1140,23 @@ static void __mfc_enc_set_buf_ctrls_exception(struct mfc_ctx *ctx,
                                enc->roi_buf[buf_ctrl->old_val2].daddr,
                                buf_ctrl->val);
        }
+
+       /* set drop control */
+       if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_DROP_CONTROL) {
+               if (!ctx->ts_last_interval) {
+                       p->rc_frame_delta = FRAME_RATE_RESOLUTION / p->rc_framerate;
+                       mfc_debug(3, "[DROPCTRL] default delta: %d\n", p->rc_frame_delta);
+               } else {
+                       p->rc_frame_delta = ctx->ts_last_interval / FRAME_RATE_RESOLUTION;
+               }
+               value = MFC_READL(MFC_REG_E_RC_FRAME_RATE);
+               value &= ~(0xFFFF);
+               value |= (p->rc_frame_delta & 0xFFFF);
+               MFC_WRITEL(value, MFC_REG_E_RC_FRAME_RATE);
+               mfc_debug(3, "[DROPCTRL] fps %d -> %d, delta: %d, reg: %#x\n",
+                               p->rc_framerate, USEC_PER_SEC / ctx->ts_last_interval,
+                               p->rc_frame_delta, value);
+       }
 }
 
 static int mfc_enc_set_buf_ctrls_val(struct mfc_ctx *ctx, struct list_head *head)
@@ -1427,6 +1456,22 @@ static int mfc_enc_set_buf_ctrls_val_nal_q(struct mfc_ctx *ctx,
                                (buf_ctrl->val & buf_ctrl->mask) << buf_ctrl->shft;
                        param_change = 1;
                        break;
+               case V4L2_CID_MPEG_VIDEO_DROP_CONTROL:
+                       if (!ctx->ts_last_interval) {
+                               p->rc_frame_delta = FRAME_RATE_RESOLUTION / p->rc_framerate;
+                               mfc_debug(3, "[NALQ][DROPCTRL] default delta: %d\n", p->rc_frame_delta);
+                       } else {
+                               p->rc_frame_delta = ctx->ts_last_interval / FRAME_RATE_RESOLUTION;
+                       }
+                       pInStr->RcFrameRate &= ~(0xFFFF << 16);
+                       pInStr->RcFrameRate |= (FRAME_RATE_RESOLUTION & 0xFFFF) << 16;
+                       pInStr->RcFrameRate &= ~(buf_ctrl->mask << buf_ctrl->shft);
+                       pInStr->RcFrameRate |=
+                               (p->rc_frame_delta & buf_ctrl->mask) << buf_ctrl->shft;
+                       mfc_debug(3, "[NALQ][DROPCTRL] fps %d -> %d, delta: %d, reg: %#x\n",
+                                       p->rc_framerate, USEC_PER_SEC / ctx->ts_last_interval,
+                                       p->rc_frame_delta, pInStr->RcFrameRate);
+                       break;
                /* If new dynamic controls are added, insert here */
                default:
                        mfc_info_ctx("[NALQ] can't find control, id: 0x%x\n",
index 5966ccea2764f1e81ec5f3046f395bdeac2acbb9..2daacf3cdc5335f520e9395fb3f154bc19e1c627 100644 (file)
@@ -2374,6 +2374,15 @@ static struct v4l2_queryctrl controls[] = {
                .step = 1,
                .default_value = 0,
        },
+       {
+               .id = V4L2_CID_MPEG_VIDEO_DROP_CONTROL,
+               .type = V4L2_CTRL_TYPE_INTEGER,
+               .name = "Drop control",
+               .minimum = INT_MIN,
+               .maximum = INT_MAX,
+               .step = 1,
+               .default_value = 0,
+       },
 };
 
 #define NUM_CTRLS ARRAY_SIZE(controls)
index 95374998cc91dea3ab6e701b342f8b22e710a654..134fbb13e4d1376eeeef737e3b7f1370f10171d5 100644 (file)
@@ -15,7 +15,6 @@
 #include "mfc_reg_api.h"
 
 /* Definition */
-#define FRAME_DELTA_DEFAULT            1
 #define CBR_FIX_MAX                    10
 #define CBR_I_LIMIT_MAX                        5
 #define BPG_EXTENSION_TAG_SIZE         5
@@ -221,10 +220,21 @@ static void __mfc_set_enc_params(struct mfc_ctx *ctx)
        mfc_clear_set_bits(reg, 0x1, 8, p->rc_mb);
        /* frame-level rate control */
        mfc_clear_set_bits(reg, 0x1, 9, p->rc_frame);
-       /* 'DROP_CONTROL_ENABLE', disable */
-       mfc_clear_bits(reg, 0x1, 10);
+       /* drop control */
+       mfc_clear_set_bits(reg, 0x1, 10, p->drop_control);
        MFC_RAW_WRITEL(reg, MFC_REG_E_RC_CONFIG);
 
+       /*
+        * frame rate
+        * delta is timestamp diff
+        * ex) 30fps: 33, 60fps: 16
+        */
+       p->rc_frame_delta = FRAME_RATE_RESOLUTION / p->rc_framerate;
+       reg = MFC_RAW_READL(MFC_REG_E_RC_FRAME_RATE);
+       mfc_clear_set_bits(reg, 0xFFFF, 16, FRAME_RATE_RESOLUTION);
+       mfc_clear_set_bits(reg, 0xFFFF, 0, p->rc_frame_delta);
+       MFC_RAW_WRITEL(reg, MFC_REG_E_RC_FRAME_RATE);
+
        /* bit rate */
        ctx->Kbps = p->rc_bitrate / 1024;
        MFC_RAW_WRITEL(p->rc_bitrate, MFC_REG_E_RC_BIT_RATE);
@@ -477,14 +487,6 @@ static void __mfc_set_enc_params_h264(struct mfc_ctx *ctx)
                mfc_set_bits(reg, 0x1, 11, 0x1);
        MFC_RAW_WRITEL(reg, MFC_REG_E_RC_CONFIG);
 
-       /* frame rate */
-       /* Fix value for H.264, H.263 in the driver */
-       p->rc_frame_delta = FRAME_DELTA_DEFAULT;
-       reg = MFC_RAW_READL(MFC_REG_E_RC_FRAME_RATE);
-       mfc_clear_set_bits(reg, 0xFFFF, 16, p->rc_framerate);
-       mfc_clear_set_bits(reg, 0xFFFF, 0, p->rc_frame_delta);
-       MFC_RAW_WRITEL(reg, MFC_REG_E_RC_FRAME_RATE);
-
        /* max & min value of QP for I frame */
        reg = MFC_RAW_READL(MFC_REG_E_RC_QP_BOUND);
        /** max I frame QP */
@@ -619,13 +621,6 @@ static void __mfc_set_enc_params_mpeg4(struct mfc_ctx *ctx)
        mfc_clear_set_bits(reg, 0xFF, 0, p_mpeg4->rc_frame_qp);
        MFC_RAW_WRITEL(reg, MFC_REG_E_FIXED_PICTURE_QP);
 
-       /* frame rate */
-       p->rc_frame_delta = p_mpeg4->vop_frm_delta;
-       reg = MFC_RAW_READL(MFC_REG_E_RC_FRAME_RATE);
-       mfc_clear_set_bits(reg, 0xFFFF, 16, p_mpeg4->vop_time_res);
-       mfc_clear_set_bits(reg, 0xFFFF, 0, p_mpeg4->vop_frm_delta);
-       MFC_RAW_WRITEL(reg, MFC_REG_E_RC_FRAME_RATE);
-
        /* rate control config. */
        reg = MFC_RAW_READL(MFC_REG_E_RC_CONFIG);
        /** frame QP */
@@ -683,14 +678,6 @@ static void __mfc_set_enc_params_h263(struct mfc_ctx *ctx)
        mfc_clear_set_bits(reg, 0xFF, 0, p_mpeg4->rc_frame_qp);
        MFC_RAW_WRITEL(reg, MFC_REG_E_FIXED_PICTURE_QP);
 
-       /* frame rate */
-       /* Fix value for H.264, H.263 in the driver */
-       p->rc_frame_delta = FRAME_DELTA_DEFAULT;
-       reg = MFC_RAW_READL(MFC_REG_E_RC_FRAME_RATE);
-       mfc_clear_set_bits(reg, 0xFFFF, 16, p->rc_framerate);
-       mfc_clear_set_bits(reg, 0xFFFF, 0, p->rc_frame_delta);
-       MFC_RAW_WRITEL(reg, MFC_REG_E_RC_FRAME_RATE);
-
        /* rate control config. */
        reg = MFC_RAW_READL(MFC_REG_E_RC_CONFIG);
        /** frame QP */
@@ -798,13 +785,6 @@ static void __mfc_set_enc_params_vp8(struct mfc_ctx *ctx)
        mfc_clear_set_bits(reg, 0xFF, 0, p_vp8->rc_frame_qp);
        MFC_RAW_WRITEL(reg, MFC_REG_E_FIXED_PICTURE_QP);
 
-       /* frame rate */
-       p->rc_frame_delta = FRAME_DELTA_DEFAULT;
-       reg = MFC_RAW_READL(MFC_REG_E_RC_FRAME_RATE);
-       mfc_clear_set_bits(reg, 0xFFFF, 16, p->rc_framerate);
-       mfc_clear_set_bits(reg, 0xFFFF, 0, p->rc_frame_delta);
-       MFC_RAW_WRITEL(reg, MFC_REG_E_RC_FRAME_RATE);
-
        /* rate control config. */
        reg = MFC_RAW_READL(MFC_REG_E_RC_CONFIG);
        /** frame QP */
@@ -923,13 +903,6 @@ static void __mfc_set_enc_params_vp9(struct mfc_ctx *ctx)
        mfc_clear_set_bits(reg, 0xFF, 0, p_vp9->rc_frame_qp);
        MFC_RAW_WRITEL(reg, MFC_REG_E_FIXED_PICTURE_QP);
 
-       /* frame rate */
-       p->rc_frame_delta = FRAME_DELTA_DEFAULT;
-       reg = MFC_RAW_READL(MFC_REG_E_RC_FRAME_RATE);
-       mfc_clear_set_bits(reg, 0xFFFF, 16, p->rc_framerate);
-       mfc_clear_set_bits(reg, 0xFFFF, 0, p->rc_frame_delta);
-       MFC_RAW_WRITEL(reg, MFC_REG_E_RC_FRAME_RATE);
-
        /* rate control config. */
        reg = MFC_RAW_READL(MFC_REG_E_RC_CONFIG);
        /** frame QP */
@@ -1116,13 +1089,6 @@ static void __mfc_set_enc_params_hevc(struct mfc_ctx *ctx)
        mfc_clear_set_bits(reg, 0xFF, 0, p_hevc->rc_frame_qp);
        MFC_RAW_WRITEL(reg, MFC_REG_E_RC_CONFIG);
 
-       /* frame rate */
-       p->rc_frame_delta = FRAME_DELTA_DEFAULT;
-       reg = MFC_RAW_READL(MFC_REG_E_RC_FRAME_RATE);
-       mfc_clear_set_bits(reg, 0xFFFF, 16, p->rc_framerate);
-       mfc_clear_set_bits(reg, 0xFFFF, 0, p->rc_frame_delta);
-       MFC_RAW_WRITEL(reg, MFC_REG_E_RC_FRAME_RATE);
-
        /* max & min value of QP for I frame */
        reg = MFC_RAW_READL(MFC_REG_E_RC_QP_BOUND);
        /** max I frame QP */
index 221cec3942e1faf09fa84801d5c7ee3d320988c5..e29eaaae23e4615037a2645a675795f638c2d4ef 100644 (file)
@@ -884,6 +884,7 @@ static int __mfc_enc_ext_info(struct mfc_ctx *ctx)
        val |= ENC_SET_FIXED_SLICE;
        val |= ENC_SET_PVC_MODE;
        val |= ENC_SET_RATIO_OF_INTRA;
+       val |= ENC_SET_DROP_CONTROL;
 
        if (MFC_FEATURE_SUPPORT(dev, dev->pdata->color_aspect_enc))
                val |= ENC_SET_COLOR_ASPECT;
@@ -1763,6 +1764,9 @@ static int __mfc_enc_set_param(struct mfc_ctx *ctx, struct v4l2_control *ctrl)
        case V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_2:
                p->display_primaries_2 = ctrl->value;
                break;
+       case V4L2_CID_MPEG_VIDEO_DROP_CONTROL:
+               p->drop_control = ctrl->value;
+               break;
        case V4L2_CID_MPEG_MFC_HDR_USER_SHARED_HANDLE:
                if (enc->sh_handle_hdr.fd == -1) {
                        enc->sh_handle_hdr.fd = ctrl->value;
@@ -1849,6 +1853,7 @@ static int __mfc_enc_set_ctrl_val(struct mfc_ctx *ctx, struct v4l2_control *ctrl
        case V4L2_CID_MPEG_VIDEO_ROI_CONTROL:
        case V4L2_CID_MPEG_VIDEO_YSUM:
        case V4L2_CID_MPEG_VIDEO_RATIO_OF_INTRA:
+       case V4L2_CID_MPEG_VIDEO_DROP_CONTROL:
                list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
                        if (!(ctx_ctrl->type & MFC_CTRL_TYPE_SET))
                                continue;
index d37048fa6d3eddbcf7bf1bd3f5a9dca44f4f26ce..83dcc8fdf7efb1d62bd7aa6bef0d2cbb1f2d3c4f 100644 (file)
@@ -838,6 +838,7 @@ static int __mfc_qos_add_timestamp(struct mfc_ctx *ctx,
 
 static unsigned long __mfc_qos_get_fps_by_timestamp(struct mfc_ctx *ctx, struct timeval *time)
 {
+       struct list_head *head = &ctx->ts_list;
        struct mfc_timestamp *temp_ts;
        int found;
        int index = 0;
@@ -903,6 +904,10 @@ static unsigned long __mfc_qos_get_fps_by_timestamp(struct mfc_ctx *ctx, struct
                                min_interval, max_framerate);
        }
 
+       /* Calculation the last frame fps for drop control */
+       temp_ts = list_entry(head->prev, struct mfc_timestamp, list);
+       ctx->ts_last_interval = temp_ts->interval;
+
        if (!ctx->ts_is_full) {
                if (debug_ts == 1)
                        mfc_info_ctx("[TS] ts doesn't full, keep %ld fps\n", ctx->framerate);