xref: /rockchip-linux_mpp/mpp/base/mpp_dec_hdr_meta.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
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 }