From: Ayoung Sim Date: Wed, 10 Apr 2019 07:39:19 +0000 (+0900) Subject: [COMMON] media: mfc: supports drop control X-Git-Tag: MMI-QSAS30.62-33-3~881 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=f051d7f3b1b3866ffdb260ccee9a55f0f10ef80c;p=GitHub%2FMotorolaMobilityLLC%2Fkernel-slsi.git [COMMON] media: mfc: supports drop control When the input interval is lower than set fps, bit allocation is adjusted by drop control. Change-Id: Ic628a72c55bc6cb1c69ebe0a07968b4567d65a81 Signed-off-by: Ayoung Sim --- diff --git a/drivers/media/platform/exynos/mfc/exynos_mfc_media.h b/drivers/media/platform/exynos/mfc/exynos_mfc_media.h index 5e93f31c13e1..8c7bd16ab1d0 100644 --- a/drivers/media/platform/exynos/mfc/exynos_mfc_media.h +++ b/drivers/media/platform/exynos/mfc/exynos_mfc_media.h @@ -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 \ diff --git a/drivers/media/platform/exynos/mfc/mfc_common.h b/drivers/media/platform/exynos/mfc/mfc_common.h index 3badb63a5574..c387cec69b31 100644 --- a/drivers/media/platform/exynos/mfc/mfc_common.h +++ b/drivers/media/platform/exynos/mfc/mfc_common.h @@ -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 @@ -182,6 +184,7 @@ #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) diff --git a/drivers/media/platform/exynos/mfc/mfc_data_struct.h b/drivers/media/platform/exynos/mfc/mfc_data_struct.h index 6fbb116df331..97cd24fb1b05 100644 --- a/drivers/media/platform/exynos/mfc/mfc_data_struct.h +++ b/drivers/media/platform/exynos/mfc/mfc_data_struct.h @@ -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]; diff --git a/drivers/media/platform/exynos/mfc/mfc_enc_ctrl.c b/drivers/media/platform/exynos/mfc/mfc_enc_ctrl.c index c6cf3d3f1f72..7a99fa1c966e 100644 --- a/drivers/media/platform/exynos/mfc/mfc_enc_ctrl.c +++ b/drivers/media/platform/exynos/mfc/mfc_enc_ctrl.c @@ -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", diff --git a/drivers/media/platform/exynos/mfc/mfc_enc_internal.h b/drivers/media/platform/exynos/mfc/mfc_enc_internal.h index 5966ccea2764..2daacf3cdc53 100644 --- a/drivers/media/platform/exynos/mfc/mfc_enc_internal.h +++ b/drivers/media/platform/exynos/mfc/mfc_enc_internal.h @@ -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) diff --git a/drivers/media/platform/exynos/mfc/mfc_enc_param.c b/drivers/media/platform/exynos/mfc/mfc_enc_param.c index 95374998cc91..134fbb13e4d1 100644 --- a/drivers/media/platform/exynos/mfc/mfc_enc_param.c +++ b/drivers/media/platform/exynos/mfc/mfc_enc_param.c @@ -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 */ diff --git a/drivers/media/platform/exynos/mfc/mfc_enc_v4l2.c b/drivers/media/platform/exynos/mfc/mfc_enc_v4l2.c index 221cec3942e1..e29eaaae23e4 100644 --- a/drivers/media/platform/exynos/mfc/mfc_enc_v4l2.c +++ b/drivers/media/platform/exynos/mfc/mfc_enc_v4l2.c @@ -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; diff --git a/drivers/media/platform/exynos/mfc/mfc_qos.c b/drivers/media/platform/exynos/mfc/mfc_qos.c index d37048fa6d3e..83dcc8fdf7ef 100644 --- a/drivers/media/platform/exynos/mfc/mfc_qos.c +++ b/drivers/media/platform/exynos/mfc/mfc_qos.c @@ -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);