Extract VideoFilterGraphSet.
authorCarl Hetherington <cth@carlh.net>
Thu, 6 Oct 2022 21:38:07 +0000 (23:38 +0200)
committerCarl Hetherington <cth@carlh.net>
Tue, 18 Oct 2022 18:25:57 +0000 (20:25 +0200)
src/lib/ffmpeg_decoder.cc
src/lib/ffmpeg_decoder.h
src/lib/video_filter_graph_set.cc [new file with mode: 0644]
src/lib/video_filter_graph_set.h [new file with mode: 0644]
src/lib/wscript

index 986e51ab6c890c32b5305f2113e3aa1f35f2a312..27b7aa7b7514e4cdcc20d9c2c79c0dd87cf873a5 100644 (file)
@@ -77,6 +77,7 @@ using namespace dcpomatic;
 FFmpegDecoder::FFmpegDecoder (shared_ptr<const Film> film, shared_ptr<const FFmpegContent> c, bool fast)
        : FFmpeg (c)
        , Decoder (film)
+       , _filter_graphs(c->filters(), dcp::Fraction(lrint(_ffmpeg_content->video_frame_rate().get_value_or(24) * 1000), 1000))
 {
        if (c->video && c->video->use()) {
                video = make_shared<VideoDecoder>(this, c);
@@ -577,23 +578,7 @@ FFmpegDecoder::decode_and_process_video_packet (AVPacket* packet)
 void
 FFmpegDecoder::process_video_frame ()
 {
-       shared_ptr<VideoFilterGraph> graph;
-
-       auto i = _filter_graphs.begin();
-       while (i != _filter_graphs.end() && !(*i)->can_process(dcp::Size(_video_frame->width, _video_frame->height), (AVPixelFormat) _video_frame->format)) {
-               ++i;
-       }
-
-       if (i == _filter_graphs.end ()) {
-               dcp::Fraction vfr (lrint(_ffmpeg_content->video_frame_rate().get() * 1000), 1000);
-               graph = make_shared<VideoFilterGraph>(dcp::Size(_video_frame->width, _video_frame->height), (AVPixelFormat) _video_frame->format, vfr);
-               graph->setup (_ffmpeg_content->filters ());
-               _filter_graphs.push_back (graph);
-               LOG_GENERAL (N_("New graph for %1x%2, pixel format %3"), _video_frame->width, _video_frame->height, _video_frame->format);
-       } else {
-               graph = *i;
-       }
-
+       auto graph = _filter_graphs.get(dcp::Size(_video_frame->width, _video_frame->height), static_cast<AVPixelFormat>(_video_frame->format));
        auto images = graph->process (_video_frame);
 
        for (auto const& i: images) {
index c6d76f1e8c1f7fe272332ffbbbb9f827aa063966..9de44333ca9267da4b1ef7ffd341b621a0bba37d 100644 (file)
@@ -27,6 +27,7 @@
 #include "bitmap_text.h"
 #include "decoder.h"
 #include "ffmpeg.h"
+#include "video_filter_graph_set.h"
 #include "util.h"
 extern "C" {
 #include <libavcodec/avcodec.h>
@@ -76,7 +77,7 @@ private:
 
        void maybe_add_subtitle ();
 
-       std::list<std::shared_ptr<VideoFilterGraph>> _filter_graphs;
+       VideoFilterGraphSet _filter_graphs;
 
        dcpomatic::ContentTime _pts_offset;
        boost::optional<dcpomatic::ContentTime> _current_subtitle_to;
diff --git a/src/lib/video_filter_graph_set.cc b/src/lib/video_filter_graph_set.cc
new file mode 100644 (file)
index 0000000..dbae17d
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+    Copyright (C) 2022 Carl Hetherington <cth@carlh.net>
+
+    This file is part of DCP-o-matic.
+
+    DCP-o-matic is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    DCP-o-matic is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include "dcpomatic_log.h"
+#include "video_filter_graph.h"
+#include "video_filter_graph_set.h"
+
+#include "i18n.h"
+
+
+using std::make_shared;
+using std::shared_ptr;
+
+
+shared_ptr<VideoFilterGraph>
+VideoFilterGraphSet::get(dcp::Size size, AVPixelFormat format)
+{
+       auto graph = std::find_if(
+               _graphs.begin(),
+               _graphs.end(),
+               [size, format](shared_ptr<VideoFilterGraph> g) {
+                       return g->can_process(size, format);
+               });
+
+       if (graph != _graphs.end()) {
+               return *graph;
+       }
+
+       auto new_graph = make_shared<VideoFilterGraph>(size, format, _frame_rate);
+       new_graph->setup(_filters);
+       _graphs.push_back(new_graph);
+
+       LOG_GENERAL(N_("New graph for %1x%2, pixel format %3"), size.width, size.height, static_cast<int>(format));
+
+       return new_graph;
+}
+
+
+void
+VideoFilterGraphSet::clear()
+{
+       _graphs.clear();
+}
+
diff --git a/src/lib/video_filter_graph_set.h b/src/lib/video_filter_graph_set.h
new file mode 100644 (file)
index 0000000..9353784
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+    Copyright (C) 2022 Carl Hetherington <cth@carlh.net>
+
+    This file is part of DCP-o-matic.
+
+    DCP-o-matic is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    DCP-o-matic is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#ifndef DCPOMATIC_VIDEO_FILTER_GRAPH_SET_H
+#define DCPOMATIC_VIDEO_FILTER_GRAPH_SET_H
+
+
+#include <dcp/types.h>
+extern "C" {
+#include <libavutil/avutil.h>
+}
+#include <memory>
+#include <vector>
+
+
+class Filter;
+class VideoFilterGraph;
+
+
+class VideoFilterGraphSet
+{
+public:
+       VideoFilterGraphSet(std::vector<Filter const*> filters, dcp::Fraction frame_rate)
+               : _filters(filters)
+               , _frame_rate(frame_rate)
+       {}
+
+       VideoFilterGraphSet(VideoFilterGraphSet const&) = delete;
+       VideoFilterGraphSet& operator=(VideoFilterGraphSet const&) = delete;
+
+       std::shared_ptr<VideoFilterGraph> get(dcp::Size size, AVPixelFormat format);
+
+       void clear();
+
+private:
+       std::vector<Filter const*> _filters;
+       dcp::Fraction _frame_rate;
+       std::vector<std::shared_ptr<VideoFilterGraph>> _graphs;
+};
+
+
+#endif
+
index 55c4e735f76e7e2e3344fc41bcfca8e6808ac91f..26fcb21e50e24e975795c5272a5ffcdd6a69eb06 100644 (file)
@@ -194,6 +194,7 @@ sources = """
           video_content.cc
           video_decoder.cc
           video_filter_graph.cc
+          video_filter_graph_set.cc
           video_mxf_content.cc
           video_mxf_decoder.cc
           video_mxf_examiner.cc