From 30ac9fb8b0568f549229e3f8b907b49ef2ce29fe Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Sat, 22 Jun 2019 13:44:05 +0000
Subject: [PATCH] [h265d]: export mastering display and content light metadata

---
 inc/mpp_frame.h                   | 16 ++++++++++++++++
 mpp/base/inc/mpp_frame_impl.h     |  2 ++
 mpp/base/mpp_frame.cpp            |  2 ++
 mpp/codec/dec/h265/h265d_parser.h |  3 +++
 mpp/codec/dec/h265/h265d_refs.c   |  2 ++
 mpp/codec/dec/h265/h265d_sei.c    | 21 +++++++++++++++++++++
 6 files changed, 46 insertions(+)

diff --git a/inc/mpp_frame.h b/inc/mpp_frame.h
index 33a6e644..a2a4cf81 100644
--- a/inc/mpp_frame.h
+++ b/inc/mpp_frame.h
@@ -199,6 +199,18 @@ typedef struct MppFrameRational {
     RK_S32 den; ///< Denominator
 } MppFrameRational;
 
+typedef struct MppFrameMasteringDisplayMetadata {
+    RK_U16 display_primaries[3][2];
+    RK_U16 white_point[2];
+    RK_U32 max_luminance;
+    RK_U32 min_luminance;
+} MppFrameMasteringDisplayMetadata;
+
+typedef struct MppFrameContentLightMetadata {
+    RK_U16 MaxCLL;
+    RK_U16 MaxFALL;
+} MppFrameContentLightMetadata;
+
 typedef enum {
     MPP_FRAME_ERR_UNKNOW           = 0x0001,
     MPP_FRAME_ERR_UNSUPPORT        = 0x0002,
@@ -278,6 +290,10 @@ MppFrameFormat mpp_frame_get_fmt(MppFrame frame);
 void    mpp_frame_set_fmt(MppFrame frame, MppFrameFormat fmt);
 MppFrameRational mpp_frame_get_sar(const MppFrame frame);
 void    mpp_frame_set_sar(MppFrame frame, MppFrameRational sar);
+MppFrameMasteringDisplayMetadata mpp_frame_get_mastering_display(const MppFrame frame);
+void    mpp_frame_set_mastering_display(MppFrame frame, MppFrameMasteringDisplayMetadata mastering_display);
+MppFrameContentLightMetadata mpp_frame_get_content_light(const MppFrame frame);
+void    mpp_frame_set_content_light(MppFrame frame, MppFrameContentLightMetadata content_light);
 
 /*
  * HDR parameter
diff --git a/mpp/base/inc/mpp_frame_impl.h b/mpp/base/inc/mpp_frame_impl.h
index 30898a1a..a5433888 100644
--- a/mpp/base/inc/mpp_frame_impl.h
+++ b/mpp/base/inc/mpp_frame_impl.h
@@ -89,6 +89,8 @@ struct MppFrameImpl_t {
     MppFrameFormat fmt;
 
     MppFrameRational sar;
+    MppFrameMasteringDisplayMetadata mastering_display;
+    MppFrameContentLightMetadata content_light;
 
     /*
      * buffer information
diff --git a/mpp/base/mpp_frame.cpp b/mpp/base/mpp_frame.cpp
index b94d1622..d58786c9 100644
--- a/mpp/base/mpp_frame.cpp
+++ b/mpp/base/mpp_frame.cpp
@@ -200,5 +200,7 @@ MPP_FRAME_ACCESSORS(MppFrameColorSpace, colorspace)
 MPP_FRAME_ACCESSORS(MppFrameChromaLocation, chroma_location)
 MPP_FRAME_ACCESSORS(MppFrameFormat, fmt)
 MPP_FRAME_ACCESSORS(MppFrameRational, sar)
+MPP_FRAME_ACCESSORS(MppFrameMasteringDisplayMetadata, mastering_display)
+MPP_FRAME_ACCESSORS(MppFrameContentLightMetadata, content_light)
 MPP_FRAME_ACCESSORS(size_t, buf_size)
 MPP_FRAME_ACCESSORS(RK_U32, errinfo)
diff --git a/mpp/codec/dec/h265/h265d_parser.h b/mpp/codec/dec/h265/h265d_parser.h
index bf42eb97..3b1264fa 100644
--- a/mpp/codec/dec/h265/h265d_parser.h
+++ b/mpp/codec/dec/h265/h265d_parser.h
@@ -678,6 +678,9 @@ typedef struct HEVCContext {
     RK_U32    got_frame;
     RK_U32    extra_has_frame;
 
+    MppFrameMasteringDisplayMetadata mastering_display;
+    MppFrameContentLightMetadata content_light;
+
     MppBufSlots slots;
 
     MppBufSlots packet_slots;
diff --git a/mpp/codec/dec/h265/h265d_refs.c b/mpp/codec/dec/h265/h265d_refs.c
index 80905d98..8d5092a5 100644
--- a/mpp/codec/dec/h265/h265d_refs.c
+++ b/mpp/codec/dec/h265/h265d_refs.c
@@ -95,6 +95,8 @@ static HEVCFrame *alloc_frame(HEVCContext *s)
         mpp_frame_set_color_primaries(frame->frame, s->sps->vui.colour_primaries);
         mpp_frame_set_color_trc(frame->frame, s->sps->vui.transfer_characteristic);
         mpp_frame_set_colorspace(frame->frame, s->h265dctx->colorspace);
+        mpp_frame_set_mastering_display(frame->frame, s->mastering_display);
+        mpp_frame_set_content_light(frame->frame, s->content_light);
         h265d_dbg(H265D_DBG_GLOBAL, "w_stride %d h_stride %d\n", s->h265dctx->coded_width, s->h265dctx->coded_height);
         ret = mpp_buf_slot_get_unused(s->slots, &frame->slot_index);
         mpp_assert(ret == MPP_OK);
diff --git a/mpp/codec/dec/h265/h265d_sei.c b/mpp/codec/dec/h265/h265d_sei.c
index 4706b922..86beb428 100644
--- a/mpp/codec/dec/h265/h265d_sei.c
+++ b/mpp/codec/dec/h265/h265d_sei.c
@@ -154,12 +154,18 @@ static RK_S32 mastering_display_colour_volume(HEVCContext *s)
     BitReadCtx_t *gb = &s->HEVClc->gb;
     for (i = 0; i < 3; i++) {
         READ_BITS(gb, 16, &value);
+        s->mastering_display.display_primaries[i][0] = value;
         READ_BITS(gb, 16, &value);
+        s->mastering_display.display_primaries[i][1] = value;
     }
     READ_BITS(gb, 16, &value);
+    s->mastering_display.white_point[0] = value;
     READ_BITS(gb, 16, &value);
+    s->mastering_display.white_point[1] = value;
     mpp_read_longbits(gb, 32, &lum);
+    s->mastering_display.max_luminance = lum;
     mpp_read_longbits(gb, 32, &lum);
+    s->mastering_display.min_luminance = lum;
 
     return 0;
 
@@ -167,6 +173,17 @@ __BITREAD_ERR:
     return  MPP_ERR_STREAM;
 }
 
+static RK_S32 content_light_info(HEVCContext *s)
+{
+    RK_U32 value = 0;
+    BitReadCtx_t *gb = &s->HEVClc->gb;
+    mpp_read_longbits(gb, 16, &value);
+    s->content_light.MaxCLL = value;
+    mpp_read_longbits(gb, 16, &value);
+    s->content_light.MaxFALL = value;
+    return 0;
+}
+
 static RK_S32 colour_remapping_info(HEVCContext *s)
 {
     RK_U32 i = 0, j = 0;
@@ -344,6 +361,10 @@ static RK_S32 decode_nal_sei_message(HEVCContext *s)
             h265d_dbg(H265D_DBG_SEI, "mastering_display_colour_volume in\n");
             mastering_display_colour_volume(s);
             return 1;
+        } else if (payload_type == 144) {
+            h265d_dbg(H265D_DBG_SEI, "content_light_info in\n");
+            content_light_info(s);
+            return 1;
         } else if (payload_type == 143) {
             h265d_dbg(H265D_DBG_SEI, "colour_remapping_info in\n");
             colour_remapping_info(s);
