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