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 ¶m)
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 ¶m)
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 ¶m)
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