[COMMON] media: mfc: consider the bitrate for the QoS
authorAyoung Sim <a.sim@samsung.com>
Wed, 20 Mar 2019 07:47:16 +0000 (16:47 +0900)
committerKim Gunho <gunho.kim@samsung.com>
Fri, 28 Jun 2019 14:45:43 +0000 (23:45 +0900)
Change-Id: Ibc09e0fc5e517ce34d540c3a47e2694930ab9e46
Signed-off-by: Ayoung Sim <a.sim@samsung.com>
drivers/media/platform/exynos/mfc/mfc.c
drivers/media/platform/exynos/mfc/mfc_common.h
drivers/media/platform/exynos/mfc/mfc_data_struct.h
drivers/media/platform/exynos/mfc/mfc_dec_v4l2.c
drivers/media/platform/exynos/mfc/mfc_enc_param.c
drivers/media/platform/exynos/mfc/mfc_enc_vb2.c
drivers/media/platform/exynos/mfc/mfc_isr.c
drivers/media/platform/exynos/mfc/mfc_otf.c
drivers/media/platform/exynos/mfc/mfc_qos.c
drivers/media/platform/exynos/mfc/mfc_qos.h

index 77200400f6144220bce087705043ecca88ea69b0..66a77c402c0699b21c132d61215daf10d05b3de6 100644 (file)
@@ -150,6 +150,7 @@ static int __mfc_init_dec_ctx(struct mfc_ctx *ctx)
 #ifdef CONFIG_MFC_USE_BUS_DEVFREQ
        INIT_LIST_HEAD(&ctx->qos_list);
 #endif
+       INIT_LIST_HEAD(&ctx->bitrate_list);
        INIT_LIST_HEAD(&ctx->ts_list);
 
        dec->display_delay = -1;
@@ -1075,6 +1076,9 @@ static void __mfc_parse_dt(struct device_node *np, struct mfc_dev *mfc)
        of_property_read_u32(np, "qos_weight_num_of_tile", &pdata->qos_weight.weight_num_of_tile);
        of_property_read_u32(np, "qos_weight_super64_bframe", &pdata->qos_weight.weight_super64_bframe);
 #endif
+       /* Bitrate control for QoS */
+       of_property_read_u32_array(np, "max_Kbps", pdata->max_Kbps, MAX_NUM_MFC_BPS);
+       dev->bps_ratio = pdata->max_Kbps[0] / dev->pdata->max_Kbps[1];
 }
 
 static void *__mfc_get_drv_data(struct platform_device *pdev);
index 0e7c28c29862194797286fb4036c65e65a792ba2..3badb63a55742b4908ff1e9d0a6aedb97e94216f 100644 (file)
 #define CODEC_422FORMAT(ctx)   (IS_HEVC_DEC(ctx) || IS_HEVC_ENC(ctx) ||        \
                                IS_VP9_DEC(ctx) || IS_VP9_ENC(ctx) ||           \
                                IS_BPG_DEC(ctx) || IS_BPG_ENC(ctx))
+#define CODEC_HIGH_PERF(ctx)   (IS_H264_DEC(ctx) || IS_H264_MVC_DEC(ctx) || IS_HEVC_DEC(ctx))
 #define ON_RES_CHANGE(ctx)     (((ctx)->state >= MFCINST_RES_CHANGE_INIT) &&   \
                                 ((ctx)->state <= MFCINST_RES_CHANGE_END))
 
index 0f6e0dc793d17cd8b18eca3029dac87461993708..a069cfed8dcb2f48a0291698fe6cbecfa27309c8 100644 (file)
@@ -59,7 +59,9 @@
 
 #define MAX_NUM_IMAGES_IN_VB           8
 #define MAX_NUM_BUFCON_BUFS            32
+
 #define MAX_NUM_CLUSTER                        3
+#define MAX_NUM_MFC_BPS                        2
 
 /*
  *  MFC region id for smc
@@ -483,6 +485,7 @@ struct mfc_platdata {
        struct mfc_qos *qos_table;
        struct mfc_qos_boost *qos_boost_table;
 #endif
+       unsigned int max_Kbps[MAX_NUM_MFC_BPS];
        /* NAL-Q size */
        unsigned int nal_q_entry_size;
        unsigned int nal_q_dump_size;
@@ -851,6 +854,8 @@ struct mfc_dev {
        int qos_has_enc_ctx;
        struct mutex qos_mutex;
 #endif
+       int bps_ratio;
+
        int id;
        atomic_t clk_ref;
 
@@ -1347,6 +1352,11 @@ struct mfc_timestamp {
        int interval;
 };
 
+struct mfc_bitrate {
+       struct list_head list;
+       int bytesused;
+};
+
 struct mfc_dec {
        int total_dpb_count;
 
@@ -1554,6 +1564,12 @@ struct mfc_ctx {
        int ts_count;
        int ts_is_full;
 
+       struct mfc_bitrate bitrate_array[MFC_TIME_INDEX];
+       struct list_head bitrate_list;
+       int bitrate_index;
+       int bitrate_is_full;
+       int Kbps;
+
        int buf_process_type;
 
        unsigned long raw_protect_flag;
index 3e7a596099b607000ae5bcc9fa371dc07936236d..87a5e7c1dc565dab4ac5902964a0fddc0746db56 100644 (file)
@@ -726,7 +726,7 @@ static int mfc_dec_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
                        return -EIO;
                }
 
-               mfc_qos_update_framerate(ctx);
+               mfc_qos_update_framerate(ctx, buf->m.planes[0].bytesused);
 
                if (!buf->m.planes[0].bytesused) {
                        buf->m.planes[0].bytesused = buf->m.planes[0].length;
index b409811d2c2b4b0a136884bcce28cc93ec76986d..95374998cc91dea3ab6e701b342f8b22e710a654 100644 (file)
@@ -226,6 +226,7 @@ static void __mfc_set_enc_params(struct mfc_ctx *ctx)
        MFC_RAW_WRITEL(reg, MFC_REG_E_RC_CONFIG);
 
        /* bit rate */
+       ctx->Kbps = p->rc_bitrate / 1024;
        MFC_RAW_WRITEL(p->rc_bitrate, MFC_REG_E_RC_BIT_RATE);
 
        reg = MFC_RAW_READL(MFC_REG_E_RC_MODE);
index 4849e9b55a7b5d0c9ec6f70304a99efe42ddc538..fd6e811eb8f81bf00a892a149e4d7115b895ea88 100644 (file)
@@ -442,7 +442,7 @@ static void mfc_enc_buf_queue(struct vb2_buffer *vb)
                                        ctx->framerate, buf->vb.vb2_buf.timestamp);
 
                mfc_qos_update_last_framerate(ctx, buf->vb.vb2_buf.timestamp);
-               mfc_qos_update_framerate(ctx);
+               mfc_qos_update_framerate(ctx, 0);
        } else {
                mfc_err_ctx("unsupported buffer type (%d)\n", vq->type);
        }
index 95a90f798663e2dc05a47b1a458d299f03748686..0d9682f6bb1a0cd1e833254f458c2031bc2a5141 100644 (file)
@@ -676,6 +676,7 @@ static void __mfc_handle_frame(struct mfc_ctx *ctx,
        if (dst_frame_status == MFC_REG_DEC_STATUS_DECODING_EMPTY) {
                if (ctx->state == MFCINST_RES_CHANGE_FLUSH) {
                        struct mfc_timestamp *temp_ts = NULL;
+                       struct mfc_bitrate *temp_bitrate = NULL;
 
                        mfc_debug(2, "[DRC] Last frame received after resolution change\n");
                        __mfc_handle_frame_all_extracted(ctx);
@@ -697,6 +698,15 @@ static void __mfc_handle_frame(struct mfc_ctx *ctx,
                        mfc_qos_reset_last_framerate(ctx);
                        mfc_qos_set_framerate(ctx, DEC_DEFAULT_FPS);
 
+                       /* empty the bitrate queue */
+                       while (!list_empty(&ctx->bitrate_list)) {
+                               temp_bitrate = list_entry((&ctx->bitrate_list)->next,
+                                               struct mfc_bitrate, list);
+                               list_del(&temp_bitrate->list);
+                       }
+                       ctx->bitrate_index = 0;
+                       ctx->bitrate_is_full = 0;
+
                        goto leave_handle_frame;
                } else {
                        __mfc_handle_frame_all_extracted(ctx);
index e2c2915dbc95d886bb419ac6aa52c77191fea9c9..584fb580d164bf761483a31a7e37e1ef69f6cebd 100644 (file)
@@ -476,7 +476,7 @@ int mfc_otf_run_enc_frame(struct mfc_ctx *ctx)
 
        /* Change timestamp usec -> nsec */
        mfc_qos_update_last_framerate(ctx, handle->otf_time_stamp * 1000);
-       mfc_qos_update_framerate(ctx);
+       mfc_qos_update_framerate(ctx, 0);
 
        /* Set stream buffer size to handle buffer full */
        mfc_clean_ctx_int_flags(ctx);
index 8b5460a531855cdfe60f89b39ce1b814004e7270..a208fd338e69cac43db046476634ec2ec227b6c2 100644 (file)
@@ -847,8 +847,48 @@ static unsigned long __mfc_qos_get_fps_by_timestamp(struct mfc_ctx *ctx, struct
        return max_framerate;
 }
 
-void mfc_qos_update_framerate(struct mfc_ctx *ctx)
+static void __mfc_qos_get_bps(struct mfc_ctx *ctx, u32 bytesused)
 {
+       struct mfc_dev *dev = ctx->dev;
+       struct list_head *head = &ctx->bitrate_list;
+       struct mfc_bitrate *temp_bitrate;
+       struct mfc_bitrate *new_bitrate = &ctx->bitrate_array[ctx->bitrate_index];
+       unsigned long sum_size = 0, avg_Kbits;
+       int count = 0;
+
+       if (ctx->bitrate_is_full) {
+               temp_bitrate = list_entry(head->next, struct mfc_bitrate, list);
+               list_del(&temp_bitrate->list);
+       }
+
+       new_bitrate->bytesused = bytesused;
+       list_add_tail(&new_bitrate->list, head);
+
+       list_for_each_entry(temp_bitrate, head, list) {
+               mfc_debug(4, "[QoS][%d] strm_size %d\n", count, temp_bitrate->bytesused);
+               sum_size += temp_bitrate->bytesused;
+               count++;
+       }
+
+       avg_Kbits = ((sum_size * BITS_PER_BYTE) / count) / 1024;
+       ctx->Kbps = (int)(avg_Kbits * (ctx->last_framerate / 1000));
+       /* Standardization to high bitrate spec */
+       if (!CODEC_HIGH_PERF(ctx))
+               ctx->Kbps = dev->bps_ratio * ctx->Kbps;
+       mfc_debug(3, "[QoS] %d Kbps, average %lld Kbits per frame\n", ctx->Kbps, avg_Kbits);
+
+       ctx->bitrate_index++;
+       if (ctx->bitrate_index == MFC_TIME_INDEX) {
+               ctx->bitrate_is_full = 1;
+               ctx->bitrate_index %= MFC_TIME_INDEX;
+       }
+}
+
+void mfc_qos_update_framerate(struct mfc_ctx *ctx, u32 bytesused)
+{
+       if (ctx->type == MFCINST_DECODER)
+               __mfc_qos_get_bps(ctx, bytesused);
+
        if (ctx->last_framerate != 0 && ctx->last_framerate != ctx->framerate) {
                mfc_debug(2, "[QoS] fps changed: %ld -> %ld, qos ratio: %d\n",
                                ctx->framerate, ctx->last_framerate, ctx->qos_ratio);
index a56e57cb8bfbc6bda053405e5c1eb1120994c8b2..73755d8a6a20d6d323f372d9bb5a29fc6bad0630 100644 (file)
@@ -38,7 +38,7 @@ void mfc_qos_off(struct mfc_ctx *ctx);
 #define mfc_qos_off(ctx)               do {} while (0)
 #endif
 
-void mfc_qos_update_framerate(struct mfc_ctx *ctx);
+void mfc_qos_update_framerate(struct mfc_ctx *ctx, u32 bytesused);
 void mfc_qos_update_last_framerate(struct mfc_ctx *ctx, u64 timestamp);
 
 static inline void mfc_qos_reset_framerate(struct mfc_ctx *ctx)