/* * Copyright (c) 2021-2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef HISTREAMER_PLUGIN_COMMON_BUFFER_H #define HISTREAMER_PLUGIN_COMMON_BUFFER_H #include #include #include #include "plugin_tags.h" #include "plugin_audio_tags.h" #include "plugin_video_tags.h" #if !defined(OHOS_LITE) && defined(VIDEO_SUPPORT) #include "refbase.h" #include "surface/surface.h" #endif namespace OHOS { namespace Media { namespace Plugin { constexpr size_t INVALID_POSITION = -1; /// End of Stream Buffer Flag #define BUFFER_FLAG_EOS 0x00000001 /// Video Key Frame Flag #define BUFFER_FLAG_KEY_FRAME 0x00000002 // Align value template template using MakeUnsigned = typename std::make_unsigned::type; template constexpr T AlignUp(T num, U alignment) { return (alignment > 0) ? (static_cast((num + static_cast>(alignment) - 1)) & static_cast((~(static_cast>(alignment) - 1)))) : num; } /** * @enum MemoryType * * @since 1.0 * @version 1.0 */ enum struct MemoryType : uint8_t { VIRTUAL_ADDR = 0, ///< Virtual address SURFACE_BUFFER, ///< Surface SHARE_MEMORY, ///< Share Memory fd }; /** * @brief Memory allocator, which is provided by the plugin implementer. * * @since 1.0 * @version 1.0 */ struct Allocator { explicit Allocator(MemoryType type = MemoryType::VIRTUAL_ADDR) : memoryType(type) {} virtual ~Allocator() = default; /** * @brief Allocates a buffer using the specified size * . * @param size Allocation parameters. * @return Pointer of the allocated buffer. */ virtual void* Alloc(size_t size) = 0; /** * @brief Frees a buffer. * Buffer handles returned by Alloc() must be freed with this function when no longer needed. * * @param ptr Pointer of the allocated buffer. */ virtual void Free(void* ptr) = 0; // NOLINT: intentionally using void* here MemoryType GetMemoryType() { return memoryType; } private: MemoryType memoryType; }; /** * @enum Buffer Meta Type * * @since 1.0 * @version 1.0 */ enum struct BufferMetaType : uint32_t { AUDIO, ///< Meta used to describe audio data VIDEO, ///< Meta used to describe video data }; /** * @brief Memory description. Only manager the basic memory information. * * here is the memory layout. * | capacity | * |------------------------------------------| * | buffer size | * |-------------------------| * addr offset buffer end * +---------+-------------------------+----------------+ * |*********| used buffer | unused buffer | * +---------+-------------------------+----------------+ * * operate position: * position * +----------------+ * * @since 1.0 * @version 1.0 */ class Memory { public: /// Destructor virtual ~Memory() = default; // Todo: Add the documentation description. size_t GetCapacity(); size_t GetSize(); const uint8_t* GetReadOnlyData(size_t position = 0); uint8_t *GetWritableAddr(size_t estimatedWriteSize, size_t position = 0); // If estimatedWriteSize doesn't equal to realWriteSize, should call UpdateDataSize void UpdateDataSize(size_t realWriteSize, size_t position = 0); size_t Write(const uint8_t* in, size_t writeSize, size_t position = INVALID_POSITION); size_t Read(uint8_t* out, size_t readSize, size_t position = INVALID_POSITION); void Reset(); MemoryType GetMemoryType(); protected: /** * Allocates memory by the specified allocator. * Allocation and release are the responsibility of the external allocator. * * @param capacity Allocated memory size. * @param allocator External allocator. * @param align The alignment of the memory. */ explicit Memory(size_t capacity, std::shared_ptr allocator = nullptr, size_t align = 1, MemoryType type = MemoryType::VIRTUAL_ADDR, bool allocMem = true); /** * Get real memory address, it is addr + offset, the offset is calculated according to alignment. */ virtual uint8_t *GetRealAddr() const; /// Memory type MemoryType memoryType; /// Allocated memory size. size_t capacity; /// The alignment of the memory. #if (defined(__GNUC__) || defined(__clang__)) && (!defined(WIN32)) __attribute__((unused)) #endif size_t alignment; /// Offset of the buffer address to make sure access according to alignment. size_t offset {0}; /// Valid data size size_t size; /// Externally specified allocator, optional. std::shared_ptr allocator; private: /** * Create objects based on the external memory, use shared pointers, * the allocation and release of memory are managed externally. * * @param capacity Allocated memory size. * @param bufData External memory. * @param align The alignment of the memory. */ Memory(size_t capacity, std::shared_ptr bufData, size_t align = 1, MemoryType type = MemoryType::VIRTUAL_ADDR); /// Allocated virtual memory address. std::shared_ptr addr; friend class Buffer; }; /** * @brief Buffer Meta. * Base class that describes various media metadata. * * @since 1.0 * @version 1.0 */ class BufferMeta { public: /// Destructor virtual ~BufferMeta() = default; ValueType GetMeta(Tag tag); void SetMeta(Tag tag, ValueType value); BufferMetaType GetType() const; protected: /// Constructor explicit BufferMeta(BufferMetaType type); private: BufferMetaType type; /// Buffer metadata information of the buffer, which is represented by the key-value pair of the tag. std::shared_ptr tags {}; }; /** * @brief Audio buffer metadata. * * Buffer metadata describing how data is laid out inside the buffer. * * @since 1.0 * @version 1.0 */ class AudioBufferMeta : public BufferMeta { public: /// Destructor ~AudioBufferMeta() override = default; /// the number of valid samples in the buffer size_t samples {0}; /// Audio sample formats AudioSampleFormat sampleFormat {AudioSampleFormat::S8}; /// the audio sample rate uint32_t sampleRate {0}; /// the number of channels uint32_t channels {0}; /// the number bytes for one frame, this is the size of one sample * channels uint32_t bytesPreFrame {0}; /// Indicates that the channel order. AudioChannelLayout channelLayout {AudioChannelLayout::MONO}; /// the offsets (in bytes) where each channel plane starts in the buffer. std::vector offsets {}; private: /// Constructor AudioBufferMeta() : BufferMeta(BufferMetaType::AUDIO) {} friend class Buffer; }; /** * @brief Video buffer metadata. * * Extra buffer metadata describing video properties. * * @since 1.0 * @version 1.0 */ class VideoBufferMeta : public BufferMeta { public: /// Destructor ~VideoBufferMeta() override = default; /// describing video formats. VideoPixelFormat videoPixelFormat {VideoPixelFormat::UNKNOWN}; /// identifier of the frame。 uint32_t id {0}; /// the video width. uint32_t width {0}; /// the video height. uint32_t height {0}; /// the number of planes in the image. uint32_t planes {0}; /// array of strides for the planes. std::vector stride {}; /// array of offsets for the planes. std::vector offset {}; private: /// Constructor VideoBufferMeta() : BufferMeta(BufferMetaType::VIDEO) {} friend class Buffer; }; /** * @brief Buffer base class. * Contains the data storage and metadata information of the buffer (buffer description information). * * @since 1.0 * @version 1.0 */ class Buffer { public: /// Construct an empty buffer. explicit Buffer(BufferMetaType type = BufferMetaType::AUDIO); /// Destructor ~Buffer() = default; static std::shared_ptr CreateDefaultBuffer(BufferMetaType type, size_t capacity, std::shared_ptr allocator = nullptr, size_t align = 1); std::shared_ptr WrapMemory(uint8_t* data, size_t capacity, size_t size); std::shared_ptr WrapMemoryPtr(std::shared_ptr data, size_t capacity, size_t size); std::shared_ptr AllocMemory(std::shared_ptr allocator, size_t capacity, size_t align = 1); uint32_t GetMemoryCount(); std::shared_ptr GetMemory(uint32_t index = 0); std::shared_ptr GetBufferMeta(); void Reset(); /// no memory in the buffer. bool IsEmpty(); /// track index. uint32_t trackID; /// presentation timestamp of the buffer based on {@link HST_TIME_BASE}. uint64_t pts; /// decoding timestamp of the buffer based on {@link HST_TIME_BASE}. uint64_t dts; /// duration in time of the buffer data based on {@link HST_TIME_BASE}. uint64_t duration; /// flag of the buffer, which is used to record extra information. /// @see BUFFER_FLAG_EOS uint64_t flag; private: /// Data described by this buffer. std::vector> data {}; /// The buffer meta information. std::shared_ptr meta; }; } // namespace Plugin } // namespace Media } // namespace OHOS #endif // HISTREAMER_PLUGIN_COMMON_BUFFER_H