1/* 2 * Copyright (c) 2021-2021 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 "plugin/common/plugin_buffer.h" 17#include "plugin/common/share_memory.h" 18#include "plugin/common/surface_memory.h" 19 20namespace OHOS { 21namespace Media { 22namespace Plugin { 23Memory::Memory(size_t capacity, std::shared_ptr<uint8_t> bufData, size_t align, MemoryType type) 24 : memoryType(type), capacity(capacity), alignment(align), 25 offset(0), size(0), allocator(nullptr), addr(std::move(bufData)) 26{ 27} 28 29Memory::Memory(size_t capacity, std::shared_ptr<Allocator> allocator, size_t align, MemoryType type, bool allocMem) 30 : memoryType(type), capacity(capacity), alignment(align), offset(0), 31 size(0), allocator(std::move(allocator)), addr(nullptr) 32{ 33 if (!allocMem) { // SurfaceMemory alloc mem in subclass 34 return; 35 } 36 size_t allocSize = align ? (capacity + align - 1) : capacity; 37 if (this->allocator) { 38 addr = std::shared_ptr<uint8_t>(static_cast<uint8_t*>(this->allocator->Alloc(allocSize)), 39 [this](uint8_t* ptr) { this->allocator->Free(static_cast<void*>(ptr)); }); 40 } else { 41 addr = std::shared_ptr<uint8_t>(new uint8_t[allocSize], std::default_delete<uint8_t[]>()); 42 } 43 offset = static_cast<size_t>(AlignUp(reinterpret_cast<uintptr_t>(addr.get()), static_cast<uintptr_t>(align)) - 44 reinterpret_cast<uintptr_t>(addr.get())); 45} 46 47size_t Memory::GetCapacity() 48{ 49 return capacity; 50} 51 52void Memory::Reset() 53{ 54 this->size = 0; 55} 56 57size_t Memory::Write(const uint8_t* in, size_t writeSize, size_t position) 58{ 59 size_t start = 0; 60 if (position == INVALID_POSITION) { 61 start = size; 62 } else { 63 start = std::min(position, capacity); 64 } 65 size_t length = std::min(writeSize, capacity - start); 66 if (memcpy_s(GetRealAddr() + start, length, in, length) != EOK) { 67 return 0; 68 } 69 size = start + length; 70 return length; 71} 72 73size_t Memory::Read(uint8_t* out, size_t readSize, size_t position) 74{ 75 size_t start = 0; 76 size_t maxLength = size; 77 if (position != INVALID_POSITION) { 78 start = std::min(position, size); 79 maxLength = size - start; 80 } 81 size_t length = std::min(readSize, maxLength); 82 if (memcpy_s(out, length, GetRealAddr() + start, length) != EOK) { 83 return 0; 84 } 85 return length; 86} 87 88const uint8_t* Memory::GetReadOnlyData(size_t position) 89{ 90 if (position > capacity) { 91 return nullptr; 92 } 93 return GetRealAddr() + position; 94} 95 96uint8_t* Memory::GetWritableAddr(size_t estimatedWriteSize, size_t position) 97{ 98 if (position + estimatedWriteSize > capacity) { 99 return nullptr; 100 } 101 uint8_t* ptr = GetRealAddr() + position; 102 size = (estimatedWriteSize + position); 103 return ptr; 104} 105 106void Memory::UpdateDataSize(size_t realWriteSize, size_t position) 107{ 108 if (position + realWriteSize > capacity) { 109 return; 110 } 111 size = (realWriteSize + position); 112} 113 114size_t Memory::GetSize() 115{ 116 return size; 117} 118 119uint8_t* Memory::GetRealAddr() const 120{ 121 return addr.get() + offset; 122} 123 124MemoryType Memory::GetMemoryType() 125{ 126 return memoryType; 127} 128 129BufferMeta::BufferMeta(BufferMetaType type) : type_(type), tags_(std::make_shared<Meta>()) 130{ 131} 132 133ValueType BufferMeta::GetMeta(Tag tag) 134{ 135 if (tags_) { 136 return (*tags_)[tag]; 137 } 138 return {}; 139} 140 141void BufferMeta::SetMeta(Tag tag, ValueType value) 142{ 143 (*tags_)[tag] = value; 144} 145 146BufferMetaType BufferMeta::GetType() const 147{ 148 return type_; 149} 150 151bool BufferMeta::IsExist(Tag tag) 152{ 153 return tags_->Find(tag) != tags_->end(); 154} 155 156void BufferMeta::Update(const BufferMeta& bufferMeta) 157{ 158 type_ = bufferMeta.GetType(); 159 *tags_ = *bufferMeta.tags_; 160} 161 162std::shared_ptr<BufferMeta> AudioBufferMeta::Clone() 163{ 164 auto bufferMeta = std::shared_ptr<AudioBufferMeta>(new AudioBufferMeta()); 165 bufferMeta->samples = samples; 166 bufferMeta->sampleFormat = sampleFormat; 167 bufferMeta->sampleRate = sampleRate; 168 bufferMeta->channels = channels; 169 bufferMeta->bytesPreFrame = bytesPreFrame; 170 bufferMeta->channelLayout = channelLayout; 171 bufferMeta->offsets = offsets; 172 bufferMeta->Update(*this); 173 return bufferMeta; 174} 175 176std::shared_ptr<BufferMeta> VideoBufferMeta::Clone() 177{ 178 auto bufferMeta = std::shared_ptr<VideoBufferMeta>(new VideoBufferMeta()); 179 bufferMeta->videoPixelFormat = videoPixelFormat; 180 bufferMeta->id = id; 181 bufferMeta->width = width; 182 bufferMeta->height = height; 183 bufferMeta->planes = planes; 184 bufferMeta->stride = stride; 185 bufferMeta->offset = offset; 186 bufferMeta->Update(*this); 187 return bufferMeta; 188} 189 190Buffer::Buffer(BufferMetaType type) : trackID(0), pts(0), dts(0), duration(0), flag (0), meta() 191{ 192 if (type == BufferMetaType::AUDIO) { 193 meta = std::shared_ptr<AudioBufferMeta>(new AudioBufferMeta()); 194 } else if (type == BufferMetaType::VIDEO) { 195 meta = std::shared_ptr<VideoBufferMeta>(new VideoBufferMeta()); 196 } 197} 198 199std::shared_ptr<Buffer> Buffer::CreateDefaultBuffer(BufferMetaType type, size_t capacity, 200 std::shared_ptr<Allocator> allocator, size_t align) 201{ 202 auto buffer = std::make_shared<Buffer>(type); 203 std::shared_ptr<Memory> memory = std::shared_ptr<Memory>(new Memory(capacity, allocator, align)); 204 buffer->data.push_back(memory); 205 return buffer; 206} 207 208std::shared_ptr<Memory> Buffer::WrapMemory(uint8_t* data, size_t capacity, size_t size) 209{ 210 auto memory = std::shared_ptr<Memory>(new Memory(capacity, std::shared_ptr<uint8_t>(data, [](void* ptr) {}))); 211 memory->size = size; 212 this->data.push_back(memory); 213 return memory; 214} 215 216std::shared_ptr<Memory> Buffer::WrapMemoryPtr(std::shared_ptr<uint8_t> data, size_t capacity, size_t size) 217{ 218 auto memory = std::shared_ptr<Memory>(new Memory(capacity, data)); 219 memory->size = size; 220 this->data.push_back(memory); 221 return memory; 222} 223 224#if !defined(OHOS_LITE) && defined(VIDEO_SUPPORT) 225std::shared_ptr<Memory> Buffer::WrapSurfaceMemory(sptr<SurfaceBuffer> surfaceBuffer) 226{ 227 int32_t bufferSize; 228 auto ret = surfaceBuffer->GetExtraData()->ExtraGet("dataSize", bufferSize); 229 if (ret != OHOS::SurfaceError::SURFACE_ERROR_OK || bufferSize <= 0) { 230 return nullptr; 231 } 232 auto memory = std::shared_ptr<SurfaceMemory>(new SurfaceMemory(surfaceBuffer, bufferSize)); 233 this->data.push_back(memory); 234 return memory; 235} 236#endif 237 238std::shared_ptr<Memory> Buffer::AllocMemory(std::shared_ptr<Allocator> allocator, size_t capacity, size_t align) 239{ 240 auto type = (allocator != nullptr) ? allocator->GetMemoryType() : MemoryType::VIRTUAL_ADDR; 241 std::shared_ptr<Memory> memory = nullptr; 242 switch (type) { 243 case MemoryType::VIRTUAL_ADDR: { 244 memory = std::shared_ptr<Memory>(new Memory(capacity, allocator, align)); 245 break; 246 } 247#if !defined(OHOS_LITE) && defined(VIDEO_SUPPORT) 248 case MemoryType::SURFACE_BUFFER: { 249 memory = std::shared_ptr<Memory>(new SurfaceMemory(capacity, allocator, align)); 250 break; 251 } 252 case MemoryType::SHARE_MEMORY: 253 memory = std::shared_ptr<Memory>(new ShareMemory(capacity, allocator, align)); 254 break; 255#endif 256 default: 257 break; 258 } 259 if (memory == nullptr) { 260 return nullptr; 261 } 262 data.push_back(memory); 263 return memory; 264} 265 266uint32_t Buffer::GetMemoryCount() 267{ 268 return data.size(); 269} 270 271std::shared_ptr<Memory> Buffer::GetMemory(uint32_t index) 272{ 273 if (data.size() <= index) { 274 return nullptr; 275 } 276 return data[index]; 277} 278 279std::shared_ptr<BufferMeta> Buffer::GetBufferMeta() 280{ 281 return meta; 282} 283 284void Buffer::UpdateBufferMeta(const BufferMeta& bufferMeta) 285{ 286 meta->Update(bufferMeta); 287} 288 289bool Buffer::IsEmpty() 290{ 291 return data.empty(); 292} 293 294void Buffer::Reset() 295{ 296 data[0]->Reset(); 297 trackID = 0; 298 pts = 0; 299 dts = 0; 300 duration = 0; 301 flag = 0; 302 BufferMetaType type = meta->GetType(); 303 meta.reset(); 304 if (type == BufferMetaType::AUDIO) { 305 meta = std::shared_ptr<AudioBufferMeta>(new AudioBufferMeta()); 306 } else if (type == BufferMetaType::VIDEO) { 307 meta = std::shared_ptr<VideoBufferMeta>(new VideoBufferMeta()); 308 } 309} 310 311void Buffer::ChangeBufferMetaType(BufferMetaType type) 312{ 313 meta.reset(); 314 if (type == BufferMetaType::AUDIO) { 315 meta = std::shared_ptr<AudioBufferMeta>(new AudioBufferMeta()); 316 } else if (type == BufferMetaType::VIDEO) { 317 meta = std::shared_ptr<VideoBufferMeta>(new VideoBufferMeta()); 318 } 319} 320 321} // namespace Plugin 322} // namespace Media 323} // namespace OHOS 324