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#ifndef HISTREAMER_PLUGIN_COMMON_BUFFER_H
17#define HISTREAMER_PLUGIN_COMMON_BUFFER_H
18
19#include <memory>
20#include <map>
21#include <vector>
22
23#include "plugin/common/plugin_memory.h"
24#include "plugin/common/plugin_meta.h"
25#if !defined(OHOS_LITE) && defined(VIDEO_SUPPORT)
26#include "refbase.h"
27#include "surface/surface.h"
28#endif
29
30namespace OHOS {
31namespace Media {
32namespace Plugin {
33/// End of Stream Buffer Flag
34#define BUFFER_FLAG_EOS 0x00000001
35/// Video Key Frame Flag
36#define BUFFER_FLAG_KEY_FRAME 0x00000002
37
38// Align value template
39template <typename T>
40using MakeUnsigned = typename std::make_unsigned<T>::type;
41
42template <typename T, typename U>
43constexpr T AlignUp(T num, U alignment)
44{
45    return (alignment > 0) ? (static_cast<uint64_t>((static_cast<MakeUnsigned<T>>(num)
46        + static_cast<MakeUnsigned<T>>(alignment) - 1)) &
47        static_cast<uint64_t>((~(static_cast<MakeUnsigned<T>>(alignment) - 1)))) :
48        num;
49}
50
51/**
52 * @enum Buffer Meta Type
53 *
54 * @since 1.0
55 * @version 1.0
56 */
57enum struct BufferMetaType : uint32_t {
58    AUDIO,      ///< Meta used to describe audio data
59    VIDEO,      ///< Meta used to describe video data
60};
61
62/**
63 * @brief Buffer Meta.
64 * Base class that describes various media metadata.
65 *
66 * @since 1.0
67 * @version 1.0
68 */
69class BufferMeta {
70public:
71    /// Destructor
72    virtual ~BufferMeta() = default;
73
74    ValueType GetMeta(Tag tag);
75
76    void SetMeta(Tag tag, ValueType value);
77
78    BufferMetaType GetType() const;
79
80    bool IsExist(Tag tag);
81
82    void Update(const BufferMeta& bufferMeta);
83
84    virtual std::shared_ptr<BufferMeta> Clone() = 0;
85
86protected:
87    /// Constructor
88    explicit BufferMeta(BufferMetaType type);
89
90private:
91    BufferMetaType type_;
92
93    /// Buffer metadata information of the buffer, which is represented by the key-value pair of the tag.
94    std::shared_ptr<Meta> tags_ {};
95};
96
97/**
98 * @brief Audio buffer metadata.
99 *
100 * Buffer metadata describing how data is laid out inside the buffer.
101 *
102 * @since 1.0
103 * @version 1.0
104 */
105class AudioBufferMeta : public BufferMeta {
106public:
107    /// Destructor
108    ~AudioBufferMeta() override = default;
109
110    std::shared_ptr<BufferMeta> Clone() override;
111
112    /// the number of valid samples in the buffer
113    size_t samples {0};
114
115    /// Audio sample formats
116    AudioSampleFormat sampleFormat {AudioSampleFormat::S8};
117
118    /// the audio sample rate
119    uint32_t sampleRate {0};
120
121    /// the number of channels
122    uint32_t channels {0};
123
124    /// the number bytes for one frame, this is the size of one sample * channels
125    uint32_t bytesPreFrame {0};
126
127    /// Indicates that the channel order.
128    AudioChannelLayout channelLayout {AudioChannelLayout::MONO};
129
130    /// the offsets (in bytes) where each channel plane starts in the buffer.
131    std::vector<size_t> offsets {};
132
133private:
134    /// Constructor
135    AudioBufferMeta() : BufferMeta(BufferMetaType::AUDIO) {}
136
137    friend class Buffer;
138};
139
140/**
141 * @brief Video buffer metadata.
142 *
143 *  Extra buffer metadata describing video properties.
144 *
145 *  @since 1.0
146 *  @version 1.0
147 */
148class VideoBufferMeta : public BufferMeta {
149public:
150    /// Destructor
151    ~VideoBufferMeta() override = default;
152
153    std::shared_ptr<BufferMeta> Clone() override;
154
155    /// describing video formats.
156    VideoPixelFormat videoPixelFormat {VideoPixelFormat::UNKNOWN};
157
158    /// identifier of the frame。
159    uint32_t id {0};
160
161    /// the video width.
162    uint32_t width {0};
163
164    /// the video height.
165    uint32_t height {0};
166
167    /// the number of planes in the image.
168    uint32_t planes {0};
169
170    /// array of strides for the planes.
171    std::vector<uint32_t> stride {};
172
173    /// array of offsets for the planes.
174    std::vector<uint32_t> offset {};
175
176private:
177    /// Constructor
178    VideoBufferMeta() : BufferMeta(BufferMetaType::VIDEO) {}
179
180    friend class Buffer;
181};
182
183/**
184* @brief Buffer base class.
185* Contains the data storage and metadata information of the buffer (buffer description information).
186*
187* @since 1.0
188* @version 1.0
189*/
190class Buffer {
191public:
192    /// Construct an empty buffer.
193    explicit Buffer(BufferMetaType type = BufferMetaType::AUDIO);
194
195    /// Destructor
196    ~Buffer() = default;
197
198    static std::shared_ptr<Buffer> CreateDefaultBuffer(BufferMetaType type, size_t capacity,
199                                                       std::shared_ptr<Allocator> allocator = nullptr,
200                                                       size_t align = 1);
201
202    std::shared_ptr<Memory> WrapMemory(uint8_t* data, size_t capacity, size_t size);
203
204    std::shared_ptr<Memory> WrapMemoryPtr(std::shared_ptr<uint8_t> data, size_t capacity, size_t size);
205
206    std::shared_ptr<Memory> AllocMemory(std::shared_ptr<Allocator> allocator, size_t capacity, size_t align = 1);
207
208#if !defined(OHOS_LITE) && defined(VIDEO_SUPPORT)
209    std::shared_ptr<Memory> WrapSurfaceMemory(sptr<SurfaceBuffer> surfaceBuffer);
210#endif
211
212    uint32_t GetMemoryCount();
213
214    std::shared_ptr<Memory> GetMemory(uint32_t index = 0);
215
216    std::shared_ptr<BufferMeta> GetBufferMeta();
217
218    void UpdateBufferMeta(const BufferMeta& bufferMeta);
219
220    void Reset();
221
222    /// no memory in the buffer.
223    bool IsEmpty();
224
225    void ChangeBufferMetaType(BufferMetaType type);
226
227    /// track index.
228    uint32_t trackID;
229
230    /// presentation timestamp of the buffer based on {@link HST_TIME_BASE}.
231    int64_t pts;
232
233    /// decoding timestamp of the buffer based on {@link HST_TIME_BASE}.
234    int64_t dts;
235
236    /// duration in time of the buffer data based on {@link HST_TIME_BASE}.
237    int64_t duration;
238
239    /// flag of the buffer, which is used to record extra information.
240    /// @see BUFFER_FLAG_EOS
241    uint64_t flag;
242
243private:
244    /// Data described by this buffer.
245    std::vector<std::shared_ptr<Memory>> data {};
246
247    /// The buffer meta information.
248    std::shared_ptr<BufferMeta> meta;
249};
250} // namespace Plugin
251} // namespace Media
252} // namespace OHOS
253#endif // HISTREAMER_PLUGIN_COMMON_BUFFER_H
254