• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2024 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 "avmetadatahelper_impl.h"
17 
18 #include <sys/stat.h>
19 #include <unistd.h>
20 
21 #include "v1_0/hdr_static_metadata.h"
22 #include "v1_0/buffer_handle_meta_key_type.h"
23 
24 #include "securec.h"
25 #include "image_source.h"
26 #include "i_media_service.h"
27 #include "media_log.h"
28 #include "media_errors.h"
29 #include "scope_guard.h"
30 #include "hisysevent.h"
31 #include "image_type.h"
32 #include "param_wrapper.h"
33 #include "hdr_type.h"
34 #include "metadata_convertor.h"
35 
36 namespace {
37 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_METADATA, "AVMetadatahelperImpl" };
38 constexpr int32_t SCENE_CODE_EFFECTIVE_DURATION_MS = 20000;
39 static constexpr char PERFORMANCE_STATS[] = "PERFORMANCE";
40 static std::atomic<uint32_t> concurrentWorkCount_ = 0;
41 static constexpr uint8_t HIGH_CONCRENT_WORK_NUM = 4;
42 static constexpr int32_t PLANE_Y = 0;
43 static constexpr int32_t PLANE_U = 1;
44 static constexpr uint8_t HDR_PIXEL_SIZE = 2;
45 static constexpr uint8_t SDR_PIXEL_SIZE = 1;
46 constexpr int32_t NUM_180 = 180;
47 static const std::string FILE_DIR_IN_THE_SANDBOX = "/data/storage/el2/base/files/";
48 const std::string DUMP_FILE_NAME_AVBUFFER = "_avbuffer.dat";
49 const std::string DUMP_FILE_NAME_PIXEMAP = "_pixelMap.dat";
50 const std::string DUMP_FILE_NAME_AFTER_SCLAE = "_afterScale.dat";
51 const std::string DUMP_FILE_NAME_AFTER_ROTATE = "_afterRotate.dat";
52 
53 constexpr uint8_t COLORPRIMARIES_OFFSET = 0;
54 constexpr uint8_t TRANSFUNC_OFFSET = 8;
55 constexpr uint8_t MATRIX_OFFSET = 16;
56 constexpr uint8_t RANGE_OFFSET = 21;
57 }
58 
59 namespace OHOS {
60 namespace Media {
61 using namespace OHOS::HDI::Display::Graphic::Common::V1_0;
62 static constexpr uint8_t PIXEL_SIZE_HDR_YUV = 3;
63 static std::map<Scene, long> SCENE_CODE_MAP = { { Scene::AV_META_SCENE_CLONE, 1 },
64                                                 { Scene::AV_META_SCENE_BATCH_HANDLE, 2 } };
65 static std::map<Scene, int64_t> SCENE_TIMESTAMP_MAP = { { Scene::AV_META_SCENE_CLONE, 0 },
66                                                         { Scene::AV_META_SCENE_BATCH_HANDLE, 0 } };
67 /*
68  * CM_ColorSpaceType from
69  * {@link ${system_general}/drivers/interface/display/graphic/common/v1_0/CMColorSpace.idl}
70  *
71  * ColorManager::ColorSpaceName from
72  * {@link ${system_general}/foundation/graphic/graphic_2d/utils/color_manager/export/color_space.h}
73  *
74  * maps with #IsHdr()
75  * {@link ${system_general}/foundation/multimedia/image_framework/frameworks/innerkitsimpl/common/src/pixel_map.cpp}
76  */
77 static const std::unordered_map<unsigned int, ColorManager::ColorSpaceName> SDR_COLORSPACE_MAP = {
78     { CM_BT601_EBU_FULL, ColorManager::ColorSpaceName::BT601_EBU },
79     { CM_BT601_EBU_LIMIT, ColorManager::ColorSpaceName::BT601_EBU_LIMIT },
80     { CM_BT601_SMPTE_C_FULL, ColorManager::ColorSpaceName::BT601_SMPTE_C },
81     { CM_BT601_SMPTE_C_LIMIT, ColorManager::ColorSpaceName::BT601_SMPTE_C_LIMIT },
82     { CM_BT709_FULL, ColorManager::ColorSpaceName::BT709 },
83     { CM_BT709_LIMIT, ColorManager::ColorSpaceName::BT709_LIMIT },
84     { CM_SRGB_FULL, ColorManager::ColorSpaceName::SRGB },
85     { CM_SRGB_LIMIT, ColorManager::ColorSpaceName::SRGB_LIMIT },
86     { CM_P3_FULL, ColorManager::ColorSpaceName::DISPLAY_P3 },
87     { CM_P3_LIMIT, ColorManager::ColorSpaceName::DISPLAY_P3_LIMIT },
88     { CM_P3_HLG_FULL, ColorManager::ColorSpaceName::P3_HLG },
89     { CM_P3_HLG_LIMIT, ColorManager::ColorSpaceName::P3_HLG_LIMIT },
90     { CM_P3_PQ_FULL, ColorManager::ColorSpaceName::P3_PQ_LIMIT },
91     { CM_P3_PQ_LIMIT, ColorManager::ColorSpaceName::P3_PQ_LIMIT },
92     { CM_ADOBERGB_FULL, ColorManager::ColorSpaceName::ADOBE_RGB },
93     { CM_ADOBERGB_LIMIT, ColorManager::ColorSpaceName::ADOBE_RGB_LIMIT },
94     { CM_LINEAR_SRGB, ColorManager::ColorSpaceName::LINEAR_SRGB },
95     { CM_LINEAR_BT709, ColorManager::ColorSpaceName::LINEAR_BT709 },
96     { CM_LINEAR_P3, ColorManager::ColorSpaceName::LINEAR_P3 },
97     { CM_LINEAR_BT2020, ColorManager::ColorSpaceName::LINEAR_BT2020 },
98 
99     // sdr pixelMap can use BT2020 color space, but hdr can't use color space except BT2020
100     { CM_BT2020_HLG_FULL, ColorManager::ColorSpaceName::BT2020_HLG },
101     { CM_BT2020_PQ_FULL, ColorManager::ColorSpaceName::BT2020_PQ },
102     { CM_BT2020_HLG_LIMIT, ColorManager::ColorSpaceName::BT2020_HLG_LIMIT },
103     { CM_BT2020_PQ_LIMIT, ColorManager::ColorSpaceName::BT2020_PQ_LIMIT },
104 };
105 
106 static const std::unordered_map<unsigned int, ColorManager::ColorSpaceName> HDR_COLORSPACE_MAP = {
107     { CM_BT2020_HLG_FULL, ColorManager::ColorSpaceName::BT2020_HLG },
108     { CM_BT2020_PQ_FULL, ColorManager::ColorSpaceName::BT2020_PQ },
109     { CM_BT2020_HLG_LIMIT, ColorManager::ColorSpaceName::BT2020_HLG_LIMIT },
110     { CM_BT2020_PQ_LIMIT, ColorManager::ColorSpaceName::BT2020_PQ_LIMIT },
111 };
112 
113 struct PixelMapMemHolder {
114     bool isShmem;
115     std::shared_ptr<AVSharedMemory> shmem;
116     uint8_t *heap;
117 };
118 
119 struct AVBufferHolder {
120     std::shared_ptr<AVBuffer> buffer;
121 };
122 
FreePixelMapData(void * addr,void * context,uint32_t size)123 static void FreePixelMapData(void *addr, void *context, uint32_t size)
124 {
125     (void)size;
126 
127     MEDIA_LOGD("free pixel map data");
128 
129     CHECK_AND_RETURN_LOG(context != nullptr, "context is nullptr");
130     PixelMapMemHolder *holder = reinterpret_cast<PixelMapMemHolder *>(context);
131     if (holder->isShmem) {
132         if (holder->shmem == nullptr) {
133             MEDIA_LOGE("shmem is nullptr");
134         }
135         holder->shmem = nullptr;
136         holder->heap = nullptr;
137     } else {
138         if (holder->heap == nullptr || holder->heap != addr) {
139             MEDIA_LOGE("heap is invalid");
140         } else {
141             delete [] holder->heap;
142             holder->heap = nullptr;
143         }
144     }
145     delete holder;
146 }
147 
FreeAvBufferData(void * addr,void * context,uint32_t size)148 static void FreeAvBufferData(void *addr, void *context, uint32_t size)
149 {
150     (void)addr;
151     (void)size;
152     CHECK_AND_RETURN_LOG(context != nullptr, "context is nullptr");
153     AVBufferHolder *holder = reinterpret_cast<AVBufferHolder *>(context);
154     delete holder;
155 }
156 
FreeSurfaceBuffer(void * addr,void * context,uint32_t size)157 static void FreeSurfaceBuffer(void *addr, void *context, uint32_t size)
158 {
159     (void)addr;
160     (void)size;
161     CHECK_AND_RETURN_LOG(context != nullptr, "context is nullptr");
162     void* nativeBuffer = context;
163     RefBase *ref = reinterpret_cast<RefBase *>(nativeBuffer);
164     ref->DecStrongRef(ref);
165 }
166 
CreatePixelMapData(const std::shared_ptr<AVSharedMemory> & mem,const OutputFrame & frame)167 static PixelMapMemHolder *CreatePixelMapData(const std::shared_ptr<AVSharedMemory> &mem, const OutputFrame &frame)
168 {
169     PixelMapMemHolder *holder = new (std::nothrow) PixelMapMemHolder;
170     CHECK_AND_RETURN_RET_LOG(holder != nullptr, nullptr, "alloc pixelmap mem holder failed");
171 
172     ON_SCOPE_EXIT(0) {
173         delete holder;
174     };
175 
176     int32_t minStride = frame.width_ * frame.bytesPerPixel_;
177     CHECK_AND_RETURN_RET_LOG(minStride <= frame.stride_, nullptr, "stride info wrong");
178 
179     if (frame.stride_ == minStride) {
180         CANCEL_SCOPE_EXIT_GUARD(0);
181         holder->isShmem = true;
182         holder->shmem = mem;
183         holder->heap = frame.GetFlattenedData();
184         return holder;
185     }
186 
187     static constexpr int64_t maxAllowedSize = 100 * 1024 * 1024;
188     int64_t memSize = static_cast<int64_t>(minStride) * frame.height_;
189     CHECK_AND_RETURN_RET_LOG(memSize <= maxAllowedSize, nullptr, "alloc heap size too large");
190 
191     uint8_t *heap = new (std::nothrow) uint8_t[memSize];
192     CHECK_AND_RETURN_RET_LOG(heap != nullptr, nullptr, "alloc heap failed");
193 
194     ON_SCOPE_EXIT(1) {
195         delete [] heap;
196     };
197 
198     uint8_t *currDstPos = heap;
199     uint8_t *currSrcPos = frame.GetFlattenedData();
200     for (int32_t row = 0; row < frame.height_; ++row) {
201         errno_t rc = memcpy_s(currDstPos, static_cast<size_t>(memSize), currSrcPos, static_cast<size_t>(minStride));
202         CHECK_AND_RETURN_RET_LOG(rc == EOK, nullptr, "memcpy_s failed");
203 
204         currDstPos += minStride;
205         currSrcPos += frame.stride_;
206         memSize -= minStride;
207     }
208 
209     holder->isShmem = false;
210     holder->heap = heap;
211 
212     CANCEL_SCOPE_EXIT_GUARD(0);
213     CANCEL_SCOPE_EXIT_GUARD(1);
214     return holder;
215 }
216 
CreateAVBufferHolder(const std::shared_ptr<AVBuffer> & avBuffer)217 static AVBufferHolder *CreateAVBufferHolder(const std::shared_ptr<AVBuffer> &avBuffer)
218 {
219     CHECK_AND_RETURN_RET(avBuffer != nullptr && avBuffer->memory_ != nullptr, nullptr);
220     AVBufferHolder *holder = new (std::nothrow) AVBufferHolder;
221     CHECK_AND_RETURN_RET_LOG(holder != nullptr, nullptr, "alloc avBuffer holder failed");
222     holder->buffer = avBuffer;
223     return holder;
224 }
225 
CreatePixelMap(const std::shared_ptr<AVSharedMemory> & mem,PixelFormat color,int32_t & rotation)226 static std::shared_ptr<PixelMap> CreatePixelMap(const std::shared_ptr<AVSharedMemory> &mem, PixelFormat color,
227     int32_t &rotation)
228 {
229     CHECK_AND_RETURN_RET_LOG(mem != nullptr, nullptr, "Fetch frame failed");
230     CHECK_AND_RETURN_RET_LOG(mem->GetBase() != nullptr, nullptr, "Addr is nullptr");
231     CHECK_AND_RETURN_RET_LOG(mem->GetSize() > 0, nullptr, "size is incorrect");
232     CHECK_AND_RETURN_RET_LOG(static_cast<uint32_t>(mem->GetSize()) >= sizeof(OutputFrame),
233                              nullptr, "size is incorrect");
234 
235     OutputFrame *frame = reinterpret_cast<OutputFrame *>(mem->GetBase());
236     MEDIA_LOGD("width: %{public}d, stride : %{public}d, height: %{public}d, size: %{public}d, format: %{public}d",
237         frame->width_, frame->stride_, frame->height_, frame->size_, color);
238 
239     rotation = frame->rotation_;
240     InitializationOptions opts;
241     opts.size.width = frame->width_;
242     opts.size.height = frame->height_;
243     opts.pixelFormat = color;
244     opts.editable = true;
245     std::shared_ptr<PixelMap> pixelMap = PixelMap::Create(opts);
246 
247     CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, nullptr, "pixelMap create failed");
248     CHECK_AND_RETURN_RET_LOG(pixelMap->GetByteCount() <= frame->size_, nullptr, "Size inconsistent !");
249 
250     PixelMapMemHolder *holder = CreatePixelMapData(mem, *frame);
251     CHECK_AND_RETURN_RET_LOG(holder != nullptr, nullptr, "create pixel map data failed");
252 
253     pixelMap->SetPixelsAddr(holder->heap, holder, static_cast<uint32_t>(pixelMap->GetByteCount()),
254         AllocatorType::CUSTOM_ALLOC, FreePixelMapData);
255     return pixelMap;
256 }
257 
SaveDataToFile(const std::string & fileName,const char * data,const size_t & totalSize)258 int32_t AVMetadataHelperImpl::SaveDataToFile(const std::string &fileName, const char *data, const size_t &totalSize)
259 {
260     CHECK_AND_RETURN_RET_LOG(data != nullptr, MSERR_INVALID_VAL, "data is nullptr");
261     auto rootPath = FILE_DIR_IN_THE_SANDBOX;
262     auto fullPath = rootPath + fileName;
263     char realPath[PATH_MAX] = { 0x00 };
264     CHECK_AND_RETURN_RET((fullPath.length() < PATH_MAX) && (realpath(rootPath.c_str(), realPath) != nullptr),
265                          MSERR_INVALID_VAL);
266     std::string verifiedPath(realPath);
267     std::ofstream outFile(verifiedPath.append("/" + fileName), std::ofstream::out);
268     if (!outFile.is_open()) {
269         MEDIA_LOGI("SaveDataToFile write error, path=%{public}s", verifiedPath.c_str());
270         return MSERR_UNKNOWN;
271     }
272 
273     outFile.write(data, totalSize);
274     return MSERR_OK;
275 }
276 
InitDumpFlag()277 void AVMetadataHelperImpl::InitDumpFlag()
278 {
279     const std::string dumpTag = "sys.media.avmetadatahelper.dump.enable";
280     std::string dumpEnable;
281     int32_t dumpRes = OHOS::system::GetStringParameter(dumpTag, dumpEnable, "false");
282     isDump_ = (dumpEnable == "true");
283     MEDIA_LOGI("get dump flag, dumpRes: %{public}d, isDump_: %{public}d", dumpRes, isDump_);
284 }
285 
DumpPixelMap(bool isDump,std::shared_ptr<PixelMap> pixelMap,const std::string & fileNameSuffix)286 int32_t AVMetadataHelperImpl::DumpPixelMap(bool isDump, std::shared_ptr<PixelMap> pixelMap,
287                                            const std::string &fileNameSuffix)
288 {
289     if (!isDump) {
290         return MSERR_INVALID_VAL;
291     }
292     CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, MSERR_INVALID_VAL, "invalid pixelMap");
293     std::string width = std::to_string(pixelMap->GetWidth());
294     std::string height = std::to_string(pixelMap->GetHeight());
295     std::string pixelFormat = pixelFormatToString(pixelMap->GetPixelFormat());
296     auto fileName = GetLocalTime() + "_" + width + "_" + height + "_" + pixelFormat + fileNameSuffix;
297     if (pixelMap->GetAllocatorType() == AllocatorType::DMA_ALLOC) {
298         auto surfaceBuffer = static_cast<SurfaceBuffer*>(pixelMap->GetFd());
299         CHECK_AND_RETURN_RET_LOG(surfaceBuffer != nullptr, MSERR_INVALID_VAL, "invalid surface buffer");
300         return SaveDataToFile(fileName,
301                               reinterpret_cast<const char *>(surfaceBuffer->GetVirAddr()),
302                               surfaceBuffer->GetSize());
303     }
304     return SaveDataToFile(fileName,
305                           reinterpret_cast<const char *>(pixelMap->GetPixels()),
306                           pixelMap->GetByteCount());
307 }
308 
DumpAVBuffer(bool isDump,const std::shared_ptr<AVBuffer> & frameBuffer,const std::string & fileNameSuffix)309 int32_t AVMetadataHelperImpl::DumpAVBuffer(bool isDump, const std::shared_ptr<AVBuffer> &frameBuffer,
310                                            const std::string &fileNameSuffix)
311 {
312     if (!isDump) {
313         return MSERR_INVALID_VAL;
314     }
315     bool isValid = frameBuffer != nullptr && frameBuffer->meta_ != nullptr && frameBuffer->memory_ != nullptr;
316     CHECK_AND_RETURN_RET_LOG(isValid, MSERR_INVALID_VAL, "invalid frame buffer");
317     auto bufferMeta = frameBuffer->meta_;
318     int32_t width = 0;
319     int32_t height = 0;
320     bool isHdr = false;
321     bufferMeta->Get<Tag::VIDEO_WIDTH>(width);
322     bufferMeta->Get<Tag::VIDEO_HEIGHT>(height);
323     bufferMeta->Get<Tag::VIDEO_IS_HDR_VIVID>(isHdr);
324     std::string widthStr = std::to_string(width);
325     std::string heightStr = std::to_string(height);
326     std::string pixelFormat = isHdr ? pixelFormatToString(PixelFormat::YCBCR_P010):
327                               pixelFormatToString(PixelFormat::NV12);
328     auto fileName = GetLocalTime() + "_" + widthStr + "_" + heightStr + "_" + pixelFormat + fileNameSuffix;
329     auto surfaceBuffer = frameBuffer->memory_->GetSurfaceBuffer();
330     if (surfaceBuffer == nullptr) {
331         return SaveDataToFile(fileName,
332                               reinterpret_cast<const char *>(frameBuffer->memory_->GetAddr()),
333                               frameBuffer->memory_->GetSize());
334     }
335     return SaveDataToFile(fileName,
336                           reinterpret_cast<const char *>(surfaceBuffer->GetVirAddr()),
337                           surfaceBuffer->GetSize());
338 }
339 
pixelFormatToString(PixelFormat pixelFormat)340 std::string AVMetadataHelperImpl::pixelFormatToString(PixelFormat pixelFormat)
341 {
342     switch (pixelFormat) {
343         case PixelFormat::RGB_565:
344             return "RGB_565";
345         case PixelFormat::RGBA_8888:
346             return "RGBA_8888";
347         case PixelFormat::RGB_888:
348             return "RGB_888";
349         case PixelFormat::NV12:
350             return "NV12";
351         case PixelFormat::YCBCR_P010:
352             return "YCBCR_P010";
353         default:
354             return "UNKNOWN";
355     }
356 }
357 
CreatePixelMapYuv(const std::shared_ptr<AVBuffer> & frameBuffer,PixelMapInfo & pixelMapInfo)358 std::shared_ptr<PixelMap> AVMetadataHelperImpl::CreatePixelMapYuv(const std::shared_ptr<AVBuffer> &frameBuffer,
359                                                                   PixelMapInfo &pixelMapInfo)
360 {
361     bool isValid = frameBuffer != nullptr && frameBuffer->meta_ != nullptr && frameBuffer->memory_ != nullptr;
362     CHECK_AND_RETURN_RET_LOG(isValid, nullptr, "invalid frame buffer");
363     auto bufferMeta = frameBuffer->meta_;
364 
365     int32_t width = 0;
366     auto hasProperty = bufferMeta->Get<Tag::VIDEO_WIDTH>(width);
367     CHECK_AND_RETURN_RET_LOG(hasProperty, nullptr, "invalid width");
368     int32_t height = 0;
369     hasProperty = bufferMeta->Get<Tag::VIDEO_HEIGHT>(height);
370     CHECK_AND_RETURN_RET_LOG(hasProperty, nullptr, "invalid height");
371 
372     Plugins::VideoRotation rotation = Plugins::VideoRotation::VIDEO_ROTATION_0;
373     bufferMeta->Get<Tag::VIDEO_ROTATION>(rotation);
374     pixelMapInfo.rotation = static_cast<int32_t>(rotation);
375     bufferMeta->Get<Tag::VIDEO_IS_HDR_VIVID>(pixelMapInfo.isHdr);
376 
377     if (pixelMapInfo.pixelFormat == PixelFormat::UNKNOWN) {
378         pixelMapInfo.pixelFormat = pixelMapInfo.isHdr ? PixelFormat::YCBCR_P010 : PixelFormat::NV12;
379     }
380 
381     if (frameBuffer->memory_->GetSize() != 0 && frameBuffer->memory_->GetSurfaceBuffer() == nullptr) {
382         InitializationOptions options = { .size = { .width = width, .height = height },
383                                           .pixelFormat = PixelFormat::NV12 };
384         return CreatePixelMapFromAVShareMemory(frameBuffer, pixelMapInfo, options);
385     }
386 
387     auto surfaceBuffer = frameBuffer->memory_->GetSurfaceBuffer();
388     CHECK_AND_RETURN_RET_LOG(surfaceBuffer != nullptr, nullptr, "srcSurfaceBuffer is nullptr");
389 
390     pixelMapInfo.width = width;
391     pixelMapInfo.height = height;
392     int32_t outputHeight = height;
393     bufferMeta->Get<Tag::VIDEO_SLICE_HEIGHT>(outputHeight);
394     pixelMapInfo.outputHeight = outputHeight;
395     MEDIA_LOGD("pixelMapInfo.outputHeight = %{public}d", pixelMapInfo.outputHeight);
396 
397     return CreatePixelMapFromSurfaceBuffer(surfaceBuffer, pixelMapInfo);
398 }
399 
CreatePixelMapFromAVShareMemory(const std::shared_ptr<AVBuffer> & frameBuffer,PixelMapInfo & pixelMapInfo,InitializationOptions & options)400 std::shared_ptr<PixelMap> AVMetadataHelperImpl::CreatePixelMapFromAVShareMemory(const std::shared_ptr<AVBuffer>
401                                                                                 &frameBuffer,
402                                                                                 PixelMapInfo &pixelMapInfo,
403                                                                                 InitializationOptions &options)
404 {
405     bool isValid = frameBuffer != nullptr && frameBuffer->memory_ != nullptr;
406     CHECK_AND_RETURN_RET_LOG(isValid, nullptr, "invalid frame buffer");
407     std::shared_ptr<PixelMap> pixelMap = PixelMap::Create(options);
408     CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, nullptr, "Create pixelMap failed");
409     AVBufferHolder *holder = CreateAVBufferHolder(frameBuffer);
410     CHECK_AND_RETURN_RET_LOG(holder != nullptr, nullptr, "Create buffer holder failed");
411     uint8_t *pixelAddr = frameBuffer->memory_->GetAddr();
412     pixelMap->SetPixelsAddr(pixelAddr, holder, pixelMap->GetByteCount(),
413                             AllocatorType::CUSTOM_ALLOC, FreeAvBufferData);
414     const InitializationOptions opts = { .size = { .width = pixelMap->GetWidth(),
415                                                    .height = pixelMap->GetHeight() },
416                                          .srcPixelFormat = PixelFormat::NV12,
417                                          .pixelFormat = pixelMapInfo.pixelFormat };
418     pixelMap = PixelMap::Create(reinterpret_cast<const uint32_t *>(pixelMap->GetPixels()),
419                                 pixelMap->GetByteCount(), opts);
420     sptr<SurfaceBuffer> surfaceBuffer = nullptr;
421     SetPixelMapYuvInfo(surfaceBuffer, pixelMap, pixelMapInfo, false);
422     return pixelMap;
423 }
424 
FormatColorSpaceInfo(CM_ColorSpaceInfo & colorSpaceInfo)425 void AVMetadataHelperImpl::FormatColorSpaceInfo(CM_ColorSpaceInfo &colorSpaceInfo)
426 {
427     switch (colorSpaceInfo.primaries) {
428         case CM_ColorPrimaries::COLORPRIMARIES_P3_D65:
429             if (colorSpaceInfo.matrix == CM_Matrix::MATRIX_BT601_P) {
430                 colorSpaceInfo.matrix = CM_Matrix::MATRIX_P3; // MATRIX_P3 equals MATRIX_BT601_P and MATRIX_BT601_N
431             }
432             break;
433         case CM_ColorPrimaries::COLORPRIMARIES_BT601_P:
434             if (colorSpaceInfo.matrix == CM_Matrix::MATRIX_BT601_N || colorSpaceInfo.matrix == CM_Matrix::MATRIX_P3) {
435                 colorSpaceInfo.matrix = CM_Matrix::MATRIX_BT601_P; // MATRIX_P3 equals MATRIX_BT601_P and MATRIX_BT601_N
436             }
437             break;
438         default:
439             break;
440     }
441 }
442 
GetColorSpace(sptr<SurfaceBuffer> & surfaceBuffer,PixelMapInfo & pixelMapInfo)443 Status AVMetadataHelperImpl::GetColorSpace(sptr<SurfaceBuffer> &surfaceBuffer, PixelMapInfo &pixelMapInfo)
444 {
445     std::vector<uint8_t> colorSpaceInfoVec;
446     if (surfaceBuffer->GetMetadata(ATTRKEY_COLORSPACE_INFO, colorSpaceInfoVec) != GSERROR_OK) {
447         MEDIA_LOGW("cant find colorSpace");
448         return Status::ERROR_UNKNOWN;
449     }
450     auto outColor = reinterpret_cast<CM_ColorSpaceInfo *>(colorSpaceInfoVec.data());
451     CHECK_AND_RETURN_RET_LOG(outColor != nullptr, Status::ERROR_UNKNOWN, "colorSpaceInfoVec init failed");
452     auto colorSpaceInfo = outColor[0];
453     FormatColorSpaceInfo(colorSpaceInfo);
454     pixelMapInfo.srcRange = colorSpaceInfo.range == CM_Range::RANGE_FULL ? 1 : 0;
455     auto type = ((static_cast<unsigned int>(colorSpaceInfo.primaries) << COLORPRIMARIES_OFFSET) +
456                  (static_cast<unsigned int>(colorSpaceInfo.transfunc) << TRANSFUNC_OFFSET) +
457                  (static_cast<unsigned int>(colorSpaceInfo.matrix) << MATRIX_OFFSET) +
458                  (static_cast<unsigned int>(colorSpaceInfo.range) << RANGE_OFFSET));
459     pixelMapInfo.primaries = colorSpaceInfo.primaries;
460     MEDIA_LOGI("colorSpaceType is %{public}u", type);
461     if (pixelMapInfo.isHdr) {
462         auto it = HDR_COLORSPACE_MAP.find(type);
463         CHECK_AND_RETURN_RET_LOG(it != HDR_COLORSPACE_MAP.end(), Status::ERROR_UNKNOWN,
464             "can't find mapped colorSpace name in hdr map");
465         pixelMapInfo.colorSpaceName = it->second;
466         return Status::OK;
467     }
468     auto it = SDR_COLORSPACE_MAP.find(type);
469     CHECK_AND_RETURN_RET_LOG(it != SDR_COLORSPACE_MAP.end(), Status::ERROR_UNKNOWN,
470         "can't find mapped colorSpace name in sdr map");
471     pixelMapInfo.colorSpaceName = it->second;
472     return Status::OK;
473 }
474 
CreatePixelMapFromSurfaceBuffer(sptr<SurfaceBuffer> & surfaceBuffer,PixelMapInfo & pixelMapInfo)475 std::shared_ptr<PixelMap> AVMetadataHelperImpl::CreatePixelMapFromSurfaceBuffer(sptr<SurfaceBuffer> &surfaceBuffer,
476                                                                                 PixelMapInfo &pixelMapInfo)
477 {
478     CHECK_AND_RETURN_RET_LOG(surfaceBuffer != nullptr, nullptr, "surfaceBuffer is nullptr");
479     auto getColorSpaceInfoRes = GetColorSpace(surfaceBuffer, pixelMapInfo);
480     InitializationOptions options = { .size = { .width = pixelMapInfo.width,
481                                                 .height = pixelMapInfo.height } };
482     bool isHdr = pixelMapInfo.isHdr;
483     options.srcPixelFormat = isHdr ? PixelFormat::YCBCR_P010 : PixelFormat::NV12;
484     options.pixelFormat = isHdr ? PixelFormat::YCBCR_P010 : PixelFormat::NV12;
485     options.useDMA = isHdr;
486     bool needModifyStride = false;
487     options.convertColorSpace.srcRange = pixelMapInfo.srcRange;
488     int32_t colorLength = pixelMapInfo.width * pixelMapInfo.height * PIXEL_SIZE_HDR_YUV;
489     colorLength = isHdr ? colorLength : colorLength / HDR_PIXEL_SIZE;
490     std::shared_ptr<PixelMap> pixelMap;
491 
492     if (!options.useDMA) {
493         pixelMap = PixelMap::Create(options);
494         CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, nullptr, "Create pixelMap failed");
495         auto ret = CopySurfaceBufferToPixelMap(surfaceBuffer, pixelMap, pixelMapInfo);
496         CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, nullptr, "CopySurfaceBufferToPixelMap failed");
497         options.pixelFormat = pixelMapInfo.pixelFormat;
498         int32_t primaries = pixelMapInfo.primaries;
499         options.convertColorSpace.srcYuvConversion = primaries == CM_ColorPrimaries::COLORPRIMARIES_BT709 ?
500             YuvConversion::BT709 : YuvConversion::BT601;
501         options.convertColorSpace.dstYuvConversion = primaries == CM_ColorPrimaries::COLORPRIMARIES_BT709 ?
502             YuvConversion::BT709 : YuvConversion::BT601;
503         MEDIA_LOGD("conversion: %{public}d", options.convertColorSpace.srcYuvConversion);
504         pixelMap = PixelMap::Create(reinterpret_cast<const uint32_t *>(pixelMap->GetPixels()),
505                                     pixelMap->GetByteCount(), options);
506         CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, nullptr, "Create non-DMA pixelMap failed");
507         pixelMap->InnerSetColorSpace(OHOS::ColorManager::ColorSpace(
508             getColorSpaceInfoRes == Status::OK ? pixelMapInfo.colorSpaceName : ColorManager::SRGB));
509     } else {
510         pixelMap = PixelMap::Create(reinterpret_cast<const uint32_t *>(surfaceBuffer->GetVirAddr()),
511                                     static_cast<uint32_t>(colorLength), options);
512         CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, nullptr, "Create DMA pixelMap failed");
513         void* nativeBuffer = surfaceBuffer.GetRefPtr();
514         RefBase *ref = reinterpret_cast<RefBase *>(nativeBuffer);
515         ref->IncStrongRef(ref);
516         if (isHdr) {
517             pixelMap->SetHdrType(ImageHdrType::HDR_VIVID_SINGLE);
518             pixelMap->InnerSetColorSpace(OHOS::ColorManager::ColorSpace(
519                 getColorSpaceInfoRes == Status::OK ? pixelMapInfo.colorSpaceName : ColorManager::BT2020_HLG));
520         }
521         pixelMap->SetPixelsAddr(surfaceBuffer->GetVirAddr(), surfaceBuffer.GetRefPtr(), surfaceBuffer->GetSize(),
522                                 AllocatorType::DMA_ALLOC, FreeSurfaceBuffer);
523         needModifyStride = true;
524     }
525 
526     SetPixelMapYuvInfo(surfaceBuffer, pixelMap, pixelMapInfo, needModifyStride);
527 
528     return pixelMap;
529 }
530 
CopySurfaceBufferToPixelMap(sptr<SurfaceBuffer> & surfaceBuffer,std::shared_ptr<PixelMap> pixelMap,PixelMapInfo & pixelMapInfo)531 int32_t AVMetadataHelperImpl::CopySurfaceBufferToPixelMap(sptr<SurfaceBuffer> &surfaceBuffer,
532                                                           std::shared_ptr<PixelMap> pixelMap,
533                                                           PixelMapInfo &pixelMapInfo)
534 {
535     CHECK_AND_RETURN_RET(surfaceBuffer != nullptr && pixelMap != nullptr, MSERR_INVALID_VAL);
536     int32_t width = surfaceBuffer->GetWidth();
537     int32_t height = surfaceBuffer->GetHeight();
538     int32_t stride = surfaceBuffer->GetStride();
539 
540     uint8_t *srcPtr = static_cast<uint8_t *>(surfaceBuffer->GetVirAddr());
541     uint8_t *dstPtr = const_cast<uint8_t *>(pixelMap->GetPixels());
542         // copy src Y component to dst
543     int32_t lineByteCount = width;
544     for (int32_t y = 0; y < height; y++) {
545         auto ret = memcpy_s(dstPtr, lineByteCount, srcPtr, lineByteCount);
546         TRUE_LOG(ret != EOK, MEDIA_LOGW, "Memcpy Y component failed.");
547         srcPtr += stride;
548         dstPtr += lineByteCount;
549     }
550 
551     srcPtr = static_cast<uint8_t *>(surfaceBuffer->GetVirAddr()) + stride * pixelMapInfo.outputHeight;
552 
553     // copy src UV component to dst, height(UV) = height(Y) / 2
554     for (int32_t uv = 0; uv < height / 2; uv++) {
555         auto ret = memcpy_s(dstPtr, lineByteCount, srcPtr, lineByteCount);
556         TRUE_LOG(ret != EOK, MEDIA_LOGW, "Memcpy UV component failed.");
557         srcPtr += stride;
558         dstPtr += lineByteCount;
559     }
560     return MSERR_OK;
561 }
562 
SetPixelMapYuvInfo(sptr<SurfaceBuffer> & surfaceBuffer,std::shared_ptr<PixelMap> pixelMap,PixelMapInfo & pixelMapInfo,bool needModifyStride)563 void AVMetadataHelperImpl::SetPixelMapYuvInfo(sptr<SurfaceBuffer> &surfaceBuffer, std::shared_ptr<PixelMap> pixelMap,
564                                               PixelMapInfo &pixelMapInfo, bool needModifyStride)
565 {
566     CHECK_AND_RETURN_LOG(pixelMap != nullptr, "invalid pixelMap");
567     uint8_t ratio = pixelMapInfo.isHdr ? HDR_PIXEL_SIZE : SDR_PIXEL_SIZE;
568     int32_t srcWidth = pixelMap->GetWidth();
569     int32_t srcHeight = pixelMap->GetHeight();
570     YUVDataInfo yuvDataInfo = { .yWidth = srcWidth,
571                                 .yHeight = srcHeight,
572                                 .uvWidth = srcWidth / 2,
573                                 .uvHeight = srcHeight / 2,
574                                 .yStride = srcWidth,
575                                 .uvStride = srcWidth,
576                                 .uvOffset = srcWidth * srcHeight};
577 
578     if (surfaceBuffer == nullptr || !needModifyStride) {
579         pixelMap->SetImageYUVInfo(yuvDataInfo);
580         return;
581     }
582     OH_NativeBuffer_Planes *planes = nullptr;
583     GSError retVal = surfaceBuffer->GetPlanesInfo(reinterpret_cast<void**>(&planes));
584     if (retVal != OHOS::GSERROR_OK || planes == nullptr) {
585         pixelMap->SetImageYUVInfo(yuvDataInfo);
586         return;
587     }
588 
589     yuvDataInfo.yStride = planes->planes[PLANE_Y].columnStride / ratio;
590     yuvDataInfo.uvStride = planes->planes[PLANE_U].columnStride / ratio;
591     yuvDataInfo.yOffset = planes->planes[PLANE_Y].offset / ratio;
592     yuvDataInfo.uvOffset = planes->planes[PLANE_U].offset / ratio;
593 
594     pixelMap->SetImageYUVInfo(yuvDataInfo);
595 }
596 
CreateAVMetadataHelper()597 std::shared_ptr<AVMetadataHelper> AVMetadataHelperFactory::CreateAVMetadataHelper()
598 {
599     std::shared_ptr<AVMetadataHelperImpl> impl = std::make_shared<AVMetadataHelperImpl>();
600     CHECK_AND_RETURN_RET_LOG(impl != nullptr, nullptr, "failed to new AVMetadataHelperImpl");
601 
602     int32_t ret = impl->Init();
603     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, nullptr, "failed to init AVMetadataHelperImpl");
604 
605     return impl;
606 }
607 
Init()608 int32_t AVMetadataHelperImpl::Init()
609 {
610     avMetadataHelperService_ = MediaServiceFactory::GetInstance().CreateAVMetadataHelperService();
611     CHECK_AND_RETURN_RET_LOG(avMetadataHelperService_ != nullptr, MSERR_NO_MEMORY,
612         "failed to create avmetadatahelper service");
613     InitDumpFlag();
614     return MSERR_OK;
615 }
616 
AVMetadataHelperImpl()617 AVMetadataHelperImpl::AVMetadataHelperImpl()
618 {
619     MEDIA_LOGD("AVMetadataHelperImpl:0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
620 }
621 
~AVMetadataHelperImpl()622 AVMetadataHelperImpl::~AVMetadataHelperImpl()
623 {
624     if (avMetadataHelperService_ != nullptr) {
625         (void)MediaServiceFactory::GetInstance().DestroyAVMetadataHelperService(avMetadataHelperService_);
626         avMetadataHelperService_ = nullptr;
627     }
628     MEDIA_LOGD("AVMetadataHelperImpl:0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
629 }
630 
SetHelperCallback(const std::shared_ptr<HelperCallback> & callback)631 int32_t AVMetadataHelperImpl::SetHelperCallback(const std::shared_ptr<HelperCallback> &callback)
632 {
633     MEDIA_LOGD("AVMetadataHelperImpl:0x%{public}06" PRIXPTR " SetHelperCallback in", FAKE_POINTER(this));
634     CHECK_AND_RETURN_RET_LOG(avMetadataHelperService_ != nullptr, MSERR_SERVICE_DIED,
635         "metadata helper service does not exist..");
636     CHECK_AND_RETURN_RET_LOG(callback != nullptr, MSERR_INVALID_VAL, "callback is nullptr");
637     return avMetadataHelperService_->SetHelperCallback(callback);
638 }
639 
SetScene(Scene scene)640 void AVMetadataHelperImpl::SetScene(Scene scene)
641 {
642     ReportSceneCode(scene);
643 }
644 
ReportSceneCode(Scene scene)645 void AVMetadataHelperImpl::ReportSceneCode(Scene scene)
646 {
647     if (scene != Scene::AV_META_SCENE_CLONE && scene != Scene::AV_META_SCENE_BATCH_HANDLE) {
648         return;
649     }
650     if (scene == Scene::AV_META_SCENE_BATCH_HANDLE && concurrentWorkCount_ < HIGH_CONCRENT_WORK_NUM) {
651         return;
652     }
653     auto sceneCode = SCENE_CODE_MAP[scene];
654     auto lastTsp = SCENE_TIMESTAMP_MAP[scene];
655     auto now =
656         std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
657     auto duration = now - std::chrono::milliseconds(lastTsp);
658     if (duration < std::chrono::milliseconds(SCENE_CODE_EFFECTIVE_DURATION_MS)) {
659         return;
660     }
661     SCENE_TIMESTAMP_MAP[scene] = now.count();
662     MEDIA_LOGI("Report scene code %{public}ld", sceneCode);
663     int32_t ret = HiSysEventWrite(
664         PERFORMANCE_STATS, "CPU_SCENE_ENTRY", OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR, "PACKAGE_NAME",
665         "media_service", "SCENE_ID", std::to_string(sceneCode).c_str(), "HAPPEN_TIME", now.count());
666     if (ret != MSERR_OK) {
667         MEDIA_LOGW("report error");
668     }
669 }
670 
SetSource(const std::string & uri,int32_t usage)671 int32_t AVMetadataHelperImpl::SetSource(const std::string &uri, int32_t usage)
672 {
673     CHECK_AND_RETURN_RET_LOG(avMetadataHelperService_ != nullptr, MSERR_NO_MEMORY,
674         "avmetadatahelper service does not exist..");
675     CHECK_AND_RETURN_RET_LOG(!uri.empty(), MSERR_INVALID_VAL, "uri is empty.");
676 
677     concurrentWorkCount_++;
678     ReportSceneCode(AV_META_SCENE_BATCH_HANDLE);
679     auto res = avMetadataHelperService_->SetSource(uri, usage);
680     concurrentWorkCount_--;
681     return res;
682 }
683 
SetSource(int32_t fd,int64_t offset,int64_t size,int32_t usage)684 int32_t AVMetadataHelperImpl::SetSource(int32_t fd, int64_t offset, int64_t size, int32_t usage)
685 {
686     CHECK_AND_RETURN_RET_LOG(avMetadataHelperService_ != nullptr, MSERR_NO_MEMORY,
687         "avmetadatahelper service does not exist..");
688     MEDIA_LOGI("Set file source fd: %{public}d, offset: %{public}" PRIu64 ", size: %{public}" PRIu64,
689         fd, offset, size);
690     CHECK_AND_RETURN_RET_LOG(fd > 0 && offset >= 0 && size >= -1, MSERR_INVALID_VAL,
691         "invalid param");
692 
693     concurrentWorkCount_++;
694     ReportSceneCode(AV_META_SCENE_BATCH_HANDLE);
695     auto res = avMetadataHelperService_->SetSource(fd, offset, size, usage);
696     concurrentWorkCount_--;
697     return res;
698 }
699 
SetSource(const std::shared_ptr<IMediaDataSource> & dataSrc)700 int32_t AVMetadataHelperImpl::SetSource(const std::shared_ptr<IMediaDataSource> &dataSrc)
701 {
702     MEDIA_LOGD("AVMetadataHelperImpl:0x%{public}06" PRIXPTR " SetSource in(dataSrc)", FAKE_POINTER(this));
703     CHECK_AND_RETURN_RET_LOG(dataSrc != nullptr, MSERR_INVALID_VAL, "failed to create data source");
704 
705     concurrentWorkCount_++;
706     ReportSceneCode(AV_META_SCENE_BATCH_HANDLE);
707     auto res = avMetadataHelperService_->SetSource(dataSrc);
708     concurrentWorkCount_--;
709     return res;
710 }
711 
ResolveMetadata(int32_t key)712 std::string AVMetadataHelperImpl::ResolveMetadata(int32_t key)
713 {
714     CHECK_AND_RETURN_RET_LOG(avMetadataHelperService_ != nullptr, "",
715         "avmetadatahelper service does not exist.");
716     concurrentWorkCount_++;
717     auto res = avMetadataHelperService_->ResolveMetadata(key);
718     concurrentWorkCount_--;
719     return res;
720 }
721 
ResolveMetadata()722 std::unordered_map<int32_t, std::string> AVMetadataHelperImpl::ResolveMetadata()
723 {
724     CHECK_AND_RETURN_RET_LOG(avMetadataHelperService_ != nullptr, {},
725         "avmetadatahelper service does not exist.");
726     concurrentWorkCount_++;
727     auto res = avMetadataHelperService_->ResolveMetadata();
728     concurrentWorkCount_--;
729     return res;
730 }
731 
GetAVMetadata()732 std::shared_ptr<Meta> AVMetadataHelperImpl::GetAVMetadata()
733 {
734     CHECK_AND_RETURN_RET_LOG(avMetadataHelperService_ != nullptr, nullptr,
735         "avmetadatahelper service does not exist.");
736     concurrentWorkCount_++;
737     auto res = avMetadataHelperService_->GetAVMetadata();
738     concurrentWorkCount_--;
739     return res;
740 }
741 
FetchArtPicture()742 std::shared_ptr<AVSharedMemory> AVMetadataHelperImpl::FetchArtPicture()
743 {
744     CHECK_AND_RETURN_RET_LOG(avMetadataHelperService_ != nullptr, nullptr,
745         "avmetadatahelper service does not exist.");
746     concurrentWorkCount_++;
747     auto res = avMetadataHelperService_->FetchArtPicture();
748     concurrentWorkCount_--;
749     return res;
750 }
751 
FetchFrameAtTime(int64_t timeUs,int32_t option,const PixelMapParams & param)752 std::shared_ptr<PixelMap> AVMetadataHelperImpl::FetchFrameAtTime(
753     int64_t timeUs, int32_t option, const PixelMapParams &param)
754 {
755     CHECK_AND_RETURN_RET_LOG(avMetadataHelperService_ != nullptr, nullptr,
756         "avmetadatahelper service does not exist.");
757 
758     concurrentWorkCount_++;
759     ReportSceneCode(AV_META_SCENE_BATCH_HANDLE);
760 
761     OutputConfiguration config;
762     config.colorFormat = param.colorFormat;
763     config.dstHeight = param.dstHeight;
764     config.dstWidth = param.dstWidth;
765 
766     auto mem = avMetadataHelperService_->FetchFrameAtTime(timeUs, option, config);
767     auto pixelMap = CreatePixelMap(mem, PixelFormat::NV12, rotation_);
768 
769     concurrentWorkCount_--;
770 
771     CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, nullptr, "pixelMap does not exist.");
772 
773     const InitializationOptions opts = { .size = { .width = pixelMap->GetWidth(), .height = pixelMap->GetHeight() },
774                                          .srcPixelFormat = PixelFormat::NV12 };
775     pixelMap =
776         PixelMap::Create(reinterpret_cast<const uint32_t *>(pixelMap->GetPixels()), pixelMap->GetByteCount(), opts);
777     if (pixelMap == nullptr) {
778         return nullptr;
779     }
780     if (rotation_ > 0) {
781         pixelMap->rotate(rotation_);
782     }
783     int32_t srcWidth = pixelMap->GetWidth();
784     int32_t srcHeight = pixelMap->GetHeight();
785     bool needScale = (param.dstWidth > 0 && param.dstHeight > 0) &&
786                      (param.dstWidth <= srcWidth && param.dstHeight <= srcHeight) &&
787                      (param.dstWidth < srcWidth || param.dstHeight < srcHeight) && srcWidth > 0 && srcHeight > 0;
788     if (needScale) {
789         pixelMap->scale((1.0f * param.dstWidth) / srcWidth, (1.0f * param.dstHeight) / srcHeight);
790     }
791     return pixelMap;
792 }
793 
ScalePixelMap(std::shared_ptr<PixelMap> & pixelMap,PixelMapInfo & info,const PixelMapParams & param)794 void AVMetadataHelperImpl::ScalePixelMap(
795     std::shared_ptr<PixelMap> &pixelMap, PixelMapInfo &info, const PixelMapParams &param)
796 {
797     int32_t srcWidth = pixelMap->GetWidth();
798     int32_t srcHeight = pixelMap->GetHeight();
799     int32_t dstWidth = info.rotation % NUM_180 == 0 ? param.dstWidth : param.dstHeight;
800     int32_t dstHeight = info.rotation % NUM_180 == 0 ? param.dstHeight : param.dstWidth;
801     bool needScale = (dstWidth > 0 && dstHeight > 0) &&
802                      (dstWidth <= srcWidth && dstHeight <= srcHeight) &&
803                      (dstWidth < srcWidth || dstHeight < srcHeight) && srcWidth > 0 && srcHeight > 0;
804     CHECK_AND_RETURN(needScale);
805     pixelMap->scale((1.0f * dstWidth) / srcWidth, (1.0f * dstHeight) / srcHeight, AntiAliasingOption::LOW);
806 }
807 
FetchFrameYuv(int64_t timeUs,int32_t option,const PixelMapParams & param)808 std::shared_ptr<PixelMap> AVMetadataHelperImpl::FetchFrameYuv(int64_t timeUs, int32_t option,
809                                                               const PixelMapParams &param)
810 {
811     std::shared_ptr<IAVMetadataHelperService> avMetadataHelperService = avMetadataHelperService_;
812     CHECK_AND_RETURN_RET_LOG(avMetadataHelperService != nullptr, nullptr, "avmetadatahelper service does not exist.");
813 
814     concurrentWorkCount_++;
815     ReportSceneCode(AV_META_SCENE_BATCH_HANDLE);
816     OutputConfiguration config = { .dstWidth = param.dstWidth,
817                                    .dstHeight = param.dstHeight,
818                                    .colorFormat = param.colorFormat };
819     auto frameBuffer = avMetadataHelperService->FetchFrameYuv(timeUs, option, config);
820     CHECK_AND_RETURN_RET(frameBuffer != nullptr && frameBuffer->memory_ != nullptr, nullptr);
821     concurrentWorkCount_--;
822 
823     DumpAVBuffer(isDump_, frameBuffer, DUMP_FILE_NAME_AVBUFFER);
824 
825     PixelMapInfo pixelMapInfo = { .pixelFormat = param.colorFormat };
826     auto pixelMap = CreatePixelMapYuv(frameBuffer, pixelMapInfo);
827     CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, nullptr, "convert to pixelMap failed");
828 
829     DumpPixelMap(isDump_, pixelMap, DUMP_FILE_NAME_PIXEMAP);
830 
831     ScalePixelMap(pixelMap, pixelMapInfo, param);
832 
833     DumpPixelMap(isDump_, pixelMap, DUMP_FILE_NAME_AFTER_SCLAE);
834 
835     if (pixelMapInfo.rotation > 0) {
836         pixelMap->rotate(pixelMapInfo.rotation);
837     }
838 
839     MEDIA_LOGI("final colorSpace %{public}u", pixelMap->InnerGetGrColorSpace().GetColorSpaceName());
840 
841     DumpPixelMap(isDump_, pixelMap, DUMP_FILE_NAME_AFTER_ROTATE);
842     return pixelMap;
843 }
844 
GetTimeByFrameIndex(uint32_t index,uint64_t & time)845 int32_t AVMetadataHelperImpl::GetTimeByFrameIndex(uint32_t index, uint64_t &time)
846 {
847     CHECK_AND_RETURN_RET_LOG(avMetadataHelperService_ != nullptr, 0, "avmetadatahelper service does not exist.");
848     concurrentWorkCount_++;
849     auto res = avMetadataHelperService_->GetTimeByFrameIndex(index, time);
850     concurrentWorkCount_--;
851     return res;
852 }
853 
GetFrameIndexByTime(uint64_t time,uint32_t & index)854 int32_t AVMetadataHelperImpl::GetFrameIndexByTime(uint64_t time, uint32_t &index)
855 {
856     CHECK_AND_RETURN_RET_LOG(avMetadataHelperService_ != nullptr, 0, "avmetadatahelper service does not exist.");
857     concurrentWorkCount_++;
858     auto res = avMetadataHelperService_->GetFrameIndexByTime(time, index);
859     concurrentWorkCount_--;
860     return res;
861 }
862 
Release()863 void AVMetadataHelperImpl::Release()
864 {
865     std::lock_guard<std::mutex> lock(releaseMutex_);
866     MEDIA_LOGI("0x%{public}06" PRIXPTR " Release", FAKE_POINTER(this));
867     CHECK_AND_RETURN_LOG(avMetadataHelperService_ != nullptr, "avmetadatahelper service does not exist.");
868     avMetadataHelperService_->Release();
869     (void)MediaServiceFactory::GetInstance().DestroyAVMetadataHelperService(avMetadataHelperService_);
870     avMetadataHelperService_ = nullptr;
871     MEDIA_LOGI("0x%{public}06" PRIXPTR " Release out", FAKE_POINTER(this));
872 }
873 } // namespace Media
874 } // namespace OHOS
875