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