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