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