Files
2026-03-03 08:13:16 +03:00

157 lines
3.7 KiB
C++

#ifndef ECLIPT_DECODER_H
#define ECLIPT_DECODER_H
#include "Frame.h"
#include "Demuxer.h"
#include "Config.h"
#include <string>
#include <vector>
#include <memory>
#include <functional>
#include <atomic>
#ifdef __cplusplus
extern "C" {
#endif
#include <libavcodec/avcodec.h>
#include <libavutil/hwcontext.h>
#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<HardwareAPI> supported_apis;
std::vector<std::string> 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<HardwareAPI> getAvailableHardwareAPIs();
static HardwareAPI probeBestHardwareAPI(const std::string& codec);
void* getHardwareDeviceContext() const;
private:
struct Impl;
std::unique_ptr<Impl> 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<Impl> pImpl;
};
class DecoderPool {
public:
DecoderPool();
~DecoderPool();
void setMaxDecoders(size_t count);
size_t getMaxDecoders() const;
std::shared_ptr<FFmpegDecoder> acquire(const StreamMetadata& stream, const DecoderConfig& config);
void release(std::shared_ptr<FFmpegDecoder> decoder);
void clear();
size_t activeCount() const;
private:
struct Impl;
std::unique_ptr<Impl> pImpl;
};
}
#endif