diff --git a/src/filter/plugins/FfmpegFilter.cxx b/src/filter/plugins/FfmpegFilter.cxx index c42ed1538..7786407fe 100644 --- a/src/filter/plugins/FfmpegFilter.cxx +++ b/src/filter/plugins/FfmpegFilter.cxx @@ -32,12 +32,12 @@ extern "C" { FfmpegFilter::FfmpegFilter(const AudioFormat &in_audio_format, const AudioFormat &_out_audio_format, Ffmpeg::FilterGraph &&_graph, - Ffmpeg::FilterContext &&_buffer_src, - Ffmpeg::FilterContext &&_buffer_sink) noexcept + AVFilterContext &_buffer_src, + AVFilterContext &_buffer_sink) noexcept :Filter(_out_audio_format), graph(std::move(_graph)), - buffer_src(std::move(_buffer_src)), - buffer_sink(std::move(_buffer_sink)), + buffer_src(_buffer_src), + buffer_sink(_buffer_sink), in_format(Ffmpeg::ToFfmpegSampleFormat(in_audio_format.format)), in_sample_rate(in_audio_format.sample_rate), in_channels(in_audio_format.channels), @@ -61,7 +61,7 @@ FfmpegFilter::FilterPCM(ConstBuffer src) 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) throw MakeFfmpegError(err, "av_buffersrc_write_frame() failed"); @@ -69,7 +69,7 @@ FfmpegFilter::FilterPCM(ConstBuffer src) 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 == AVERROR(EAGAIN) || err == AVERROR_EOF) return nullptr; diff --git a/src/filter/plugins/FfmpegFilter.hxx b/src/filter/plugins/FfmpegFilter.hxx index 30e86d2bb..e889eb672 100644 --- a/src/filter/plugins/FfmpegFilter.hxx +++ b/src/filter/plugins/FfmpegFilter.hxx @@ -30,7 +30,7 @@ */ class FfmpegFilter final : public Filter { Ffmpeg::FilterGraph graph; - Ffmpeg::FilterContext buffer_src, buffer_sink; + AVFilterContext &buffer_src, &buffer_sink; Ffmpeg::Frame frame; FfmpegBuffer interleave_buffer; @@ -51,8 +51,8 @@ public: FfmpegFilter(const AudioFormat &in_audio_format, const AudioFormat &_out_audio_format, Ffmpeg::FilterGraph &&_graph, - Ffmpeg::FilterContext &&_buffer_src, - Ffmpeg::FilterContext &&_buffer_sink) noexcept; + AVFilterContext &_buffer_src, + AVFilterContext &_buffer_sink) noexcept; /* virtual methods from class Filter */ ConstBuffer FilterPCM(ConstBuffer src) override; diff --git a/src/filter/plugins/FfmpegFilterPlugin.cxx b/src/filter/plugins/FfmpegFilterPlugin.cxx index e07c50d32..0cbd85821 100644 --- a/src/filter/plugins/FfmpegFilterPlugin.cxx +++ b/src/filter/plugins/FfmpegFilterPlugin.cxx @@ -42,14 +42,13 @@ PreparedFfmpegFilter::Open(AudioFormat &in_audio_format) { Ffmpeg::FilterGraph graph; - auto buffer_src = - Ffmpeg::FilterContext::MakeAudioBufferSource(in_audio_format, - *graph); + auto &buffer_src = + Ffmpeg::MakeAudioBufferSource(in_audio_format, *graph); - auto buffer_sink = Ffmpeg::FilterContext::MakeAudioBufferSink(*graph); + auto &buffer_sink = Ffmpeg::MakeAudioBufferSink(*graph); - Ffmpeg::FilterInOut io_sink("out", *buffer_sink); - Ffmpeg::FilterInOut io_src("in", *buffer_src); + Ffmpeg::FilterInOut io_sink("out", buffer_sink); + Ffmpeg::FilterInOut io_src("in", buffer_src); auto io = graph.Parse(graph_string, std::move(io_sink), std::move(io_src)); @@ -62,14 +61,14 @@ PreparedFfmpegFilter::Open(AudioFormat &in_audio_format) graph.CheckAndConfigure(); const auto out_audio_format = - Ffmpeg::DetectFilterOutputFormat(in_audio_format, *buffer_src, - *buffer_sink); + Ffmpeg::DetectFilterOutputFormat(in_audio_format, buffer_src, + buffer_sink); return std::make_unique(in_audio_format, out_audio_format, std::move(graph), - std::move(buffer_src), - std::move(buffer_sink)); + buffer_src, + buffer_sink); } static std::unique_ptr diff --git a/src/filter/plugins/HdcdFilterPlugin.cxx b/src/filter/plugins/HdcdFilterPlugin.cxx index c632e8d67..a1781f34d 100644 --- a/src/filter/plugins/HdcdFilterPlugin.cxx +++ b/src/filter/plugins/HdcdFilterPlugin.cxx @@ -42,14 +42,14 @@ OpenHdcdFilter(AudioFormat &in_audio_format) { Ffmpeg::FilterGraph graph; - auto buffer_src = - Ffmpeg::FilterContext::MakeAudioBufferSource(in_audio_format, - *graph); + auto &buffer_src = + Ffmpeg::MakeAudioBufferSource(in_audio_format, + *graph); - auto buffer_sink = Ffmpeg::FilterContext::MakeAudioBufferSink(*graph); + auto &buffer_sink = Ffmpeg::MakeAudioBufferSink(*graph); - Ffmpeg::FilterInOut io_sink("out", *buffer_sink); - Ffmpeg::FilterInOut io_src("in", *buffer_src); + Ffmpeg::FilterInOut io_sink("out", buffer_sink); + Ffmpeg::FilterInOut io_src("in", buffer_src); auto io = graph.Parse(hdcd_graph, std::move(io_sink), std::move(io_src)); @@ -69,8 +69,8 @@ OpenHdcdFilter(AudioFormat &in_audio_format) return std::make_unique(in_audio_format, out_audio_format, std::move(graph), - std::move(buffer_src), - std::move(buffer_sink)); + buffer_src, + buffer_sink); } class PreparedHdcdFilter final : public PreparedFilter { diff --git a/src/lib/ffmpeg/Filter.cxx b/src/lib/ffmpeg/Filter.cxx index a91a30a53..c5e7a3a5c 100644 --- a/src/lib/ffmpeg/Filter.cxx +++ b/src/lib/ffmpeg/Filter.cxx @@ -39,9 +39,32 @@ RequireFilterByName(const char *name) return *filter; } -FilterContext -FilterContext::MakeAudioBufferSource(AudioFormat &audio_format, - AVFilterGraph &graph_ctx) +static AVFilterContext & +CreateFilter(const AVFilter &filt, + 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); if (src_format == AV_SAMPLE_FMT_NONE) { @@ -66,13 +89,15 @@ FilterContext::MakeAudioBufferSource(AudioFormat &audio_format, ToFfmpegChannelLayout(audio_format.channels), audio_format.sample_rate); - return {RequireFilterByName("abuffer"), "abuffer", abuffer_args, nullptr, graph_ctx}; + return CreateFilter(RequireFilterByName("abuffer"), "abuffer", + abuffer_args, nullptr, graph_ctx); } -FilterContext -FilterContext::MakeAudioBufferSink(AVFilterGraph &graph_ctx) +AVFilterContext & +MakeAudioBufferSink(AVFilterGraph &graph_ctx) { - return {RequireFilterByName("abuffersink"), "abuffersink", graph_ctx}; + return CreateFilter(RequireFilterByName("abuffersink"), "abuffersink", + graph_ctx); } } // namespace Ffmpeg diff --git a/src/lib/ffmpeg/Filter.hxx b/src/lib/ffmpeg/Filter.hxx index 3cf11546d..0cac102f7 100644 --- a/src/lib/ffmpeg/Filter.hxx +++ b/src/lib/ffmpeg/Filter.hxx @@ -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; - - FilterContext(const AVFilter &filt, - const char *name, const char *args, void *opaque, - 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; - } -}; +/** + * Create an "abuffersink" filter. + */ +AVFilterContext & +MakeAudioBufferSink(AVFilterGraph &graph_ctx); class FilterGraph { AVFilterGraph *graph = nullptr;