• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }