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/plugin_buffer.h"
17 #include "securec.h"
18 
19 namespace OHOS {
20 namespace Media {
21 namespace Plugins {
Memory(size_t capacity,std::shared_ptr<uint8_t> bufData,size_t align,MemoryType type)22 Memory::Memory(size_t capacity, std::shared_ptr<uint8_t> bufData, size_t align, MemoryType type)
23     : memoryType(type), capacity(capacity), alignment(align),
24       offset(0), size(0), allocator(nullptr), addr(std::move(bufData))
25 {
26 }
27 
Memory(size_t capacity,std::shared_ptr<Allocator> allocator,size_t align,MemoryType type,bool allocMem)28 Memory::Memory(size_t capacity, std::shared_ptr<Allocator> allocator, size_t align, MemoryType type, bool allocMem)
29     : memoryType(type), capacity(capacity), alignment(align), offset(0),
30       size(0), allocator(std::move(allocator)), addr(nullptr)
31 {
32     if (!allocMem) { // SurfaceMemory alloc mem in subclass
33         return;
34     }
35     size_t allocSize = align ? (capacity + align - 1) : capacity;
36     if (this->allocator) {
37         addr = std::shared_ptr<uint8_t>(static_cast<uint8_t*>(this->allocator->Alloc(allocSize)),
38                                         [this](uint8_t* ptr) { this->allocator->Free(static_cast<void*>(ptr)); });
39     } else {
40         addr = std::shared_ptr<uint8_t>(new uint8_t[allocSize], std::default_delete<uint8_t[]>());
41     }
42     offset = static_cast<size_t>(AlignUp(reinterpret_cast<uintptr_t>(addr.get()), static_cast<uintptr_t>(align)) -
43         reinterpret_cast<uintptr_t>(addr.get()));
44 }
45 
GetCapacity()46 size_t Memory::GetCapacity()
47 {
48     return capacity;
49 }
50 
Reset()51 void Memory::Reset()
52 {
53     this->size = 0;
54 }
55 
Write(const uint8_t * in,size_t writeSize,size_t position)56 size_t Memory::Write(const uint8_t* in, size_t writeSize, size_t position)
57 {
58     size_t start = 0;
59     if (position == MEM_INVALID_POSITION) {
60         start = size;
61     } else {
62         start = std::min(position, capacity);
63     }
64     size_t length = std::min(writeSize, capacity - start);
65     if (memcpy_s(GetRealAddr() + start, length, in, length) != EOK) {
66         return 0;
67     }
68     size = start + length;
69     return length;
70 }
71 
Read(uint8_t * out,size_t readSize,size_t position)72 size_t Memory::Read(uint8_t* out, size_t readSize, size_t position)
73 {
74     size_t start = 0;
75     size_t maxLength = size;
76     if (position != MEM_INVALID_POSITION) {
77         start = std::min(position, size);
78         maxLength = size - start;
79     }
80     size_t length = std::min(readSize, maxLength);
81     if (memcpy_s(out, length, GetRealAddr() + start, length) != EOK) {
82         return 0;
83     }
84     return length;
85 }
86 
GetReadOnlyData(size_t position)87 const uint8_t* Memory::GetReadOnlyData(size_t position)
88 {
89     if (position > capacity) {
90         return nullptr;
91     }
92     return GetRealAddr() + position;
93 }
94 
GetWritableAddr(size_t estimatedWriteSize,size_t position)95 uint8_t* Memory::GetWritableAddr(size_t estimatedWriteSize, size_t position)
96 {
97     if (position + estimatedWriteSize > capacity) {
98         return nullptr;
99     }
100     uint8_t* ptr = GetRealAddr() + position;
101     size = (estimatedWriteSize + position);
102     return ptr;
103 }
104 
UpdateDataSize(size_t realWriteSize,size_t position)105 void Memory::UpdateDataSize(size_t realWriteSize, size_t position)
106 {
107     if (position + realWriteSize > capacity) {
108         return;
109     }
110     size = (realWriteSize + position);
111 }
112 
GetSize()113 size_t Memory::GetSize()
114 {
115     return size;
116 }
117 
GetRealAddr() const118 uint8_t* Memory::GetRealAddr() const
119 {
120     return addr.get() + offset;
121 }
122 
GetMemoryType()123 MemoryType Memory::GetMemoryType()
124 {
125     return memoryType;
126 }
127 
Buffer()128 Buffer::Buffer() : streamID(0), trackID(0), pts(0), dts(0), duration(0), flag (0)
129 {
130 }
131 
CreateDefaultBuffer(size_t capacity,std::shared_ptr<Allocator> allocator,size_t align)132 std::shared_ptr<Buffer> Buffer::CreateDefaultBuffer(size_t capacity, std::shared_ptr<Allocator> allocator, size_t align)
133 {
134     auto buffer = std::make_shared<Buffer>();
135     std::shared_ptr<Memory> memory = std::shared_ptr<Memory>(new Memory(capacity, allocator, align));
136     buffer->data.push_back(memory);
137     return buffer;
138 }
139 
WrapMemory(uint8_t * data,size_t capacity,size_t size)140 std::shared_ptr<Memory> Buffer::WrapMemory(uint8_t* data, size_t capacity, size_t size)
141 {
142     auto memory = std::shared_ptr<Memory>(new Memory(capacity, std::shared_ptr<uint8_t>(data, [](void* ptr) {})));
143     memory->size = size;
144     this->data.push_back(memory);
145     return memory;
146 }
147 
WrapMemoryPtr(std::shared_ptr<uint8_t> data,size_t capacity,size_t size)148 std::shared_ptr<Memory> Buffer::WrapMemoryPtr(std::shared_ptr<uint8_t> data, size_t capacity, size_t size)
149 {
150     auto memory = std::shared_ptr<Memory>(new Memory(capacity, data));
151     memory->size = size;
152     this->data.push_back(memory);
153     return memory;
154 }
155 
AllocMemory(std::shared_ptr<Allocator> allocator,size_t capacity,size_t align)156 std::shared_ptr<Memory> Buffer::AllocMemory(std::shared_ptr<Allocator> allocator, size_t capacity, size_t align)
157 {
158     auto type = (allocator != nullptr) ? allocator->GetMemoryType() : MemoryType::VIRTUAL_MEMORY;
159     std::shared_ptr<Memory> memory = nullptr;
160     switch (type) {
161         case MemoryType::VIRTUAL_MEMORY: {
162             memory = std::shared_ptr<Memory>(new Memory(capacity, allocator, align));
163             break;
164         }
165         default:
166             break;
167     }
168     if (memory == nullptr) {
169         return nullptr;
170     }
171     data.push_back(memory);
172     return memory;
173 }
174 
GetMemoryCount()175 uint32_t Buffer::GetMemoryCount()
176 {
177     return data.size();
178 }
179 
GetMemory(uint32_t index)180 std::shared_ptr<Memory> Buffer::GetMemory(uint32_t index)
181 {
182     if (data.size() <= index) {
183         return nullptr;
184     }
185     return data[index];
186 }
187 
IsEmpty()188 bool Buffer::IsEmpty()
189 {
190     return data.empty();
191 }
192 
Reset()193 void Buffer::Reset()
194 {
195     data[0]->Reset();
196     streamID = 0;
197     trackID = 0;
198     pts = 0;
199     dts = 0;
200     duration = 0;
201     flag = 0;
202 }
203 } // namespace Plugins
204 } // namespace Media
205 } // namespace OHOS
206