1 /*
2 * Copyright (c) 2022 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 "native_buffer_inner.h"
17
18 #include <linux/dma-buf.h>
19 #include <sys/ioctl.h>
20 #include <cinttypes>
21 #include "surface_type.h"
22 #include "buffer_log.h"
23 #include "native_window.h"
24 #include "surface_buffer_impl.h"
25 #include "metadata_helper.h"
26
27 #define DMA_BUF_SET_TYPE _IOW(DMA_BUF_BASE, 2, const char *)
28
29 using namespace OHOS;
30 using namespace HDI::Display::Graphic::Common::V1_0;
31 static std::unordered_map<OH_NativeBuffer_ColorSpace, CM_ColorSpaceType> NATIVE_COLORSPACE_TO_HDI_MAP = {
32 {OH_COLORSPACE_NONE, CM_COLORSPACE_NONE},
33 {OH_COLORSPACE_BT601_EBU_FULL, CM_BT601_EBU_FULL},
34 {OH_COLORSPACE_BT601_SMPTE_C_FULL, CM_BT601_SMPTE_C_FULL},
35 {OH_COLORSPACE_BT709_FULL, CM_BT709_FULL},
36 {OH_COLORSPACE_BT2020_HLG_FULL, CM_BT2020_HLG_FULL},
37 {OH_COLORSPACE_BT2020_PQ_FULL, CM_BT2020_PQ_FULL},
38 {OH_COLORSPACE_BT601_EBU_LIMIT, CM_BT601_EBU_LIMIT},
39 {OH_COLORSPACE_BT601_SMPTE_C_LIMIT, CM_BT601_SMPTE_C_LIMIT},
40 {OH_COLORSPACE_BT709_LIMIT, CM_BT709_LIMIT},
41 {OH_COLORSPACE_BT2020_HLG_LIMIT, CM_BT2020_HLG_LIMIT},
42 {OH_COLORSPACE_BT2020_PQ_LIMIT, CM_BT2020_PQ_LIMIT},
43 {OH_COLORSPACE_SRGB_FULL, CM_SRGB_FULL},
44 {OH_COLORSPACE_P3_FULL, CM_P3_FULL},
45 {OH_COLORSPACE_P3_HLG_FULL, CM_P3_HLG_FULL},
46 {OH_COLORSPACE_P3_PQ_FULL, CM_P3_PQ_FULL},
47 {OH_COLORSPACE_ADOBERGB_FULL, CM_ADOBERGB_FULL},
48 {OH_COLORSPACE_SRGB_LIMIT, CM_SRGB_LIMIT},
49 {OH_COLORSPACE_P3_LIMIT, CM_P3_LIMIT},
50 {OH_COLORSPACE_P3_HLG_LIMIT, CM_P3_HLG_LIMIT},
51 {OH_COLORSPACE_P3_PQ_LIMIT, CM_P3_PQ_LIMIT},
52 {OH_COLORSPACE_ADOBERGB_LIMIT, CM_ADOBERGB_LIMIT},
53 {OH_COLORSPACE_LINEAR_SRGB, CM_LINEAR_SRGB},
54 {OH_COLORSPACE_LINEAR_BT709, CM_LINEAR_BT709},
55 {OH_COLORSPACE_LINEAR_P3, CM_LINEAR_P3},
56 {OH_COLORSPACE_LINEAR_BT2020, CM_LINEAR_BT2020},
57 {OH_COLORSPACE_DISPLAY_SRGB, CM_DISPLAY_SRGB},
58 {OH_COLORSPACE_DISPLAY_P3_SRGB, CM_DISPLAY_P3_SRGB},
59 {OH_COLORSPACE_DISPLAY_P3_HLG, CM_DISPLAY_P3_HLG},
60 {OH_COLORSPACE_DISPLAY_P3_PQ, CM_DISPLAY_P3_PQ},
61 {OH_COLORSPACE_DISPLAY_BT2020_SRGB, CM_DISPLAY_BT2020_SRGB},
62 {OH_COLORSPACE_DISPLAY_BT2020_HLG, CM_DISPLAY_BT2020_HLG},
63 {OH_COLORSPACE_DISPLAY_BT2020_PQ, CM_DISPLAY_BT2020_PQ}
64 };
65
66 static std::unordered_map<OH_NativeBuffer_MetadataType, CM_HDR_Metadata_Type> NATIVE_METADATATYPE_TO_HDI_MAP = {
67 {OH_VIDEO_HDR_HLG, CM_VIDEO_HLG},
68 {OH_VIDEO_HDR_HDR10, CM_VIDEO_HDR10},
69 {OH_VIDEO_HDR_VIVID, CM_VIDEO_HDR_VIVID},
70 };
71
OH_NativeBufferFromSurfaceBuffer(SurfaceBuffer * buffer)72 static OH_NativeBuffer* OH_NativeBufferFromSurfaceBuffer(SurfaceBuffer* buffer)
73 {
74 if (buffer == nullptr) {
75 return nullptr;
76 }
77 return buffer->SurfaceBufferToNativeBuffer();
78 }
79
OH_NativeBufferToSurfaceBuffer(OH_NativeBuffer * buffer)80 static SurfaceBuffer* OH_NativeBufferToSurfaceBuffer(OH_NativeBuffer *buffer)
81 {
82 return SurfaceBuffer::NativeBufferToSurfaceBuffer(buffer);
83 }
84
OH_NativeBufferToSurfaceBuffer(const OH_NativeBuffer * buffer)85 static const SurfaceBuffer* OH_NativeBufferToSurfaceBuffer(const OH_NativeBuffer *buffer)
86 {
87 return SurfaceBuffer::NativeBufferToSurfaceBuffer(buffer);
88 }
89
OH_NativeBuffer_Alloc(const OH_NativeBuffer_Config * config)90 OH_NativeBuffer* OH_NativeBuffer_Alloc(const OH_NativeBuffer_Config* config)
91 {
92 if (config == nullptr) {
93 return nullptr;
94 }
95 BufferRequestConfig bfConfig = {};
96 bfConfig.width = config->width;
97 bfConfig.height = config->height;
98 bfConfig.strideAlignment = 0x8; // set 0x8 as default value to alloc SurfaceBufferImpl
99 bfConfig.format = config->format; // PixelFormat
100 bfConfig.usage = config->usage;
101 bfConfig.timeout = 0;
102 bfConfig.colorGamut = GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB;
103 bfConfig.transform = GraphicTransformType::GRAPHIC_ROTATE_NONE;
104 sptr<SurfaceBuffer> bufferImpl = new SurfaceBufferImpl();
105 GSError ret = bufferImpl->Alloc(bfConfig);
106 if (ret != OHOS::SURFACE_ERROR_OK) {
107 BLOGE("Alloc failed ret: %{public}d, config info: width[%{public}d, height[%{public}d,"
108 "format[%{public}d], usage[%{public}d]", ret, config->width, config->height,
109 config->format, config->usage);
110 return nullptr;
111 }
112
113 OH_NativeBuffer* buffer = OH_NativeBufferFromSurfaceBuffer(bufferImpl);
114 int32_t err = OH_NativeBuffer_Reference(buffer);
115 if (err != OHOS::SURFACE_ERROR_OK) {
116 BLOGE("NativeBufferReference failed, err: %{public}d.", err);
117 return nullptr;
118 }
119 if (bufferImpl->GetBufferHandle() != nullptr && bufferImpl->GetBufferHandle()->fd > 0) {
120 ioctl(bufferImpl->GetBufferHandle()->fd, DMA_BUF_SET_TYPE, "external");
121 }
122 return buffer;
123 }
124
OH_NativeBuffer_Reference(OH_NativeBuffer * buffer)125 int32_t OH_NativeBuffer_Reference(OH_NativeBuffer *buffer)
126 {
127 if (buffer == nullptr) {
128 return OHOS::GSERROR_INVALID_ARGUMENTS;
129 }
130 OHOS::RefBase *ref = reinterpret_cast<OHOS::RefBase *>(buffer);
131 ref->IncStrongRef(ref);
132 return OHOS::SURFACE_ERROR_OK;
133 }
134
OH_NativeBuffer_Unreference(OH_NativeBuffer * buffer)135 int32_t OH_NativeBuffer_Unreference(OH_NativeBuffer *buffer)
136 {
137 if (buffer == nullptr) {
138 return OHOS::GSERROR_INVALID_ARGUMENTS;
139 }
140 OHOS::RefBase *ref = reinterpret_cast<OHOS::RefBase *>(buffer);
141 ref->DecStrongRef(ref);
142 return OHOS::SURFACE_ERROR_OK;
143 }
144
OH_NativeBuffer_GetConfig(OH_NativeBuffer * buffer,OH_NativeBuffer_Config * config)145 void OH_NativeBuffer_GetConfig(OH_NativeBuffer *buffer, OH_NativeBuffer_Config* config)
146 {
147 if (buffer == nullptr || config == nullptr) {
148 return;
149 }
150 const SurfaceBuffer* sbuffer = OH_NativeBufferToSurfaceBuffer(buffer);
151 config->width = sbuffer->GetWidth();
152 config->height = sbuffer->GetHeight();
153 config->format = sbuffer->GetFormat();
154 config->usage = sbuffer->GetUsage();
155 config->stride = sbuffer->GetStride();
156 }
157
OH_NativeBuffer_Map(OH_NativeBuffer * buffer,void ** virAddr)158 int32_t OH_NativeBuffer_Map(OH_NativeBuffer *buffer, void **virAddr)
159 {
160 if (buffer == nullptr || virAddr == nullptr) {
161 return OHOS::SURFACE_ERROR_INVALID_PARAM;
162 }
163 SurfaceBuffer* sbuffer = OH_NativeBufferToSurfaceBuffer(buffer);
164 int32_t ret = sbuffer->Map();
165 if (ret == OHOS::SURFACE_ERROR_OK) {
166 *virAddr = sbuffer->GetVirAddr();
167 } else {
168 BLOGE("Map failed, ret:%{public}d", ret);
169 ret = OHOS::SURFACE_ERROR_UNKOWN;
170 }
171 return ret;
172 }
173
OH_NativeBuffer_Unmap(OH_NativeBuffer * buffer)174 int32_t OH_NativeBuffer_Unmap(OH_NativeBuffer *buffer)
175 {
176 if (buffer == nullptr) {
177 return OHOS::SURFACE_ERROR_INVALID_PARAM;
178 }
179 SurfaceBuffer* sbuffer = OH_NativeBufferToSurfaceBuffer(buffer);
180 int32_t ret = sbuffer->Unmap();
181 if (ret != OHOS::SURFACE_ERROR_OK) {
182 BLOGE("Unmap failed, ret:%{public}d", ret);
183 ret = OHOS::SURFACE_ERROR_UNKOWN;
184 }
185 return ret;
186 }
187
OH_NativeBuffer_GetSeqNum(OH_NativeBuffer * buffer)188 uint32_t OH_NativeBuffer_GetSeqNum(OH_NativeBuffer *buffer)
189 {
190 if (buffer == nullptr) {
191 return UINT_MAX;
192 }
193 const SurfaceBuffer* sbuffer = OH_NativeBufferToSurfaceBuffer(buffer);
194 return sbuffer->GetSeqNum();
195 }
196
OH_NativeBuffer_GetBufferHandle(const OH_NativeBuffer * buffer)197 const BufferHandle* OH_NativeBuffer_GetBufferHandle(const OH_NativeBuffer *buffer)
198 {
199 if (buffer == nullptr) {
200 return nullptr;
201 }
202 const SurfaceBuffer* sbuffer = OH_NativeBufferToSurfaceBuffer(buffer);
203 return sbuffer->GetBufferHandle();
204 }
205
OH_NativeBuffer_GetNativeBufferConfig(const OH_NativeBuffer * buffer,OH_NativeBuffer_Config * config)206 void OH_NativeBuffer_GetNativeBufferConfig(const OH_NativeBuffer *buffer, OH_NativeBuffer_Config* config)
207 {
208 if (buffer == nullptr || config == nullptr) {
209 return;
210 }
211 const SurfaceBuffer* sbuffer = OH_NativeBufferToSurfaceBuffer(buffer);
212 config->width = sbuffer->GetWidth();
213 config->height = sbuffer->GetHeight();
214 config->format = sbuffer->GetFormat();
215 config->usage = sbuffer->GetUsage();
216 config->stride = sbuffer->GetStride();
217 }
218
OH_NativeBufferFromNativeWindowBuffer(OHNativeWindowBuffer * nativeWindowBuffer)219 OH_NativeBuffer* OH_NativeBufferFromNativeWindowBuffer(OHNativeWindowBuffer* nativeWindowBuffer)
220 {
221 if (nativeWindowBuffer == nullptr) {
222 return nullptr;
223 }
224 OH_NativeBuffer* buffer = OH_NativeBufferFromSurfaceBuffer(nativeWindowBuffer->sfbuffer);
225 return buffer;
226 }
227
OH_NativeBuffer_SetColorSpace(OH_NativeBuffer * buffer,OH_NativeBuffer_ColorSpace colorSpace)228 int32_t OH_NativeBuffer_SetColorSpace(OH_NativeBuffer *buffer, OH_NativeBuffer_ColorSpace colorSpace)
229 {
230 if (buffer == nullptr || NATIVE_COLORSPACE_TO_HDI_MAP.find(colorSpace) == NATIVE_COLORSPACE_TO_HDI_MAP.end()) {
231 return OHOS::SURFACE_ERROR_INVALID_PARAM;
232 }
233 sptr<SurfaceBuffer> sbuffer = OH_NativeBufferToSurfaceBuffer(buffer);
234 GSError ret = MetadataHelper::SetColorSpaceType(sbuffer, NATIVE_COLORSPACE_TO_HDI_MAP[colorSpace]);
235 if (ret == OHOS::GSERROR_HDI_ERROR) {
236 return OHOS::SURFACE_ERROR_NOT_SUPPORT;
237 } else if (ret != OHOS::SURFACE_ERROR_OK) {
238 return OHOS::SURFACE_ERROR_UNKOWN;
239 }
240 return OHOS::SURFACE_ERROR_OK;
241 }
242
OH_NativeBuffer_MapPlanes(OH_NativeBuffer * buffer,void ** virAddr,OH_NativeBuffer_Planes * outPlanes)243 int32_t OH_NativeBuffer_MapPlanes(OH_NativeBuffer *buffer, void **virAddr, OH_NativeBuffer_Planes *outPlanes)
244 {
245 if (buffer == nullptr || virAddr == nullptr || outPlanes == nullptr) {
246 return OHOS::SURFACE_ERROR_INVALID_PARAM;
247 }
248 sptr<SurfaceBuffer> sbuffer = OH_NativeBufferToSurfaceBuffer(buffer);
249 int32_t ret = sbuffer->Map();
250 if (ret == OHOS::SURFACE_ERROR_OK) {
251 *virAddr = sbuffer->GetVirAddr();
252 } else {
253 BLOGE("Map failed, %{public}d", ret);
254 return ret;
255 }
256 OH_NativeBuffer_Planes *planes = nullptr;
257 GSError retVal = sbuffer->GetPlanesInfo(reinterpret_cast<void**>(&planes));
258 if (retVal != OHOS::SURFACE_ERROR_OK) {
259 BLOGE("GetPlanesInfo failed, retVal:%{public}d", retVal);
260 return retVal;
261 }
262 outPlanes->planeCount = planes->planeCount;
263 for (uint32_t i = 0; i < planes->planeCount && i < 4; i++) { // 4: max plane count
264 outPlanes->planes[i].offset = planes->planes[i].offset;
265 outPlanes->planes[i].rowStride = planes->planes[i].rowStride;
266 outPlanes->planes[i].columnStride = planes->planes[i].columnStride;
267 }
268 return OHOS::SURFACE_ERROR_OK;
269 }
270
OH_NativeBuffer_FromNativeWindowBuffer(OHNativeWindowBuffer * nativeWindowBuffer,OH_NativeBuffer ** buffer)271 int32_t OH_NativeBuffer_FromNativeWindowBuffer(OHNativeWindowBuffer *nativeWindowBuffer, OH_NativeBuffer **buffer)
272 {
273 if (nativeWindowBuffer == nullptr || buffer == nullptr) {
274 return OHOS::SURFACE_ERROR_INVALID_PARAM;
275 }
276 *buffer = OH_NativeBufferFromSurfaceBuffer(nativeWindowBuffer->sfbuffer);
277 if (*buffer == nullptr) {
278 BLOGE("get sfbuffer is nullptr");
279 return OHOS::GSERROR_INVALID_OPERATING;
280 }
281 return OHOS::SURFACE_ERROR_OK;
282 }
283
OH_NativeBuffer_GetColorSpace(OH_NativeBuffer * buffer,OH_NativeBuffer_ColorSpace * colorSpace)284 int32_t OH_NativeBuffer_GetColorSpace(OH_NativeBuffer *buffer, OH_NativeBuffer_ColorSpace *colorSpace)
285 {
286 if (buffer == nullptr || colorSpace == nullptr) {
287 return OHOS::SURFACE_ERROR_INVALID_PARAM;
288 }
289 sptr<SurfaceBuffer> sbuffer = OH_NativeBufferToSurfaceBuffer(buffer);
290 OHOS::HDI::Display::Graphic::Common::V1_0::CM_ColorSpaceType colorSpaceType;
291 GSError ret = MetadataHelper::GetColorSpaceType(sbuffer, colorSpaceType);
292 if (ret == OHOS::GSERROR_HDI_ERROR) {
293 return OHOS::SURFACE_ERROR_NOT_SUPPORT;
294 } else if (ret != OHOS::SURFACE_ERROR_OK) {
295 BLOGE("GetColorSpaceType failed!, retVal:%{public}d", ret);
296 return OHOS::SURFACE_ERROR_UNKOWN;
297 }
298 auto it = std::find_if(NATIVE_COLORSPACE_TO_HDI_MAP.begin(), NATIVE_COLORSPACE_TO_HDI_MAP.end(),
299 [colorSpaceType](const std::pair<OH_NativeBuffer_ColorSpace, CM_ColorSpaceType>& element) {
300 return element.second == colorSpaceType;
301 });
302 if (it != NATIVE_COLORSPACE_TO_HDI_MAP.end()) {
303 *colorSpace = it->first;
304 return OHOS::SURFACE_ERROR_OK;
305 }
306 BLOGE("the colorSpace does not support it.");
307 return OHOS::SURFACE_ERROR_UNKOWN;
308 }
309
OH_NativeBuffer_SetMetadataValue(OH_NativeBuffer * buffer,OH_NativeBuffer_MetadataKey metadataKey,int32_t size,uint8_t * metadata)310 int32_t OH_NativeBuffer_SetMetadataValue(OH_NativeBuffer *buffer, OH_NativeBuffer_MetadataKey metadataKey,
311 int32_t size, uint8_t *metadata)
312 {
313 if (buffer == nullptr || metadata == nullptr || size <= 0) {
314 return OHOS::SURFACE_ERROR_INVALID_PARAM;
315 }
316 sptr<SurfaceBuffer> sbuffer = OH_NativeBufferToSurfaceBuffer(buffer);
317 GSError ret = GSERROR_OK;
318 std::vector<uint8_t> mD(metadata, metadata + size);
319 if (metadataKey == OH_HDR_DYNAMIC_METADATA) {
320 ret = MetadataHelper::SetHDRDynamicMetadata(sbuffer, mD);
321 } else if (metadataKey == OH_HDR_STATIC_METADATA) {
322 ret = MetadataHelper::SetHDRStaticMetadata(sbuffer, mD);
323 } else if (metadataKey == OH_HDR_METADATA_TYPE) {
324 OH_NativeBuffer_MetadataType hdrMetadataType = static_cast<OH_NativeBuffer_MetadataType>(*metadata);
325 if (MetadataHelper::IsImageMetadataType(metadata)) {
326 return MetadataHelper::SetImageHDRMetadataType(sbuffer, metadata);
327 }
328 if (NATIVE_METADATATYPE_TO_HDI_MAP.find(hdrMetadataType) == NATIVE_METADATATYPE_TO_HDI_MAP.end()) {
329 BLOGE("the metadataType is not defined.");
330 return OHOS::SURFACE_ERROR_INVALID_PARAM;
331 }
332 ret = MetadataHelper::SetHDRMetadataType(sbuffer, NATIVE_METADATATYPE_TO_HDI_MAP[hdrMetadataType]);
333 } else {
334 BLOGE("the metadataKey does not support it.");
335 return OHOS::SURFACE_ERROR_UNKOWN;
336 }
337 if (ret == OHOS::GSERROR_HDI_ERROR) {
338 return OHOS::SURFACE_ERROR_NOT_SUPPORT;
339 } else if (ret != OHOS::SURFACE_ERROR_OK) {
340 BLOGE("SetHDRMetadata failed!, retVal:%{public}d", ret);
341 return OHOS::SURFACE_ERROR_UNKOWN;
342 }
343 return OHOS::SURFACE_ERROR_OK;
344 }
345
OH_NativeBuffer_GetMatedataValueType(sptr<SurfaceBuffer> sbuffer,int32_t * size,uint8_t ** metadata)346 static GSError OH_NativeBuffer_GetMatedataValueType(sptr<SurfaceBuffer> sbuffer, int32_t *size, uint8_t **metadata)
347 {
348 CM_HDR_Metadata_Type hdrMetadataType = CM_METADATA_NONE;
349 GSError ret = MetadataHelper::GetHDRMetadataType(sbuffer, hdrMetadataType);
350 if (ret == OHOS::GSERROR_HDI_ERROR) {
351 return OHOS::SURFACE_ERROR_NOT_SUPPORT;
352 } else if (ret != OHOS::SURFACE_ERROR_OK) {
353 BLOGE("GetHDRMetadataType failed!, ret: %{public}d", ret);
354 return OHOS::SURFACE_ERROR_UNKOWN;
355 }
356 auto it = std::find_if(NATIVE_METADATATYPE_TO_HDI_MAP.begin(), NATIVE_METADATATYPE_TO_HDI_MAP.end(),
357 [hdrMetadataType](const std::pair<OH_NativeBuffer_MetadataType, CM_HDR_Metadata_Type>& element) {
358 return element.second == hdrMetadataType;
359 });
360 if (it != NATIVE_METADATATYPE_TO_HDI_MAP.end()) {
361 *size = sizeof(OH_NativeBuffer_MetadataType);
362 *metadata = new uint8_t[*size];
363 errno_t err = memcpy_s(*metadata, *size, &(it->first), *size);
364 if (err != 0) {
365 delete[] *metadata;
366 *metadata = nullptr;
367 BLOGE("memcpy_s failed!, ret: %{public}d", err);
368 return OHOS::SURFACE_ERROR_UNKOWN;
369 }
370 return OHOS::SURFACE_ERROR_OK;
371 }
372 BLOGE("the hdrMetadataType does not support it.");
373 return OHOS::SURFACE_ERROR_NOT_SUPPORT;
374 }
375
OH_NativeBuffer_GetMetadataValue(OH_NativeBuffer * buffer,OH_NativeBuffer_MetadataKey metadataKey,int32_t * size,uint8_t ** metadata)376 int32_t OH_NativeBuffer_GetMetadataValue(OH_NativeBuffer *buffer, OH_NativeBuffer_MetadataKey metadataKey,
377 int32_t *size, uint8_t **metadata)
378 {
379 if (buffer == nullptr || metadata == nullptr || size == nullptr) {
380 return OHOS::SURFACE_ERROR_INVALID_PARAM;
381 }
382 sptr<SurfaceBuffer> sbuffer = OH_NativeBufferToSurfaceBuffer(buffer);
383 GSError ret = GSERROR_OK;
384 std::vector<uint8_t> mD;
385 if (metadataKey == OH_HDR_DYNAMIC_METADATA) {
386 ret = MetadataHelper::GetHDRDynamicMetadata(sbuffer, mD);
387 } else if (metadataKey == OH_HDR_STATIC_METADATA) {
388 ret = MetadataHelper::GetHDRStaticMetadata(sbuffer, mD);
389 } else if (metadataKey == OH_HDR_METADATA_TYPE) {
390 ret = OH_NativeBuffer_GetMatedataValueType(sbuffer, size, metadata);
391 return ret;
392 } else {
393 BLOGE("the metadataKey does not support it.");
394 return OHOS::SURFACE_ERROR_UNKOWN;
395 }
396 if (ret == OHOS::GSERROR_HDI_ERROR) {
397 return OHOS::SURFACE_ERROR_NOT_SUPPORT;
398 } else if (ret != OHOS::SURFACE_ERROR_OK) {
399 BLOGE("SetHDRSMetadata failed!, ret: %{public}d", ret);
400 return OHOS::SURFACE_ERROR_UNKOWN;
401 }
402 *size = mD.size();
403 if (mD.empty()) {
404 BLOGE("Metadata is empty!");
405 return OHOS::SURFACE_ERROR_UNKOWN;
406 }
407 *metadata = new uint8_t[mD.size()];
408 errno_t err = memcpy_s(*metadata, mD.size(), &mD[0], mD.size());
409 if (err != 0) {
410 delete[] *metadata;
411 *metadata = nullptr;
412 BLOGE("memcpy_s failed!, ret: %{public}d", err);
413 return OHOS::SURFACE_ERROR_UNKOWN;
414 }
415 return OHOS::SURFACE_ERROR_OK;
416 }