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 }