xref: /rockchip-linux_mpp/mpp/base/mpp_dec_hdr_meta.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka  * Copyright 2022 Rockchip Electronics Co. LTD
3*437bfbebSnyanmisaka  *
4*437bfbebSnyanmisaka  * Licensed under the Apache License, Version 2.0 (the "License");
5*437bfbebSnyanmisaka  * you may not use this file except in compliance with the License.
6*437bfbebSnyanmisaka  * You may obtain a copy of the License at
7*437bfbebSnyanmisaka  *
8*437bfbebSnyanmisaka  *      http://www.apache.org/licenses/LICENSE-2.0
9*437bfbebSnyanmisaka  *
10*437bfbebSnyanmisaka  * Unless required by applicable law or agreed to in writing, software
11*437bfbebSnyanmisaka  * distributed under the License is distributed on an "AS IS" BASIS,
12*437bfbebSnyanmisaka  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*437bfbebSnyanmisaka  * See the License for the specific language governing permissions and
14*437bfbebSnyanmisaka  * limitations under the License.
15*437bfbebSnyanmisaka  */
16*437bfbebSnyanmisaka 
17*437bfbebSnyanmisaka #include <string.h>
18*437bfbebSnyanmisaka #include "rk_hdr_meta_com.h"
19*437bfbebSnyanmisaka #include "mpp_common.h"
20*437bfbebSnyanmisaka #include "mpp_log.h"
21*437bfbebSnyanmisaka #include "mpp_frame.h"
22*437bfbebSnyanmisaka 
23*437bfbebSnyanmisaka /* h(104) + d(100) + r(114) */
24*437bfbebSnyanmisaka #define HDR_META_MAGIC 318
25*437bfbebSnyanmisaka 
hdr_get_offset_from_frame(MppFrame frame)26*437bfbebSnyanmisaka static RK_U32 hdr_get_offset_from_frame(MppFrame frame)
27*437bfbebSnyanmisaka {
28*437bfbebSnyanmisaka     return mpp_frame_get_buf_size(frame);
29*437bfbebSnyanmisaka }
30*437bfbebSnyanmisaka 
fill_hdr_meta_to_frame(MppFrame frame,MppCodingType in_type)31*437bfbebSnyanmisaka void fill_hdr_meta_to_frame(MppFrame frame, MppCodingType in_type)
32*437bfbebSnyanmisaka {
33*437bfbebSnyanmisaka     RK_U32 off = hdr_get_offset_from_frame(frame);
34*437bfbebSnyanmisaka     MppBuffer buf = mpp_frame_get_buffer(frame);
35*437bfbebSnyanmisaka     void *ptr = mpp_buffer_get_ptr(buf);
36*437bfbebSnyanmisaka     MppFrameHdrDynamicMeta *dynamic_meta = mpp_frame_get_hdr_dynamic_meta(frame);
37*437bfbebSnyanmisaka     MppFrameMasteringDisplayMetadata mastering_display = mpp_frame_get_mastering_display(frame);
38*437bfbebSnyanmisaka     MppFrameContentLightMetadata content_light = mpp_frame_get_content_light(frame);
39*437bfbebSnyanmisaka     RkMetaHdrHeader *hdr_static_meta_header;
40*437bfbebSnyanmisaka     RkMetaHdrHeader *hdr_dynamic_meta_header;
41*437bfbebSnyanmisaka     RK_U32 msg_idx = 0;
42*437bfbebSnyanmisaka     RK_U16 hdr_format = HDR_NONE;
43*437bfbebSnyanmisaka     MppMeta meta = NULL;
44*437bfbebSnyanmisaka     RK_U32 max_size = mpp_buffer_get_size(buf);
45*437bfbebSnyanmisaka     RK_U32 static_size, dynamic_size = 0, total_size = 0;
46*437bfbebSnyanmisaka     HdrCodecType codec_type = HDR_CODEC_UNSPECIFIED;
47*437bfbebSnyanmisaka 
48*437bfbebSnyanmisaka     if (!ptr || !buf) {
49*437bfbebSnyanmisaka         mpp_err_f("buf is null!\n");
50*437bfbebSnyanmisaka         return;
51*437bfbebSnyanmisaka     }
52*437bfbebSnyanmisaka 
53*437bfbebSnyanmisaka     if (mpp_frame_get_thumbnail_en(frame) == MPP_FRAME_THUMBNAIL_ONLY) {
54*437bfbebSnyanmisaka         // only for 8K thumbnail downscale to 4K 8bit mode
55*437bfbebSnyanmisaka         RK_U32 downscale_width = mpp_frame_get_width(frame) / 2;
56*437bfbebSnyanmisaka         RK_U32 downscale_height = mpp_frame_get_height(frame) / 2;
57*437bfbebSnyanmisaka 
58*437bfbebSnyanmisaka         off = downscale_width * downscale_height * 3 / 2;
59*437bfbebSnyanmisaka     }
60*437bfbebSnyanmisaka     off = MPP_ALIGN(off, SZ_4K);
61*437bfbebSnyanmisaka 
62*437bfbebSnyanmisaka     static_size = sizeof(RkMetaHdrHeader) + sizeof(HdrStaticMeta);
63*437bfbebSnyanmisaka     if (dynamic_meta && dynamic_meta->size)
64*437bfbebSnyanmisaka         dynamic_size = sizeof(RkMetaHdrHeader) + dynamic_meta->size;
65*437bfbebSnyanmisaka 
66*437bfbebSnyanmisaka     total_size = static_size + dynamic_size;
67*437bfbebSnyanmisaka 
68*437bfbebSnyanmisaka     if ((off + total_size) > max_size) {
69*437bfbebSnyanmisaka         mpp_err_f("fill hdr meta overflow off %d size %d max %d\n",
70*437bfbebSnyanmisaka                   off, total_size, max_size);
71*437bfbebSnyanmisaka         return;
72*437bfbebSnyanmisaka     }
73*437bfbebSnyanmisaka     meta = mpp_frame_get_meta(frame);
74*437bfbebSnyanmisaka     mpp_meta_set_s32(meta, KEY_HDR_META_OFFSET, off);
75*437bfbebSnyanmisaka     /* 1. fill hdr static meta date */
76*437bfbebSnyanmisaka     hdr_static_meta_header = (RkMetaHdrHeader*)(ptr + off);
77*437bfbebSnyanmisaka     /* For transmission */
78*437bfbebSnyanmisaka     hdr_static_meta_header->magic = HDR_META_MAGIC;
79*437bfbebSnyanmisaka     hdr_static_meta_header->size = static_size;
80*437bfbebSnyanmisaka     hdr_static_meta_header->message_index = msg_idx++;
81*437bfbebSnyanmisaka 
82*437bfbebSnyanmisaka     switch (in_type) {
83*437bfbebSnyanmisaka     case MPP_VIDEO_CodingAVS2 : {
84*437bfbebSnyanmisaka         codec_type = HDR_AVS2;
85*437bfbebSnyanmisaka     } break;
86*437bfbebSnyanmisaka     case MPP_VIDEO_CodingHEVC : {
87*437bfbebSnyanmisaka         codec_type = HDR_HEVC;
88*437bfbebSnyanmisaka     } break;
89*437bfbebSnyanmisaka     case MPP_VIDEO_CodingAVC : {
90*437bfbebSnyanmisaka         codec_type = HDR_H264;
91*437bfbebSnyanmisaka     } break;
92*437bfbebSnyanmisaka     case MPP_VIDEO_CodingAV1 : {
93*437bfbebSnyanmisaka         codec_type = HDR_AV1;
94*437bfbebSnyanmisaka     } break;
95*437bfbebSnyanmisaka     default : break;
96*437bfbebSnyanmisaka     }
97*437bfbebSnyanmisaka 
98*437bfbebSnyanmisaka     /* For payload identification */
99*437bfbebSnyanmisaka     hdr_static_meta_header->hdr_payload_type = STATIC;
100*437bfbebSnyanmisaka     hdr_static_meta_header->video_format = codec_type;
101*437bfbebSnyanmisaka     {
102*437bfbebSnyanmisaka         HdrStaticMeta *static_meta = (HdrStaticMeta*)hdr_static_meta_header->payload;
103*437bfbebSnyanmisaka 
104*437bfbebSnyanmisaka         static_meta->min_luminance = mastering_display.min_luminance;
105*437bfbebSnyanmisaka         static_meta->max_luminance = mastering_display.max_luminance;
106*437bfbebSnyanmisaka         static_meta->green_x = mastering_display.display_primaries[0][0];
107*437bfbebSnyanmisaka         static_meta->green_y = mastering_display.display_primaries[0][1];
108*437bfbebSnyanmisaka         static_meta->blue_x = mastering_display.display_primaries[1][0];
109*437bfbebSnyanmisaka         static_meta->blue_y = mastering_display.display_primaries[1][1];
110*437bfbebSnyanmisaka         static_meta->red_x = mastering_display.display_primaries[2][0];
111*437bfbebSnyanmisaka         static_meta->red_y = mastering_display.display_primaries[2][1];
112*437bfbebSnyanmisaka         static_meta->white_point_x = mastering_display.white_point[0];
113*437bfbebSnyanmisaka         static_meta->white_point_y = mastering_display.white_point[1];
114*437bfbebSnyanmisaka         static_meta->color_trc = mpp_frame_get_color_trc(frame);
115*437bfbebSnyanmisaka         static_meta->color_space = mpp_frame_get_colorspace(frame);
116*437bfbebSnyanmisaka         static_meta->color_primaries = mpp_frame_get_color_primaries(frame);
117*437bfbebSnyanmisaka         static_meta->max_cll = content_light.MaxCLL;
118*437bfbebSnyanmisaka         static_meta->max_fall = content_light.MaxFALL;
119*437bfbebSnyanmisaka         /*
120*437bfbebSnyanmisaka          * hlg:
121*437bfbebSnyanmisaka          *  hevc trc = 18
122*437bfbebSnyanmisaka          *  avs trc = 14
123*437bfbebSnyanmisaka          * hdr10:
124*437bfbebSnyanmisaka          *  hevc/h264 trc = 16
125*437bfbebSnyanmisaka          *  avs trc = 12
126*437bfbebSnyanmisaka          */
127*437bfbebSnyanmisaka         switch (codec_type) {
128*437bfbebSnyanmisaka         case HDR_AV1 :
129*437bfbebSnyanmisaka         case HDR_HEVC :
130*437bfbebSnyanmisaka         case HDR_H264 : {
131*437bfbebSnyanmisaka             if (static_meta->color_trc == MPP_FRAME_TRC_ARIB_STD_B67)
132*437bfbebSnyanmisaka                 hdr_format = HLG;
133*437bfbebSnyanmisaka             else if (static_meta->color_trc == MPP_FRAME_TRC_SMPTEST2084)
134*437bfbebSnyanmisaka                 hdr_format = HDR10;
135*437bfbebSnyanmisaka         } break;
136*437bfbebSnyanmisaka         case HDR_AVS2 : {
137*437bfbebSnyanmisaka             if (static_meta->color_trc == MPP_FRAME_TRC_BT2020_10)
138*437bfbebSnyanmisaka                 hdr_format = HLG;
139*437bfbebSnyanmisaka             else if (static_meta->color_trc == MPP_FRAME_TRC_BT1361_ECG)
140*437bfbebSnyanmisaka                 hdr_format = HDR10;
141*437bfbebSnyanmisaka         } break;
142*437bfbebSnyanmisaka         default : {
143*437bfbebSnyanmisaka         } break;
144*437bfbebSnyanmisaka         }
145*437bfbebSnyanmisaka     }
146*437bfbebSnyanmisaka     off += hdr_static_meta_header->size;
147*437bfbebSnyanmisaka 
148*437bfbebSnyanmisaka     /* 2. fill hdr dynamic meta date */
149*437bfbebSnyanmisaka     if (dynamic_meta && dynamic_meta->size) {
150*437bfbebSnyanmisaka         hdr_dynamic_meta_header = (RkMetaHdrHeader*)(ptr + off);
151*437bfbebSnyanmisaka 
152*437bfbebSnyanmisaka         /* For transmission */
153*437bfbebSnyanmisaka         hdr_dynamic_meta_header->magic = HDR_META_MAGIC;
154*437bfbebSnyanmisaka         hdr_dynamic_meta_header->size = dynamic_size;
155*437bfbebSnyanmisaka         hdr_dynamic_meta_header->message_index = msg_idx++;
156*437bfbebSnyanmisaka 
157*437bfbebSnyanmisaka         /* For payload identification */
158*437bfbebSnyanmisaka         hdr_dynamic_meta_header->hdr_payload_type = DYNAMIC;
159*437bfbebSnyanmisaka         hdr_dynamic_meta_header->video_format = codec_type;
160*437bfbebSnyanmisaka         hdr_format = dynamic_meta->hdr_fmt;
161*437bfbebSnyanmisaka 
162*437bfbebSnyanmisaka         memcpy(hdr_dynamic_meta_header->payload, dynamic_meta->data, dynamic_meta->size);
163*437bfbebSnyanmisaka         hdr_dynamic_meta_header->message_total = msg_idx;
164*437bfbebSnyanmisaka         hdr_dynamic_meta_header->hdr_format = hdr_format;
165*437bfbebSnyanmisaka     }
166*437bfbebSnyanmisaka 
167*437bfbebSnyanmisaka     mpp_meta_set_s32(meta, KEY_HDR_META_SIZE, total_size);
168*437bfbebSnyanmisaka     hdr_static_meta_header->message_total = msg_idx;
169*437bfbebSnyanmisaka     hdr_static_meta_header->hdr_format = hdr_format;
170*437bfbebSnyanmisaka }