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_buffer.h"
17 #include "share_memory.h"
18 #include "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)
130 {
131 }
132
GetMeta(Tag tag)133 ValueType BufferMeta::GetMeta(Tag tag)
134 {
135 if (tags) {
136 return (*tags)[tag];
137 }
138 return ValueType();
139 }
140
SetMeta(Tag tag,ValueType value)141 void BufferMeta::SetMeta(Tag tag, ValueType value)
142 {
143 if (!tags) {
144 tags = std::make_shared<TagMap>();
145 }
146 (*tags)[tag] = value;
147 }
148
GetType() const149 BufferMetaType BufferMeta::GetType() const
150 {
151 return type;
152 }
153
Buffer(BufferMetaType type)154 Buffer::Buffer(BufferMetaType type) : trackID(0), pts(0), dts(0), duration(0), flag (0), meta()
155 {
156 if (type == BufferMetaType::AUDIO) {
157 meta = std::shared_ptr<AudioBufferMeta>(new AudioBufferMeta());
158 } else if (type == BufferMetaType::VIDEO) {
159 meta = std::shared_ptr<VideoBufferMeta>(new VideoBufferMeta());
160 }
161 }
162
CreateDefaultBuffer(BufferMetaType type,size_t capacity,std::shared_ptr<Allocator> allocator,size_t align)163 std::shared_ptr<Buffer> Buffer::CreateDefaultBuffer(BufferMetaType type, size_t capacity,
164 std::shared_ptr<Allocator> allocator, size_t align)
165 {
166 auto buffer = std::make_shared<Buffer>(type);
167 std::shared_ptr<Memory> memory = std::shared_ptr<Memory>(new Memory(capacity, allocator, align));
168 buffer->data.push_back(memory);
169 return buffer;
170 }
171
WrapMemory(uint8_t * data,size_t capacity,size_t size)172 std::shared_ptr<Memory> Buffer::WrapMemory(uint8_t* data, size_t capacity, size_t size)
173 {
174 auto memory = std::shared_ptr<Memory>(new Memory(capacity, std::shared_ptr<uint8_t>(data, [](void* ptr) {})));
175 memory->size = size;
176 this->data.push_back(memory);
177 return memory;
178 }
179
WrapMemoryPtr(std::shared_ptr<uint8_t> data,size_t capacity,size_t size)180 std::shared_ptr<Memory> Buffer::WrapMemoryPtr(std::shared_ptr<uint8_t> data, size_t capacity, size_t size)
181 {
182 auto memory = std::shared_ptr<Memory>(new Memory(capacity, data));
183 memory->size = size;
184 this->data.push_back(memory);
185 return memory;
186 }
187
AllocMemory(std::shared_ptr<Allocator> allocator,size_t capacity,size_t align)188 std::shared_ptr<Memory> Buffer::AllocMemory(std::shared_ptr<Allocator> allocator, size_t capacity, size_t align)
189 {
190 auto type = (allocator != nullptr) ? allocator->GetMemoryType() : MemoryType::VIRTUAL_ADDR;
191 std::shared_ptr<Memory> memory = nullptr;
192 switch (type) {
193 case MemoryType::VIRTUAL_ADDR: {
194 memory = std::shared_ptr<Memory>(new Memory(capacity, allocator, align));
195 break;
196 }
197 #if !defined(OHOS_LITE) && defined(VIDEO_SUPPORT)
198 case MemoryType::SURFACE_BUFFER: {
199 memory = std::shared_ptr<Memory>(new SurfaceMemory(capacity, allocator, align));
200 break;
201 }
202 case MemoryType::SHARE_MEMORY:
203 memory = std::shared_ptr<Memory>(new ShareMemory(capacity, allocator, align));
204 break;
205 #endif
206 default:
207 break;
208 }
209 if (memory == nullptr) {
210 return nullptr;
211 }
212 data.push_back(memory);
213 return memory;
214 }
215
GetMemoryCount()216 uint32_t Buffer::GetMemoryCount()
217 {
218 return data.size();
219 }
220
GetMemory(uint32_t index)221 std::shared_ptr<Memory> Buffer::GetMemory(uint32_t index)
222 {
223 if (data.size() <= index) {
224 return nullptr;
225 }
226 return data[index];
227 }
228
GetBufferMeta()229 std::shared_ptr<BufferMeta> Buffer::GetBufferMeta()
230 {
231 return meta;
232 }
233
IsEmpty()234 bool Buffer::IsEmpty()
235 {
236 return data.empty();
237 }
238
Reset()239 void Buffer::Reset()
240 {
241 data[0]->Reset();
242 trackID = 0;
243 pts = 0;
244 dts = 0;
245 duration = 0;
246 flag = 0;
247 BufferMetaType type = meta->GetType();
248 meta.reset();
249 if (type == BufferMetaType::AUDIO) {
250 meta = std::shared_ptr<AudioBufferMeta>(new AudioBufferMeta());
251 } else if (type == BufferMetaType::VIDEO) {
252 meta = std::shared_ptr<VideoBufferMeta>(new VideoBufferMeta());
253 }
254 }
255 } // namespace Plugin
256 } // namespace Media
257 } // namespace OHOS
258