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