From 52b3ae574ebd66a52d5882f98ec41980ade185ba Mon Sep 17 00:00:00 2001 From: Jeonghee Kim Date: Tue, 19 Dec 2017 19:28:18 +0900 Subject: [PATCH] media: mfc: support encoder color aspect Change-Id: I0225094b7a606297d3ff69c846f53f76c34a08ff Signed-off-by: Jeonghee Kim --- .../platform/exynos/mfc/s5p_mfc_common.h | 3 + .../platform/exynos/mfc/s5p_mfc_data_struct.h | 11 +++- .../platform/exynos/mfc/s5p_mfc_dec_ops.c | 10 +-- .../media/platform/exynos/mfc/s5p_mfc_enc.c | 15 +++++ .../exynos/mfc/s5p_mfc_enc_internal.h | 36 +++++++++++ .../platform/exynos/mfc/s5p_mfc_enc_param.c | 63 +++++++++++++++++++ .../media/platform/exynos/mfc/s5p_mfc_irq.c | 8 +-- .../media/platform/exynos/mfc/s5p_mfc_nal_q.c | 2 +- .../platform/exynos/mfc/s5p_mfc_regs_v10.h | 1 + 9 files changed, 137 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_common.h b/drivers/media/platform/exynos/mfc/s5p_mfc_common.h index 00b8fd150492..e97e36ad4228 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_common.h +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_common.h @@ -159,6 +159,7 @@ #define ENC_SET_FIXED_SLICE (1 << 6) #define ENC_SET_PVC_MODE (1 << 7) #define ENC_SET_RATIO_OF_INTRA (1 << 8) +#define ENC_SET_COLOR_ASPECT (1 << 9) #define MFC_VER_MAJOR(dev) ((s5p_mfc_version(dev) >> 8) & 0xFF) #define MFC_VER_MINOR(dev) (s5p_mfc_version(dev) & 0xFF) @@ -191,6 +192,8 @@ (dev->fw.date >= 0x171023)) #define FW_HAS_RATIO_INTRA_CTRL(dev) (FROM_MFCV11X(dev) && \ (dev->fw.date >= 0x171113)) +#define FW_HAS_ENC_COLOR_ASPECT(dev) (FROM_MFCV11X(dev) && \ + (dev->fw.date >= 0x171023)) static inline unsigned int s5p_mfc_version(struct s5p_mfc_dev *dev) { diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h b/drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h index 55a68a4ca4be..3d42385a255f 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h @@ -967,6 +967,11 @@ struct s5p_mfc_enc_params { u32 i_frm_ctrl_mode; u32 i_frm_ctrl; + u32 color_range; + u32 colour_primaries; + u32 transfer_characteristics; + u32 matrix_coefficients; + union { struct s5p_mfc_h264_enc_params h264; struct s5p_mfc_mpeg4_enc_params mpeg4; @@ -1161,6 +1166,9 @@ struct s5p_mfc_dec { unsigned char frame_cnt; unsigned int num_of_tile_over_4; + + unsigned int color_range; + unsigned int color_space; }; struct s5p_mfc_enc { @@ -1308,9 +1316,6 @@ struct s5p_mfc_ctx { int ts_count; int ts_is_full; - unsigned int color_range; - unsigned int color_space; - int buf_process_type; unsigned long raw_protect_flag; diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_dec_ops.c b/drivers/media/platform/exynos/mfc/s5p_mfc_dec_ops.c index 0f8f8f0d9313..018eeade5be4 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_dec_ops.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_dec_ops.c @@ -691,6 +691,7 @@ static int s5p_mfc_dec_get_buf_ctrls_val(struct s5p_mfc_ctx *ctx, struct list_he { struct s5p_mfc_buf_ctrl *buf_ctrl; struct s5p_mfc_dev *dev = ctx->dev; + struct s5p_mfc_dec *dec = ctx->dec_priv; unsigned int value = 0; list_for_each_entry(buf_ctrl, head, list) { @@ -705,9 +706,9 @@ static int s5p_mfc_dec_get_buf_ctrls_val(struct s5p_mfc_ctx *ctx, struct list_he if (IS_VP9_DEC(ctx)) { if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_FULL_RANGE_FLAG) - buf_ctrl->val = ctx->color_range; + buf_ctrl->val = dec->color_range; else if (buf_ctrl->id == V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES) - buf_ctrl->val = ctx->color_space; + buf_ctrl->val = dec->color_space; } mfc_debug(8, "Get buffer control "\ "id: 0x%08x val: %d\n", @@ -755,6 +756,7 @@ static int s5p_mfc_dec_set_buf_ctrls_val_nal_q_dec(struct s5p_mfc_ctx *ctx, static int s5p_mfc_dec_get_buf_ctrls_val_nal_q_dec(struct s5p_mfc_ctx *ctx, struct list_head *head, DecoderOutputStr *pOutStr) { + struct s5p_mfc_dec *dec = ctx->dec_priv; struct s5p_mfc_buf_ctrl *buf_ctrl; unsigned int value = 0; @@ -816,13 +818,13 @@ static int s5p_mfc_dec_get_buf_ctrls_val_nal_q_dec(struct s5p_mfc_ctx *ctx, break; case V4L2_CID_MPEG_VIDEO_FULL_RANGE_FLAG: if (IS_VP9_DEC(ctx)) { - buf_ctrl->val = ctx->color_range; + buf_ctrl->val = dec->color_range; buf_ctrl->has_new = 1; continue; } case V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES: if (IS_VP9_DEC(ctx)) { - buf_ctrl->val = ctx->color_space; + buf_ctrl->val = dec->color_space; buf_ctrl->has_new = 1; continue; } diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_enc.c b/drivers/media/platform/exynos/mfc/s5p_mfc_enc.c index 9d24dae74e4a..a7c7877734b4 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_enc.c @@ -761,6 +761,9 @@ static int mfc_enc_ext_info(struct s5p_mfc_ctx *ctx) if (FW_HAS_RATIO_INTRA_CTRL(dev)) val |= ENC_SET_RATIO_OF_INTRA; + if (FW_HAS_ENC_COLOR_ASPECT(dev)) + val |= ENC_SET_COLOR_ASPECT; + return val; } @@ -1578,6 +1581,18 @@ static int mfc_enc_set_param(struct s5p_mfc_ctx *ctx, struct v4l2_control *ctrl) case V4L2_CID_MPEG_VIDEO_RATIO_OF_INTRA: p->ratio_intra = ctrl->value; break; + case V4L2_CID_MPEG_VIDEO_FULL_RANGE_FLAG: + p->color_range = ctrl->value; + break; + case V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES: + p->colour_primaries = ctrl->value; + break; + case V4L2_CID_MPEG_VIDEO_TRANSFER_CHARACTERISTICS: + p->transfer_characteristics = ctrl->value; + break; + case V4L2_CID_MPEG_VIDEO_MATRIX_COEFFICIENTS: + p->matrix_coefficients = ctrl->value; + break; default: mfc_err_ctx("Invalid control: 0x%08x\n", ctrl->id); ret = -EINVAL; diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_enc_internal.h b/drivers/media/platform/exynos/mfc/s5p_mfc_enc_internal.h index 1e567cfd4c4d..75ddf6fc1271 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_enc_internal.h +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_enc_internal.h @@ -2237,6 +2237,42 @@ static struct v4l2_queryctrl controls[] = { .step = 1, .default_value = 0, }, + { + .id = V4L2_CID_MPEG_VIDEO_FULL_RANGE_FLAG, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Color range", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + { + .id = V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Colour primaries", + .minimum = 0, + .maximum = 10, + .step = 1, + .default_value = 0, + }, + { + .id = V4L2_CID_MPEG_VIDEO_TRANSFER_CHARACTERISTICS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Transfer characteristics", + .minimum = 0, + .maximum = 17, + .step = 1, + .default_value = 0, + }, + { + .id = V4L2_CID_MPEG_VIDEO_MATRIX_COEFFICIENTS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Matrix coefficients", + .minimum = 0, + .maximum = 10, + .step = 1, + .default_value = 0, + }, }; #define NUM_CTRLS ARRAY_SIZE(controls) diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_enc_param.c b/drivers/media/platform/exynos/mfc/s5p_mfc_enc_param.c index 4f615f0a66b4..088025d82908 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_enc_param.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_enc_param.c @@ -641,6 +641,30 @@ void s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx) MFC_WRITEL(reg, S5P_FIMV_E_H264_FRAME_PACKING_SEI_INFO); } + if (FW_HAS_ENC_COLOR_ASPECT(dev)) { + reg = MFC_READL(S5P_FIMV_E_VIDEO_SIGNAL_TYPE); + /* VIDEO_SIGNAL_TYPE_FLAG */ + reg |= 0x1 << 31; + /* COLOR_RANGE */ + reg &= ~(0x1 << 25); + reg |= p->color_range << 25; + /* COLOUR_DESCRIPTION_PRESENT_FLAG */ + reg |= 0x1 << 24; + /* COLOUR_PRIMARIES */ + reg &= ~(0xFF << 16); + reg |= p->colour_primaries << 16; + /* TRANSFER_CHARACTERISTICS */ + reg &= ~(0xFF << 8); + reg |= p->transfer_characteristics << 8; + /* MATRIX_COEFFICIENTS */ + reg &= ~(0xFF); + reg |= p->matrix_coefficients; + MFC_WRITEL(reg, S5P_FIMV_E_VIDEO_SIGNAL_TYPE); + mfc_debug(2, "H264 ENC Color aspect: range:%s, pri:%d, trans:%d, mat:%d\n", + p->color_range ? "Full" : "Limited", p->colour_primaries, + p->transfer_characteristics, p->matrix_coefficients); + } + mfc_set_fmo_slice_map_h264(ctx, p_264); mfc_debug_leave(); @@ -1067,6 +1091,21 @@ void s5p_mfc_set_enc_params_vp9(struct s5p_mfc_ctx *ctx) reg |= p_vp9->rc_min_qp_p & 0xFF; MFC_WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND_PB); + if (FW_HAS_ENC_COLOR_ASPECT(dev)) { + reg = MFC_READL(S5P_FIMV_E_VIDEO_SIGNAL_TYPE); + /* VIDEO_SIGNAL_TYPE_FLAG */ + reg |= 0x1 << 31; + /* COLOR_SPACE: VP9 uses colour_primaries interface for color space */ + reg &= ~(0x1F << 26); + reg |= p->colour_primaries << 26; + /* COLOR_RANGE */ + reg &= ~(0x1 << 25); + reg |= p->color_range << 25; + MFC_WRITEL(reg, S5P_FIMV_E_VIDEO_SIGNAL_TYPE); + mfc_debug(2, "VP9 ENC Color aspect: range:%s, space: %d\n", + p->color_range ? "Full" : "Limited", p->colour_primaries); + } + mfc_debug_leave(); } @@ -1281,6 +1320,30 @@ void s5p_mfc_set_enc_params_hevc(struct s5p_mfc_ctx *ctx) MFC_WRITEL(reg, S5P_FIMV_E_RC_ROI_CTRL); mfc_debug(3, "ROI: HEVC ROI enable\n"); + if (FW_HAS_ENC_COLOR_ASPECT(dev)) { + reg = MFC_READL(S5P_FIMV_E_VIDEO_SIGNAL_TYPE); + /* VIDEO_SIGNAL_TYPE_FLAG */ + reg |= 0x1 << 31; + /* COLOR_RANGE */ + reg &= ~(0x1 << 25); + reg |= p->color_range << 25; + /* COLOUR_DESCRIPTION_PRESENT_FLAG */ + reg |= 0x1 << 24; + /* COLOUR_PRIMARIES */ + reg &= ~(0xFF << 16); + reg |= p->colour_primaries << 16; + /* TRANSFER_CHARACTERISTICS */ + reg &= ~(0xFF << 8); + reg |= p->transfer_characteristics << 8; + /* MATRIX_COEFFICIENTS */ + reg &= ~(0xFF); + reg |= p->matrix_coefficients; + MFC_WRITEL(reg, S5P_FIMV_E_VIDEO_SIGNAL_TYPE); + mfc_debug(2, "HEVC ENC Color aspect: range:%s, pri:%d, trans:%d, mat:%d\n", + p->color_range ? "Full" : "Limited", p->colour_primaries, + p->transfer_characteristics, p->matrix_coefficients); + } + mfc_debug_leave(); } diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_irq.c b/drivers/media/platform/exynos/mfc/s5p_mfc_irq.c index 0e4c91d548f2..1d9f4bde8d41 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_irq.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_irq.c @@ -284,7 +284,7 @@ static void mfc_handle_frame_output_del(struct s5p_mfc_ctx *ctx, } if (IS_VP9_DEC(ctx) && FW_HAS_VP9_HDR(dev)) { - if (ctx->color_space != S5P_FIMV_D_COLOR_UNKNOWN) { + if (dec->color_space != S5P_FIMV_D_COLOR_UNKNOWN) { ref_mb->vb.reserved2 |= (1 << 3); mfc_debug(2, "color space parsed\n"); } @@ -1108,10 +1108,10 @@ static int mfc_handle_seq_dec(struct s5p_mfc_ctx *ctx) } if (IS_VP9_DEC(ctx)) { - ctx->color_range = s5p_mfc_get_color_range(); - ctx->color_space = s5p_mfc_get_color_space(); + dec->color_range = s5p_mfc_get_color_range(); + dec->color_space = s5p_mfc_get_color_space(); mfc_debug(2, "color range: %d, color space: %d, It's valid for VP9\n", - ctx->color_range, ctx->color_space); + dec->color_range, dec->color_space); } 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 eab303f8551e..99500045ee39 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_nal_q.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_nal_q.c @@ -1124,7 +1124,7 @@ static void mfc_nal_q_handle_frame_output_del(struct s5p_mfc_ctx *ctx, } if (IS_VP9_DEC(ctx) && FW_HAS_VP9_HDR(dev)) { - if (ctx->color_space != S5P_FIMV_D_COLOR_UNKNOWN) { + if (dec->color_space != S5P_FIMV_D_COLOR_UNKNOWN) { ref_mb->vb.reserved2 |= (1 << 3); mfc_debug(2, "NAL Q: color space parsed\n"); } diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_regs_v10.h b/drivers/media/platform/exynos/mfc/s5p_mfc_regs_v10.h index ed07e9a9a4ce..02997c3b48cc 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_regs_v10.h +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_regs_v10.h @@ -268,6 +268,7 @@ #define S5P_FIMV_E_MV_VER_RANGE 0xF7B8 #define S5P_FIMV_E_HIGH_QUALITY_MODE 0xF7C0 +#define S5P_FIMV_E_VIDEO_SIGNAL_TYPE 0xF7C4 #define S5P_FIMV_E_SAO_WEIGHT0 0xF7C8 #define S5P_FIMV_E_SAO_WEIGHT1 0xF7CC -- 2.20.1