#ifndef ECLIPT_DECODER_H #define ECLIPT_DECODER_H #include "Frame.h" #include "Demuxer.h" #include "Config.h" #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif #include #include #ifdef __cplusplus } #endif namespace eclipt { enum class DecoderType { Software, Hardware, Auto }; enum class HardwareAPI { None, VAAPI, VDPAU, CUDA, D3D11VA, VideoToolbox, MediaCodec, MMAL, OMX }; struct DecoderCapabilities { bool supports_hw_decode = false; bool supports_hw_encode = false; std::vector supported_apis; std::vector supported_codecs; int max_resolution_width = 0; int max_resolution_height = 0; bool supports_10bit = false; bool supports_hdr = false; }; struct DecodeStats { int decoded_frames = 0; int dropped_frames = 0; int corrupted_frames = 0; int64_t decode_time_us = 0; double fps = 0.0; bool is_hardware = false; HardwareAPI hw_api = HardwareAPI::None; }; class IDecoder { public: virtual ~IDecoder() = default; virtual bool open(const StreamMetadata& stream, const DecoderConfig& config) = 0; virtual void close() = 0; virtual bool isOpen() const = 0; virtual bool sendPacket(const Packet& packet) = 0; virtual bool receiveFrame(VideoFrame& frame) = 0; virtual bool flush() = 0; virtual DecoderType getDecoderType() const = 0; virtual HardwareAPI getHardwareAPI() const = 0; virtual const DecodeStats& getStats() const = 0; virtual void setHardwareAPI(HardwareAPI api) = 0; virtual bool supportsFormat(const std::string& codec) const = 0; virtual std::string getLastError() const = 0; }; class FFmpegDecoder : public IDecoder { public: FFmpegDecoder(); ~FFmpegDecoder() override; bool open(const StreamMetadata& stream, const DecoderConfig& config) override; void close() override; bool isOpen() const override; bool sendPacket(const Packet& packet) override; bool receiveFrame(VideoFrame& frame) override; bool flush() override; DecoderType getDecoderType() const override; HardwareAPI getHardwareAPI() const override; const DecodeStats& getStats() const override; void setHardwareAPI(HardwareAPI api) override; bool supportsFormat(const std::string& codec) const override; std::string getLastError() const override; static DecoderCapabilities getCapabilities(); static std::vector getAvailableHardwareAPIs(); static HardwareAPI probeBestHardwareAPI(const std::string& codec); void* getHardwareDeviceContext() const; private: struct Impl; std::unique_ptr pImpl; }; class FramePool : public IFramePool { public: FramePool(size_t max_size, PixelFormat format, uint32_t width, uint32_t height); ~FramePool() override; VideoFrame acquire() override; void release(VideoFrame&& frame) override; void clear() override; size_t available() const override; void setFormat(PixelFormat format); void setDimensions(uint32_t width, uint32_t height); private: struct Impl; std::unique_ptr pImpl; }; class DecoderPool { public: DecoderPool(); ~DecoderPool(); void setMaxDecoders(size_t count); size_t getMaxDecoders() const; std::shared_ptr acquire(const StreamMetadata& stream, const DecoderConfig& config); void release(std::shared_ptr decoder); void clear(); size_t activeCount() const; private: struct Impl; std::unique_ptr pImpl; }; } #endif