[COMMON] media: mfc: support HDR10 plus SEI decoding
authorAyoung Sim <a.sim@samsung.com>
Mon, 16 Jul 2018 07:29:52 +0000 (16:29 +0900)
committerhskang <hs1218.kang@samsung.com>
Sun, 9 Sep 2018 21:39:01 +0000 (06:39 +0900)
Change-Id: Ie879b6b7824c71baf553bd2afe16efa82dbd9d62
Signed-off-by: Ayoung Sim <a.sim@samsung.com>
12 files changed:
drivers/media/platform/exynos/mfc/exynos_mfc_media.h
drivers/media/platform/exynos/mfc/mfc.c
drivers/media/platform/exynos/mfc/mfc_cmd.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_internal.h
drivers/media/platform/exynos/mfc/mfc_dec_v4l2.c
drivers/media/platform/exynos/mfc/mfc_isr.c
drivers/media/platform/exynos/mfc/mfc_nal_q.c
drivers/media/platform/exynos/mfc/mfc_reg_api.c
drivers/media/platform/exynos/mfc/mfc_reg_api.h
drivers/media/platform/exynos/mfc/mfc_regs.h

index 02d26f4bfec1b70715a456787c663b6509385d4b..f75062c8a09c0d18b239e66c3ccad68e27d3ff1e 100644 (file)
@@ -258,6 +258,8 @@ enum v4l2_mpeg_video_hevc_hierarchical_coding_type {
                                        (V4L2_CID_MPEG_MFC_BASE + 107)
 #define V4L2_CID_MPEG_MFC_CONFIG_QP_ENABLE             \
                                        (V4L2_CID_MPEG_MFC_BASE + 108)
+#define V4L2_CID_MPEG_MFC_HDR_USER_SHARED_HANDLE       \
+                                       (V4L2_CID_MPEG_MFC_BASE + 109)
 
 /* CIDs for HEVC encoding. Number gaps are for compatibility */
 
index 659b4f7039a20576e047bf5cdf5f7029e7656823..192c8265f4cc79cb5500cfaf40bb528bde95ee58 100644 (file)
@@ -101,6 +101,8 @@ static void __mfc_deinit_dec_ctx(struct mfc_ctx *ctx)
        mfc_delete_queue(&ctx->ref_buf_queue);
 
        mfc_mem_cleanup_user_shared_handle(ctx, &dec->sh_handle);
+       mfc_mem_cleanup_user_shared_handle(ctx, &dec->sh_handle_hdr);
+       kfree(dec->hdr10_plus_info);
        kfree(dec->ref_info);
        kfree(dec);
 }
@@ -162,6 +164,8 @@ static int __mfc_init_dec_ctx(struct mfc_ctx *ctx)
        dec->is_dpb_full = 0;
        mfc_cleanup_assigned_fd(ctx);
        mfc_clear_assigned_dpb(ctx);
+
+       /* sh_handle: released dpb info */
        dec->sh_handle.fd = -1;
        dec->ref_info = kzalloc(
                (sizeof(struct dec_dpb_ref_info) * MFC_MAX_DPBS), GFP_KERNEL);
@@ -173,6 +177,16 @@ static int __mfc_init_dec_ctx(struct mfc_ctx *ctx)
        for (i = 0; i < MFC_MAX_BUFFERS; i++)
                dec->ref_info[i].dpb[0].fd[0] = MFC_INFO_INIT_FD;
 
+       /* sh_handle: HDR10+ HEVC SEI meta */
+       dec->sh_handle_hdr.fd = -1;
+       dec->hdr10_plus_info = kzalloc(
+                       (sizeof(struct hdr10_plus_meta) * MFC_MAX_DPBS), GFP_KERNEL);
+       if (!dec->hdr10_plus_info) {
+               mfc_err_dev("[HDR+] failed to allocate HDR10+ information data\n");
+               ret = -ENOMEM;
+               goto fail_dec_init;
+       }
+
        /* Init videobuf2 queue for OUTPUT */
        ctx->vq_src.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
        ctx->vq_src.drv_priv = ctx;
@@ -972,6 +986,7 @@ static void __mfc_parse_dt(struct device_node *np, struct mfc_dev *mfc)
        of_property_read_u32_array(np, "static_info_dec", &pdata->static_info_dec.support, 2);
        of_property_read_u32_array(np, "color_aspect_enc", &pdata->color_aspect_enc.support, 2);
        of_property_read_u32_array(np, "static_info_enc", &pdata->static_info_enc.support, 2);
+       of_property_read_u32_array(np, "hdr10_plus", &pdata->hdr10_plus.support, 2);
 
        /* Default 10bit format for decoding */
        of_property_read_u32(np, "P010_decoding", &pdata->P010_decoding);
@@ -981,6 +996,9 @@ static void __mfc_parse_dt(struct device_node *np, struct mfc_dev *mfc)
        of_property_read_u32(np, "support_422", &pdata->support_422);
        of_property_read_u32(np, "support_rgb", &pdata->support_rgb);
 
+       /* HDR10+ num max window */
+       of_property_read_u32(np, "max_hdr_win", &pdata->max_hdr_win);
+
        /* Encoder default parameter */
        of_property_read_u32(np, "enc_param_num", &pdata->enc_param_num);
        if (pdata->enc_param_num) {
@@ -1634,7 +1652,7 @@ static const struct dev_pm_ops mfc_pm_ops = {
 struct mfc_ctx_buf_size mfc_ctx_buf_size = {
        .dev_ctx        = PAGE_ALIGN(0x7800),   /*  30KB */
        .h264_dec_ctx   = PAGE_ALIGN(0x200000), /* 1.6MB */
-       .other_dec_ctx  = PAGE_ALIGN(0x7800),   /*  30KB */
+       .other_dec_ctx  = PAGE_ALIGN(0xC800),   /*  50KB */
        .h264_enc_ctx   = PAGE_ALIGN(0x19000),  /* 100KB */
        .hevc_enc_ctx   = PAGE_ALIGN(0xA000),   /*  40KB */
        .other_enc_ctx  = PAGE_ALIGN(0x6400),   /*  25KB */
index 5a0a1e79b5e15606d87f0c3bf7bc522104ae7de2..c9278aa86b1ffe51b9dc3db6b8f4659c96047d24 100644 (file)
@@ -229,6 +229,8 @@ void mfc_cmd_dec_seq_header(struct mfc_ctx *ctx)
                reg |= (0x1 << MFC_REG_D_SEI_ENABLE_MASTERING_DISPLAY_SHIFT);
        }
        reg |= (0x1 << MFC_REG_D_SEI_ENABLE_RECOVERY_PARSING_SHIFT);
+       if (MFC_FEATURE_SUPPORT(dev, dev->pdata->hdr10_plus))
+               reg |= (0x1 << MFC_REG_D_SEI_ENABLE_ST_2094_40_SEI_SHIFT);
 
        MFC_WRITEL(reg, MFC_REG_D_SEI_ENABLE);
        mfc_debug(2, "SEI enable was set, 0x%x\n", MFC_READL(MFC_REG_D_SEI_ENABLE));
index 20bec22dfb652c5d3045846813f1ad49e8808700..497296218b379a23023f0a91b7e32e9adc68c326 100644 (file)
 #define        DEC_SET_DYNAMIC_DPB             (1 << 1)
 #define        DEC_SET_LAST_FRAME_INFO         (1 << 2)
 #define        DEC_SET_SKYPE_FLAG              (1 << 3)
+#define        DEC_SET_HDR10_PLUS              (1 << 4)
 
 /* Extra information for Encoder */
 #define        ENC_SET_RGB_INPUT               (1 << 0)
index 504765aa5b61137475d2de90b228d350ac17a81d..d5d37927f134e880659a3b2072d113b7eea95126 100644 (file)
 #define HWFC_MAX_BUF                   10
 #define OTF_MAX_BUF                    30
 
+#define HDR_MAX_WINDOWS                        3
+#define HDR_MAX_SCL                    3
+#define HDR_MAX_DISTRIBUTION           15
+#define HDR_MAX_BEZIER_CURVES          15
+
 /* Maximum number of temporal layers */
 #define VIDEO_MAX_TEMPORAL_LAYERS      7
 
@@ -177,6 +182,7 @@ enum mfc_vb_flag {
        MFC_FLAG_HDR_COLOUR_DESC        = 3,
        MFC_FLAG_HDR_VIDEO_SIGNAL_TYPE  = 4,
        MFC_FLAG_BLACKBAR_DETECT        = 5,
+       MFC_FLAG_HDR_PLUS               = 6,
        MFC_FLAG_CSD                    = 29,
        MFC_FLAG_EMPTY_DATA             = 30,
        MFC_FLAG_LAST_FRAME             = 31,
@@ -427,6 +433,8 @@ struct mfc_platdata {
        unsigned int support_10bit;
        unsigned int support_422;
        unsigned int support_rgb;
+       /* HDR10+ */
+       unsigned int max_hdr_win;
 #ifdef CONFIG_MFC_USE_BUS_DEVFREQ
        /* QoS */
        unsigned int num_qos_steps;
@@ -446,6 +454,7 @@ struct mfc_platdata {
        struct mfc_feature static_info_dec;
        struct mfc_feature color_aspect_enc;
        struct mfc_feature static_info_enc;
+       struct mfc_feature hdr10_plus;
 #ifdef CONFIG_EXYNOS_BTS
        struct mfc_bw_info mfc_bw_info;
 #endif
@@ -465,15 +474,16 @@ struct mfc_platdata {
 };
 
 /************************ NAL_Q data structure ************************/
-#define NAL_Q_IN_ENTRY_SIZE            256
-#define NAL_Q_OUT_ENTRY_SIZE           256
+#define NAL_Q_IN_ENTRY_SIZE            512
+#define NAL_Q_OUT_ENTRY_SIZE           512
 
 #define NAL_Q_IN_DEC_STR_SIZE          112
 #define NAL_Q_IN_ENC_STR_SIZE          204
-#define NAL_Q_OUT_DEC_STR_SIZE         248
+#define NAL_Q_OUT_DEC_STR_SIZE         376
 #define NAL_Q_OUT_ENC_STR_SIZE         64
+#define NAL_Q_DUMP_MAX_STR_SIZE                376
 
-/* 256*128(max instance 32 * slot 4) = 32 kbytes */
+/* 512*128(max instance 32 * slot 4) = 64 kbytes */
 #define NAL_Q_IN_QUEUE_SIZE            128
 #define NAL_Q_OUT_QUEUE_SIZE           128
 
@@ -606,8 +616,11 @@ typedef struct __DecoderOutputStr {
        int MasteringDisplayColourVolumeSei3;
        int MasteringDisplayColourVolumeSei4;
        int MasteringDisplayColourVolumeSei5;
+       int FirstPlaneDpbSize;
+       int SecondPlaneDpbSize;
+       int St2094_40sei[30];
        char reserved[NAL_Q_OUT_ENTRY_SIZE - NAL_Q_OUT_DEC_STR_SIZE];
-} DecoderOutputStr; /* 62*4 =  248 bytes */
+} DecoderOutputStr; /* 94*4 =  376 bytes */
 
 typedef struct __EncoderOutputStr {
        int StartCode; /* 0xBBBBBBBB; Encoder output structure marker */
@@ -1224,6 +1237,70 @@ struct mfc_raw_info {
        unsigned int total_plane_size;
 };
 
+/* HDR10+ ST 2094 40 Metadata HEVC SEI Message */
+struct hdr10_plus_meta_per_win {
+       unsigned int  maxscl[HDR_MAX_SCL];
+       unsigned int  average_maxrgb;
+       unsigned char num_distribution_maxrgb_percentiles;
+       unsigned char distribution_maxrgb_percentages[HDR_MAX_DISTRIBUTION];
+       unsigned int  distribution_maxrgb_percentiles[HDR_MAX_DISTRIBUTION];
+       unsigned int  fraction_bright_pixels;
+
+       unsigned short tone_mapping_flag;
+       unsigned short knee_point_x;
+       unsigned short knee_point_y;
+       unsigned short num_bezier_curve_anchors;
+       unsigned short bezier_curve_anchors[HDR_MAX_BEZIER_CURVES];
+
+       unsigned char color_saturation_mapping_flag;
+       unsigned char color_saturation_weight;
+
+       /*
+        * This field is reserved for ST2094-40 SEI below or the others
+        * window_upper_left_corner_x
+        * window_upper_left_corner_y
+        * window_lower_right_corner_x
+        * window_lower_right_corner_y
+        * center_of_ellipse_x
+        * center_of_ellipse_y
+        * rotation_angle
+        * semimajor_axis_internal_ellipse
+        * semimajor_axis_external_ellipse
+        * semiminor_axis_external_ellipse
+        * overlap_process_option
+        */
+       unsigned int reserved[11];
+};
+
+struct hdr10_plus_meta {
+       unsigned int valid;
+
+       unsigned char  t35_country_code;
+       unsigned short t35_terminal_provider_code;
+       unsigned short t35_terminal_provider_oriented_code;
+       unsigned char  application_identifier;
+       unsigned short application_version;
+       unsigned char  num_windows;
+
+       unsigned int  target_maximum_luminance;
+       unsigned char target_actual_peak_luminance_flag;
+       unsigned char num_rows_target_luminance;
+       unsigned char num_cols_target_luminance;
+
+       unsigned char mastering_actual_peak_luminance_flag;
+       unsigned char num_rows_mastering_luminance;
+       unsigned char num_cols_mastering_luminance;
+
+       struct hdr10_plus_meta_per_win win_info[HDR_MAX_WINDOWS];
+
+       /*
+        * This field is reserved for ST2094-40 SEI below or the others
+        * targeted_system_display_actual_peak_luminance[rows][cols]
+        * mastering_display_actual_peak_luminance[rows][cols]
+        */
+       unsigned int reserved[11];
+};
+
 struct mfc_timestamp {
        struct list_head list;
        struct timeval timestamp;
@@ -1275,6 +1352,8 @@ struct mfc_dec {
        struct dec_dpb_ref_info *ref_info;
        int assigned_fd[MFC_MAX_DPBS];
        struct mfc_user_shared_handle sh_handle;
+       struct mfc_user_shared_handle sh_handle_hdr;
+       struct hdr10_plus_meta *hdr10_plus_info;
 
        int has_multiframe;
 
index e906d5e131ba36a9add6befcc38f98f6588c891f..cdf8cc6952eb7c0deb78fc6eed7a4d74b8439d8d 100644 (file)
@@ -535,6 +535,15 @@ static struct v4l2_queryctrl controls[] = {
                .step = 1,
                .default_value = 0,
        },
+       {
+               .id = V4L2_CID_MPEG_MFC_HDR_USER_SHARED_HANDLE,
+               .type = V4L2_CTRL_TYPE_INTEGER,
+               .name = "Dynamic HDR10+ SEI metadata",
+               .minimum = INT_MIN,
+               .maximum = INT_MAX,
+               .step = 1,
+               .default_value = 0,
+       },
 };
 
 #define NUM_CTRLS ARRAY_SIZE(controls)
index 6f43039edad5f3dc6cd81761cf3c8ceb74eed043..3533ea28c071c252681f31f49eb359da03289c13 100644 (file)
@@ -739,6 +739,7 @@ static int mfc_dec_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
        struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
        struct mfc_dec *dec = ctx->dec_priv;
        struct dec_dpb_ref_info *dstBuf, *srcBuf;
+       struct hdr10_plus_meta *dst_sei_meta, *src_sei_meta;
        int ret;
        int ncount = 0;
 
@@ -775,6 +776,14 @@ static int mfc_dec_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
                        memcpy(dstBuf, srcBuf, sizeof(struct dec_dpb_ref_info));
                        dstBuf->index = buf->index;
                }
+
+               /* Memcpy from dec->hdr10_plus_info to shared memory */
+               src_sei_meta = &dec->hdr10_plus_info[buf->index];
+               if (dec->sh_handle_hdr.vaddr != NULL) {
+                       dst_sei_meta = (struct hdr10_plus_meta *)
+                               dec->sh_handle_hdr.vaddr + buf->index;
+                       memcpy(dst_sei_meta, src_sei_meta, sizeof(struct hdr10_plus_meta));
+               }
        }
        mfc_debug_leave();
        return ret;
@@ -865,6 +874,9 @@ static int __mfc_dec_ext_info(struct mfc_ctx *ctx)
        if (MFC_FEATURE_SUPPORT(dev, dev->pdata->skype))
                val |= DEC_SET_SKYPE_FLAG;
 
+       if (MFC_FEATURE_SUPPORT(dev, dev->pdata->hdr10_plus))
+               val |= DEC_SET_HDR10_PLUS;
+
        mfc_debug(5, "[CTRLS] ext info val: %#x\n", val);
 
        return val;
@@ -1087,6 +1099,15 @@ static int mfc_dec_s_ctrl(struct file *file, void *priv,
        case V4L2_CID_MPEG_VIDEO_BLACK_BAR_DETECT:
                dec->detect_black_bar = ctrl->value;
                break;
+       case V4L2_CID_MPEG_MFC_HDR_USER_SHARED_HANDLE:
+               dec->sh_handle_hdr.fd = ctrl->value;
+               if (mfc_mem_get_user_shared_handle(ctx, &dec->sh_handle_hdr)) {
+                       dec->sh_handle_hdr.fd = -1;
+                       return -EINVAL;
+               }
+               mfc_debug(2, "[MEMINFO][HDR+] shared handle fd: %d, vaddr: 0x%p\n",
+                               dec->sh_handle_hdr.fd, dec->sh_handle_hdr.vaddr);
+               break;
        default:
                list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
                        if (!(ctx_ctrl->type & MFC_CTRL_TYPE_SET))
index 0ccdf85661966ec5d59ea59990660c87b6495c36..afc3ea4bfae239499a783d90204b6361d44cf3f0 100644 (file)
@@ -225,6 +225,7 @@ static void __mfc_handle_frame_output_del(struct mfc_ctx *ctx,
        unsigned int dst_frame_status;
        unsigned int is_video_signal_type = 0, is_colour_description = 0;
        unsigned int is_content_light = 0, is_display_colour = 0;
+       unsigned int is_hdr10_plus_sei = 0;
        unsigned int i, index;
 
        if (MFC_FEATURE_SUPPORT(dev, dev->pdata->color_aspect_dec)) {
@@ -237,6 +238,9 @@ static void __mfc_handle_frame_output_del(struct mfc_ctx *ctx,
                is_display_colour = mfc_get_sei_avail_mastering_display();
        }
 
+       if (MFC_FEATURE_SUPPORT(dev, dev->pdata->hdr10_plus))
+               is_hdr10_plus_sei = mfc_get_sei_avail_st_2094_40();
+
        if (MFC_FEATURE_SUPPORT(dev, dev->pdata->black_bar) && dec->detect_black_bar)
                __mfc_handle_black_bar_info(dev, ctx);
        else
@@ -299,6 +303,14 @@ static void __mfc_handle_frame_output_del(struct mfc_ctx *ctx,
                        mfc_debug(3, "[BLACKBAR] black bar detected\n");
                }
 
+               if (is_hdr10_plus_sei) {
+                       mfc_get_hdr_plus_info(ctx, &dec->hdr10_plus_info[index]);
+                       mfc_set_vb_flag(ref_mb, MFC_FLAG_HDR_PLUS);
+                       mfc_debug(2, "[HDR+] HDR10 plus dyanmic SEI metadata parsed\n");
+               } else {
+                       dec->hdr10_plus_info[index].valid = 0;
+               }
+
                if (ctx->src_fmt->mem_planes == 1) {
                        vb2_set_plane_payload(&ref_mb->vb.vb2_buf, 0,
                                        raw->total_plane_size);
index 3afcfb2870d5e42ba60ea70f264ed882bbf39e40..9a1b16d61971f9478559a88350032eb6ffbc062d 100644 (file)
@@ -551,6 +551,98 @@ static void __mfc_nal_q_set_slice_mode(struct mfc_ctx *ctx, EncoderInputStr *pIn
        }
 }
 
+static void __mfc_nal_q_get_hdr_plus_info(struct mfc_ctx *ctx, DecoderOutputStr *pOutStr,
+               struct hdr10_plus_meta *sei_meta)
+{
+       struct mfc_dev *dev = ctx->dev;
+       unsigned int upper_value, lower_value;
+       int num_win, num_distribution;
+       int i, j;
+
+       sei_meta->valid = 1;
+
+       /* iru_t_t35 */
+       sei_meta->t35_country_code = pOutStr->St2094_40sei[0] & 0xFF;
+       sei_meta->t35_terminal_provider_code = pOutStr->St2094_40sei[0] >> 8 & 0xFF;
+       upper_value = pOutStr->St2094_40sei[0] >> 24 & 0xFF;
+       lower_value = pOutStr->St2094_40sei[1] & 0xFF;
+       sei_meta->t35_terminal_provider_oriented_code = (upper_value << 8) | lower_value;
+
+       /* application */
+       sei_meta->application_identifier = pOutStr->St2094_40sei[1] >> 8 & 0xFF;
+       sei_meta->application_version = pOutStr->St2094_40sei[1] >> 16 & 0xFF;
+
+       /* window information */
+       sei_meta->num_windows = pOutStr->St2094_40sei[1] >> 24 & 0x3;
+       num_win = sei_meta->num_windows;
+       if (num_win > dev->pdata->max_hdr_win) {
+               mfc_err_ctx("NAL Q:[HDR+] num_window(%d) is exceeded supported max_num_window(%d)\n",
+                               num_win, dev->pdata->max_hdr_win);
+               num_win = dev->pdata->max_hdr_win;
+       }
+
+       /* luminance */
+       sei_meta->target_maximum_luminance = pOutStr->St2094_40sei[2] & 0x7FFFFFF;
+       sei_meta->target_actual_peak_luminance_flag = pOutStr->St2094_40sei[2] >> 27 & 0x1;
+       sei_meta->mastering_actual_peak_luminance_flag = pOutStr->St2094_40sei[22] >> 10 & 0x1;
+
+       /* per window setting */
+       for (i = 0; i < num_win; i++) {
+               /* scl */
+               for (j = 0; j < HDR_MAX_SCL; j++) {
+                       sei_meta->win_info[i].maxscl[j] =
+                               pOutStr->St2094_40sei[3 + j] & 0x1FFFF;
+               }
+               sei_meta->win_info[i].average_maxrgb =
+                       pOutStr->St2094_40sei[6] & 0x1FFFF;
+
+               /* distribution */
+               sei_meta->win_info[i].num_distribution_maxrgb_percentiles =
+                       pOutStr->St2094_40sei[6] >> 17 & 0xF;
+               num_distribution = sei_meta->win_info[i].num_distribution_maxrgb_percentiles;
+               for (j = 0; j < num_distribution; j++) {
+                       sei_meta->win_info[i].distribution_maxrgb_percentages[j] =
+                               pOutStr->St2094_40sei[7 + j] & 0x7F;
+                       sei_meta->win_info[i].distribution_maxrgb_percentiles[j] =
+                               pOutStr->St2094_40sei[7 + j] >> 7 & 0x1FFFF;
+               }
+
+               /* bright pixels */
+               sei_meta->win_info[i].fraction_bright_pixels =
+                       pOutStr->St2094_40sei[22] & 0x3FF;
+
+               /* tone mapping */
+               sei_meta->win_info[i].tone_mapping_flag =
+                       pOutStr->St2094_40sei[22] >> 11 & 0x1;
+               if (sei_meta->win_info[i].tone_mapping_flag) {
+                       sei_meta->win_info[i].knee_point_x =
+                               pOutStr->St2094_40sei[23] & 0xFFF;
+                       sei_meta->win_info[i].knee_point_y =
+                               pOutStr->St2094_40sei[23] >> 12 & 0xFFF;
+                       sei_meta->win_info[i].num_bezier_curve_anchors =
+                               pOutStr->St2094_40sei[23] >> 24 & 0xF;
+                       for (j = 0; j < HDR_MAX_BEZIER_CURVES / 3; j++) {
+                               sei_meta->win_info[i].bezier_curve_anchors[j * 3] =
+                                       pOutStr->St2094_40sei[24 + j] & 0x3FF;
+                               sei_meta->win_info[i].bezier_curve_anchors[j * 3 + 1] =
+                                       pOutStr->St2094_40sei[24 + j] >> 10 & 0x3FF;
+                               sei_meta->win_info[i].bezier_curve_anchors[j * 3 + 2] =
+                                       pOutStr->St2094_40sei[24 + j] >> 20 & 0x3FF;
+                       }
+               }
+
+               /* color saturation */
+               sei_meta->win_info[i].color_saturation_mapping_flag =
+                       pOutStr->St2094_40sei[29] & 0x1;
+               if (sei_meta->win_info[i].color_saturation_mapping_flag)
+                       sei_meta->win_info[i].color_saturation_weight =
+                               pOutStr->St2094_40sei[29] >> 1 & 0x3F;
+       }
+
+       if (debug_level >= 5)
+               mfc_print_dec_hdr_plus_info(ctx, index);
+}
+
 static int __mfc_nal_q_run_in_buf_enc(struct mfc_ctx *ctx, EncoderInputStr *pInStr)
 {
        struct mfc_dev *dev = ctx->dev;
@@ -1140,6 +1232,7 @@ static void __mfc_nal_q_handle_frame_output_del(struct mfc_ctx *ctx,
        unsigned int dst_frame_status;
        unsigned int is_video_signal_type = 0, is_colour_description = 0;
        unsigned int is_content_light = 0, is_display_colour = 0;
+       unsigned int is_hdr10_plus_sei = 0;
        unsigned int disp_err;
        int i, index;
 
@@ -1159,6 +1252,9 @@ static void __mfc_nal_q_handle_frame_output_del(struct mfc_ctx *ctx,
                                        & MFC_REG_D_SEI_AVAIL_MASTERING_DISPLAY_MASK);
        }
 
+       if (MFC_FEATURE_SUPPORT(dev, dev->pdata->hdr10_plus))
+               is_hdr10_plus_sei = ((pOutStr->SeiAvail >> MFC_REG_D_SEI_AVAIL_ST_2094_40_SHIFT)
+                                       & MFC_REG_D_SEI_AVAIL_ST_2094_40_MASK);
        if (dec->immediate_display == 1) {
                dspl_y_addr = pOutStr->DecodedAddr[0];
                frame_type = pOutStr->DecodedFrameType & MFC_REG_DECODED_FRAME_MASK;
@@ -1208,6 +1304,14 @@ static void __mfc_nal_q_handle_frame_output_del(struct mfc_ctx *ctx,
                        mfc_debug(2, "[NALQ][HDR] color range parsed\n");
                }
 
+               if (is_hdr10_plus_sei) {
+                       __mfc_nal_q_get_hdr_plus_info(ctx, pOutStr, &dec->hdr10_plus_info[index]);
+                       mfc_set_vb_flag(ref_mb, MFC_FLAG_HDR_PLUS);
+                       mfc_debug(2, "[NALQ][HDR+] HDR10 plus dyanmic SEI metadata parsed\n");
+               } else {
+                       dec->hdr10_plus_info[index].valid = 0;
+               }
+
                for (i = 0; i < raw->num_planes; i++)
                        vb2_set_plane_payload(&ref_mb->vb.vb2_buf, i,
                                        raw->plane_size[i]);
@@ -1680,7 +1784,8 @@ int mfc_nal_q_enqueue_in_buf(struct mfc_dev *dev, struct mfc_ctx *ctx,
                mfc_err_dev("[NAL-Q][DUMP][%s INPUT][c: %d] diff: %d, count: %d, exe: %d\n",
                                ctx->type == MFCINST_ENCODER ? "ENC" : "DEC", dev->curr_ctx,
                                input_diff, input_count, input_exe_count);
-               print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 32, 4, (int *)pStr, 256, false);
+               print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 32, 4,
+                               (int *)pStr, NAL_Q_DUMP_MAX_STR_SIZE, false);
                printk("...\n");
        }
        input_count++;
@@ -1763,7 +1868,8 @@ EncoderOutputStr *mfc_nal_q_dequeue_out_buf(struct mfc_dev *dev,
                                ctx->type == MFCINST_ENCODER ? "ENC" : "DEC",
                                nal_q_out_handle->nal_q_ctx,
                                output_diff, output_count, output_exe_count);
-               print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 32, 4, (int *)pStr, 256, false);
+               print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 32, 4,
+                               (int *)pStr, NAL_Q_DUMP_MAX_STR_SIZE, false);
                printk("...\n");
        }
        nal_q_out_handle->out_exe_count++;
index 263c663dcc565788544f7b93546026eb38bda4ee..1c82ab926c78c1137c63036df50311c5ca6c781f 100644 (file)
@@ -514,3 +514,167 @@ void mfc_set_pixel_format(struct mfc_dev *dev, unsigned int format)
        mfc_debug(2, "[FRAME] pixel format: %d, mem_type_10bit for 10bit: %d (reg: %#x)\n",
                        pix_val, mem_type_10bit, reg);
 }
+
+void mfc_print_dec_hdr_plus_info(struct mfc_ctx *ctx, int index)
+{
+       struct mfc_dev *dev = ctx->dev;
+       struct mfc_dec *dec = ctx->dec_priv;
+       struct hdr10_plus_meta *sei_meta;
+       int num_distribution;
+       int i, j;
+
+       sei_meta = &dec->hdr10_plus_info[index];
+
+       mfc_debug(5, "[HDR+] ================================================================\n");
+       mfc_debug(5, "[HDR+] valid: %#x\n", sei_meta->valid);
+       mfc_debug(5, "[HDR+] itu t35 country_code: %#x, provider_code %#x, oriented_code: %#x\n",
+                       sei_meta->t35_country_code, sei_meta->t35_terminal_provider_code,
+                       sei_meta->t35_terminal_provider_oriented_code);
+       mfc_debug(5, "[HDR+] application identifier: %#x, version: %#x, num_windows: %#x\n",
+                       sei_meta->application_identifier, sei_meta->application_version,
+                       sei_meta->num_windows);
+       mfc_debug(5, "[HDR+] target_maximum_luminance: %#x, target_actual_peak_luminance_flag %#x\n",
+                       sei_meta->target_maximum_luminance,
+                       sei_meta->target_actual_peak_luminance_flag);
+       mfc_debug(5, "[HDR+] mastering_actual_peak_luminance_flag %#x\n",
+                       sei_meta->mastering_actual_peak_luminance_flag);
+
+       for (i = 0; i < sei_meta->num_windows; i++) {
+               mfc_debug(5, "[HDR+] -------- window[%d] info --------\n", i);
+               for (j = 0; j < HDR_MAX_SCL; j++)
+                       mfc_debug(5, "[HDR+] maxscl[%d] %#x\n", j,
+                                       sei_meta->win_info[i].maxscl[j]);
+               mfc_debug(5, "[HDR+] average_maxrgb %#x, num_distribution_maxrgb_percentiles %#x\n",
+                               sei_meta->win_info[i].average_maxrgb,
+                               sei_meta->win_info[i].num_distribution_maxrgb_percentiles);
+               num_distribution = sei_meta->win_info[i].num_distribution_maxrgb_percentiles;
+               for (j = 0; j < num_distribution; j++)
+                       mfc_debug(5, "[HDR+] percentages[%d] %#x, percentiles[%d] %#x\n", j,
+                                       sei_meta->win_info[i].distribution_maxrgb_percentages[j], j,
+                                       sei_meta->win_info[i].distribution_maxrgb_percentiles[j]);
+
+               mfc_debug(5, "[HDR+] fraction_bright_pixels %#x, tone_mapping_flag %#x\n",
+                               sei_meta->win_info[i].fraction_bright_pixels,
+                               sei_meta->win_info[i].tone_mapping_flag);
+               if (sei_meta->win_info[i].tone_mapping_flag) {
+                       mfc_debug(5, "[HDR+] knee point x %#x, knee point y %#x\n",
+                                       sei_meta->win_info[i].knee_point_x,
+                                       sei_meta->win_info[i].knee_point_y);
+                       mfc_debug(5, "[HDR+] num_bezier_curve_anchors %#x\n",
+                                       sei_meta->win_info[i].num_bezier_curve_anchors);
+                       for (j = 0; j < HDR_MAX_BEZIER_CURVES / 3; j++)
+                               mfc_debug(5, "[HDR+] anchors[%d] %#x, [%d] %#x, [%d] %#x\n",
+                                               j * 3,
+                                               sei_meta->win_info[i].bezier_curve_anchors[j * 3],
+                                               j * 3 + 1,
+                                               sei_meta->win_info[i].bezier_curve_anchors[j * 3 + 1],
+                                               j * 3 + 2,
+                                               sei_meta->win_info[i].bezier_curve_anchors[j * 3 + 2]);
+               }
+               mfc_debug(5, "[HDR+] color_saturation mapping_flag %#x, weight: %#x\n",
+                               sei_meta->win_info[i].color_saturation_mapping_flag,
+                               sei_meta->win_info[i].color_saturation_weight);
+       }
+
+       mfc_debug(5, "[HDR+] ================================================================\n");
+
+       /* Do not need to dump register */
+       if (dev->nal_q_handle)
+               if (dev->nal_q_handle->nal_q_state == NAL_Q_STATE_STARTED)
+                       return;
+
+       print_hex_dump(KERN_ERR, "[HDR+] ", DUMP_PREFIX_ADDRESS, 32, 4,
+                       dev->regs_base + MFC_REG_D_ST_2094_40_SEI_0, 0x78, false);
+}
+
+void mfc_get_hdr_plus_info(struct mfc_ctx *ctx, struct hdr10_plus_meta *sei_meta)
+{
+       struct mfc_dev *dev = ctx->dev;
+       unsigned int upper_value, lower_value;
+       int num_win, num_distribution;
+       int i, j;
+
+       sei_meta->valid = 1;
+
+       /* iru_t_t35 */
+       sei_meta->t35_country_code = MFC_READL(MFC_REG_D_ST_2094_40_SEI_0) & 0xFF;
+       sei_meta->t35_terminal_provider_code = MFC_READL(MFC_REG_D_ST_2094_40_SEI_0) >> 8 & 0xFF;
+       upper_value = MFC_READL(MFC_REG_D_ST_2094_40_SEI_0) >> 24 & 0xFF;
+       lower_value = MFC_READL(MFC_REG_D_ST_2094_40_SEI_1) & 0xFF;
+       sei_meta->t35_terminal_provider_oriented_code = (upper_value << 8) | lower_value;
+
+       /* application */
+       sei_meta->application_identifier = MFC_READL(MFC_REG_D_ST_2094_40_SEI_1) >> 8 & 0xFF;
+       sei_meta->application_version = MFC_READL(MFC_REG_D_ST_2094_40_SEI_1) >> 16 & 0xFF;
+
+       /* window information */
+       sei_meta->num_windows = MFC_READL(MFC_REG_D_ST_2094_40_SEI_1) >> 24 & 0x3;
+       num_win = sei_meta->num_windows;
+       if (num_win > dev->pdata->max_hdr_win) {
+               mfc_err_ctx("[HDR+] num_window(%d) is exceeded supported max_num_window(%d)\n",
+                               num_win, dev->pdata->max_hdr_win);
+               num_win = dev->pdata->max_hdr_win;
+               sei_meta->num_windows = num_win;
+       }
+
+       /* luminance */
+       sei_meta->target_maximum_luminance = MFC_READL(MFC_REG_D_ST_2094_40_SEI_2) & 0x7FFFFFF;
+       sei_meta->target_actual_peak_luminance_flag = MFC_READL(MFC_REG_D_ST_2094_40_SEI_2) >> 27 & 0x1;
+       sei_meta->mastering_actual_peak_luminance_flag = MFC_READL(MFC_REG_D_ST_2094_40_SEI_22) >> 10 & 0x1;
+
+       /* per window setting */
+       for (i = 0; i < num_win; i++) {
+               /* scl */
+               for (j = 0; j < HDR_MAX_SCL; j++) {
+                       sei_meta->win_info[i].maxscl[j] =
+                               MFC_READL(MFC_REG_D_ST_2094_40_SEI_3 + (4 * j)) & 0x1FFFF;
+               }
+               sei_meta->win_info[i].average_maxrgb =
+                       MFC_READL(MFC_REG_D_ST_2094_40_SEI_6) & 0x1FFFF;
+
+               /* distribution */
+               sei_meta->win_info[i].num_distribution_maxrgb_percentiles =
+                       MFC_READL(MFC_REG_D_ST_2094_40_SEI_6) >> 17 & 0xF;
+               num_distribution = sei_meta->win_info[i].num_distribution_maxrgb_percentiles;
+               for (j = 0; j < num_distribution; j++) {
+                       sei_meta->win_info[i].distribution_maxrgb_percentages[j] =
+                               MFC_READL(MFC_REG_D_ST_2094_40_SEI_7 + (4 * j)) & 0x7F;
+                       sei_meta->win_info[i].distribution_maxrgb_percentiles[j] =
+                               MFC_READL(MFC_REG_D_ST_2094_40_SEI_7 + (4 * j)) >> 7 & 0x1FFFF;
+               }
+
+               /* bright pixels */
+               sei_meta->win_info[i].fraction_bright_pixels =
+                       MFC_READL(MFC_REG_D_ST_2094_40_SEI_22) & 0x3FF;
+
+               /* tone mapping */
+               sei_meta->win_info[i].tone_mapping_flag =
+                       MFC_READL(MFC_REG_D_ST_2094_40_SEI_22) >> 11 & 0x1;
+               if (sei_meta->win_info[i].tone_mapping_flag) {
+                       sei_meta->win_info[i].knee_point_x =
+                               MFC_READL(MFC_REG_D_ST_2094_40_SEI_23) & 0xFFF;
+                       sei_meta->win_info[i].knee_point_y =
+                               MFC_READL(MFC_REG_D_ST_2094_40_SEI_23) >> 12 & 0xFFF;
+                       sei_meta->win_info[i].num_bezier_curve_anchors =
+                               MFC_READL(MFC_REG_D_ST_2094_40_SEI_23) >> 24 & 0xF;
+                       for (j = 0; j < HDR_MAX_BEZIER_CURVES / 3; j++) {
+                               sei_meta->win_info[i].bezier_curve_anchors[j * 3] =
+                                       MFC_READL(MFC_REG_D_ST_2094_40_SEI_24 + (4 * j)) & 0x3FF;
+                               sei_meta->win_info[i].bezier_curve_anchors[j * 3 + 1] =
+                                       MFC_READL(MFC_REG_D_ST_2094_40_SEI_24 + (4 * j)) >> 10 & 0x3FF;
+                               sei_meta->win_info[i].bezier_curve_anchors[j * 3 + 2] =
+                                       MFC_READL(MFC_REG_D_ST_2094_40_SEI_24 + (4 * j)) >> 20 & 0x3FF;
+                       }
+               }
+
+               /* color saturation */
+               sei_meta->win_info[i].color_saturation_mapping_flag =
+                       MFC_READL(MFC_REG_D_ST_2094_40_SEI_29) & 0x1;
+               if (sei_meta->win_info[i].color_saturation_mapping_flag)
+                       sei_meta->win_info[i].color_saturation_weight =
+                               MFC_READL(MFC_REG_D_ST_2094_40_SEI_29) >> 1 & 0x3F;
+       }
+
+       if (debug_level >= 5)
+               mfc_print_dec_hdr_plus_info(ctx, index);
+}
index 25754a8d9ff66803f9ffe7cfc12d0997dcf9a7dc..251904e79a8e50fd8b0838d8bb5130223b7738fa 100644 (file)
 #define mfc_get_sei_avail_mastering_display()  ((MFC_READL(MFC_REG_D_SEI_AVAIL)        \
                                                >> MFC_REG_D_SEI_AVAIL_MASTERING_DISPLAY_SHIFT) \
                                                & MFC_REG_D_SEI_AVAIL_MASTERING_DISPLAY_MASK)
+#define mfc_get_sei_avail_st_2094_40()         ((MFC_READL(MFC_REG_D_SEI_AVAIL)        \
+                                               >> MFC_REG_D_SEI_AVAIL_ST_2094_40_SHIFT)        \
+                                               & MFC_REG_D_SEI_AVAIL_ST_2094_40_MASK)
 #define mfc_get_video_signal_type()            ((MFC_READL(MFC_REG_D_VIDEO_SIGNAL_TYPE)        \
                                                >> MFC_REG_D_VIDEO_SIGNAL_TYPE_FLAG_SHIFT)      \
                                                & MFC_REG_D_VIDEO_SIGNAL_TYPE_FLAG_MASK)
@@ -271,4 +274,7 @@ int mfc_set_dynamic_dpb(struct mfc_ctx *ctx, struct mfc_buf *dst_vb);
 
 void mfc_set_pixel_format(struct mfc_dev *dev, unsigned int format);
 
+void mfc_print_dec_hdr_plus_info(struct mfc_ctx *ctx, int index);
+void mfc_get_hdr_plus_info(struct mfc_ctx *ctx, struct hdr10_plus_meta *sei_meta);
+
 #endif /* __MFC_REG_API_H */
index ee569f44849a26c012fbff8a6daba8150cc54b31..bb9fb73c5d9579e97f4e81e2b24140975ac75135 100644 (file)
 #define MFC_REG_E_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_4        0xFE0C
 #define MFC_REG_E_MASTERING_DISPLAY_COLOUR_VOLUME_SEI_5        0xFE10
 
+#define MFC_REG_D_ST_2094_40_SEI_0                             0xFF00
+#define MFC_REG_D_ST_2094_40_SEI_1                             0xFF04
+#define MFC_REG_D_ST_2094_40_SEI_2                             0xFF08
+#define MFC_REG_D_ST_2094_40_SEI_3                             0xFF0C
+#define MFC_REG_D_ST_2094_40_SEI_4                             0xFF10
+#define MFC_REG_D_ST_2094_40_SEI_5                             0xFF14
+#define MFC_REG_D_ST_2094_40_SEI_6                             0xFF18
+#define MFC_REG_D_ST_2094_40_SEI_7                             0xFF1C
+#define MFC_REG_D_ST_2094_40_SEI_8                             0xFF20
+#define MFC_REG_D_ST_2094_40_SEI_9                             0xFF24
+#define MFC_REG_D_ST_2094_40_SEI_10                            0xFF28
+#define MFC_REG_D_ST_2094_40_SEI_11                            0xFF2C
+#define MFC_REG_D_ST_2094_40_SEI_12                            0xFF30
+#define MFC_REG_D_ST_2094_40_SEI_13                            0xFF34
+#define MFC_REG_D_ST_2094_40_SEI_14                            0xFF38
+#define MFC_REG_D_ST_2094_40_SEI_15                            0xFF3C
+#define MFC_REG_D_ST_2094_40_SEI_16                            0xFF40
+#define MFC_REG_D_ST_2094_40_SEI_17                            0xFF44
+#define MFC_REG_D_ST_2094_40_SEI_18                            0xFF48
+#define MFC_REG_D_ST_2094_40_SEI_19                            0xFF4C
+#define MFC_REG_D_ST_2094_40_SEI_20                            0xFF50
+#define MFC_REG_D_ST_2094_40_SEI_21                            0xFF54
+#define MFC_REG_D_ST_2094_40_SEI_22                            0xFF58
+#define MFC_REG_D_ST_2094_40_SEI_23                            0xFF5C
+#define MFC_REG_D_ST_2094_40_SEI_24                            0xFF60
+#define MFC_REG_D_ST_2094_40_SEI_25                            0xFF64
+#define MFC_REG_D_ST_2094_40_SEI_26                            0xFF68
+#define MFC_REG_D_ST_2094_40_SEI_27                            0xFF6C
+#define MFC_REG_D_ST_2094_40_SEI_28                            0xFF70
+#define MFC_REG_D_ST_2094_40_SEI_29                            0xFF74
+
 
 #define MFC_REG_REG_CLEAR_BEGIN                        0xf000
 #define MFC_REG_REG_CLEAR_COUNT                        1024
 #define MFC_REG_D_SEI_ENABLE_RECOVERY_PARSING_SHIFT    2
 #define MFC_REG_D_SEI_ENABLE_CONTENT_LIGHT_SHIFT       4
 #define MFC_REG_D_SEI_ENABLE_MASTERING_DISPLAY_SHIFT   5
+#define MFC_REG_D_SEI_ENABLE_ST_2094_40_SEI_SHIFT      6
 
 
 /* 0xF154: MFC_REG_D_INIT_BUFFER_OPTIONS */
 #define MFC_REG_D_SEI_AVAIL_CONTENT_LIGHT_SHIFT        1
 #define MFC_REG_D_SEI_AVAIL_MASTERING_DISPLAY_MASK     0x1
 #define MFC_REG_D_SEI_AVAIL_MASTERING_DISPLAY_SHIFT    2
+#define MFC_REG_D_SEI_AVAIL_ST_2094_40_MASK            0x1
+#define MFC_REG_D_SEI_AVAIL_ST_2094_40_SHIFT           3
 
 
 /* 0xF70C: MFC_REG_D_VIDEO_SIGNAL_TYPE */