157 lines
3.7 KiB
C++
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
|