1fa7767c5Sopenharmony_ci/* 2fa7767c5Sopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd. 3fa7767c5Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4fa7767c5Sopenharmony_ci * you may not use this file except in compliance with the License. 5fa7767c5Sopenharmony_ci * You may obtain a copy of the License at 6fa7767c5Sopenharmony_ci * 7fa7767c5Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8fa7767c5Sopenharmony_ci * 9fa7767c5Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10fa7767c5Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11fa7767c5Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fa7767c5Sopenharmony_ci * See the License for the specific language governing permissions and 13fa7767c5Sopenharmony_ci * limitations under the License. 14fa7767c5Sopenharmony_ci */ 15fa7767c5Sopenharmony_ci 16fa7767c5Sopenharmony_ci#include "buffer/avbuffer.h" 17fa7767c5Sopenharmony_ci#include <atomic> 18fa7767c5Sopenharmony_ci#include <iomanip> 19fa7767c5Sopenharmony_ci#include <sstream> 20fa7767c5Sopenharmony_ci#include "avbuffer_utils.h" 21fa7767c5Sopenharmony_ci#include "common/log.h" 22fa7767c5Sopenharmony_ci#include "common/status.h" 23fa7767c5Sopenharmony_ci#include "surface_buffer.h" 24fa7767c5Sopenharmony_ci#include "surface_type.h" 25fa7767c5Sopenharmony_ci#include "unistd.h" 26fa7767c5Sopenharmony_ci 27fa7767c5Sopenharmony_cinamespace { 28fa7767c5Sopenharmony_ciconstexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_FOUNDATION, "AVBuffer" }; 29fa7767c5Sopenharmony_ci} 30fa7767c5Sopenharmony_ci 31fa7767c5Sopenharmony_cinamespace OHOS { 32fa7767c5Sopenharmony_cinamespace Media { 33fa7767c5Sopenharmony_ciAVBuffer::AVBuffer() : pts_(0), dts_(0), duration_(0), flag_(0), meta_(nullptr), memory_(nullptr) {} 34fa7767c5Sopenharmony_ci 35fa7767c5Sopenharmony_ciAVBuffer::~AVBuffer() {} 36fa7767c5Sopenharmony_ci 37fa7767c5Sopenharmony_cistd::shared_ptr<AVBuffer> AVBuffer::CreateAVBuffer(const AVBufferConfig &config) 38fa7767c5Sopenharmony_ci{ 39fa7767c5Sopenharmony_ci std::shared_ptr<AVAllocator> allocator = nullptr; 40fa7767c5Sopenharmony_ci int32_t capacity = std::max(config.size, config.capacity); 41fa7767c5Sopenharmony_ci MemoryFlag memflag = MemoryFlag::MEMORY_READ_WRITE; 42fa7767c5Sopenharmony_ci switch (config.memoryType) { 43fa7767c5Sopenharmony_ci case MemoryType::VIRTUAL_MEMORY: { 44fa7767c5Sopenharmony_ci allocator = AVAllocatorFactory::CreateVirtualAllocator(); 45fa7767c5Sopenharmony_ci break; 46fa7767c5Sopenharmony_ci } 47fa7767c5Sopenharmony_ci case MemoryType::SHARED_MEMORY: { 48fa7767c5Sopenharmony_ci memflag = config.memoryFlag; 49fa7767c5Sopenharmony_ci allocator = AVAllocatorFactory::CreateSharedAllocator(config.memoryFlag); 50fa7767c5Sopenharmony_ci break; 51fa7767c5Sopenharmony_ci } 52fa7767c5Sopenharmony_ci case MemoryType::SURFACE_MEMORY: { 53fa7767c5Sopenharmony_ci allocator = AVAllocatorFactory::CreateSurfaceAllocator(*(config.surfaceBufferConfig)); 54fa7767c5Sopenharmony_ci break; 55fa7767c5Sopenharmony_ci } 56fa7767c5Sopenharmony_ci case MemoryType::HARDWARE_MEMORY: { 57fa7767c5Sopenharmony_ci memflag = config.memoryFlag; 58fa7767c5Sopenharmony_ci allocator = AVAllocatorFactory::CreateHardwareAllocator(config.dmaFd, capacity, config.memoryFlag); 59fa7767c5Sopenharmony_ci break; 60fa7767c5Sopenharmony_ci } 61fa7767c5Sopenharmony_ci default: 62fa7767c5Sopenharmony_ci return nullptr; 63fa7767c5Sopenharmony_ci } 64fa7767c5Sopenharmony_ci auto buffer = CreateAVBuffer(allocator, capacity, config.align); 65fa7767c5Sopenharmony_ci if (buffer != nullptr) { 66fa7767c5Sopenharmony_ci buffer->config_ = config; 67fa7767c5Sopenharmony_ci buffer->config_.capacity = capacity; 68fa7767c5Sopenharmony_ci buffer->config_.memoryFlag = memflag; 69fa7767c5Sopenharmony_ci } 70fa7767c5Sopenharmony_ci return buffer; 71fa7767c5Sopenharmony_ci} 72fa7767c5Sopenharmony_ci 73fa7767c5Sopenharmony_ciconst AVBufferConfig &AVBuffer::GetConfig() 74fa7767c5Sopenharmony_ci{ 75fa7767c5Sopenharmony_ci FALSE_RETURN_V(memory_ != nullptr, config_); 76fa7767c5Sopenharmony_ci config_.size = memory_->GetSize(); 77fa7767c5Sopenharmony_ci if (config_.memoryType == MemoryType::UNKNOWN_MEMORY) { 78fa7767c5Sopenharmony_ci config_.memoryType = memory_->GetMemoryType(); 79fa7767c5Sopenharmony_ci config_.capacity = memory_->GetCapacity(); 80fa7767c5Sopenharmony_ci config_.align = memory_->align_; 81fa7767c5Sopenharmony_ci config_.memoryFlag = memory_->GetMemoryFlag(); 82fa7767c5Sopenharmony_ci switch (config_.memoryType) { 83fa7767c5Sopenharmony_ci case MemoryType::VIRTUAL_MEMORY: { 84fa7767c5Sopenharmony_ci break; 85fa7767c5Sopenharmony_ci } 86fa7767c5Sopenharmony_ci case MemoryType::SHARED_MEMORY: { 87fa7767c5Sopenharmony_ci break; 88fa7767c5Sopenharmony_ci } 89fa7767c5Sopenharmony_ci case MemoryType::HARDWARE_MEMORY: { 90fa7767c5Sopenharmony_ci config_.dmaFd = memory_->GetFileDescriptor(); 91fa7767c5Sopenharmony_ci break; 92fa7767c5Sopenharmony_ci } 93fa7767c5Sopenharmony_ci case MemoryType::SURFACE_MEMORY: { 94fa7767c5Sopenharmony_ci auto surfaceBuffer = memory_->GetSurfaceBuffer(); 95fa7767c5Sopenharmony_ci config_.surfaceBufferConfig->width = surfaceBuffer->GetWidth(); 96fa7767c5Sopenharmony_ci config_.surfaceBufferConfig->height = surfaceBuffer->GetHeight(); 97fa7767c5Sopenharmony_ci config_.surfaceBufferConfig->strideAlignment = surfaceBuffer->GetStride(); 98fa7767c5Sopenharmony_ci config_.surfaceBufferConfig->format = surfaceBuffer->GetFormat(); 99fa7767c5Sopenharmony_ci config_.surfaceBufferConfig->usage = surfaceBuffer->GetUsage(); 100fa7767c5Sopenharmony_ci config_.surfaceBufferConfig->colorGamut = surfaceBuffer->GetSurfaceBufferColorGamut(); 101fa7767c5Sopenharmony_ci config_.surfaceBufferConfig->transform = surfaceBuffer->GetSurfaceBufferTransform(); 102fa7767c5Sopenharmony_ci break; 103fa7767c5Sopenharmony_ci } 104fa7767c5Sopenharmony_ci default: 105fa7767c5Sopenharmony_ci break; 106fa7767c5Sopenharmony_ci } 107fa7767c5Sopenharmony_ci } 108fa7767c5Sopenharmony_ci return config_; 109fa7767c5Sopenharmony_ci} 110fa7767c5Sopenharmony_ci 111fa7767c5Sopenharmony_cistd::shared_ptr<AVBuffer> AVBuffer::CreateAVBuffer(std::shared_ptr<AVAllocator> allocator, int32_t capacity, 112fa7767c5Sopenharmony_ci int32_t align) 113fa7767c5Sopenharmony_ci{ 114fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(allocator != nullptr, nullptr, "allocator is nullptr"); 115fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(capacity >= 0, nullptr, "capacity is invalid"); 116fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(align >= 0, nullptr, "align is invalid"); 117fa7767c5Sopenharmony_ci 118fa7767c5Sopenharmony_ci auto buffer = std::shared_ptr<AVBuffer>(new AVBuffer()); 119fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(buffer != nullptr, nullptr, "Create AVBuffer failed, no memory"); 120fa7767c5Sopenharmony_ci 121fa7767c5Sopenharmony_ci Status ret = buffer->Init(allocator, capacity, align); 122fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(ret == Status::OK, nullptr, "Init AVBuffer failed"); 123fa7767c5Sopenharmony_ci 124fa7767c5Sopenharmony_ci buffer->meta_ = std::make_shared<Meta>(); 125fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(buffer->meta_ != nullptr, nullptr, "Create meta_ failed, no memory"); 126fa7767c5Sopenharmony_ci return buffer; 127fa7767c5Sopenharmony_ci} 128fa7767c5Sopenharmony_ci 129fa7767c5Sopenharmony_cistd::shared_ptr<AVBuffer> AVBuffer::CreateAVBuffer(uint8_t *ptr, int32_t capacity, int32_t size) 130fa7767c5Sopenharmony_ci{ 131fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(ptr != nullptr, nullptr, "ptr is nullptr"); 132fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(capacity >= 0, nullptr, "capacity is invalid"); 133fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E((0 <= size) && (size <= capacity), nullptr, "size is invalid"); 134fa7767c5Sopenharmony_ci 135fa7767c5Sopenharmony_ci auto buffer = std::shared_ptr<AVBuffer>(new AVBuffer()); 136fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(buffer != nullptr, nullptr, "Create AVBuffer failed, no memory"); 137fa7767c5Sopenharmony_ci 138fa7767c5Sopenharmony_ci buffer->meta_ = std::make_shared<Meta>(); 139fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(buffer->meta_ != nullptr, nullptr, "Create meta_ failed, no memory"); 140fa7767c5Sopenharmony_ci 141fa7767c5Sopenharmony_ci Status ret = buffer->Init(ptr, capacity, size); 142fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(ret == Status::OK, nullptr, "Init AVBuffer failed"); 143fa7767c5Sopenharmony_ci return buffer; 144fa7767c5Sopenharmony_ci} 145fa7767c5Sopenharmony_ci 146fa7767c5Sopenharmony_cistd::shared_ptr<AVBuffer> AVBuffer::CreateAVBuffer(sptr<SurfaceBuffer> surfaceBuffer) 147fa7767c5Sopenharmony_ci{ 148fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(surfaceBuffer != nullptr, nullptr, "surfaceBuffer is nullptr"); 149fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(surfaceBuffer->GetSptrRefCount() > 0, nullptr, "GetSptrRefCount is invalid, count:%{public}d", 150fa7767c5Sopenharmony_ci surfaceBuffer->GetSptrRefCount()); 151fa7767c5Sopenharmony_ci 152fa7767c5Sopenharmony_ci auto buffer = std::shared_ptr<AVBuffer>(new AVBuffer()); 153fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(buffer != nullptr, nullptr, "Create AVBuffer failed, no memory"); 154fa7767c5Sopenharmony_ci 155fa7767c5Sopenharmony_ci buffer->meta_ = std::make_shared<Meta>(); 156fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(buffer->meta_ != nullptr, nullptr, "Create meta_ failed, no memory"); 157fa7767c5Sopenharmony_ci 158fa7767c5Sopenharmony_ci Status ret = buffer->Init(surfaceBuffer); 159fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(ret == Status::OK, nullptr, "Init AVBuffer failed"); 160fa7767c5Sopenharmony_ci return buffer; 161fa7767c5Sopenharmony_ci} 162fa7767c5Sopenharmony_ci 163fa7767c5Sopenharmony_cistd::shared_ptr<AVBuffer> AVBuffer::CreateAVBuffer() 164fa7767c5Sopenharmony_ci{ 165fa7767c5Sopenharmony_ci auto buffer = std::shared_ptr<AVBuffer>(new AVBuffer()); 166fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(buffer != nullptr, nullptr, "Create AVBuffer failed, no memory"); 167fa7767c5Sopenharmony_ci 168fa7767c5Sopenharmony_ci buffer->meta_ = std::make_shared<Meta>(); 169fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(buffer->meta_ != nullptr, nullptr, "Create meta_ failed, no memory"); 170fa7767c5Sopenharmony_ci return buffer; 171fa7767c5Sopenharmony_ci} 172fa7767c5Sopenharmony_ci 173fa7767c5Sopenharmony_ciStatus AVBuffer::Init(std::shared_ptr<AVAllocator> allocator, int32_t capacity, int32_t align) 174fa7767c5Sopenharmony_ci{ 175fa7767c5Sopenharmony_ci memory_ = AVMemory::CreateAVMemory(allocator, capacity, align); 176fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(memory_ != nullptr, Status::ERROR_UNKNOWN, "Create memory failed"); 177fa7767c5Sopenharmony_ci return Status::OK; 178fa7767c5Sopenharmony_ci} 179fa7767c5Sopenharmony_ci 180fa7767c5Sopenharmony_ciStatus AVBuffer::Init(uint8_t *ptr, int32_t capacity, int32_t size) 181fa7767c5Sopenharmony_ci{ 182fa7767c5Sopenharmony_ci memory_ = AVMemory::CreateAVMemory(ptr, capacity, size); 183fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(memory_ != nullptr, Status::ERROR_UNKNOWN, "Create memory failed"); 184fa7767c5Sopenharmony_ci return Status::OK; 185fa7767c5Sopenharmony_ci} 186fa7767c5Sopenharmony_ci 187fa7767c5Sopenharmony_ciStatus AVBuffer::Init(sptr<SurfaceBuffer> surfaceBuffer) 188fa7767c5Sopenharmony_ci{ 189fa7767c5Sopenharmony_ci memory_ = AVMemory::CreateAVMemory(surfaceBuffer); 190fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(memory_ != nullptr, Status::ERROR_UNKNOWN, "Create memory failed"); 191fa7767c5Sopenharmony_ci return Status::OK; 192fa7767c5Sopenharmony_ci} 193fa7767c5Sopenharmony_ci 194fa7767c5Sopenharmony_ciuint64_t AVBuffer::GetUniqueId() 195fa7767c5Sopenharmony_ci{ 196fa7767c5Sopenharmony_ci if (memory_ == nullptr) { 197fa7767c5Sopenharmony_ci return 0; 198fa7767c5Sopenharmony_ci } 199fa7767c5Sopenharmony_ci return memory_->uid_; 200fa7767c5Sopenharmony_ci} 201fa7767c5Sopenharmony_ci 202fa7767c5Sopenharmony_cibool AVBuffer::WriteToMessageParcel(MessageParcel &parcel) 203fa7767c5Sopenharmony_ci{ 204fa7767c5Sopenharmony_ci#ifdef MEDIA_OHOS 205fa7767c5Sopenharmony_ci MessageParcel bufferParcel; 206fa7767c5Sopenharmony_ci bool ret = bufferParcel.WriteUint64(GetUniqueId()) && bufferParcel.WriteInt64(pts_) && 207fa7767c5Sopenharmony_ci bufferParcel.WriteInt64(dts_) && bufferParcel.WriteInt64(duration_) && bufferParcel.WriteUint32(flag_) && 208fa7767c5Sopenharmony_ci meta_->ToParcel(bufferParcel); 209fa7767c5Sopenharmony_ci 210fa7767c5Sopenharmony_ci if (memory_ != nullptr) { 211fa7767c5Sopenharmony_ci MemoryType type = memory_->GetMemoryType(); 212fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(type != MemoryType::VIRTUAL_MEMORY, false, "Virtual memory not support"); 213fa7767c5Sopenharmony_ci 214fa7767c5Sopenharmony_ci ret = ret && bufferParcel.WriteUint8(static_cast<uint8_t>(type)) && 215fa7767c5Sopenharmony_ci memory_->WriteCommonToMessageParcel(bufferParcel) && memory_->WriteToMessageParcel(bufferParcel); 216fa7767c5Sopenharmony_ci } 217fa7767c5Sopenharmony_ci if (ret) { 218fa7767c5Sopenharmony_ci parcel.Append(bufferParcel); 219fa7767c5Sopenharmony_ci } 220fa7767c5Sopenharmony_ci return ret; 221fa7767c5Sopenharmony_ci#else 222fa7767c5Sopenharmony_ci return false; 223fa7767c5Sopenharmony_ci#endif 224fa7767c5Sopenharmony_ci} 225fa7767c5Sopenharmony_ci 226fa7767c5Sopenharmony_cibool AVBuffer::ReadFromMessageParcel(MessageParcel &parcel, bool isSurfaceBuffer) 227fa7767c5Sopenharmony_ci{ 228fa7767c5Sopenharmony_ci#ifdef MEDIA_OHOS 229fa7767c5Sopenharmony_ci if (isSurfaceBuffer) { 230fa7767c5Sopenharmony_ci FALSE_RETURN_V(memory_ == nullptr, false); 231fa7767c5Sopenharmony_ci memory_ = AVMemory::CreateAVMemory(parcel, true); 232fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(memory_ != nullptr, false, "Create memory failed"); 233fa7767c5Sopenharmony_ci return true; 234fa7767c5Sopenharmony_ci } 235fa7767c5Sopenharmony_ci // 1. 不同buffer更新attr: memroy != nullptr,uid != fromParcel, 返回错误 236fa7767c5Sopenharmony_ci // 2. 相同buffer更新attr: memroy != nullptr,uid == fromParcel,不创建memory,更新attr + memory的attr 237fa7767c5Sopenharmony_ci // 3. 初始化buffer: memroy == nullptr,fromParcel != 0,创建memory 238fa7767c5Sopenharmony_ci // 4. 只传buffer的attr: memroy == nullptr,fromParcel == 0,更新attr 239fa7767c5Sopenharmony_ci uint64_t uid = 0; 240fa7767c5Sopenharmony_ci int64_t pts = 0; 241fa7767c5Sopenharmony_ci int64_t dts = 0; 242fa7767c5Sopenharmony_ci int64_t duration = 0; 243fa7767c5Sopenharmony_ci uint32_t flag = 0; 244fa7767c5Sopenharmony_ci Meta meta; 245fa7767c5Sopenharmony_ci bool ret = parcel.ReadUint64(uid) && parcel.ReadInt64(pts) && parcel.ReadInt64(dts) && 246fa7767c5Sopenharmony_ci parcel.ReadInt64(duration) && parcel.ReadUint32(flag) && meta.FromParcel(parcel); 247fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(ret, false, "Unmarshalling buffer info failed"); 248fa7767c5Sopenharmony_ci 249fa7767c5Sopenharmony_ci if (memory_ != nullptr) { 250fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(GetUniqueId() == uid, false, "Can't read message parcel from other AVBuffer object!"); 251fa7767c5Sopenharmony_ci (void)parcel.ReadUint8(); 252fa7767c5Sopenharmony_ci ret = memory_->SkipCommonFromMessageParcel(parcel) && memory_->ReadFromMessageParcel(parcel); 253fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(ret, false, "Update memory info failed"); 254fa7767c5Sopenharmony_ci } else if (uid != 0) { 255fa7767c5Sopenharmony_ci memory_ = AVMemory::CreateAVMemory(parcel, false); 256fa7767c5Sopenharmony_ci FALSE_RETURN_V_MSG_E(memory_ != nullptr, false, "Create memory failed"); 257fa7767c5Sopenharmony_ci memory_->uid_ = uid; 258fa7767c5Sopenharmony_ci } 259fa7767c5Sopenharmony_ci pts_ = pts; 260fa7767c5Sopenharmony_ci dts_ = dts; 261fa7767c5Sopenharmony_ci duration_ = duration; 262fa7767c5Sopenharmony_ci flag_ = flag; 263fa7767c5Sopenharmony_ci if (meta_ == nullptr) { 264fa7767c5Sopenharmony_ci meta_ = std::make_shared<Meta>(); 265fa7767c5Sopenharmony_ci } 266fa7767c5Sopenharmony_ci *meta_ = std::move(meta); 267fa7767c5Sopenharmony_ci#endif 268fa7767c5Sopenharmony_ci return true; 269fa7767c5Sopenharmony_ci} 270fa7767c5Sopenharmony_ci} // namespace Media 271fa7767c5Sopenharmony_ci} // namespace OHOS