lib/ffmpeg/Filter: eliminate class FilterContext
Since AVFilterContext are freed automatically, this wrapper class serves no purpose. Let's remove it.
This commit is contained in:
parent
a62a35e1db
commit
71a5311b06
@ -32,12 +32,12 @@ extern "C" {
|
|||||||
FfmpegFilter::FfmpegFilter(const AudioFormat &in_audio_format,
|
FfmpegFilter::FfmpegFilter(const AudioFormat &in_audio_format,
|
||||||
const AudioFormat &_out_audio_format,
|
const AudioFormat &_out_audio_format,
|
||||||
Ffmpeg::FilterGraph &&_graph,
|
Ffmpeg::FilterGraph &&_graph,
|
||||||
Ffmpeg::FilterContext &&_buffer_src,
|
AVFilterContext &_buffer_src,
|
||||||
Ffmpeg::FilterContext &&_buffer_sink) noexcept
|
AVFilterContext &_buffer_sink) noexcept
|
||||||
:Filter(_out_audio_format),
|
:Filter(_out_audio_format),
|
||||||
graph(std::move(_graph)),
|
graph(std::move(_graph)),
|
||||||
buffer_src(std::move(_buffer_src)),
|
buffer_src(_buffer_src),
|
||||||
buffer_sink(std::move(_buffer_sink)),
|
buffer_sink(_buffer_sink),
|
||||||
in_format(Ffmpeg::ToFfmpegSampleFormat(in_audio_format.format)),
|
in_format(Ffmpeg::ToFfmpegSampleFormat(in_audio_format.format)),
|
||||||
in_sample_rate(in_audio_format.sample_rate),
|
in_sample_rate(in_audio_format.sample_rate),
|
||||||
in_channels(in_audio_format.channels),
|
in_channels(in_audio_format.channels),
|
||||||
@ -61,7 +61,7 @@ FfmpegFilter::FilterPCM(ConstBuffer<void> src)
|
|||||||
|
|
||||||
memcpy(frame.GetData(0), src.data, src.size);
|
memcpy(frame.GetData(0), src.data, src.size);
|
||||||
|
|
||||||
int err = av_buffersrc_add_frame(buffer_src.get(), frame.get());
|
int err = av_buffersrc_add_frame(&buffer_src, frame.get());
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
throw MakeFfmpegError(err, "av_buffersrc_write_frame() failed");
|
throw MakeFfmpegError(err, "av_buffersrc_write_frame() failed");
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ FfmpegFilter::FilterPCM(ConstBuffer<void> src)
|
|||||||
|
|
||||||
frame.Unref();
|
frame.Unref();
|
||||||
|
|
||||||
err = av_buffersink_get_frame(buffer_sink.get(), frame.get());
|
err = av_buffersink_get_frame(&buffer_sink, frame.get());
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
if (err == AVERROR(EAGAIN) || err == AVERROR_EOF)
|
if (err == AVERROR(EAGAIN) || err == AVERROR_EOF)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
*/
|
*/
|
||||||
class FfmpegFilter final : public Filter {
|
class FfmpegFilter final : public Filter {
|
||||||
Ffmpeg::FilterGraph graph;
|
Ffmpeg::FilterGraph graph;
|
||||||
Ffmpeg::FilterContext buffer_src, buffer_sink;
|
AVFilterContext &buffer_src, &buffer_sink;
|
||||||
Ffmpeg::Frame frame;
|
Ffmpeg::Frame frame;
|
||||||
|
|
||||||
FfmpegBuffer interleave_buffer;
|
FfmpegBuffer interleave_buffer;
|
||||||
@ -51,8 +51,8 @@ public:
|
|||||||
FfmpegFilter(const AudioFormat &in_audio_format,
|
FfmpegFilter(const AudioFormat &in_audio_format,
|
||||||
const AudioFormat &_out_audio_format,
|
const AudioFormat &_out_audio_format,
|
||||||
Ffmpeg::FilterGraph &&_graph,
|
Ffmpeg::FilterGraph &&_graph,
|
||||||
Ffmpeg::FilterContext &&_buffer_src,
|
AVFilterContext &_buffer_src,
|
||||||
Ffmpeg::FilterContext &&_buffer_sink) noexcept;
|
AVFilterContext &_buffer_sink) noexcept;
|
||||||
|
|
||||||
/* virtual methods from class Filter */
|
/* virtual methods from class Filter */
|
||||||
ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override;
|
ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override;
|
||||||
|
@ -42,14 +42,13 @@ PreparedFfmpegFilter::Open(AudioFormat &in_audio_format)
|
|||||||
{
|
{
|
||||||
Ffmpeg::FilterGraph graph;
|
Ffmpeg::FilterGraph graph;
|
||||||
|
|
||||||
auto buffer_src =
|
auto &buffer_src =
|
||||||
Ffmpeg::FilterContext::MakeAudioBufferSource(in_audio_format,
|
Ffmpeg::MakeAudioBufferSource(in_audio_format, *graph);
|
||||||
*graph);
|
|
||||||
|
|
||||||
auto buffer_sink = Ffmpeg::FilterContext::MakeAudioBufferSink(*graph);
|
auto &buffer_sink = Ffmpeg::MakeAudioBufferSink(*graph);
|
||||||
|
|
||||||
Ffmpeg::FilterInOut io_sink("out", *buffer_sink);
|
Ffmpeg::FilterInOut io_sink("out", buffer_sink);
|
||||||
Ffmpeg::FilterInOut io_src("in", *buffer_src);
|
Ffmpeg::FilterInOut io_src("in", buffer_src);
|
||||||
auto io = graph.Parse(graph_string, std::move(io_sink),
|
auto io = graph.Parse(graph_string, std::move(io_sink),
|
||||||
std::move(io_src));
|
std::move(io_src));
|
||||||
|
|
||||||
@ -62,14 +61,14 @@ PreparedFfmpegFilter::Open(AudioFormat &in_audio_format)
|
|||||||
graph.CheckAndConfigure();
|
graph.CheckAndConfigure();
|
||||||
|
|
||||||
const auto out_audio_format =
|
const auto out_audio_format =
|
||||||
Ffmpeg::DetectFilterOutputFormat(in_audio_format, *buffer_src,
|
Ffmpeg::DetectFilterOutputFormat(in_audio_format, buffer_src,
|
||||||
*buffer_sink);
|
buffer_sink);
|
||||||
|
|
||||||
return std::make_unique<FfmpegFilter>(in_audio_format,
|
return std::make_unique<FfmpegFilter>(in_audio_format,
|
||||||
out_audio_format,
|
out_audio_format,
|
||||||
std::move(graph),
|
std::move(graph),
|
||||||
std::move(buffer_src),
|
buffer_src,
|
||||||
std::move(buffer_sink));
|
buffer_sink);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::unique_ptr<PreparedFilter>
|
static std::unique_ptr<PreparedFilter>
|
||||||
|
@ -42,14 +42,14 @@ OpenHdcdFilter(AudioFormat &in_audio_format)
|
|||||||
{
|
{
|
||||||
Ffmpeg::FilterGraph graph;
|
Ffmpeg::FilterGraph graph;
|
||||||
|
|
||||||
auto buffer_src =
|
auto &buffer_src =
|
||||||
Ffmpeg::FilterContext::MakeAudioBufferSource(in_audio_format,
|
Ffmpeg::MakeAudioBufferSource(in_audio_format,
|
||||||
*graph);
|
*graph);
|
||||||
|
|
||||||
auto buffer_sink = Ffmpeg::FilterContext::MakeAudioBufferSink(*graph);
|
auto &buffer_sink = Ffmpeg::MakeAudioBufferSink(*graph);
|
||||||
|
|
||||||
Ffmpeg::FilterInOut io_sink("out", *buffer_sink);
|
Ffmpeg::FilterInOut io_sink("out", buffer_sink);
|
||||||
Ffmpeg::FilterInOut io_src("in", *buffer_src);
|
Ffmpeg::FilterInOut io_src("in", buffer_src);
|
||||||
|
|
||||||
auto io = graph.Parse(hdcd_graph, std::move(io_sink),
|
auto io = graph.Parse(hdcd_graph, std::move(io_sink),
|
||||||
std::move(io_src));
|
std::move(io_src));
|
||||||
@ -69,8 +69,8 @@ OpenHdcdFilter(AudioFormat &in_audio_format)
|
|||||||
return std::make_unique<FfmpegFilter>(in_audio_format,
|
return std::make_unique<FfmpegFilter>(in_audio_format,
|
||||||
out_audio_format,
|
out_audio_format,
|
||||||
std::move(graph),
|
std::move(graph),
|
||||||
std::move(buffer_src),
|
buffer_src,
|
||||||
std::move(buffer_sink));
|
buffer_sink);
|
||||||
}
|
}
|
||||||
|
|
||||||
class PreparedHdcdFilter final : public PreparedFilter {
|
class PreparedHdcdFilter final : public PreparedFilter {
|
||||||
|
@ -39,9 +39,32 @@ RequireFilterByName(const char *name)
|
|||||||
return *filter;
|
return *filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
FilterContext
|
static AVFilterContext &
|
||||||
FilterContext::MakeAudioBufferSource(AudioFormat &audio_format,
|
CreateFilter(const AVFilter &filt,
|
||||||
AVFilterGraph &graph_ctx)
|
const char *name, const char *args, void *opaque,
|
||||||
|
AVFilterGraph &graph_ctx)
|
||||||
|
{
|
||||||
|
AVFilterContext *context = nullptr;
|
||||||
|
int err = avfilter_graph_create_filter(&context, &filt,
|
||||||
|
name, args, opaque,
|
||||||
|
&graph_ctx);
|
||||||
|
if (err < 0)
|
||||||
|
throw MakeFfmpegError(err, "avfilter_graph_create_filter() failed");
|
||||||
|
|
||||||
|
return *context;
|
||||||
|
}
|
||||||
|
|
||||||
|
static AVFilterContext &
|
||||||
|
CreateFilter(const AVFilter &filt,
|
||||||
|
const char *name,
|
||||||
|
AVFilterGraph &graph_ctx)
|
||||||
|
{
|
||||||
|
return CreateFilter(filt, name, nullptr, nullptr, graph_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
AVFilterContext &
|
||||||
|
MakeAudioBufferSource(AudioFormat &audio_format,
|
||||||
|
AVFilterGraph &graph_ctx)
|
||||||
{
|
{
|
||||||
AVSampleFormat src_format = ToFfmpegSampleFormat(audio_format.format);
|
AVSampleFormat src_format = ToFfmpegSampleFormat(audio_format.format);
|
||||||
if (src_format == AV_SAMPLE_FMT_NONE) {
|
if (src_format == AV_SAMPLE_FMT_NONE) {
|
||||||
@ -66,13 +89,15 @@ FilterContext::MakeAudioBufferSource(AudioFormat &audio_format,
|
|||||||
ToFfmpegChannelLayout(audio_format.channels),
|
ToFfmpegChannelLayout(audio_format.channels),
|
||||||
audio_format.sample_rate);
|
audio_format.sample_rate);
|
||||||
|
|
||||||
return {RequireFilterByName("abuffer"), "abuffer", abuffer_args, nullptr, graph_ctx};
|
return CreateFilter(RequireFilterByName("abuffer"), "abuffer",
|
||||||
|
abuffer_args, nullptr, graph_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
FilterContext
|
AVFilterContext &
|
||||||
FilterContext::MakeAudioBufferSink(AVFilterGraph &graph_ctx)
|
MakeAudioBufferSink(AVFilterGraph &graph_ctx)
|
||||||
{
|
{
|
||||||
return {RequireFilterByName("abuffersink"), "abuffersink", graph_ctx};
|
return CreateFilter(RequireFilterByName("abuffersink"), "abuffersink",
|
||||||
|
graph_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Ffmpeg
|
} // namespace Ffmpeg
|
||||||
|
@ -77,63 +77,21 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class FilterContext {
|
/**
|
||||||
AVFilterContext *context = nullptr;
|
* Create an "abuffer" filter.
|
||||||
|
*
|
||||||
|
* @param the input audio format; may be modified by the
|
||||||
|
* function to ask the caller to do format conversion
|
||||||
|
*/
|
||||||
|
AVFilterContext &
|
||||||
|
MakeAudioBufferSource(AudioFormat &audio_format,
|
||||||
|
AVFilterGraph &graph_ctx);
|
||||||
|
|
||||||
public:
|
/**
|
||||||
FilterContext() = default;
|
* Create an "abuffersink" filter.
|
||||||
|
*/
|
||||||
FilterContext(const AVFilter &filt,
|
AVFilterContext &
|
||||||
const char *name, const char *args, void *opaque,
|
MakeAudioBufferSink(AVFilterGraph &graph_ctx);
|
||||||
AVFilterGraph &graph_ctx) {
|
|
||||||
int err = avfilter_graph_create_filter(&context, &filt,
|
|
||||||
name, args, opaque,
|
|
||||||
&graph_ctx);
|
|
||||||
if (err < 0)
|
|
||||||
throw MakeFfmpegError(err, "avfilter_graph_create_filter() failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
FilterContext(const AVFilter &filt,
|
|
||||||
const char *name,
|
|
||||||
AVFilterGraph &graph_ctx)
|
|
||||||
:FilterContext(filt, name, nullptr, nullptr, graph_ctx) {}
|
|
||||||
|
|
||||||
FilterContext(FilterContext &&src) noexcept
|
|
||||||
:context(std::exchange(src.context, nullptr)) {}
|
|
||||||
|
|
||||||
/* note: we don't need a destructor calling avfilter_free()
|
|
||||||
here because the AVFilterGraph owns and frees all the
|
|
||||||
AVFilterContext instances */
|
|
||||||
// TODO: do we really need this wrapper class anymore?
|
|
||||||
|
|
||||||
FilterContext &operator=(FilterContext &&src) noexcept {
|
|
||||||
using std::swap;
|
|
||||||
swap(context, src.context);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an "abuffer" filter.
|
|
||||||
*
|
|
||||||
* @param the input audio format; may be modified by the
|
|
||||||
* function to ask the caller to do format conversion
|
|
||||||
*/
|
|
||||||
static FilterContext MakeAudioBufferSource(AudioFormat &audio_format,
|
|
||||||
AVFilterGraph &graph_ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an "abuffersink" filter.
|
|
||||||
*/
|
|
||||||
static FilterContext MakeAudioBufferSink(AVFilterGraph &graph_ctx);
|
|
||||||
|
|
||||||
auto &operator*() noexcept {
|
|
||||||
return *context;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto *get() noexcept {
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class FilterGraph {
|
class FilterGraph {
|
||||||
AVFilterGraph *graph = nullptr;
|
AVFilterGraph *graph = nullptr;
|
||||||
|
Loading…
Reference in New Issue
Block a user