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