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 
20 namespace OHOS {
21 namespace Media {
22 namespace Plugin {
Memory(size_t capacity,std::shared_ptr<uint8_t> bufData,size_t align,MemoryType type)23 Memory::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 
Memory(size_t capacity,std::shared_ptr<Allocator> allocator,size_t align,MemoryType type,bool allocMem)29 Memory::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 
GetCapacity()47 size_t Memory::GetCapacity()
48 {
49     return capacity;
50 }
51 
Reset()52 void Memory::Reset()
53 {
54     this->size = 0;
55 }
56 
Write(const uint8_t * in,size_t writeSize,size_t position)57 size_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 
Read(uint8_t * out,size_t readSize,size_t position)73 size_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 
GetReadOnlyData(size_t position)88 const uint8_t* Memory::GetReadOnlyData(size_t position)
89 {
90     if (position > capacity) {
91         return nullptr;
92     }
93     return GetRealAddr() + position;
94 }
95 
GetWritableAddr(size_t estimatedWriteSize,size_t position)96 uint8_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 
UpdateDataSize(size_t realWriteSize,size_t position)106 void Memory::UpdateDataSize(size_t realWriteSize, size_t position)
107 {
108     if (position + realWriteSize > capacity) {
109         return;
110     }
111     size = (realWriteSize + position);
112 }
113 
GetSize()114 size_t Memory::GetSize()
115 {
116     return size;
117 }
118 
GetRealAddr() const119 uint8_t* Memory::GetRealAddr() const
120 {
121     return addr.get() + offset;
122 }
123 
GetMemoryType()124 MemoryType Memory::GetMemoryType()
125 {
126     return memoryType;
127 }
128 
BufferMeta(BufferMetaType type)129 BufferMeta::BufferMeta(BufferMetaType type) : type_(type), tags_(std::make_shared<Meta>())
130 {
131 }
132 
GetMeta(Tag tag)133 ValueType BufferMeta::GetMeta(Tag tag)
134 {
135     if (tags_) {
136         return (*tags_)[tag];
137     }
138     return {};
139 }
140 
SetMeta(Tag tag,ValueType value)141 void BufferMeta::SetMeta(Tag tag, ValueType value)
142 {
143     (*tags_)[tag] = value;
144 }
145 
GetType() const146 BufferMetaType BufferMeta::GetType() const
147 {
148     return type_;
149 }
150 
IsExist(Tag tag)151 bool BufferMeta::IsExist(Tag tag)
152 {
153     return tags_->Find(tag) != tags_->end();
154 }
155 
Update(const BufferMeta & bufferMeta)156 void BufferMeta::Update(const BufferMeta& bufferMeta)
157 {
158     type_ = bufferMeta.GetType();
159     *tags_ = *bufferMeta.tags_;
160 }
161 
Clone()162 std::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 
Clone()176 std::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 
Buffer(BufferMetaType type)190 Buffer::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 
CreateDefaultBuffer(BufferMetaType type,size_t capacity,std::shared_ptr<Allocator> allocator,size_t align)199 std::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 
WrapMemory(uint8_t * data,size_t capacity,size_t size)208 std::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 
WrapMemoryPtr(std::shared_ptr<uint8_t> data,size_t capacity,size_t size)216 std::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)
WrapSurfaceMemory(sptr<SurfaceBuffer> surfaceBuffer)225 std::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 
AllocMemory(std::shared_ptr<Allocator> allocator,size_t capacity,size_t align)238 std::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 
GetMemoryCount()266 uint32_t Buffer::GetMemoryCount()
267 {
268     return data.size();
269 }
270 
GetMemory(uint32_t index)271 std::shared_ptr<Memory> Buffer::GetMemory(uint32_t index)
272 {
273     if (data.size() <= index) {
274         return nullptr;
275     }
276     return data[index];
277 }
278 
GetBufferMeta()279 std::shared_ptr<BufferMeta> Buffer::GetBufferMeta()
280 {
281     return meta;
282 }
283 
UpdateBufferMeta(const BufferMeta & bufferMeta)284 void Buffer::UpdateBufferMeta(const BufferMeta& bufferMeta)
285 {
286     meta->Update(bufferMeta);
287 }
288 
IsEmpty()289 bool Buffer::IsEmpty()
290 {
291     return data.empty();
292 }
293 
Reset()294 void 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 
ChangeBufferMetaType(BufferMetaType type)311 void 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