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,HdrCodecType codec_type)31 void fill_hdr_meta_to_frame(MppFrame frame, HdrCodecType codec_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
47 if (!ptr || !buf) {
48 mpp_err_f("buf is null!\n");
49 return;
50 }
51
52 off = MPP_ALIGN(off, SZ_4K);
53
54 static_size = sizeof(RkMetaHdrHeader) + sizeof(HdrStaticMeta);
55 if (dynamic_meta && dynamic_meta->size)
56 dynamic_size = sizeof(RkMetaHdrHeader) + dynamic_meta->size;
57
58 total_size = static_size + dynamic_size;
59
60 if ((off + total_size) > max_size) {
61 mpp_err_f("fill hdr meta overflow off %d size %d max %d\n",
62 off, total_size, max_size);
63 return;
64 }
65 meta = mpp_frame_get_meta(frame);
66 mpp_meta_set_s32(meta, KEY_HDR_META_OFFSET, off);
67 /* 1. fill hdr static meta date */
68 hdr_static_meta_header = (RkMetaHdrHeader*)(ptr + off);
69 /* For transmission */
70 hdr_static_meta_header->magic = HDR_META_MAGIC;
71 hdr_static_meta_header->size = static_size;
72 hdr_static_meta_header->message_index = msg_idx++;
73
74 /* For payload identification */
75 hdr_static_meta_header->hdr_payload_type = STATIC;
76 hdr_static_meta_header->video_format = codec_type;
77 {
78 HdrStaticMeta *static_meta = (HdrStaticMeta*)hdr_static_meta_header->payload;
79
80 static_meta->min_luminance = mastering_display.min_luminance;
81 static_meta->max_luminance = mastering_display.max_luminance;
82 static_meta->green_x = mastering_display.display_primaries[0][0];
83 static_meta->green_y = mastering_display.display_primaries[0][1];
84 static_meta->blue_x = mastering_display.display_primaries[1][0];
85 static_meta->blue_y = mastering_display.display_primaries[1][1];
86 static_meta->red_x = mastering_display.display_primaries[2][0];
87 static_meta->red_y = mastering_display.display_primaries[2][1];
88 static_meta->white_point_x = mastering_display.white_point[0];
89 static_meta->white_point_y = mastering_display.white_point[1];
90 static_meta->color_trc = mpp_frame_get_color_trc(frame);
91 static_meta->color_space = mpp_frame_get_colorspace(frame);
92 static_meta->color_primaries = mpp_frame_get_color_primaries(frame);
93 static_meta->max_cll = content_light.MaxCLL;
94 static_meta->max_fall = content_light.MaxFALL;
95 /*
96 * hlg:
97 * hevc trc = 18
98 * avs trc = 14
99 * hdr10:
100 * hevc trc = 16
101 * avs trc = 12
102 */
103 if ((codec_type == HDR_HEVC && static_meta->color_trc == MPP_FRAME_TRC_ARIB_STD_B67) ||
104 (codec_type == HDR_AVS2 && static_meta->color_trc == MPP_FRAME_TRC_BT2020_10))
105 hdr_format = HLG;
106 if ((codec_type == HDR_HEVC && static_meta->color_trc == MPP_FRAME_TRC_SMPTEST2084) ||
107 (codec_type == HDR_AVS2 && static_meta->color_trc == MPP_FRAME_TRC_BT1361_ECG))
108 hdr_format = HDR10;
109 }
110 off += hdr_static_meta_header->size;
111
112 /* 2. fill hdr dynamic meta date */
113 if (dynamic_meta && dynamic_meta->size) {
114 hdr_dynamic_meta_header = (RkMetaHdrHeader*)(ptr + off);
115
116 /* For transmission */
117 hdr_dynamic_meta_header->magic = HDR_META_MAGIC;
118 hdr_dynamic_meta_header->size = dynamic_size;
119 hdr_dynamic_meta_header->message_index = msg_idx++;
120
121 /* For payload identification */
122 hdr_dynamic_meta_header->hdr_payload_type = DYNAMIC;
123 hdr_dynamic_meta_header->video_format = codec_type;
124 hdr_format = dynamic_meta->hdr_fmt;
125
126 memcpy(hdr_dynamic_meta_header->payload, dynamic_meta->data, dynamic_meta->size);
127 hdr_dynamic_meta_header->message_total = msg_idx;
128 hdr_dynamic_meta_header->hdr_format = hdr_format;
129 }
130
131 mpp_meta_set_s32(meta, KEY_HDR_META_SIZE, total_size);
132 hdr_static_meta_header->message_total = msg_idx;
133 hdr_static_meta_header->hdr_format = hdr_format;
134 }