1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "metadata_helper.h"
17 #include "buffer_log.h"
18
19 #include "v2_1/buffer_handle_meta_key_type.h"
20
21 using namespace OHOS::HDI::Display::Graphic::Common::V1_0;
22
23 namespace OHOS {
ConvertColorSpaceTypeToInfo(const CM_ColorSpaceType & colorSpaceType,CM_ColorSpaceInfo & colorSpaceInfo)24 GSError MetadataHelper::ConvertColorSpaceTypeToInfo(const CM_ColorSpaceType& colorSpaceType,
25 CM_ColorSpaceInfo& colorSpaceInfo)
26 {
27 uint32_t colorSpace = static_cast<uint32_t>(colorSpaceType);
28 colorSpaceInfo.primaries = static_cast<CM_ColorPrimaries>(colorSpace & PRIMARIES_MASK);
29 colorSpaceInfo.transfunc = static_cast<CM_TransFunc>((colorSpace & TRANSFUNC_MASK) >> TRANSFUNC_OFFSET);
30 colorSpaceInfo.matrix = static_cast<CM_Matrix>((colorSpace & MATRIX_MASK) >> MATRIX_OFFSET);
31 colorSpaceInfo.range = static_cast<CM_Range>((colorSpace & RANGE_MASK) >> RANGE_OFFSET);
32 return GSERROR_OK;
33 }
34
ConvertColorSpaceInfoToType(const CM_ColorSpaceInfo & colorSpaceInfo,CM_ColorSpaceType & colorSpaceType)35 GSError MetadataHelper::ConvertColorSpaceInfoToType(const CM_ColorSpaceInfo& colorSpaceInfo,
36 CM_ColorSpaceType& colorSpaceType)
37 {
38 uint32_t primaries = static_cast<uint32_t>(colorSpaceInfo.primaries);
39 uint32_t transfunc = static_cast<uint32_t>(colorSpaceInfo.transfunc);
40 uint32_t matrix = static_cast<uint32_t>(colorSpaceInfo.matrix);
41 uint32_t range = static_cast<uint32_t>(colorSpaceInfo.range);
42 colorSpaceType = static_cast<CM_ColorSpaceType>(primaries | (transfunc << TRANSFUNC_OFFSET) |
43 (matrix << MATRIX_OFFSET) | (range << RANGE_OFFSET));
44
45 return GSERROR_OK;
46 }
47
SetColorSpaceInfo(sptr<SurfaceBuffer> & buffer,const CM_ColorSpaceInfo & colorSpaceInfo)48 GSError MetadataHelper::SetColorSpaceInfo(sptr<SurfaceBuffer>& buffer, const CM_ColorSpaceInfo& colorSpaceInfo)
49 {
50 if (buffer == nullptr) {
51 return GSERROR_NO_BUFFER;
52 }
53
54 std::vector<uint8_t> colorSpaceInfoVec;
55 auto ret = ConvertMetadataToVec(colorSpaceInfo, colorSpaceInfoVec);
56 if (ret != GSERROR_OK) {
57 return ret;
58 }
59 return buffer->SetMetadata(ATTRKEY_COLORSPACE_INFO, colorSpaceInfoVec);
60 }
61
GetColorSpaceInfo(const sptr<SurfaceBuffer> & buffer,CM_ColorSpaceInfo & colorSpaceInfo)62 GSError MetadataHelper::GetColorSpaceInfo(const sptr<SurfaceBuffer>& buffer, CM_ColorSpaceInfo& colorSpaceInfo)
63 {
64 if (buffer == nullptr) {
65 return GSERROR_NO_BUFFER;
66 }
67
68 std::vector<uint8_t> colorSpaceInfoVec;
69 auto ret = buffer->GetMetadata(ATTRKEY_COLORSPACE_INFO, colorSpaceInfoVec);
70 if (ret != GSERROR_OK) {
71 return ret;
72 }
73 return ConvertVecToMetadata(colorSpaceInfoVec, colorSpaceInfo);
74 }
75
SetColorSpaceType(sptr<SurfaceBuffer> & buffer,const CM_ColorSpaceType & colorSpaceType)76 GSError MetadataHelper::SetColorSpaceType(sptr<SurfaceBuffer>& buffer, const CM_ColorSpaceType& colorSpaceType)
77 {
78 if (buffer == nullptr) {
79 return GSERROR_NO_BUFFER;
80 }
81
82 CM_ColorSpaceInfo colorSpaceInfo;
83 auto ret = ConvertColorSpaceTypeToInfo(colorSpaceType, colorSpaceInfo);
84 if (ret != GSERROR_OK) {
85 return ret;
86 }
87 return SetColorSpaceInfo(buffer, colorSpaceInfo);
88 }
89
GetColorSpaceType(const sptr<SurfaceBuffer> & buffer,CM_ColorSpaceType & colorSpaceType)90 GSError MetadataHelper::GetColorSpaceType(const sptr<SurfaceBuffer>& buffer, CM_ColorSpaceType& colorSpaceType)
91 {
92 if (buffer == nullptr) {
93 return GSERROR_NO_BUFFER;
94 }
95
96 CM_ColorSpaceInfo colorSpaceInfo;
97 auto ret = GetColorSpaceInfo(buffer, colorSpaceInfo);
98 if (ret != GSERROR_OK) {
99 return ret;
100 }
101 return ConvertColorSpaceInfoToType(colorSpaceInfo, colorSpaceType);
102 }
103
SetHDRMetadataType(sptr<SurfaceBuffer> & buffer,const CM_HDR_Metadata_Type & hdrMetadataType)104 GSError MetadataHelper::SetHDRMetadataType(sptr<SurfaceBuffer>& buffer, const CM_HDR_Metadata_Type& hdrMetadataType)
105 {
106 if (buffer == nullptr) {
107 return GSERROR_NO_BUFFER;
108 }
109
110 std::vector<uint8_t> hdrMetadataTypeVec;
111 auto ret = ConvertMetadataToVec(hdrMetadataType, hdrMetadataTypeVec);
112 if (ret != GSERROR_OK) {
113 return ret;
114 }
115 return buffer->SetMetadata(ATTRKEY_HDR_METADATA_TYPE, hdrMetadataTypeVec);
116 }
117
GetHDRMetadataType(const sptr<SurfaceBuffer> & buffer,CM_HDR_Metadata_Type & hdrMetadataType)118 GSError MetadataHelper::GetHDRMetadataType(const sptr<SurfaceBuffer>& buffer, CM_HDR_Metadata_Type& hdrMetadataType)
119 {
120 if (buffer == nullptr) {
121 return GSERROR_NO_BUFFER;
122 }
123
124 std::vector<uint8_t> hdrMetadataTypeVec;
125 auto ret = buffer->GetMetadata(ATTRKEY_HDR_METADATA_TYPE, hdrMetadataTypeVec);
126 if (ret != GSERROR_OK) {
127 return ret;
128 }
129 return ConvertVecToMetadata(hdrMetadataTypeVec, hdrMetadataType);
130 }
131
SetHDRStaticMetadata(sptr<SurfaceBuffer> & buffer,const HdrStaticMetadata & hdrStaticMetadata)132 GSError MetadataHelper::SetHDRStaticMetadata(sptr<SurfaceBuffer>& buffer,
133 const HdrStaticMetadata& hdrStaticMetadata)
134 {
135 if (buffer == nullptr) {
136 return GSERROR_NO_BUFFER;
137 }
138
139 std::vector<uint8_t> hdrStaticMetadataVec;
140 auto ret = ConvertMetadataToVec(hdrStaticMetadata, hdrStaticMetadataVec);
141 if (ret != GSERROR_OK) {
142 return ret;
143 }
144 return buffer->SetMetadata(ATTRKEY_HDR_STATIC_METADATA, hdrStaticMetadataVec);
145 }
146
GetHDRStaticMetadata(const sptr<SurfaceBuffer> & buffer,HdrStaticMetadata & hdrStaticMetadata)147 GSError MetadataHelper::GetHDRStaticMetadata(const sptr<SurfaceBuffer>& buffer,
148 HdrStaticMetadata& hdrStaticMetadata)
149 {
150 if (buffer == nullptr) {
151 return GSERROR_NO_BUFFER;
152 }
153
154 std::vector<uint8_t> hdrStaticMetadataVec;
155 auto ret = buffer->GetMetadata(ATTRKEY_HDR_STATIC_METADATA, hdrStaticMetadataVec);
156 if (ret != GSERROR_OK) {
157 return ret;
158 }
159 return ConvertVecToMetadata(hdrStaticMetadataVec, hdrStaticMetadata);
160 }
161
SetHDRDynamicMetadata(sptr<SurfaceBuffer> & buffer,const std::vector<uint8_t> & hdrDynamicMetadata)162 GSError MetadataHelper::SetHDRDynamicMetadata(sptr<SurfaceBuffer>& buffer,
163 const std::vector<uint8_t>& hdrDynamicMetadata)
164 {
165 if (buffer == nullptr) {
166 return GSERROR_NO_BUFFER;
167 }
168
169 return buffer->SetMetadata(ATTRKEY_HDR_DYNAMIC_METADATA, hdrDynamicMetadata);
170 }
171
GetHDRDynamicMetadata(const sptr<SurfaceBuffer> & buffer,std::vector<uint8_t> & hdrDynamicMetadata)172 GSError MetadataHelper::GetHDRDynamicMetadata(const sptr<SurfaceBuffer>& buffer,
173 std::vector<uint8_t>& hdrDynamicMetadata)
174 {
175 if (buffer == nullptr) {
176 return GSERROR_NO_BUFFER;
177 }
178
179 return buffer->GetMetadata(ATTRKEY_HDR_DYNAMIC_METADATA, hdrDynamicMetadata);
180 }
181
SetHDRStaticMetadata(sptr<SurfaceBuffer> & buffer,const std::vector<uint8_t> & hdrStaticMetadata)182 GSError MetadataHelper::SetHDRStaticMetadata(sptr<SurfaceBuffer>& buffer,
183 const std::vector<uint8_t>& hdrStaticMetadata)
184 {
185 if (buffer == nullptr) {
186 return GSERROR_NO_BUFFER;
187 }
188
189 return buffer->SetMetadata(ATTRKEY_HDR_STATIC_METADATA, hdrStaticMetadata);
190 }
191
GetHDRStaticMetadata(const sptr<SurfaceBuffer> & buffer,std::vector<uint8_t> & hdrStaticMetadata)192 GSError MetadataHelper::GetHDRStaticMetadata(const sptr<SurfaceBuffer>& buffer,
193 std::vector<uint8_t>& hdrStaticMetadata)
194 {
195 if (buffer == nullptr) {
196 return GSERROR_NO_BUFFER;
197 }
198
199 return buffer->GetMetadata(ATTRKEY_HDR_STATIC_METADATA, hdrStaticMetadata);
200 }
201
GetCropRectMetadata(const sptr<SurfaceBuffer> & buffer,BufferHandleMetaRegion & crop)202 GSError MetadataHelper::GetCropRectMetadata(const sptr<SurfaceBuffer>& buffer, BufferHandleMetaRegion& crop)
203 {
204 if (buffer == nullptr) {
205 return GSERROR_NO_BUFFER;
206 }
207
208 std::vector<uint8_t> cropRect;
209 auto ret = buffer->GetMetadata(ATTRKEY_CROP_REGION, cropRect);
210 if (ret != GSERROR_OK) {
211 return ret;
212 }
213 return ConvertVecToMetadata(cropRect, crop);
214 }
215
SetImageHDRMetadataType(sptr<SurfaceBuffer> & buffer,uint8_t * metadata)216 GSError MetadataHelper::SetImageHDRMetadataType(sptr<SurfaceBuffer>& buffer, uint8_t* metadata)
217 {
218 uint8_t metaDataType = static_cast<uint8_t>(*metadata);
219 GSError ret = MetadataHelper::SetHDRMetadataType(buffer, static_cast<CM_HDR_Metadata_Type>(metaDataType + 1));
220 return ret == OHOS::GSERROR_HDI_ERROR ? OHOS::SURFACE_ERROR_NOT_SUPPORT :
221 ret == OHOS::SURFACE_ERROR_OK ? OHOS::SURFACE_ERROR_OK : OHOS::SURFACE_ERROR_UNKOWN;
222 }
223
IsImageMetadataType(uint8_t * metadata)224 bool MetadataHelper::IsImageMetadataType(uint8_t* metadata)
225 {
226 uint8_t metaDataType = static_cast<uint8_t>(*metadata);
227 return (CM_IMAGE_HDR_VIVID_SINGLE == metaDataType + 1);
228 }
229
SetAdaptiveFOVMetadata(sptr<SurfaceBuffer> & buffer,const std::vector<uint8_t> & adaptiveFOVMetadata)230 GSError MetadataHelper::SetAdaptiveFOVMetadata(sptr<SurfaceBuffer>& buffer,
231 const std::vector<uint8_t>& adaptiveFOVMetadata)
232 {
233 if (buffer == nullptr) {
234 return GSERROR_NO_BUFFER;
235 }
236
237 return buffer->SetMetadata(OHOS::HDI::Display::Graphic::Common::V2_1::ATTRKEY_ADAPTIVE_FOV_METADATA,
238 adaptiveFOVMetadata);
239 }
240
GetAdaptiveFOVMetadata(const sptr<SurfaceBuffer> & buffer,std::vector<uint8_t> & adaptiveFOVMetadata)241 GSError MetadataHelper::GetAdaptiveFOVMetadata(const sptr<SurfaceBuffer>& buffer,
242 std::vector<uint8_t>& adaptiveFOVMetadata)
243 {
244 if (buffer == nullptr) {
245 return GSERROR_NO_BUFFER;
246 }
247
248 return buffer->GetMetadata(OHOS::HDI::Display::Graphic::Common::V2_1::ATTRKEY_ADAPTIVE_FOV_METADATA,
249 adaptiveFOVMetadata);
250 }
251
GetSDRDynamicMetadata(const sptr<SurfaceBuffer> & buffer,std::vector<uint8_t> & sdrDynamicMetadata)252 GSError MetadataHelper::GetSDRDynamicMetadata(const sptr<SurfaceBuffer>& buffer,
253 std::vector<uint8_t>& sdrDynamicMetadata)
254 {
255 if (buffer == nullptr) {
256 return GSERROR_NO_BUFFER;
257 }
258
259 return buffer->GetMetadata(OHOS::HDI::Display::Graphic::Common::V2_0::ATTRKEY_EXTERNAL_METADATA_002,
260 sdrDynamicMetadata);
261 }
262
263 #ifdef RS_ENABLE_TV_PQ_METADATA
264 using namespace OHOS::HDI::Display::Graphic::Common::V2_1;
265
UpdateTVMetadataField(sptr<SurfaceBuffer> & buffer,OnSetFieldsFunc func)266 GSError MetadataHelper::UpdateTVMetadataField(sptr<SurfaceBuffer>& buffer, OnSetFieldsFunc func)
267 {
268 if (buffer == nullptr) {
269 BLOGE("invalid buffer!");
270 return GSERROR_NO_BUFFER;
271 }
272 TvPQMetadata tvMetadata;
273 if (GetVideoTVMetadata(buffer, tvMetadata) != GSERROR_OK) {
274 BLOGD("tvMetadata not exist, reset data");
275 (void)memset_s(&tvMetadata, sizeof(tvMetadata), 0, sizeof(tvMetadata));
276 }
277 func(tvMetadata);
278 return SetVideoTVMetadata(buffer, tvMetadata);
279 }
280
SetVideoTVMetadata(sptr<SurfaceBuffer> & buffer,const TvPQMetadata & tvMetadata)281 GSError MetadataHelper::SetVideoTVMetadata(sptr<SurfaceBuffer>& buffer, const TvPQMetadata& tvMetadata)
282 {
283 if (buffer == nullptr) {
284 return GSERROR_NO_BUFFER;
285 }
286 std::vector<uint8_t> tvMetadataVec;
287 auto ret = ConvertMetadataToVec(tvMetadata, tvMetadataVec);
288 if (ret != GSERROR_OK) {
289 BLOGE("tvMetadata ConvertMetadataToVec failed");
290 return ret;
291 }
292 buffer->SetBufferHandle(buffer->GetBufferHandle());
293 auto ret1 = buffer->SetMetadata(ATTRKEY_VIDEO_TV_PQ, tvMetadataVec);
294 if (ret1 != GSERROR_OK) {
295 BLOGE("tvMetadata SetMetadata failed %{public}d! id = %{public}d", ret1, buffer->GetSeqNum());
296 return ret1;
297 }
298 return ret1;
299 }
300
GetVideoTVMetadata(const sptr<SurfaceBuffer> & buffer,TvPQMetadata & tvMetadata)301 GSError MetadataHelper::GetVideoTVMetadata(const sptr<SurfaceBuffer>& buffer, TvPQMetadata& tvMetadata)
302 {
303 if (buffer == nullptr) {
304 return GSERROR_NO_BUFFER;
305 }
306 std::vector<uint8_t> tvMetadataVec;
307 buffer->SetBufferHandle(buffer->GetBufferHandle());
308 auto ret = buffer->GetMetadata(ATTRKEY_VIDEO_TV_PQ, tvMetadataVec);
309 if (ret != GSERROR_OK) {
310 BLOGE("tvMetadata GetMetadata failed %{public}d! id = %{public}d", ret, buffer->GetSeqNum());
311 return ret;
312 }
313 return ConvertVecToMetadata(tvMetadataVec, tvMetadata);
314 }
315
SetSceneTag(sptr<SurfaceBuffer> & buffer,unsigned char value)316 GSError MetadataHelper::SetSceneTag(sptr<SurfaceBuffer>& buffer, unsigned char value)
317 {
318 return UpdateTVMetadataField(buffer, [=](TvPQMetadata &tvPQMetadata) {
319 tvPQMetadata.sceneTag = value;
320 BLOGD("tvMetadata sceneTag = %{public}u", tvPQMetadata.sceneTag);
321 });
322 }
323
SetUIFrameCount(sptr<SurfaceBuffer> & buffer,unsigned char value)324 GSError MetadataHelper::SetUIFrameCount(sptr<SurfaceBuffer>& buffer, unsigned char value)
325 {
326 return UpdateTVMetadataField(buffer, [=](TvPQMetadata &tvPQMetadata) {
327 tvPQMetadata.uiFrameCnt = value;
328 BLOGD("tvMetadata uiFrameCnt = %{public}u", tvPQMetadata.uiFrameCnt);
329 });
330 }
331
SetVideoFrameCount(sptr<SurfaceBuffer> & buffer,unsigned char value)332 GSError MetadataHelper::SetVideoFrameCount(sptr<SurfaceBuffer>& buffer, unsigned char value)
333 {
334 return UpdateTVMetadataField(buffer, [=](TvPQMetadata &tvPQMetadata) {
335 tvPQMetadata.vidFrameCnt = value;
336 BLOGD("tvMetadata vidFrameCnt = %{public}u", tvPQMetadata.vidFrameCnt);
337 });
338 }
339
SetVideoFrameRate(sptr<SurfaceBuffer> & buffer,unsigned char value)340 GSError MetadataHelper::SetVideoFrameRate(sptr<SurfaceBuffer>& buffer, unsigned char value)
341 {
342 return UpdateTVMetadataField(buffer, [=](TvPQMetadata &tvPQMetadata) {
343 tvPQMetadata.vidFps = value;
344 BLOGD("tvMetadata vidFps = %{public}u", tvPQMetadata.vidFps);
345 });
346 }
347
SetVideoTVInfo(sptr<SurfaceBuffer> & buffer,const TvVideoWindow & tvVideoWindow)348 GSError MetadataHelper::SetVideoTVInfo(sptr<SurfaceBuffer>& buffer, const TvVideoWindow& tvVideoWindow)
349 {
350 return UpdateTVMetadataField(buffer, [=](TvPQMetadata &tvPQMetadata) {
351 tvPQMetadata.vidWinX = tvVideoWindow.x;
352 tvPQMetadata.vidWinY = tvVideoWindow.y;
353 tvPQMetadata.vidWinWidth = tvVideoWindow.width;
354 tvPQMetadata.vidWinHeight = tvVideoWindow.height;
355 tvPQMetadata.vidWinSize = tvVideoWindow.size;
356 BLOGD("tvMetadata vid_win = (%{public}u, %{public}u, %{public}u, %{public}u), size = %{public}u",
357 tvPQMetadata.vidWinX, tvPQMetadata.vidWinY, tvPQMetadata.vidWinWidth, tvPQMetadata.vidWinHeight,
358 tvPQMetadata.vidWinSize);
359 });
360 }
361
SetVideoDecoderHigh(sptr<SurfaceBuffer> & buffer,unsigned short vidVdhWidth,unsigned short vidVdhHeight)362 GSError MetadataHelper::SetVideoDecoderHigh(sptr<SurfaceBuffer>& buffer, unsigned short vidVdhWidth,
363 unsigned short vidVdhHeight)
364 {
365 return UpdateTVMetadataField(buffer, [=](TvPQMetadata &tvPQMetadata) {
366 tvPQMetadata.vidVdhWidth = vidVdhWidth;
367 tvPQMetadata.vidVdhHeight = vidVdhHeight;
368 BLOGD("tvPQMetadata vidVdhWidth = %{public}u, tvPQMetadata vidVdhHeight = %{public}u",
369 tvPQMetadata.vidVdhWidth, tvPQMetadata.vidVdhHeight);
370 });
371 }
372
SetVideoTVScaleMode(sptr<SurfaceBuffer> & buffer,unsigned char value)373 GSError MetadataHelper::SetVideoTVScaleMode(sptr<SurfaceBuffer>& buffer, unsigned char value)
374 {
375 return UpdateTVMetadataField(buffer, [=](TvPQMetadata &tvPQMetadata) {
376 tvPQMetadata.scaleMode = value;
377 BLOGD("tvMetadata scaleMode = %{public}u", tvPQMetadata.scaleMode);
378 });
379 }
380
SetVideoTVDpPixelFormat(sptr<SurfaceBuffer> & buffer,unsigned int value)381 GSError MetadataHelper::SetVideoTVDpPixelFormat(sptr<SurfaceBuffer>& buffer, unsigned int value)
382 {
383 return UpdateTVMetadataField(buffer, [=](TvPQMetadata &tvPQMetadata) {
384 tvPQMetadata.dpPixFmt = value;
385 BLOGD("tvMetadata dpPixFmt = %{public}u", tvPQMetadata.dpPixFmt);
386 });
387 }
388
SetVideoColorimetryHdr(sptr<SurfaceBuffer> & buffer,unsigned char hdr,unsigned char colorimetry)389 GSError MetadataHelper::SetVideoColorimetryHdr(sptr<SurfaceBuffer>& buffer, unsigned char hdr,
390 unsigned char colorimetry)
391 {
392 return UpdateTVMetadataField(buffer, [=](TvPQMetadata &tvPQMetadata) {
393 tvPQMetadata.colorimetry = colorimetry;
394 tvPQMetadata.hdr = hdr;
395 BLOGD("Colorimetry = %{public}u, HDR = %{public}u", tvPQMetadata.colorimetry, tvPQMetadata.hdr);
396 });
397 }
398
EraseVideoTVInfoKey(sptr<SurfaceBuffer> & buffer)399 GSError MetadataHelper::EraseVideoTVInfoKey(sptr<SurfaceBuffer>& buffer)
400 {
401 if (buffer == nullptr) {
402 return GSERROR_NO_BUFFER;
403 }
404 auto ret = buffer->EraseMetadataKey(ATTRKEY_VIDEO_TV_PQ);
405 if (ret != GSERROR_OK) {
406 BLOGE("tvMetadata EraseVideoTVInfoKey ret = %{public}d", ret);
407 return ret;
408 }
409 return GSERROR_OK;
410 }
411 #endif
412 } // namespace OHOS