Revive: dumping/ffmpeg_backend: Various fixes (#6528)
* dumping/ffmpeg_backend: Add FPS filter So that the recorded video can be at 60FPS (which is supported by most encoders) while still maintaining correct speed. * dumping/ffmpeg_backend: Add HW context support Required for some HW acceled encoders. Not tested as my devices don't seem to require this. * CMake: Copy avfilter dll for MSVC * CMakeLists: Require FFmpeg 4.0 * ffmpeg: Fix dumper compile error on MSVC. * ffmpeg: Address review comments. --------- Co-authored-by: zhupengfei <zhupf321@gmail.com>
This commit is contained in:
@@ -19,10 +19,10 @@
|
||||
|
||||
extern "C" {
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavfilter/avfilter.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavutil/opt.h>
|
||||
#include <libswresample/swresample.h>
|
||||
#include <libswscale/swscale.h>
|
||||
}
|
||||
|
||||
namespace VideoDumper {
|
||||
@@ -69,7 +69,7 @@ protected:
|
||||
|
||||
/**
|
||||
* A FFmpegStream used for video data.
|
||||
* Rescales, encodes and writes a frame.
|
||||
* Filters (scales), encodes and writes a frame.
|
||||
*/
|
||||
class FFmpegVideoStream : public FFmpegStream {
|
||||
public:
|
||||
@@ -80,21 +80,39 @@ public:
|
||||
void ProcessFrame(VideoFrame& frame);
|
||||
|
||||
private:
|
||||
struct SwsContextDeleter {
|
||||
void operator()(SwsContext* sws_context) const {
|
||||
sws_freeContext(sws_context);
|
||||
}
|
||||
};
|
||||
bool InitHWContext(const AVCodec* codec);
|
||||
bool InitFilters();
|
||||
|
||||
u64 frame_count{};
|
||||
|
||||
std::unique_ptr<AVFrame, AVFrameDeleter> current_frame{};
|
||||
std::unique_ptr<AVFrame, AVFrameDeleter> scaled_frame{};
|
||||
std::unique_ptr<SwsContext, SwsContextDeleter> sws_context{};
|
||||
std::unique_ptr<AVFrame, AVFrameDeleter> filtered_frame{};
|
||||
std::unique_ptr<AVFrame, AVFrameDeleter> hw_frame{};
|
||||
Layout::FramebufferLayout layout;
|
||||
|
||||
/// The pixel format the frames are stored in
|
||||
/// The pixel format the input frames are stored in
|
||||
static constexpr AVPixelFormat pixel_format = AVPixelFormat::AV_PIX_FMT_BGRA;
|
||||
|
||||
// Software pixel format. For normal encoders, this is the format they accept. For HW-acceled
|
||||
// encoders, this is the format the HW frames context accepts.
|
||||
AVPixelFormat sw_pixel_format = AV_PIX_FMT_NONE;
|
||||
|
||||
/// Whether the encoder we are using requires HW frames to be supplied.
|
||||
bool requires_hw_frames = false;
|
||||
|
||||
// Filter related
|
||||
struct AVFilterGraphDeleter {
|
||||
void operator()(AVFilterGraph* filter_graph) const {
|
||||
avfilter_graph_free(&filter_graph);
|
||||
}
|
||||
};
|
||||
std::unique_ptr<AVFilterGraph, AVFilterGraphDeleter> filter_graph{};
|
||||
// These don't need to be freed apparently
|
||||
AVFilterContext* source_context;
|
||||
AVFilterContext* sink_context;
|
||||
|
||||
/// The filter graph to use. This graph means 'change FPS to 60, convert format if needed'
|
||||
static constexpr std::string_view filter_graph_desc = "fps=60";
|
||||
};
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user