xref: /OK3568_Linux_fs/external/mpp/mpp/base/mpp_dec_hdr_meta.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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 }