app: route all FFmpeg access through the ffmpeg_bridge C API
Replace every direct FFmpeg call in the editor and the render worker with the pure C ffmpeg_bridge API, wrapped in thin C++ adapters that preserve the original interfaces: - avframeptr.h: olive::AVFrame adapter around FBFrame handles - ffmpegutils: format conversion helpers on FB_* constants; the int overload is renamed GetCompatibleBridgePixelFormat to avoid a silent overload-resolution trap with the PixelFormat enum - ffmpegdecoder/ffmpegencoder: rewritten as handle-based adapters over FBDecoder/FBProbe/FBEncoder/FBScaler/FBResampler - audioprocessor: FBAudioGraph push/pull adapter - pluginrenderer/OliveClip: sws/pixdesc usage converted to FBScaler and fb_pix_fmt_* queries - AudioParams/channel layouts are plain uint64_t masks everywhere Build integration: the root project no longer links FFMPEG directly; only ffmpeg_bridge does. Binaries resolve the bridge library at runtime via @loader_path inside the macOS app bundle (copied there post-build) and via $ORIGIN/../ffmpeg_bridge/bin on Linux; on Windows the DLL is installed next to the executables, so packages on all three platforms ship the bridge library. ffmpeg_bridge gains the extra API the adapters need: fb_frame_make_writable, fb_decoder_get_format_duration, fb_resampler_convert_frame, FB_PIX_FMT_YUV440P, SRT validation in fb_probe_read_subtitle_stream, packed/planar fixes in fb_encoder_write_audio, and a component-size fix in fb_pix_fmt_component_size.
This commit is contained in:
@@ -22,17 +22,9 @@
|
||||
#ifndef FFMPEGDECODER_H
|
||||
#define FFMPEGDECODER_H
|
||||
|
||||
// Fixes weird define issue when including <avfilter.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
extern "C" {
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavfilter/avfilter.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavutil/hwcontext.h>
|
||||
#include <libswscale/swscale.h>
|
||||
#include <libswresample/swresample.h>
|
||||
}
|
||||
#include <ffmpeg_bridge/ffmpeg_bridge.h>
|
||||
|
||||
#include <QTimer>
|
||||
#include <QVector>
|
||||
@@ -45,7 +37,10 @@ namespace olive
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief A Decoder derivative that wraps FFmpeg functions as on Olive decoder
|
||||
* @brief A Decoder derivative that uses the ffmpeg_bridge library as an Olive decoder
|
||||
*
|
||||
* All media access goes through the pure C API of the ffmpeg_bridge shared
|
||||
* library; this class never sees an FFmpeg structure or function.
|
||||
*/
|
||||
class FFmpegDecoder : public Decoder {
|
||||
Q_OBJECT
|
||||
@@ -84,88 +79,10 @@ protected:
|
||||
virtual rational GetAudioStartOffset() const override;
|
||||
|
||||
private:
|
||||
class Instance {
|
||||
public:
|
||||
Instance();
|
||||
|
||||
~Instance()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
bool Open(const char *filename, int stream_index);
|
||||
|
||||
bool IsOpen() const
|
||||
{
|
||||
return fmt_ctx_;
|
||||
}
|
||||
|
||||
void Close();
|
||||
|
||||
/**
|
||||
* @brief Uses the FFmpeg API to retrieve a packet (stored in pkt_) and decode it (stored in frame_)
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* An FFmpeg error code, or >= 0 on success
|
||||
*/
|
||||
int GetFrame(AVPacket *pkt, AVFrame *frame);
|
||||
|
||||
const char *GetSubtitleHeader() const;
|
||||
|
||||
int GetSubtitle(AVPacket *pkt, AVSubtitle *sub);
|
||||
|
||||
int GetPacket(AVPacket *pkt);
|
||||
|
||||
void Seek(int64_t timestamp);
|
||||
|
||||
AVFormatContext *fmt_ctx() const
|
||||
{
|
||||
return fmt_ctx_;
|
||||
}
|
||||
|
||||
AVStream *avstream() const
|
||||
{
|
||||
return avstream_;
|
||||
}
|
||||
AVCodecContext *codec_ctx()
|
||||
{
|
||||
return codec_ctx_;
|
||||
}
|
||||
|
||||
bool hwaccel_enabled() const
|
||||
{
|
||||
return hwaccel_enabled_;
|
||||
}
|
||||
|
||||
AVPixelFormat hw_pix_fmt() const
|
||||
{
|
||||
return hw_pix_fmt_;
|
||||
}
|
||||
|
||||
private:
|
||||
static AVHWDeviceType ChooseHardwareDevice();
|
||||
static AVPixelFormat GetHardwareFormat(AVCodecContext *ctx,
|
||||
const AVPixelFormat *pix_fmts);
|
||||
|
||||
bool InitHardwareAcceleration(const AVCodec *codec);
|
||||
void CleanupHardwareAcceleration();
|
||||
|
||||
AVFormatContext *fmt_ctx_;
|
||||
AVCodecContext *codec_ctx_;
|
||||
AVStream *avstream_;
|
||||
AVDictionary *opts_;
|
||||
|
||||
AVBufferRef *hw_device_ctx_;
|
||||
AVHWDeviceType hw_device_type_;
|
||||
AVPixelFormat hw_pix_fmt_;
|
||||
bool hwaccel_enabled_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Handle an FFmpeg error code
|
||||
* @brief Handle a bridge error code
|
||||
*
|
||||
* Uses the FFmpeg API to retrieve a descriptive string for this error code and sends it to Error(). As such, this
|
||||
* Uses the bridge API to retrieve a descriptive string for this error code and sends it to Error(). As such, this
|
||||
* function also automatically closes the Decoder.
|
||||
*
|
||||
* @param error_code
|
||||
@@ -176,15 +93,10 @@ private:
|
||||
|
||||
AVFramePtr TransferHardwareFrame(AVFramePtr f);
|
||||
|
||||
static PixelFormat GetNativePixelFormat(AVPixelFormat pix_fmt);
|
||||
static int GetNativeChannelCount(AVPixelFormat pix_fmt);
|
||||
static PixelFormat GetNativePixelFormat(int pix_fmt);
|
||||
static int GetNativeChannelCount(int pix_fmt);
|
||||
|
||||
static AVChannelLayout ValidateChannelLayout(AVStream *stream);
|
||||
|
||||
static const char *
|
||||
GetInterlacingModeInFFmpeg(VideoParams::Interlacing interlacing);
|
||||
|
||||
static bool IsPixelFormatGLSLCompatible(AVPixelFormat f);
|
||||
static bool IsPixelFormatGLSLCompatible(int f);
|
||||
|
||||
AVFramePtr GetFrameFromCache(const int64_t &t) const;
|
||||
|
||||
@@ -202,17 +114,17 @@ private:
|
||||
|
||||
static int MaximumQueueSize();
|
||||
|
||||
SwsContext *sws_ctx_;
|
||||
int sws_src_width_;
|
||||
int sws_src_height_;
|
||||
AVPixelFormat sws_src_format_;
|
||||
int sws_dst_width_;
|
||||
int sws_dst_height_;
|
||||
AVPixelFormat sws_dst_format_;
|
||||
AVColorRange sws_colrange_;
|
||||
AVColorSpace sws_colspace_;
|
||||
FBScaler *scaler_;
|
||||
int scaler_src_width_;
|
||||
int scaler_src_height_;
|
||||
int scaler_src_format_;
|
||||
int scaler_dst_width_;
|
||||
int scaler_dst_height_;
|
||||
int scaler_dst_format_;
|
||||
int scaler_colrange_;
|
||||
int scaler_colspace_;
|
||||
|
||||
AVPacket *working_packet_;
|
||||
FBPacket *working_packet_;
|
||||
|
||||
int64_t second_ts_;
|
||||
|
||||
@@ -221,7 +133,17 @@ private:
|
||||
bool cache_at_zero_;
|
||||
bool cache_at_eof_;
|
||||
|
||||
Instance instance_;
|
||||
FBDecoder *instance_;
|
||||
|
||||
// Stream parameters cached on open (the stream object itself lives
|
||||
// inside the bridge library)
|
||||
rational stream_time_base_;
|
||||
int64_t stream_start_time_;
|
||||
int64_t stream_duration_;
|
||||
int64_t format_start_time_;
|
||||
int input_sample_format_;
|
||||
int input_sample_rate_;
|
||||
uint64_t input_channel_layout_mask_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user