1 /*
2  * Copyright (c) 2022-2022 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 #ifndef HISTREAMER_PLUGINS_MEMORY_H
17 #define HISTREAMER_PLUGINS_MEMORY_H
18 
19 #include <cstdint>
20 #include <memory>
21 #include "buffer/avallocator.h"
22 
23 namespace OHOS {
24 namespace Media {
25 namespace Plugins {
26 constexpr size_t MEM_INVALID_POSITION = -1;
27 
28 /**
29 * @brief Memory allocator, which is provided by the plugin implementer.
30 *
31 * @since 1.0
32 * @version 1.0
33 */
34 struct Allocator {
35     explicit Allocator(MemoryType type = MemoryType::VIRTUAL_MEMORY) : memoryType(type) {}
36     virtual ~Allocator() = default;
37     /**
38      * @brief Allocates a buffer using the specified size
39      * .
40      * @param size  Allocation parameters.
41      * @return      Pointer of the allocated buffer.
42      */
43     virtual void* Alloc(size_t size) = 0;
44 
45     /**
46      * @brief Frees a buffer.
47      * Buffer handles returned by Alloc() must be freed with this function when no longer needed.
48      *
49      * @param ptr   Pointer of the allocated buffer.
50      */
51     virtual void Free(void* ptr) = 0; // NOLINT: intentionally using void* here
52 
GetMemoryTypeAllocator53     MemoryType GetMemoryType()
54     {
55         return memoryType;
56     }
57 
58 private:
59     MemoryType memoryType;
60 };
61 
62 /**
63 * @brief Memory description. Only manager the basic memory information.
64 *
65 *  here is the memory layout.
66 *            |            capacity                      |
67 *            |------------------------------------------|
68 *            |       buffer size       |
69 *            |-------------------------|
70 *  addr   offset                      buffer end
71 *  +---------+-------------------------+----------------+
72 *  |*********|        used buffer      |  unused buffer |
73 *  +---------+-------------------------+----------------+
74 *
75 *  operate position:
76 *                         position
77 *            +----------------+
78 *
79 * @since 1.0
80 * @version 1.0
81 */
82 class Memory {
83 public:
84     /// Destructor
85     virtual ~Memory() = default;
86 
87     virtual size_t GetCapacity();
88 
89     size_t GetSize();
90 
91     const uint8_t* GetReadOnlyData(size_t position = 0);
92 
93     uint8_t* GetWritableAddr(size_t estimatedWriteSize, size_t position = 0);
94 
95     // If estimatedWriteSize doesn't equal to realWriteSize, should call UpdateDataSize
96     void UpdateDataSize(size_t realWriteSize, size_t position = 0);
97 
98     virtual size_t Write(const uint8_t* in, size_t writeSize, size_t position = MEM_INVALID_POSITION);
99 
100     virtual size_t Read(uint8_t* out, size_t readSize, size_t position = MEM_INVALID_POSITION);
101 
102     void Reset();
103 
104     MemoryType GetMemoryType();
105 
106 protected:
107     /**
108      * Allocates memory by the specified allocator.
109      * Allocation and release are the responsibility of the external allocator.
110      *
111      * @param capacity Allocated memory size.
112      * @param allocator External allocator.
113      * @param align The alignment of the memory.
114      */
115     explicit Memory(size_t capacity, std::shared_ptr<Allocator> allocator = nullptr,
116                     size_t align = 1, MemoryType type = MemoryType::VIRTUAL_MEMORY, bool allocMem = true);
117 
118     /**
119      * Get real memory address, it is addr + offset, the offset is calculated according to alignment.
120      */
121     virtual uint8_t* GetRealAddr() const;
122 
123     /// Memory type
124     MemoryType memoryType;
125 
126     /// Allocated memory size.
127     size_t capacity;
128 
129     /// The alignment of the memory.
130 #if (defined(__GNUC__) || defined(__clang__)) && (!defined(WIN32))
131     __attribute__((unused))
132 #endif
133     size_t alignment;
134 
135     /// Offset of the buffer address to make sure access according to alignment.
136     size_t offset {0};
137 
138     /// Valid data size
139     size_t size;
140 
141     /// Externally specified allocator, optional.
142     std::shared_ptr<Allocator> allocator;
143 
144 private:
145     /**
146      * Create objects based on the external memory, use shared pointers,
147      * the allocation and release of memory are managed externally.
148      *
149      * @param capacity Allocated memory size.
150      * @param bufData External memory.
151      * @param align The alignment of the memory.
152      */
153     Memory(size_t capacity, std::shared_ptr<uint8_t> bufData,
154            size_t align = 1, MemoryType type = MemoryType::VIRTUAL_MEMORY);
155 
156     /// Allocated virtual memory address.
157     std::shared_ptr<uint8_t> addr;
158 
159     friend class Buffer;
160 };
161 } // namespace Plugins
162 } // namespace Media
163 } // namespace OHOS
164 #endif // HISTREAMER_PLUGINS_MEMORY_H
165