media: mfc: support encoder color aspect
authorJeonghee Kim <jhhhh.kim@samsung.com>
Tue, 19 Dec 2017 10:28:18 +0000 (19:28 +0900)
committerSunyoung Kang <sy0816.kang@samsung.com>
Tue, 29 May 2018 06:59:18 +0000 (15:59 +0900)
Change-Id: I0225094b7a606297d3ff69c846f53f76c34a08ff
Signed-off-by: Jeonghee Kim <jhhhh.kim@samsung.com>
drivers/media/platform/exynos/mfc/s5p_mfc_common.h
drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h
drivers/media/platform/exynos/mfc/s5p_mfc_dec_ops.c
drivers/media/platform/exynos/mfc/s5p_mfc_enc.c
drivers/media/platform/exynos/mfc/s5p_mfc_enc_internal.h
drivers/media/platform/exynos/mfc/s5p_mfc_enc_param.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_regs_v10.h

index 00b8fd1504922b0d5e729c6a9e62aa71f05e1360..e97e36ad4228f9a509ee8cffe96b5b0687fb395c 100644 (file)
 #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)
                                        (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)
 {
index 55a68a4ca4be91cebc4ad2a689e54dcd2520cef2..3d42385a255f15e90f1bd4c700e8f4cbf2084c3c 100644 (file)
@@ -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;
index 0f8f8f0d93134c145f7d9f4221e60bd947ab84ea..018eeade5be4281741d0c01af3aec6e5b8152fe7 100644 (file)
@@ -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;
                        }
index 9d24dae74e4a19e17f8803f8474ec905832e5e52..a7c7877734b46196889a65310892188307d8475f 100644 (file)
@@ -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;
index 1e567cfd4c4dd0369ff28d914f660c70b64a6937..75ddf6fc12718cfe5f264696dedc198769b8ae16 100644 (file)
@@ -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)
index 4f615f0a66b4ab01cc9e0372894cd774cfab9d80..088025d8290837325ed9926beb6af83ec817cdcd 100644 (file)
@@ -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();
 }
 
index 0e4c91d548f2807da976545728827f43d1b7e2de..1d9f4bde8d417405031ca6e9089fac46959b2efa 100644 (file)
@@ -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;
index eab303f8551ec0159bee46cd8e54f1537489a5c5..99500045ee39b680d929dd5b58bc97a6595d10af 100644 (file)
@@ -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");
                        }
index ed07e9a9a4ceac956eeabf945913380b954b78d9..02997c3b48cc531be4bba05d84e4edf80bc8c4f5 100644 (file)
 #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