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 static const std::unordered_map<int32_t, std::pair<bool, bool>> VIDEOORIENTATIONTYPE_FLIP_MAP = {
114 { Plugins::VideoOrientationType::FLIP_H, {true, false} },
115 { Plugins::VideoOrientationType::FLIP_V, {false, true} },
116 { Plugins::VideoOrientationType::FLIP_H_ROT90, {true, false} },
117 { Plugins::VideoOrientationType::FLIP_V_ROT90, {false, true} },
118 };
119
120 static const std::unordered_map<int32_t, int32_t> VIDEOORIENTATIONTYPE_ROTATION_MAP = {
121 { Plugins::VideoOrientationType::FLIP_H, 0 },
122 { Plugins::VideoOrientationType::FLIP_V, 0 },
123 { Plugins::VideoOrientationType::FLIP_H_ROT90, 270 },
124 { Plugins::VideoOrientationType::FLIP_V_ROT90, 270 },
125 };
126
127 struct PixelMapMemHolder {
128 bool isShmem;
129 std::shared_ptr<AVSharedMemory> shmem;
130 uint8_t *heap;
131 };
132
133 struct AVBufferHolder {
134 std::shared_ptr<AVBuffer> buffer;
135 };
136
FreePixelMapData(void * addr,void * context,uint32_t size)137 static void FreePixelMapData(void *addr, void *context, uint32_t size)
138 {
139 (void)size;
140
141 MEDIA_LOGD("free pixel map data");
142
143 CHECK_AND_RETURN_LOG(context != nullptr, "context is nullptr");
144 PixelMapMemHolder *holder = reinterpret_cast<PixelMapMemHolder *>(context);
145 if (holder->isShmem) {
146 if (holder->shmem == nullptr) {
147 MEDIA_LOGE("shmem is nullptr");
148 }
149 holder->shmem = nullptr;
150 holder->heap = nullptr;
151 } else {
152 if (holder->heap == nullptr || holder->heap != addr) {
153 MEDIA_LOGE("heap is invalid");
154 } else {
155 delete [] holder->heap;
156 holder->heap = nullptr;
157 }
158 }
159 delete holder;
160 }
161
FreeAvBufferData(void * addr,void * context,uint32_t size)162 static void FreeAvBufferData(void *addr, void *context, uint32_t size)
163 {
164 (void)addr;
165 (void)size;
166 CHECK_AND_RETURN_LOG(context != nullptr, "context is nullptr");
167 AVBufferHolder *holder = reinterpret_cast<AVBufferHolder *>(context);
168 delete holder;
169 }
170
FreeSurfaceBuffer(void * addr,void * context,uint32_t size)171 static void FreeSurfaceBuffer(void *addr, void *context, uint32_t size)
172 {
173 (void)addr;
174 (void)size;
175 CHECK_AND_RETURN_LOG(context != nullptr, "context is nullptr");
176 void* nativeBuffer = context;
177 RefBase *ref = reinterpret_cast<RefBase *>(nativeBuffer);
178 ref->DecStrongRef(ref);
179 }
180
CreatePixelMapData(const std::shared_ptr<AVSharedMemory> & mem,const OutputFrame & frame)181 static PixelMapMemHolder *CreatePixelMapData(const std::shared_ptr<AVSharedMemory> &mem, const OutputFrame &frame)
182 {
183 PixelMapMemHolder *holder = new (std::nothrow) PixelMapMemHolder;
184 CHECK_AND_RETURN_RET_LOG(holder != nullptr, nullptr, "alloc pixelmap mem holder failed");
185
186 ON_SCOPE_EXIT(0) {
187 delete holder;
188 };
189
190 int32_t minStride = frame.width_ * frame.bytesPerPixel_;
191 CHECK_AND_RETURN_RET_LOG(minStride <= frame.stride_, nullptr, "stride info wrong");
192
193 if (frame.stride_ == minStride) {
194 CANCEL_SCOPE_EXIT_GUARD(0);
195 holder->isShmem = true;
196 holder->shmem = mem;
197 holder->heap = frame.GetFlattenedData();
198 return holder;
199 }
200
201 static constexpr int64_t maxAllowedSize = 100 * 1024 * 1024;
202 int64_t memSize = static_cast<int64_t>(minStride) * frame.height_;
203 CHECK_AND_RETURN_RET_LOG(memSize <= maxAllowedSize, nullptr, "alloc heap size too large");
204
205 uint8_t *heap = new (std::nothrow) uint8_t[memSize];
206 CHECK_AND_RETURN_RET_LOG(heap != nullptr, nullptr, "alloc heap failed");
207
208 ON_SCOPE_EXIT(1) {
209 delete [] heap;
210 };
211
212 uint8_t *currDstPos = heap;
213 uint8_t *currSrcPos = frame.GetFlattenedData();
214 for (int32_t row = 0; row < frame.height_; ++row) {
215 errno_t rc = memcpy_s(currDstPos, static_cast<size_t>(memSize), currSrcPos, static_cast<size_t>(minStride));
216 CHECK_AND_RETURN_RET_LOG(rc == EOK, nullptr, "memcpy_s failed");
217
218 currDstPos += minStride;
219 currSrcPos += frame.stride_;
220 memSize -= minStride;
221 }
222
223 holder->isShmem = false;
224 holder->heap = heap;
225
226 CANCEL_SCOPE_EXIT_GUARD(0);
227 CANCEL_SCOPE_EXIT_GUARD(1);
228 return holder;
229 }
230
CreateAVBufferHolder(const std::shared_ptr<AVBuffer> & avBuffer)231 static AVBufferHolder *CreateAVBufferHolder(const std::shared_ptr<AVBuffer> &avBuffer)
232 {
233 CHECK_AND_RETURN_RET(avBuffer != nullptr && avBuffer->memory_ != nullptr, nullptr);
234 AVBufferHolder *holder = new (std::nothrow) AVBufferHolder;
235 CHECK_AND_RETURN_RET_LOG(holder != nullptr, nullptr, "alloc avBuffer holder failed");
236 holder->buffer = avBuffer;
237 return holder;
238 }
239
CreatePixelMap(const std::shared_ptr<AVSharedMemory> & mem,PixelFormat color,int32_t & rotation)240 static std::shared_ptr<PixelMap> CreatePixelMap(const std::shared_ptr<AVSharedMemory> &mem, PixelFormat color,
241 int32_t &rotation)
242 {
243 CHECK_AND_RETURN_RET_LOG(mem != nullptr, nullptr, "Fetch frame failed");
244 CHECK_AND_RETURN_RET_LOG(mem->GetBase() != nullptr, nullptr, "Addr is nullptr");
245 CHECK_AND_RETURN_RET_LOG(mem->GetSize() > 0, nullptr, "size is incorrect");
246 CHECK_AND_RETURN_RET_LOG(static_cast<uint32_t>(mem->GetSize()) >= sizeof(OutputFrame),
247 nullptr, "size is incorrect");
248
249 OutputFrame *frame = reinterpret_cast<OutputFrame *>(mem->GetBase());
250 MEDIA_LOGD("width: %{public}d, stride : %{public}d, height: %{public}d, size: %{public}d, format: %{public}d",
251 frame->width_, frame->stride_, frame->height_, frame->size_, color);
252
253 rotation = frame->rotation_;
254 InitializationOptions opts;
255 opts.size.width = frame->width_;
256 opts.size.height = frame->height_;
257 opts.pixelFormat = color;
258 opts.editable = true;
259 std::shared_ptr<PixelMap> pixelMap = PixelMap::Create(opts);
260
261 CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, nullptr, "pixelMap create failed");
262 CHECK_AND_RETURN_RET_LOG(pixelMap->GetByteCount() <= frame->size_, nullptr, "Size inconsistent !");
263
264 PixelMapMemHolder *holder = CreatePixelMapData(mem, *frame);
265 CHECK_AND_RETURN_RET_LOG(holder != nullptr, nullptr, "create pixel map data failed");
266
267 pixelMap->SetPixelsAddr(holder->heap, holder, static_cast<uint32_t>(pixelMap->GetByteCount()),
268 AllocatorType::CUSTOM_ALLOC, FreePixelMapData);
269 return pixelMap;
270 }
271
SaveDataToFile(const std::string & fileName,const char * data,const size_t & totalSize)272 int32_t AVMetadataHelperImpl::SaveDataToFile(const std::string &fileName, const char *data, const size_t &totalSize)
273 {
274 CHECK_AND_RETURN_RET_LOG(data != nullptr, MSERR_INVALID_VAL, "data is nullptr");
275 auto rootPath = FILE_DIR_IN_THE_SANDBOX;
276 auto fullPath = rootPath + fileName;
277 char realPath[PATH_MAX] = { 0x00 };
278 CHECK_AND_RETURN_RET((fullPath.length() < PATH_MAX) && (realpath(rootPath.c_str(), realPath) != nullptr),
279 MSERR_INVALID_VAL);
280 std::string verifiedPath(realPath);
281 std::ofstream outFile(verifiedPath.append("/" + fileName), std::ofstream::out);
282 if (!outFile.is_open()) {
283 MEDIA_LOGI("SaveDataToFile write error, path=%{public}s", verifiedPath.c_str());
284 return MSERR_UNKNOWN;
285 }
286
287 outFile.write(data, totalSize);
288 return MSERR_OK;
289 }
290
InitDumpFlag()291 void AVMetadataHelperImpl::InitDumpFlag()
292 {
293 const std::string dumpTag = "sys.media.avmetadatahelper.dump.enable";
294 std::string dumpEnable;
295 int32_t dumpRes = OHOS::system::GetStringParameter(dumpTag, dumpEnable, "false");
296 isDump_ = (dumpEnable == "true");
297 MEDIA_LOGI("get dump flag, dumpRes: %{public}d, isDump_: %{public}d", dumpRes, isDump_);
298 }
299
DumpPixelMap(bool isDump,std::shared_ptr<PixelMap> pixelMap,const std::string & fileNameSuffix)300 int32_t AVMetadataHelperImpl::DumpPixelMap(bool isDump, std::shared_ptr<PixelMap> pixelMap,
301 const std::string &fileNameSuffix)
302 {
303 if (!isDump) {
304 return MSERR_INVALID_VAL;
305 }
306 CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, MSERR_INVALID_VAL, "invalid pixelMap");
307 std::string width = std::to_string(pixelMap->GetWidth());
308 std::string height = std::to_string(pixelMap->GetHeight());
309 std::string pixelFormat = pixelFormatToString(pixelMap->GetPixelFormat());
310 auto fileName = GetLocalTime() + "_" + width + "_" + height + "_" + pixelFormat + fileNameSuffix;
311 if (pixelMap->GetAllocatorType() == AllocatorType::DMA_ALLOC) {
312 auto surfaceBuffer = static_cast<SurfaceBuffer*>(pixelMap->GetFd());
313 CHECK_AND_RETURN_RET_LOG(surfaceBuffer != nullptr, MSERR_INVALID_VAL, "invalid surface buffer");
314 return SaveDataToFile(fileName,
315 reinterpret_cast<const char *>(surfaceBuffer->GetVirAddr()),
316 surfaceBuffer->GetSize());
317 }
318 return SaveDataToFile(fileName,
319 reinterpret_cast<const char *>(pixelMap->GetPixels()),
320 pixelMap->GetByteCount());
321 }
322
DumpAVBuffer(bool isDump,const std::shared_ptr<AVBuffer> & frameBuffer,const std::string & fileNameSuffix)323 int32_t AVMetadataHelperImpl::DumpAVBuffer(bool isDump, const std::shared_ptr<AVBuffer> &frameBuffer,
324 const std::string &fileNameSuffix)
325 {
326 if (!isDump) {
327 return MSERR_INVALID_VAL;
328 }
329 bool isValid = frameBuffer != nullptr && frameBuffer->meta_ != nullptr && frameBuffer->memory_ != nullptr;
330 CHECK_AND_RETURN_RET_LOG(isValid, MSERR_INVALID_VAL, "invalid frame buffer");
331 auto bufferMeta = frameBuffer->meta_;
332 int32_t width = 0;
333 int32_t height = 0;
334 bool isHdr = false;
335 bufferMeta->Get<Tag::VIDEO_WIDTH>(width);
336 bufferMeta->Get<Tag::VIDEO_HEIGHT>(height);
337 bufferMeta->Get<Tag::VIDEO_IS_HDR_VIVID>(isHdr);
338 std::string widthStr = std::to_string(width);
339 std::string heightStr = std::to_string(height);
340 std::string pixelFormat = isHdr ? pixelFormatToString(PixelFormat::YCBCR_P010):
341 pixelFormatToString(PixelFormat::NV12);
342 auto fileName = GetLocalTime() + "_" + widthStr + "_" + heightStr + "_" + pixelFormat + fileNameSuffix;
343 auto surfaceBuffer = frameBuffer->memory_->GetSurfaceBuffer();
344 if (surfaceBuffer == nullptr) {
345 return SaveDataToFile(fileName,
346 reinterpret_cast<const char *>(frameBuffer->memory_->GetAddr()),
347 frameBuffer->memory_->GetSize());
348 }
349 return SaveDataToFile(fileName,
350 reinterpret_cast<const char *>(surfaceBuffer->GetVirAddr()),
351 surfaceBuffer->GetSize());
352 }
353
pixelFormatToString(PixelFormat pixelFormat)354 std::string AVMetadataHelperImpl::pixelFormatToString(PixelFormat pixelFormat)
355 {
356 switch (pixelFormat) {
357 case PixelFormat::RGB_565:
358 return "RGB_565";
359 case PixelFormat::RGBA_8888:
360 return "RGBA_8888";
361 case PixelFormat::RGB_888:
362 return "RGB_888";
363 case PixelFormat::NV12:
364 return "NV12";
365 case PixelFormat::YCBCR_P010:
366 return "YCBCR_P010";
367 default:
368 return "UNKNOWN";
369 }
370 }
371
CreatePixelMapYuv(const std::shared_ptr<AVBuffer> & frameBuffer,PixelMapInfo & pixelMapInfo)372 std::shared_ptr<PixelMap> AVMetadataHelperImpl::CreatePixelMapYuv(const std::shared_ptr<AVBuffer> &frameBuffer,
373 PixelMapInfo &pixelMapInfo)
374 {
375 bool isValid = frameBuffer != nullptr && frameBuffer->meta_ != nullptr && frameBuffer->memory_ != nullptr;
376 CHECK_AND_RETURN_RET_LOG(isValid, nullptr, "invalid frame buffer");
377 auto bufferMeta = frameBuffer->meta_;
378
379 int32_t width = 0;
380 auto hasProperty = bufferMeta->Get<Tag::VIDEO_WIDTH>(width);
381 CHECK_AND_RETURN_RET_LOG(hasProperty, nullptr, "invalid width");
382 int32_t height = 0;
383 hasProperty = bufferMeta->Get<Tag::VIDEO_HEIGHT>(height);
384 CHECK_AND_RETURN_RET_LOG(hasProperty, nullptr, "invalid height");
385
386 Plugins::VideoRotation rotation = Plugins::VideoRotation::VIDEO_ROTATION_0;
387 bufferMeta->Get<Tag::VIDEO_ROTATION>(rotation);
388 pixelMapInfo.rotation = static_cast<int32_t>(rotation);
389
390 Plugins::VideoOrientationType orientation = Plugins::VideoOrientationType::ROTATE_NONE;
391 bufferMeta->Get<Tag::VIDEO_ORIENTATION_TYPE>(orientation);
392 pixelMapInfo.orientation = static_cast<int32_t>(orientation);
393
394 bufferMeta->Get<Tag::VIDEO_IS_HDR_VIVID>(pixelMapInfo.isHdr);
395
396 if (pixelMapInfo.pixelFormat == PixelFormat::UNKNOWN) {
397 pixelMapInfo.pixelFormat = pixelMapInfo.isHdr ? PixelFormat::YCBCR_P010 : PixelFormat::NV12;
398 }
399
400 if (frameBuffer->memory_->GetSize() != 0 && frameBuffer->memory_->GetSurfaceBuffer() == nullptr) {
401 InitializationOptions options = { .size = { .width = width, .height = height },
402 .pixelFormat = PixelFormat::NV12 };
403 return CreatePixelMapFromAVShareMemory(frameBuffer, pixelMapInfo, options);
404 }
405
406 auto surfaceBuffer = frameBuffer->memory_->GetSurfaceBuffer();
407 CHECK_AND_RETURN_RET_LOG(surfaceBuffer != nullptr, nullptr, "srcSurfaceBuffer is nullptr");
408
409 pixelMapInfo.width = width;
410 pixelMapInfo.height = height;
411 int32_t outputHeight = height;
412 bufferMeta->Get<Tag::VIDEO_SLICE_HEIGHT>(outputHeight);
413 pixelMapInfo.outputHeight = outputHeight;
414 MEDIA_LOGD("pixelMapInfo.outputHeight = %{public}d", pixelMapInfo.outputHeight);
415
416 return CreatePixelMapFromSurfaceBuffer(surfaceBuffer, pixelMapInfo);
417 }
418
CreatePixelMapFromAVShareMemory(const std::shared_ptr<AVBuffer> & frameBuffer,PixelMapInfo & pixelMapInfo,InitializationOptions & options)419 std::shared_ptr<PixelMap> AVMetadataHelperImpl::CreatePixelMapFromAVShareMemory(const std::shared_ptr<AVBuffer>
420 &frameBuffer,
421 PixelMapInfo &pixelMapInfo,
422 InitializationOptions &options)
423 {
424 bool isValid = frameBuffer != nullptr && frameBuffer->memory_ != nullptr;
425 CHECK_AND_RETURN_RET_LOG(isValid, nullptr, "invalid frame buffer");
426 std::shared_ptr<PixelMap> pixelMap = PixelMap::Create(options);
427 CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, nullptr, "Create pixelMap failed");
428 AVBufferHolder *holder = CreateAVBufferHolder(frameBuffer);
429 CHECK_AND_RETURN_RET_LOG(holder != nullptr, nullptr, "Create buffer holder failed");
430 uint8_t *pixelAddr = frameBuffer->memory_->GetAddr();
431 pixelMap->SetPixelsAddr(pixelAddr, holder, pixelMap->GetByteCount(),
432 AllocatorType::CUSTOM_ALLOC, FreeAvBufferData);
433 const InitializationOptions opts = { .size = { .width = pixelMap->GetWidth(),
434 .height = pixelMap->GetHeight() },
435 .srcPixelFormat = PixelFormat::NV12,
436 .pixelFormat = pixelMapInfo.pixelFormat };
437 pixelMap = PixelMap::Create(reinterpret_cast<const uint32_t *>(pixelMap->GetPixels()),
438 pixelMap->GetByteCount(), opts);
439 sptr<SurfaceBuffer> surfaceBuffer = nullptr;
440 SetPixelMapYuvInfo(surfaceBuffer, pixelMap, pixelMapInfo, false);
441 return pixelMap;
442 }
443
FormatColorSpaceInfo(CM_ColorSpaceInfo & colorSpaceInfo)444 void AVMetadataHelperImpl::FormatColorSpaceInfo(CM_ColorSpaceInfo &colorSpaceInfo)
445 {
446 switch (colorSpaceInfo.primaries) {
447 case CM_ColorPrimaries::COLORPRIMARIES_P3_D65:
448 if (colorSpaceInfo.matrix == CM_Matrix::MATRIX_BT601_P) {
449 colorSpaceInfo.matrix = CM_Matrix::MATRIX_P3; // MATRIX_P3 equals MATRIX_BT601_P and MATRIX_BT601_N
450 }
451 break;
452 case CM_ColorPrimaries::COLORPRIMARIES_BT601_P:
453 if (colorSpaceInfo.matrix == CM_Matrix::MATRIX_BT601_N || colorSpaceInfo.matrix == CM_Matrix::MATRIX_P3) {
454 colorSpaceInfo.matrix = CM_Matrix::MATRIX_BT601_P; // MATRIX_P3 equals MATRIX_BT601_P and MATRIX_BT601_N
455 }
456 break;
457 default:
458 break;
459 }
460 }
461
GetColorSpace(sptr<SurfaceBuffer> & surfaceBuffer,PixelMapInfo & pixelMapInfo)462 Status AVMetadataHelperImpl::GetColorSpace(sptr<SurfaceBuffer> &surfaceBuffer, PixelMapInfo &pixelMapInfo)
463 {
464 std::vector<uint8_t> colorSpaceInfoVec;
465 if (surfaceBuffer->GetMetadata(ATTRKEY_COLORSPACE_INFO, colorSpaceInfoVec) != GSERROR_OK) {
466 MEDIA_LOGW("cant find colorSpace");
467 return Status::ERROR_UNKNOWN;
468 }
469 CHECK_AND_RETURN_RET_LOG(!colorSpaceInfoVec.empty(), Status::ERROR_UNKNOWN, "colorSpaceInfoVec is empty");
470 auto outColor = reinterpret_cast<CM_ColorSpaceInfo *>(colorSpaceInfoVec.data());
471 CHECK_AND_RETURN_RET_LOG(outColor != nullptr, Status::ERROR_UNKNOWN, "colorSpaceInfoVec init failed");
472 auto colorSpaceInfo = outColor[0];
473 FormatColorSpaceInfo(colorSpaceInfo);
474 pixelMapInfo.srcRange = colorSpaceInfo.range == CM_Range::RANGE_FULL ? 1 : 0;
475 auto type = ((static_cast<unsigned int>(colorSpaceInfo.primaries) << COLORPRIMARIES_OFFSET) +
476 (static_cast<unsigned int>(colorSpaceInfo.transfunc) << TRANSFUNC_OFFSET) +
477 (static_cast<unsigned int>(colorSpaceInfo.matrix) << MATRIX_OFFSET) +
478 (static_cast<unsigned int>(colorSpaceInfo.range) << RANGE_OFFSET));
479 pixelMapInfo.primaries = colorSpaceInfo.primaries;
480 MEDIA_LOGI("colorSpaceType is %{public}u", type);
481 if (pixelMapInfo.isHdr) {
482 auto it = HDR_COLORSPACE_MAP.find(type);
483 CHECK_AND_RETURN_RET_LOG(it != HDR_COLORSPACE_MAP.end(), Status::ERROR_UNKNOWN,
484 "can't find mapped colorSpace name in hdr map");
485 pixelMapInfo.colorSpaceName = it->second;
486 return Status::OK;
487 }
488 auto it = SDR_COLORSPACE_MAP.find(type);
489 CHECK_AND_RETURN_RET_LOG(it != SDR_COLORSPACE_MAP.end(), Status::ERROR_UNKNOWN,
490 "can't find mapped colorSpace name in sdr map");
491 pixelMapInfo.colorSpaceName = it->second;
492 return Status::OK;
493 }
494
CreatePixelMapFromSurfaceBuffer(sptr<SurfaceBuffer> & surfaceBuffer,PixelMapInfo & pixelMapInfo)495 std::shared_ptr<PixelMap> AVMetadataHelperImpl::CreatePixelMapFromSurfaceBuffer(sptr<SurfaceBuffer> &surfaceBuffer,
496 PixelMapInfo &pixelMapInfo)
497 {
498 CHECK_AND_RETURN_RET_LOG(surfaceBuffer != nullptr, nullptr, "surfaceBuffer is nullptr");
499 auto getColorSpaceInfoRes = GetColorSpace(surfaceBuffer, pixelMapInfo);
500 InitializationOptions options = { .size = { .width = pixelMapInfo.width,
501 .height = pixelMapInfo.height } };
502 bool isHdr = pixelMapInfo.isHdr;
503 options.srcPixelFormat = isHdr ? PixelFormat::YCBCR_P010 : PixelFormat::NV12;
504 options.pixelFormat = isHdr ? PixelFormat::YCBCR_P010 : PixelFormat::NV12;
505 options.useDMA = isHdr;
506 bool needModifyStride = false;
507 options.convertColorSpace.srcRange = pixelMapInfo.srcRange;
508 int32_t colorLength = pixelMapInfo.width * pixelMapInfo.height * PIXEL_SIZE_HDR_YUV;
509 colorLength = isHdr ? colorLength : colorLength / HDR_PIXEL_SIZE;
510 std::shared_ptr<PixelMap> pixelMap;
511
512 if (!options.useDMA) {
513 pixelMap = PixelMap::Create(options);
514 CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, nullptr, "Create pixelMap failed");
515 auto ret = CopySurfaceBufferToPixelMap(surfaceBuffer, pixelMap, pixelMapInfo);
516 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, nullptr, "CopySurfaceBufferToPixelMap failed");
517 options.pixelFormat = pixelMapInfo.pixelFormat;
518 int32_t primaries = pixelMapInfo.primaries;
519 options.convertColorSpace.srcYuvConversion = primaries == CM_ColorPrimaries::COLORPRIMARIES_BT709 ?
520 YuvConversion::BT709 : YuvConversion::BT601;
521 options.convertColorSpace.dstYuvConversion = primaries == CM_ColorPrimaries::COLORPRIMARIES_BT709 ?
522 YuvConversion::BT709 : YuvConversion::BT601;
523 MEDIA_LOGD("conversion: %{public}d", options.convertColorSpace.srcYuvConversion);
524 pixelMap = PixelMap::Create(reinterpret_cast<const uint32_t *>(pixelMap->GetPixels()),
525 pixelMap->GetByteCount(), options);
526 CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, nullptr, "Create non-DMA pixelMap failed");
527 pixelMap->InnerSetColorSpace(OHOS::ColorManager::ColorSpace(
528 getColorSpaceInfoRes == Status::OK ? pixelMapInfo.colorSpaceName : ColorManager::SRGB));
529 } else {
530 pixelMap = PixelMap::Create(reinterpret_cast<const uint32_t *>(surfaceBuffer->GetVirAddr()),
531 static_cast<uint32_t>(colorLength), options);
532 CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, nullptr, "Create DMA pixelMap failed");
533 void* nativeBuffer = surfaceBuffer.GetRefPtr();
534 RefBase *ref = reinterpret_cast<RefBase *>(nativeBuffer);
535 ref->IncStrongRef(ref);
536 if (isHdr) {
537 pixelMap->SetHdrType(ImageHdrType::HDR_VIVID_SINGLE);
538 pixelMap->InnerSetColorSpace(OHOS::ColorManager::ColorSpace(
539 getColorSpaceInfoRes == Status::OK ? pixelMapInfo.colorSpaceName : ColorManager::BT2020_HLG));
540 }
541 pixelMap->SetPixelsAddr(surfaceBuffer->GetVirAddr(), surfaceBuffer.GetRefPtr(), surfaceBuffer->GetSize(),
542 AllocatorType::DMA_ALLOC, FreeSurfaceBuffer);
543 needModifyStride = true;
544 }
545
546 SetPixelMapYuvInfo(surfaceBuffer, pixelMap, pixelMapInfo, needModifyStride);
547
548 return pixelMap;
549 }
550
CopySurfaceBufferToPixelMap(sptr<SurfaceBuffer> & surfaceBuffer,std::shared_ptr<PixelMap> pixelMap,PixelMapInfo & pixelMapInfo)551 int32_t AVMetadataHelperImpl::CopySurfaceBufferToPixelMap(sptr<SurfaceBuffer> &surfaceBuffer,
552 std::shared_ptr<PixelMap> pixelMap,
553 PixelMapInfo &pixelMapInfo)
554 {
555 CHECK_AND_RETURN_RET(surfaceBuffer != nullptr && pixelMap != nullptr, MSERR_INVALID_VAL);
556 int32_t width = surfaceBuffer->GetWidth();
557 int32_t height = surfaceBuffer->GetHeight();
558 int32_t stride = surfaceBuffer->GetStride();
559
560 CHECK_AND_RETURN_RET(width > 0 && height > 0 && stride > 0, MSERR_INVALID_VAL);
561
562 static int32_t uvDivBase = 2;
563 CHECK_AND_RETURN_RET(INT64_MAX - (static_cast<int64_t>(stride) * pixelMapInfo.outputHeight)
564 >= static_cast<int64_t>(stride) * height / uvDivBase, MSERR_INVALID_VAL);
565 int64_t copySrcSize = std::max(static_cast<int64_t>(stride) * height,
566 static_cast<int64_t>(stride) * pixelMapInfo.outputHeight + static_cast<int64_t>(stride) * height / uvDivBase);
567 CHECK_AND_RETURN_RET(static_cast<int64_t>(surfaceBuffer->GetSize()) >= copySrcSize, MSERR_INVALID_VAL);
568
569 CHECK_AND_RETURN_RET(INT64_MAX - (static_cast<int64_t>(width) * height) >=
570 static_cast<int64_t>(width) * height / uvDivBase, MSERR_INVALID_VAL);
571 int64_t copyDstSize = static_cast<int64_t>(width) * height + static_cast<int64_t>(width) * height / uvDivBase;
572 CHECK_AND_RETURN_RET(static_cast<int64_t>(pixelMap->GetCapacity()) >= copyDstSize, MSERR_INVALID_VAL);
573
574 uint8_t *srcPtr = static_cast<uint8_t *>(surfaceBuffer->GetVirAddr());
575 uint8_t *dstPtr = const_cast<uint8_t *>(pixelMap->GetPixels());
576 // copy src Y component to dst
577 int32_t lineByteCount = width;
578 for (int32_t y = 0; y < height; y++) {
579 auto ret = memcpy_s(dstPtr, lineByteCount, srcPtr, lineByteCount);
580 TRUE_LOG(ret != EOK, MEDIA_LOGW, "Memcpy Y component failed.");
581 srcPtr += stride;
582 dstPtr += lineByteCount;
583 }
584
585 srcPtr = static_cast<uint8_t *>(surfaceBuffer->GetVirAddr()) + stride * pixelMapInfo.outputHeight;
586
587 // copy src UV component to dst, height(UV) = height(Y) / 2
588 for (int32_t uv = 0; uv < height / 2; uv++) {
589 auto ret = memcpy_s(dstPtr, lineByteCount, srcPtr, lineByteCount);
590 TRUE_LOG(ret != EOK, MEDIA_LOGW, "Memcpy UV component failed.");
591 srcPtr += stride;
592 dstPtr += lineByteCount;
593 }
594 return MSERR_OK;
595 }
596
SetPixelMapYuvInfo(sptr<SurfaceBuffer> & surfaceBuffer,std::shared_ptr<PixelMap> pixelMap,PixelMapInfo & pixelMapInfo,bool needModifyStride)597 void AVMetadataHelperImpl::SetPixelMapYuvInfo(sptr<SurfaceBuffer> &surfaceBuffer, std::shared_ptr<PixelMap> pixelMap,
598 PixelMapInfo &pixelMapInfo, bool needModifyStride)
599 {
600 CHECK_AND_RETURN_LOG(pixelMap != nullptr, "invalid pixelMap");
601 uint8_t ratio = pixelMapInfo.isHdr ? HDR_PIXEL_SIZE : SDR_PIXEL_SIZE;
602 int32_t srcWidth = pixelMap->GetWidth();
603 int32_t srcHeight = pixelMap->GetHeight();
604 YUVDataInfo yuvDataInfo = { .yWidth = srcWidth,
605 .yHeight = srcHeight,
606 .uvWidth = srcWidth / 2,
607 .uvHeight = srcHeight / 2,
608 .yStride = srcWidth,
609 .uvStride = srcWidth,
610 .uvOffset = srcWidth * srcHeight};
611
612 if (surfaceBuffer == nullptr || !needModifyStride) {
613 pixelMap->SetImageYUVInfo(yuvDataInfo);
614 return;
615 }
616 OH_NativeBuffer_Planes *planes = nullptr;
617 GSError retVal = surfaceBuffer->GetPlanesInfo(reinterpret_cast<void**>(&planes));
618 if (retVal != OHOS::GSERROR_OK || planes == nullptr) {
619 pixelMap->SetImageYUVInfo(yuvDataInfo);
620 return;
621 }
622
623 yuvDataInfo.yStride = planes->planes[PLANE_Y].columnStride / ratio;
624 yuvDataInfo.uvStride = planes->planes[PLANE_U].columnStride / ratio;
625 yuvDataInfo.yOffset = planes->planes[PLANE_Y].offset / ratio;
626 yuvDataInfo.uvOffset = planes->planes[PLANE_U].offset / ratio;
627
628 pixelMap->SetImageYUVInfo(yuvDataInfo);
629 }
630
CreateAVMetadataHelper()631 std::shared_ptr<AVMetadataHelper> AVMetadataHelperFactory::CreateAVMetadataHelper()
632 {
633 std::shared_ptr<AVMetadataHelperImpl> impl = std::make_shared<AVMetadataHelperImpl>();
634 CHECK_AND_RETURN_RET_LOG(impl != nullptr, nullptr, "failed to new AVMetadataHelperImpl");
635
636 int32_t ret = impl->Init();
637 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, nullptr, "failed to init AVMetadataHelperImpl");
638
639 return impl;
640 }
641
Init()642 int32_t AVMetadataHelperImpl::Init()
643 {
644 avMetadataHelperService_ = MediaServiceFactory::GetInstance().CreateAVMetadataHelperService();
645 CHECK_AND_RETURN_RET_LOG(avMetadataHelperService_ != nullptr, MSERR_NO_MEMORY,
646 "failed to create avmetadatahelper service");
647 InitDumpFlag();
648 return MSERR_OK;
649 }
650
AVMetadataHelperImpl()651 AVMetadataHelperImpl::AVMetadataHelperImpl()
652 {
653 MEDIA_LOGD("AVMetadataHelperImpl:0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
654 }
655
~AVMetadataHelperImpl()656 AVMetadataHelperImpl::~AVMetadataHelperImpl()
657 {
658 if (avMetadataHelperService_ != nullptr) {
659 (void)MediaServiceFactory::GetInstance().DestroyAVMetadataHelperService(avMetadataHelperService_);
660 avMetadataHelperService_ = nullptr;
661 }
662 MEDIA_LOGD("AVMetadataHelperImpl:0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
663 }
664
SetHelperCallback(const std::shared_ptr<HelperCallback> & callback)665 int32_t AVMetadataHelperImpl::SetHelperCallback(const std::shared_ptr<HelperCallback> &callback)
666 {
667 MEDIA_LOGD("AVMetadataHelperImpl:0x%{public}06" PRIXPTR " SetHelperCallback in", FAKE_POINTER(this));
668 CHECK_AND_RETURN_RET_LOG(avMetadataHelperService_ != nullptr, MSERR_SERVICE_DIED,
669 "metadata helper service does not exist..");
670 CHECK_AND_RETURN_RET_LOG(callback != nullptr, MSERR_INVALID_VAL, "callback is nullptr");
671 return avMetadataHelperService_->SetHelperCallback(callback);
672 }
673
SetScene(Scene scene)674 void AVMetadataHelperImpl::SetScene(Scene scene)
675 {
676 ReportSceneCode(scene);
677 }
678
ReportSceneCode(Scene scene)679 void AVMetadataHelperImpl::ReportSceneCode(Scene scene)
680 {
681 if (scene != Scene::AV_META_SCENE_CLONE && scene != Scene::AV_META_SCENE_BATCH_HANDLE) {
682 return;
683 }
684 if (scene == Scene::AV_META_SCENE_BATCH_HANDLE && concurrentWorkCount_ < HIGH_CONCRENT_WORK_NUM) {
685 return;
686 }
687 auto sceneCode = SCENE_CODE_MAP[scene];
688 auto lastTsp = SCENE_TIMESTAMP_MAP[scene];
689 auto now =
690 std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
691 auto duration = now - std::chrono::milliseconds(lastTsp);
692 if (duration < std::chrono::milliseconds(SCENE_CODE_EFFECTIVE_DURATION_MS)) {
693 return;
694 }
695 SCENE_TIMESTAMP_MAP[scene] = now.count();
696 MEDIA_LOGI("Report scene code %{public}ld", sceneCode);
697 int32_t ret = HiSysEventWrite(
698 PERFORMANCE_STATS, "CPU_SCENE_ENTRY", OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR, "PACKAGE_NAME",
699 "media_service", "SCENE_ID", std::to_string(sceneCode).c_str(), "HAPPEN_TIME", now.count());
700 if (ret != MSERR_OK) {
701 MEDIA_LOGW("report error");
702 }
703 }
704
SetSource(const std::string & uri,int32_t usage)705 int32_t AVMetadataHelperImpl::SetSource(const std::string &uri, int32_t usage)
706 {
707 CHECK_AND_RETURN_RET_LOG(avMetadataHelperService_ != nullptr, MSERR_NO_MEMORY,
708 "avmetadatahelper service does not exist..");
709 CHECK_AND_RETURN_RET_LOG(!uri.empty(), MSERR_INVALID_VAL, "uri is empty.");
710
711 concurrentWorkCount_++;
712 ReportSceneCode(AV_META_SCENE_BATCH_HANDLE);
713 auto res = avMetadataHelperService_->SetSource(uri, usage);
714 concurrentWorkCount_--;
715 return res;
716 }
717
SetAVMetadataCaller(AVMetadataCaller caller)718 int32_t AVMetadataHelperImpl::SetAVMetadataCaller(AVMetadataCaller caller)
719 {
720 CHECK_AND_RETURN_RET_LOG(avMetadataHelperService_ != nullptr, MSERR_NO_MEMORY,
721 "avmetadatahelper service does not exist..");
722 return avMetadataHelperService_->SetAVMetadataCaller(caller);
723 }
724
SetUrlSource(const std::string & uri,const std::map<std::string,std::string> & header)725 int32_t AVMetadataHelperImpl::SetUrlSource(const std::string &uri, const std::map<std::string, std::string> &header)
726 {
727 CHECK_AND_RETURN_RET_LOG(avMetadataHelperService_ != nullptr, MSERR_NO_MEMORY,
728 "avmetadatahelper service does not exist..");
729 CHECK_AND_RETURN_RET_LOG(!uri.empty(), MSERR_INVALID_VAL, "uri is empty.");
730 CHECK_AND_RETURN_RET_LOG((uri.find("http://") == 0 || uri.find("https://") == 0),
731 MSERR_INVALID_VAL, "uri is error.");
732 concurrentWorkCount_++;
733 ReportSceneCode(AV_META_SCENE_BATCH_HANDLE);
734 auto res = avMetadataHelperService_->SetUrlSource(uri, header);
735 concurrentWorkCount_--;
736 return res;
737 }
738
SetSource(int32_t fd,int64_t offset,int64_t size,int32_t usage)739 int32_t AVMetadataHelperImpl::SetSource(int32_t fd, int64_t offset, int64_t size, int32_t usage)
740 {
741 CHECK_AND_RETURN_RET_LOG(avMetadataHelperService_ != nullptr, MSERR_NO_MEMORY,
742 "avmetadatahelper service does not exist..");
743 MEDIA_LOGI("Set file source fd: %{public}d, offset: %{public}" PRIu64 ", size: %{public}" PRIu64,
744 fd, offset, size);
745 CHECK_AND_RETURN_RET_LOG(fd > 0 && offset >= 0 && size >= -1, MSERR_INVALID_VAL,
746 "invalid param");
747
748 concurrentWorkCount_++;
749 ReportSceneCode(AV_META_SCENE_BATCH_HANDLE);
750 auto res = avMetadataHelperService_->SetSource(fd, offset, size, usage);
751 concurrentWorkCount_--;
752 return res;
753 }
754
SetSource(const std::shared_ptr<IMediaDataSource> & dataSrc)755 int32_t AVMetadataHelperImpl::SetSource(const std::shared_ptr<IMediaDataSource> &dataSrc)
756 {
757 MEDIA_LOGD("AVMetadataHelperImpl:0x%{public}06" PRIXPTR " SetSource in(dataSrc)", FAKE_POINTER(this));
758 CHECK_AND_RETURN_RET_LOG(dataSrc != nullptr, MSERR_INVALID_VAL, "failed to create data source");
759
760 concurrentWorkCount_++;
761 ReportSceneCode(AV_META_SCENE_BATCH_HANDLE);
762 auto res = avMetadataHelperService_->SetSource(dataSrc);
763 concurrentWorkCount_--;
764 return res;
765 }
766
ResolveMetadata(int32_t key)767 std::string AVMetadataHelperImpl::ResolveMetadata(int32_t key)
768 {
769 CHECK_AND_RETURN_RET_LOG(avMetadataHelperService_ != nullptr, "",
770 "avmetadatahelper service does not exist.");
771 concurrentWorkCount_++;
772 auto res = avMetadataHelperService_->ResolveMetadata(key);
773 concurrentWorkCount_--;
774 return res;
775 }
776
ResolveMetadata()777 std::unordered_map<int32_t, std::string> AVMetadataHelperImpl::ResolveMetadata()
778 {
779 CHECK_AND_RETURN_RET_LOG(avMetadataHelperService_ != nullptr, {},
780 "avmetadatahelper service does not exist.");
781 concurrentWorkCount_++;
782 auto res = avMetadataHelperService_->ResolveMetadata();
783 concurrentWorkCount_--;
784 return res;
785 }
786
GetAVMetadata()787 std::shared_ptr<Meta> AVMetadataHelperImpl::GetAVMetadata()
788 {
789 CHECK_AND_RETURN_RET_LOG(avMetadataHelperService_ != nullptr, nullptr,
790 "avmetadatahelper service does not exist.");
791 concurrentWorkCount_++;
792 auto res = avMetadataHelperService_->GetAVMetadata();
793 concurrentWorkCount_--;
794 return res;
795 }
796
FetchArtPicture()797 std::shared_ptr<AVSharedMemory> AVMetadataHelperImpl::FetchArtPicture()
798 {
799 CHECK_AND_RETURN_RET_LOG(avMetadataHelperService_ != nullptr, nullptr,
800 "avmetadatahelper service does not exist.");
801 concurrentWorkCount_++;
802 auto res = avMetadataHelperService_->FetchArtPicture();
803 concurrentWorkCount_--;
804 return res;
805 }
806
FetchFrameAtTime(int64_t timeUs,int32_t option,const PixelMapParams & param)807 std::shared_ptr<PixelMap> AVMetadataHelperImpl::FetchFrameAtTime(
808 int64_t timeUs, int32_t option, const PixelMapParams ¶m)
809 {
810 CHECK_AND_RETURN_RET_LOG(avMetadataHelperService_ != nullptr, nullptr,
811 "avmetadatahelper service does not exist.");
812
813 concurrentWorkCount_++;
814 ReportSceneCode(AV_META_SCENE_BATCH_HANDLE);
815
816 OutputConfiguration config;
817 config.colorFormat = param.colorFormat;
818 config.dstHeight = param.dstHeight;
819 config.dstWidth = param.dstWidth;
820
821 auto mem = avMetadataHelperService_->FetchFrameAtTime(timeUs, option, config);
822 auto pixelMap = CreatePixelMap(mem, PixelFormat::NV12, rotation_);
823
824 concurrentWorkCount_--;
825
826 CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, nullptr, "pixelMap does not exist.");
827
828 const InitializationOptions opts = { .size = { .width = pixelMap->GetWidth(), .height = pixelMap->GetHeight() },
829 .srcPixelFormat = PixelFormat::NV12 };
830 pixelMap =
831 PixelMap::Create(reinterpret_cast<const uint32_t *>(pixelMap->GetPixels()), pixelMap->GetByteCount(), opts);
832 if (pixelMap == nullptr) {
833 return nullptr;
834 }
835 if (rotation_ > 0) {
836 pixelMap->rotate(rotation_);
837 }
838 int32_t srcWidth = pixelMap->GetWidth();
839 int32_t srcHeight = pixelMap->GetHeight();
840 bool needScale = (param.dstWidth > 0 && param.dstHeight > 0) &&
841 (param.dstWidth <= srcWidth && param.dstHeight <= srcHeight) &&
842 (param.dstWidth < srcWidth || param.dstHeight < srcHeight) && srcWidth > 0 && srcHeight > 0;
843 if (needScale) {
844 pixelMap->scale((1.0f * param.dstWidth) / srcWidth, (1.0f * param.dstHeight) / srcHeight);
845 }
846 return pixelMap;
847 }
848
ScalePixelMapWithEqualRatio(std::shared_ptr<PixelMap> & pixelMap,PixelMapInfo & info,const PixelMapParams & param)849 void AVMetadataHelperImpl::ScalePixelMapWithEqualRatio(
850 std::shared_ptr<PixelMap> &pixelMap, PixelMapInfo &info, const PixelMapParams ¶m)
851 {
852 CHECK_AND_RETURN_LOG(pixelMap != nullptr, "pixelMap is nullptr");
853 int32_t srcWidth = pixelMap->GetWidth();
854 int32_t srcHeight = pixelMap->GetHeight();
855 int32_t dstWidth = info.rotation % NUM_180 == 0 ? param.dstWidth : param.dstHeight;
856 int32_t dstHeight = info.rotation % NUM_180 == 0 ? param.dstHeight : param.dstWidth;
857
858 bool needScale = (dstWidth > 0 || dstHeight > 0) && (srcWidth > 0 && srcHeight > 0) &&
859 (dstWidth <= srcWidth && dstHeight <= srcHeight) && (dstWidth < srcWidth || dstHeight < srcHeight);
860 CHECK_AND_RETURN(needScale);
861
862 float widthFactor = dstWidth > 0 ? (1.0f * dstWidth) / srcWidth : 1.0f;
863 float heightFactor = dstHeight > 0 ? (1.0f * dstHeight) / srcHeight : 1.0f;
864
865 if (dstWidth == 0) {
866 widthFactor = heightFactor;
867 } else if (dstHeight == 0) {
868 heightFactor = widthFactor;
869 }
870 pixelMap->scale(widthFactor, heightFactor, AntiAliasingOption::LOW);
871 MEDIA_LOGI("srcWidth: %{public}d, srcHeight : %{public}d, dstWidth: %{public}d, dstHeight: %{public}d,"
872 "widthFactor: %{public}f, HeightFactor: %{public}f, finalWidth: %{public}d, finalHeight : %{public}d",
873 srcWidth, srcHeight, dstWidth, dstHeight, widthFactor, heightFactor,
874 pixelMap->GetWidth(), pixelMap->GetHeight());
875 }
876
ScalePixelMap(std::shared_ptr<PixelMap> & pixelMap,PixelMapInfo & info,const PixelMapParams & param)877 void AVMetadataHelperImpl::ScalePixelMap(
878 std::shared_ptr<PixelMap> &pixelMap, PixelMapInfo &info, const PixelMapParams ¶m)
879 {
880 int32_t srcWidth = pixelMap->GetWidth();
881 int32_t srcHeight = pixelMap->GetHeight();
882 int32_t dstWidth = info.rotation % NUM_180 == 0 ? param.dstWidth : param.dstHeight;
883 int32_t dstHeight = info.rotation % NUM_180 == 0 ? param.dstHeight : param.dstWidth;
884 bool needScale = (dstWidth > 0 && dstHeight > 0) &&
885 (dstWidth <= srcWidth && dstHeight <= srcHeight) &&
886 (dstWidth < srcWidth || dstHeight < srcHeight) && srcWidth > 0 && srcHeight > 0;
887 CHECK_AND_RETURN(needScale);
888 pixelMap->scale((1.0f * dstWidth) / srcWidth, (1.0f * dstHeight) / srcHeight, AntiAliasingOption::LOW);
889 }
890
FetchFrameYuv(int64_t timeUs,int32_t option,const PixelMapParams & param)891 std::shared_ptr<PixelMap> AVMetadataHelperImpl::FetchFrameYuv(int64_t timeUs, int32_t option,
892 const PixelMapParams ¶m)
893 {
894 return FetchFrameBase(timeUs, option, param, FrameScaleMode::NORMAL_RATIO);
895 }
896
FetchScaledFrameYuv(int64_t timeUs,int32_t option,const PixelMapParams & param)897 std::shared_ptr<PixelMap> AVMetadataHelperImpl::FetchScaledFrameYuv(int64_t timeUs, int32_t option,
898 const PixelMapParams ¶m)
899 {
900 return FetchFrameBase(timeUs, option, param, FrameScaleMode::ASPECT_RATIO);
901 }
902
FetchFrameBase(int64_t timeUs,int32_t option,const PixelMapParams & param,int32_t scaleMode)903 std::shared_ptr<PixelMap> AVMetadataHelperImpl::FetchFrameBase(int64_t timeUs, int32_t option,
904 const PixelMapParams ¶m, int32_t scaleMode)
905 {
906 std::shared_ptr<IAVMetadataHelperService> avMetadataHelperService = avMetadataHelperService_;
907 CHECK_AND_RETURN_RET_LOG(avMetadataHelperService != nullptr, nullptr, "avmetadatahelper service does not exist.");
908
909 concurrentWorkCount_++;
910 ReportSceneCode(AV_META_SCENE_BATCH_HANDLE);
911 OutputConfiguration config = { .dstWidth = param.dstWidth,
912 .dstHeight = param.dstHeight,
913 .colorFormat = param.colorFormat };
914 auto frameBuffer = avMetadataHelperService->FetchFrameYuv(timeUs, option, config);
915 CHECK_AND_RETURN_RET(frameBuffer != nullptr && frameBuffer->memory_ != nullptr, nullptr);
916 concurrentWorkCount_--;
917
918 DumpAVBuffer(isDump_, frameBuffer, DUMP_FILE_NAME_AVBUFFER);
919
920 PixelMapInfo pixelMapInfo = { .pixelFormat = param.colorFormat };
921 auto pixelMap = CreatePixelMapYuv(frameBuffer, pixelMapInfo);
922 CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, nullptr, "convert to pixelMap failed");
923
924 DumpPixelMap(isDump_, pixelMap, DUMP_FILE_NAME_PIXEMAP);
925
926 ScalePixelMapByMode(pixelMap, pixelMapInfo, param, scaleMode);
927
928 DumpPixelMap(isDump_, pixelMap, DUMP_FILE_NAME_AFTER_SCLAE);
929
930 MEDIA_LOGI("Rotation is %{public}d, orientation is %{public}d", pixelMapInfo.rotation, pixelMapInfo.orientation);
931 if (param.isSupportFlip && VIDEOORIENTATIONTYPE_ROTATION_MAP.count(pixelMapInfo.orientation) > 0) {
932 MEDIA_LOGI("Support flip");
933 auto itFlip = VIDEOORIENTATIONTYPE_FLIP_MAP.find(pixelMapInfo.orientation);
934 CHECK_AND_RETURN_RET_LOG(itFlip != VIDEOORIENTATIONTYPE_FLIP_MAP.end(), nullptr,
935 "can't find mapped orientation name in VIDEOORIENTATIONTYPE_FLIP_MAP");
936 pixelMap->flip(itFlip->second.first, itFlip->second.second);
937 auto itRotate = VIDEOORIENTATIONTYPE_ROTATION_MAP.find(pixelMapInfo.orientation);
938 CHECK_AND_RETURN_RET_LOG(itRotate != VIDEOORIENTATIONTYPE_ROTATION_MAP.end(), nullptr,
939 "can't find mapped orientation name in VIDEOORIENTATIONTYPE_ROTATION_MAP");
940 pixelMap->rotate(itRotate->second);
941 } else if (pixelMapInfo.rotation > 0) {
942 MEDIA_LOGI("Not support flip");
943 pixelMap->rotate(pixelMapInfo.rotation);
944 }
945
946 MEDIA_LOGI("final colorSpace %{public}u", pixelMap->InnerGetGrColorSpace().GetColorSpaceName());
947
948 DumpPixelMap(isDump_, pixelMap, DUMP_FILE_NAME_AFTER_ROTATE);
949 return pixelMap;
950 }
951
ScalePixelMapByMode(std::shared_ptr<PixelMap> & pixelMap,PixelMapInfo & info,const PixelMapParams & param,int32_t scaleMode)952 void AVMetadataHelperImpl::ScalePixelMapByMode(std::shared_ptr<PixelMap> &pixelMap, PixelMapInfo &info,
953 const PixelMapParams ¶m, int32_t scaleMode)
954 {
955 CHECK_AND_RETURN_LOG(pixelMap != nullptr, "pixelMap is nullptr");
956 switch (scaleMode) {
957 case FrameScaleMode::NORMAL_RATIO:
958 ScalePixelMap(pixelMap, info, param);
959 break;
960 case FrameScaleMode::ASPECT_RATIO:
961 ScalePixelMapWithEqualRatio(pixelMap, info, param);
962 break;
963 default:
964 break;
965 }
966 }
967
GetTimeByFrameIndex(uint32_t index,uint64_t & time)968 int32_t AVMetadataHelperImpl::GetTimeByFrameIndex(uint32_t index, uint64_t &time)
969 {
970 CHECK_AND_RETURN_RET_LOG(avMetadataHelperService_ != nullptr, 0, "avmetadatahelper service does not exist.");
971 concurrentWorkCount_++;
972 auto res = avMetadataHelperService_->GetTimeByFrameIndex(index, time);
973 concurrentWorkCount_--;
974 return res;
975 }
976
GetFrameIndexByTime(uint64_t time,uint32_t & index)977 int32_t AVMetadataHelperImpl::GetFrameIndexByTime(uint64_t time, uint32_t &index)
978 {
979 CHECK_AND_RETURN_RET_LOG(avMetadataHelperService_ != nullptr, 0, "avmetadatahelper service does not exist.");
980 concurrentWorkCount_++;
981 auto res = avMetadataHelperService_->GetFrameIndexByTime(time, index);
982 concurrentWorkCount_--;
983 return res;
984 }
985
Release()986 void AVMetadataHelperImpl::Release()
987 {
988 std::lock_guard<std::mutex> lock(releaseMutex_);
989 MEDIA_LOGI("0x%{public}06" PRIXPTR " Release", FAKE_POINTER(this));
990 CHECK_AND_RETURN_LOG(avMetadataHelperService_ != nullptr, "avmetadatahelper service does not exist.");
991 avMetadataHelperService_->Release();
992 (void)MediaServiceFactory::GetInstance().DestroyAVMetadataHelperService(avMetadataHelperService_);
993 avMetadataHelperService_ = nullptr;
994 MEDIA_LOGI("0x%{public}06" PRIXPTR " Release out", FAKE_POINTER(this));
995 }
996 } // namespace Media
997 } // namespace OHOS
998