{
#ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
- _filters.push_back (new Filter("ebur128", "ebur128", "audio", "ebur128=peak=true"));
+ _filters.push_back({"ebur128", "ebur128", "audio", "ebur128=peak=true"});
_ebur128.setup(_filters);
#endif
}
-AudioAnalyser::~AudioAnalyser ()
-{
- for (auto i: _filters) {
- delete const_cast<Filter*> (i);
- }
-}
-
-
void
AudioAnalyser::analyse (shared_ptr<AudioBuffers> b, DCPTime time)
{
{
public:
AudioAnalyser (std::shared_ptr<const Film> film, std::shared_ptr<const Playlist> playlist, bool from_zero, std::function<void (float)> set_progress);
- ~AudioAnalyser ();
AudioAnalyser (AudioAnalyser const&) = delete;
AudioAnalyser& operator= (AudioAnalyser const&) = delete;
#ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
AudioFilterGraph _ebur128;
#endif
- std::vector<Filter const *> _filters;
+ std::vector<Filter> _filters;
Frame _samples_per_point = 1;
boost::scoped_ptr<leqm_nrt::Calculator> _leqm;
}
for (auto i: node->node_children("Filter")) {
- Filter const * f = Filter::from_id(i->content());
- if (f) {
- _filters.push_back (f);
+ if (auto filter = Filter::from_id(i->content())) {
+ _filters.push_back(*filter);
} else {
notes.push_back (String::compose (_("DCP-o-matic no longer supports the `%1' filter, so it has been turned off."), i->content()));
}
}
for (auto i: _filters) {
- node->add_child("Filter")->add_child_text(i->id());
+ node->add_child("Filter")->add_child_text(i.id());
}
if (_first_video) {
if (examiner->rotation()) {
auto rot = *examiner->rotation ();
if (fabs (rot - 180) < 1.0) {
- _filters.push_back (Filter::from_id ("vflip"));
- _filters.push_back (Filter::from_id ("hflip"));
+ _filters.push_back(*Filter::from_id("vflip"));
+ _filters.push_back(*Filter::from_id("hflip"));
} else if (fabs (rot - 90) < 1.0) {
- _filters.push_back (Filter::from_id ("90clock"));
+ _filters.push_back(*Filter::from_id("90clock"));
} else if (fabs (rot - 270) < 1.0) {
- _filters.push_back (Filter::from_id ("90anticlock"));
+ _filters.push_back(*Filter::from_id("90anticlock"));
}
}
}
void
-FFmpegContent::set_filters (vector<Filter const *> const & filters)
+FFmpegContent::set_filters(vector<Filter> const& filters)
{
ContentChangeSignaller cc (this, FFmpegContentProperty::FILTERS);
}
for (auto i: _filters) {
- s += "_" + i->id();
+ s += "_" + i.id();
}
return s;
*/
+
#ifndef DCPOMATIC_FFMPEG_CONTENT_H
#define DCPOMATIC_FFMPEG_CONTENT_H
-#include "content.h"
+
#include "audio_stream.h"
+#include "content.h"
+#include "filter.h"
+
struct AVFormatContext;
struct AVStream;
-class Filter;
-class FFmpegSubtitleStream;
+
class FFmpegAudioStream;
+class FFmpegSubtitleStream;
+class Filter;
class VideoContent;
struct ffmpeg_pts_offset_test;
struct audio_sampling_rate_test;
+
class FFmpegContentProperty
{
public:
static int const KDM;
};
+
class FFmpegContent : public Content
{
public:
void set_default_colour_conversion ();
- void set_filters (std::vector<Filter const *> const &);
+ void set_filters(std::vector<Filter> const&);
std::vector<std::shared_ptr<FFmpegSubtitleStream>> subtitle_streams () const {
boost::mutex::scoped_lock lm (_mutex);
std::vector<std::shared_ptr<FFmpegAudioStream>> ffmpeg_audio_streams () const;
- std::vector<Filter const *> filters () const {
+ std::vector<Filter> filters() const {
boost::mutex::scoped_lock lm (_mutex);
return _filters;
}
std::shared_ptr<FFmpegSubtitleStream> _subtitle_stream;
boost::optional<dcpomatic::ContentTime> _first_video;
/** Video filters that should be used when generating DCPs */
- std::vector<Filter const *> _filters;
+ std::vector<Filter> _filters;
boost::optional<AVColorRange> _color_range;
boost::optional<AVColorPrimaries> _color_primaries;
*/
+#include "dcpomatic_assert.h"
#include "filter.h"
#include <dcp/warnings.h>
LIBDCP_DISABLE_WARNINGS
#include <libavfilter/avfilter.h>
}
LIBDCP_ENABLE_WARNINGS
+#include <algorithm>
#include "i18n.h"
using namespace std;
+using boost::optional;
vector<Filter> Filter::_filters;
/** @return All available filters */
-vector<Filter const *>
+vector<Filter>
Filter::all ()
{
- vector<Filter const *> raw;
- for (auto& filter: _filters) {
- raw.push_back (&filter);
- }
- return raw;
+ return _filters;
}
* @return String to pass to FFmpeg for the video filters.
*/
string
-Filter::ffmpeg_string (vector<Filter const *> const & filters)
+Filter::ffmpeg_string(vector<Filter> const& filters)
{
string ff;
- for (auto const i: filters) {
+ for (auto const& i: filters) {
if (!ff.empty ()) {
ff += N_(",");
}
- ff += i->ffmpeg ();
+ ff += i.ffmpeg();
}
return ff;
/** @param d Our id.
- * @return Corresponding Filter, or 0.
+ * @return Corresponding Filter, if found.
*/
-Filter const *
-Filter::from_id (string d)
+optional<Filter>
+Filter::from_id(string id)
+{
+ auto iter = std::find_if(_filters.begin(), _filters.end(), [id](Filter const& filter) { return filter.id() == id; });
+ if (iter == _filters.end()) {
+ return {};
+ }
+ return *iter;
+}
+
+
+bool
+operator==(Filter const& a, Filter const& b)
+{
+ return a.id() == b.id() && a.name() == b.name() && a.category() == b.category() && a.ffmpeg() == b.ffmpeg();
+}
+
+
+bool
+operator!=(Filter const& a, Filter const& b)
+{
+ return a.id() != b.id() || a.name() != b.name() || a.category() != b.category() || a.ffmpeg() != b.ffmpeg();
+}
+
+
+bool
+operator<(Filter const& a, Filter const& b)
{
- auto i = _filters.begin ();
- while (i != _filters.end() && i->id() != d) {
- ++i;
+ if (a.id() != b.id()) {
+ return a.id() < b.id();
+ }
+
+ if (a.name() != b.name()) {
+ return a.name() < b.name();
}
- if (i == _filters.end ()) {
- return nullptr;
+ if (a.category() != b.category()) {
+ return a.category() < b.category();
}
- return &(*i);
+ return a.ffmpeg() < b.ffmpeg();
}
#define DCPOMATIC_FILTER_H
+#include <boost/optional.hpp>
#include <string>
#include <vector>
return _category;
}
- static std::vector<Filter const *> all ();
- static Filter const * from_id (std::string d);
+ static std::vector<Filter> all ();
+ static boost::optional<Filter> from_id(std::string d);
static void setup_filters ();
- static std::string ffmpeg_string (std::vector<Filter const *> const & filters);
+ static std::string ffmpeg_string(std::vector<Filter> const& filters);
private:
};
+bool operator==(Filter const& a, Filter const& b);
+bool operator!=(Filter const& a, Filter const& b);
+bool operator<(Filter const& a, Filter const& b);
+
+
#endif
void
-FilterGraph::setup (vector<Filter const *> filters)
+FilterGraph::setup(vector<Filter> const& filters)
{
auto const filters_string = Filter::ffmpeg_string (filters);
if (filters.empty()) {
#define DCPOMATIC_FILTER_GRAPH_H
+#include "filter.h"
#include <dcp/warnings.h>
LIBDCP_DISABLE_WARNINGS
extern "C" {
#include <vector>
+class Filter;
+class Image;
struct AVFilterContext;
struct AVFrame;
-class Image;
-class Filter;
/** @class FilterGraph
FilterGraph (FilterGraph const&) = delete;
FilterGraph& operator== (FilterGraph const&) = delete;
- void setup (std::vector<Filter const *>);
+ void setup(std::vector<Filter> const&);
AVFilterContext* get (std::string name);
protected:
class VideoFilterGraphSet
{
public:
- VideoFilterGraphSet(std::vector<Filter const*> filters, dcp::Fraction frame_rate)
+ VideoFilterGraphSet(std::vector<Filter> const& filters, dcp::Fraction frame_rate)
: _filters(filters)
, _frame_rate(frame_rate)
{}
void clear();
private:
- std::vector<Filter const*> _filters;
+ std::vector<Filter> _filters;
dcp::Fraction _frame_rate;
std::vector<std::shared_ptr<VideoFilterGraph>> _graphs;
};
void
-ContentAdvancedDialog::filters_changed (vector<Filter const *> filters)
+ContentAdvancedDialog::filters_changed(vector<Filter> const& filters)
{
_filters_list = filters;
setup_filters ();
bool ignore_video() const;
- std::vector<Filter const*> filters() {
+ std::vector<Filter> filters() {
return _filters_list;
}
private:
void edit_filters ();
- void filters_changed (std::vector<Filter const *> filters);
+ void filters_changed(std::vector<Filter> const& filters);
void setup_filters ();
void set_video_frame_rate ();
void video_frame_rate_changed ();
std::shared_ptr<Content> _content;
bool _filters_allowed = false;
- std::vector<Filter const*> _filters_list;
+ std::vector<Filter> _filters_list;
wxStaticText* _filters;
wxButton* _filters_button;
using boost::bind;
-FilterDialog::FilterDialog (wxWindow* parent, vector<Filter const *> const & active)
+FilterDialog::FilterDialog(wxWindow* parent, vector<Filter> const& active)
: wxDialog (parent, wxID_ANY, wxString(_("Filters")))
{
auto panel = new wxPanel (this);
auto filters = Filter::all ();
- map<string, list<Filter const *>> categories;
+ map<string, list<Filter>> categories;
for (auto i: filters) {
- auto j = categories.find (i->category());
+ auto j = categories.find(i.category());
if (j == categories.end ()) {
- categories[i->category()] = { i };
+ categories[i.category()] = { i };
} else {
j->second.push_back (i);
}
}
- for (auto const& i: categories) {
- auto c = new StaticText (panel, std_to_wx(i.first));
+ for (auto const& category: categories) {
+ auto c = new StaticText(panel, std_to_wx(category.first));
auto font = c->GetFont();
font.SetWeight(wxFONTWEIGHT_BOLD);
c->SetFont(font);
sizer->Add (c, 1, wxTOP | wxBOTTOM, DCPOMATIC_SIZER_GAP);
- for (auto j: i.second) {
- auto b = new CheckBox(panel, std_to_wx(j->name()));
- bool const a = find (active.begin(), active.end(), j) != active.end();
+ for (auto const& filter: category.second) {
+ auto b = new CheckBox(panel, std_to_wx(filter.name()));
+ bool const a = find(active.begin(), active.end(), filter) != active.end();
b->SetValue (a);
- _filters[j] = b;
+ _filters[filter] = b;
b->bind(&FilterDialog::filter_toggled, this);
sizer->Add (b);
}
}
-vector<Filter const*>
+vector<Filter>
FilterDialog::active () const
{
- vector<Filter const *> active;
+ vector<Filter> active;
for (auto const& i: _filters) {
if (i.second->IsChecked()) {
active.push_back(i.first);
class FilterDialog : public wxDialog
{
public:
- FilterDialog (wxWindow *, std::vector<Filter const *> const &);
+ FilterDialog(wxWindow *, std::vector<Filter> const&);
- boost::signals2::signal<void (std::vector<Filter const *>)> ActiveChanged;
+ boost::signals2::signal<void (std::vector<Filter>)> ActiveChanged;
private:
void active_changed ();
void filter_toggled ();
- std::vector<Filter const *> active () const;
+ std::vector<Filter> active() const;
- std::map<Filter const *, wxCheckBox *> _filters;
+ std::map<Filter, wxCheckBox *> _filters;
};
SimpleVideoView::SimpleVideoView (FilmViewer* viewer, wxWindow* parent)
: VideoView (viewer)
, _rec2020_filter("convert", "convert", "", "colorspace=all=bt709:iall=bt2020")
- , _rec2020_filter_graph({ &_rec2020_filter }, dcp::Fraction(24, 1))
+ , _rec2020_filter_graph({ _rec2020_filter }, dcp::Fraction(24, 1))
{
_panel = new wxPanel (parent);