Fix a load of stuff that wasn't being freed on close.
authorCarl Hetherington <cth@carlh.net>
Sun, 19 Dec 2021 23:35:11 +0000 (00:35 +0100)
committerCarl Hetherington <cth@carlh.net>
Thu, 28 Apr 2022 22:45:40 +0000 (00:45 +0200)
Nothing really that important, but it cleans up the valgrind
leak check reports.

src/lib/audio_processor.cc
src/lib/audio_processor.h
src/lib/cinema_sound_processor.cc
src/lib/cinema_sound_processor.h
src/lib/dcp_content_type.cc
src/lib/dcp_content_type.h
src/lib/filter.cc
src/lib/filter.h
src/lib/ratio.cc
src/lib/ratio.h
test/ratio_test.cc

index 1eb796b38ef7ce68e5e0169422a65e6ae81dc848..6f3b96145708356438353f16b7b80fe2ab83f86e 100644 (file)
 
 
 using std::string;
-using std::list;
+using std::unique_ptr;
+using std::vector;
 
 
-list<AudioProcessor const *> AudioProcessor::_all;
-list<AudioProcessor const *> AudioProcessor::_non_experimental;
+vector<unique_ptr<const AudioProcessor>> AudioProcessor::_experimental;
+vector<unique_ptr<const AudioProcessor>> AudioProcessor::_non_experimental;
 
 
 void
 AudioProcessor::setup_audio_processors ()
 {
-       auto mid_side = new MidSideDecoder ();
-       _all.push_back (mid_side);
-       _non_experimental.push_back (mid_side);
+       _non_experimental.push_back (unique_ptr<AudioProcessor>(new MidSideDecoder()));
 
-       _all.push_back (new UpmixerA(48000));
-       _all.push_back (new UpmixerB(48000));
+       _experimental.push_back (unique_ptr<AudioProcessor>(new UpmixerA(48000)));
+       _experimental.push_back (unique_ptr<AudioProcessor>(new UpmixerB(48000)));
 }
 
 
 AudioProcessor const *
 AudioProcessor::from_id (string id)
 {
-       for (auto i: _all) {
+       for (auto& i: _non_experimental) {
                if (i->id() == id) {
-                       return i;
+                       return i.get();
+               }
+       }
+
+       for (auto& i: _experimental) {
+               if (i->id() == id) {
+                       return i.get();
                }
        }
 
@@ -59,19 +64,35 @@ AudioProcessor::from_id (string id)
 }
 
 
-list<AudioProcessor const *>
+vector<AudioProcessor const *>
 AudioProcessor::visible ()
 {
+       vector<AudioProcessor const *> raw;
        if (Config::instance()->show_experimental_audio_processors()) {
-               return _all;
+               for (auto& processor: _experimental) {
+                       raw.push_back (processor.get());
+               }
        }
 
-       return _non_experimental;
+       for (auto& processor: _non_experimental) {
+               raw.push_back (processor.get());
+       }
+
+       return raw;
 }
 
 
-list<AudioProcessor const *>
+vector<AudioProcessor const *>
 AudioProcessor::all ()
 {
-       return _all;
+       vector<AudioProcessor const *> raw;
+       for (auto& processor: _experimental) {
+               raw.push_back (processor.get());
+       }
+
+       for (auto& processor: _non_experimental) {
+               raw.push_back (processor.get());
+       }
+
+       return raw;
 }
index ca80c92b2436b8a10009236289713614cea5b554..e24506acdf4dd287d659542e5c6dbac9e0840bcc 100644 (file)
@@ -29,7 +29,7 @@
 
 
 #include "types.h"
-#include <list>
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -65,14 +65,14 @@ public:
        /** @return the user-visible (translated) names of each of our inputs, in order */
        virtual std::vector<NamedChannel> input_names () const = 0;
 
-       static std::list<AudioProcessor const *> all ();
-       static std::list<AudioProcessor const *> visible ();
+       static std::vector<AudioProcessor const *> all ();
+       static std::vector<AudioProcessor const *> visible ();
        static void setup_audio_processors ();
        static AudioProcessor const * from_id (std::string);
 
 private:
-       static std::list<AudioProcessor const *> _all;
-       static std::list<AudioProcessor const *> _non_experimental;
+       static std::vector<std::unique_ptr<const AudioProcessor>> _experimental;
+       static std::vector<std::unique_ptr<const AudioProcessor>> _non_experimental;
 };
 
 
index 1eaf8e1fcd1904e456995190ee690e45daa22241..434fdd1cf6628ae92d79c95cb663c63c5a5390a0 100644 (file)
@@ -36,7 +36,7 @@
 using namespace std;
 
 
-vector<CinemaSoundProcessor const *> CinemaSoundProcessor::_cinema_sound_processors;
+vector<unique_ptr<const CinemaSoundProcessor>> CinemaSoundProcessor::_cinema_sound_processors;
 
 
 /** @param i Our id.
@@ -57,7 +57,11 @@ CinemaSoundProcessor::CinemaSoundProcessor (string i, string n, float knee, floa
 vector<CinemaSoundProcessor const *>
 CinemaSoundProcessor::all ()
 {
-       return _cinema_sound_processors;
+       vector<CinemaSoundProcessor const *> raw;
+       for (auto& processor: _cinema_sound_processors) {
+               raw.push_back (processor.get());
+       }
+       return raw;
 }
 
 
@@ -67,9 +71,9 @@ CinemaSoundProcessor::all ()
 void
 CinemaSoundProcessor::setup_cinema_sound_processors ()
 {
-       _cinema_sound_processors.push_back (new DolbyCP750);
-       _cinema_sound_processors.push_back (new USL);
-       _cinema_sound_processors.push_back (new DatasatAP2x);
+       _cinema_sound_processors.push_back (unique_ptr<CinemaSoundProcessor>(new DolbyCP750));
+       _cinema_sound_processors.push_back (unique_ptr<CinemaSoundProcessor>(new USL));
+       _cinema_sound_processors.push_back (unique_ptr<CinemaSoundProcessor>(new DatasatAP2x));
 }
 
 
@@ -88,26 +92,7 @@ CinemaSoundProcessor::from_id (string id)
                return nullptr;
        }
 
-       return *i;
-}
-
-
-/** @param s A sound processor from our static list.
- *  @return Index of the sound processor with the list, or -1.
- */
-int
-CinemaSoundProcessor::as_index (CinemaSoundProcessor const * s)
-{
-       vector<CinemaSoundProcessor*>::size_type i = 0;
-       while (i < _cinema_sound_processors.size() && _cinema_sound_processors[i] != s) {
-               ++i;
-       }
-
-       if (i == _cinema_sound_processors.size ()) {
-               return -1;
-       }
-
-       return i;
+       return i->get();
 }
 
 
@@ -118,7 +103,7 @@ CinemaSoundProcessor const *
 CinemaSoundProcessor::from_index (int i)
 {
        DCPOMATIC_ASSERT (i >= 0 && i < int(_cinema_sound_processors.size()));
-       return _cinema_sound_processors[i];
+       return _cinema_sound_processors[i].get();
 }
 
 
index ef003da2a3b4834e6c02ae4faf9618df4541c8f9..3ccaa5c9b35c3195603f497bc82f21b1e03c5594 100644 (file)
@@ -29,6 +29,7 @@
 
 
 #include <boost/utility.hpp>
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -64,7 +65,6 @@ public:
        static void setup_cinema_sound_processors ();
        static CinemaSoundProcessor const * from_id (std::string id);
        static CinemaSoundProcessor const * from_index (int);
-       static int as_index (CinemaSoundProcessor const *);
 
 private:
        /** id for our use */
@@ -75,8 +75,8 @@ private:
        float _below;
        float _above;
 
-       /** sll available cinema sound processors */
-       static std::vector<CinemaSoundProcessor const *> _cinema_sound_processors;
+       /** all available cinema sound processors */
+       static std::vector<std::unique_ptr<const CinemaSoundProcessor>> _cinema_sound_processors;
 };
 
 
index 6d7286a488970861930e10a17e1271ebacb001b6..f3cd02e9f2e998c4bf0e1d61ad635bcecbebb19b 100644 (file)
@@ -32,7 +32,7 @@ using boost::optional;
 using namespace std;
 
 
-vector<DCPContentType const *> DCPContentType::_dcp_content_types;
+vector<DCPContentType> DCPContentType::_dcp_content_types;
 
 
 DCPContentType::DCPContentType (string p, dcp::ContentKind k, string d)
@@ -48,18 +48,18 @@ void
 DCPContentType::setup_dcp_content_types ()
 {
        _dcp_content_types = {
-               new DCPContentType(_("Feature"), dcp::ContentKind::FEATURE, N_("FTR")),
-               new DCPContentType(_("Short"), dcp::ContentKind::SHORT, N_("SHR")),
-               new DCPContentType(_("Trailer"), dcp::ContentKind::TRAILER, N_("TLR")),
-               new DCPContentType(_("Test"), dcp::ContentKind::TEST, N_("TST")),
-               new DCPContentType(_("Transitional"), dcp::ContentKind::TRANSITIONAL, N_("XSN")),
-               new DCPContentType(_("Rating"), dcp::ContentKind::RATING, N_("RTG")),
-               new DCPContentType(_("Teaser"), dcp::ContentKind::TEASER, N_("TSR")),
-               new DCPContentType(_("Policy"), dcp::ContentKind::POLICY, N_("POL")),
-               new DCPContentType(_("Public Service Announcement"), dcp::ContentKind::PUBLIC_SERVICE_ANNOUNCEMENT, N_("PSA")),
-               new DCPContentType(_("Advertisement"), dcp::ContentKind::ADVERTISEMENT, N_("ADV")),
-               new DCPContentType(_("Episode"), dcp::ContentKind::EPISODE, N_("EPS")),
-               new DCPContentType(_("Promo"), dcp::ContentKind::PROMO, N_("PRO"))
+               DCPContentType(_("Feature"), dcp::ContentKind::FEATURE, N_("FTR")),
+               DCPContentType(_("Short"), dcp::ContentKind::SHORT, N_("SHR")),
+               DCPContentType(_("Trailer"), dcp::ContentKind::TRAILER, N_("TLR")),
+               DCPContentType(_("Test"), dcp::ContentKind::TEST, N_("TST")),
+               DCPContentType(_("Transitional"), dcp::ContentKind::TRANSITIONAL, N_("XSN")),
+               DCPContentType(_("Rating"), dcp::ContentKind::RATING, N_("RTG")),
+               DCPContentType(_("Teaser"), dcp::ContentKind::TEASER, N_("TSR")),
+               DCPContentType(_("Policy"), dcp::ContentKind::POLICY, N_("POL")),
+               DCPContentType(_("Public Service Announcement"), dcp::ContentKind::PUBLIC_SERVICE_ANNOUNCEMENT, N_("PSA")),
+               DCPContentType(_("Advertisement"), dcp::ContentKind::ADVERTISEMENT, N_("ADV")),
+               DCPContentType(_("Episode"), dcp::ContentKind::EPISODE, N_("EPS")),
+               DCPContentType(_("Promo"), dcp::ContentKind::PROMO, N_("PRO"))
        };
 }
 
@@ -67,22 +67,22 @@ DCPContentType::setup_dcp_content_types ()
 DCPContentType const *
 DCPContentType::from_isdcf_name (string n)
 {
-       for (auto i: _dcp_content_types) {
-               if (i->isdcf_name() == n) {
-                       return i;
+       for (auto& i: _dcp_content_types) {
+               if (i.isdcf_name() == n) {
+                       return &i;
                }
        }
 
-       return 0;
+       return nullptr;
 }
 
 
 DCPContentType const *
 DCPContentType::from_libdcp_kind (dcp::ContentKind kind)
 {
-       for (auto i: _dcp_content_types) {
-               if (i->libdcp_kind() == kind) {
-                       return i;
+       for (auto& i: _dcp_content_types) {
+               if (i.libdcp_kind() == kind) {
+                       return &i;
                }
        }
 
@@ -95,15 +95,15 @@ DCPContentType const *
 DCPContentType::from_index (int n)
 {
        DCPOMATIC_ASSERT (n >= 0 && n < int(_dcp_content_types.size()));
-       return _dcp_content_types[n];
+       return &_dcp_content_types[n];
 }
 
 
 optional<int>
 DCPContentType::as_index (DCPContentType const * c)
 {
-       vector<DCPContentType*>::size_type i = 0;
-       while (i < _dcp_content_types.size() && _dcp_content_types[i] != c) {
+       vector<DCPContentType>::size_type i = 0;
+       while (i < _dcp_content_types.size() && &_dcp_content_types[i] != c) {
                ++i;
        }
 
@@ -118,5 +118,9 @@ DCPContentType::as_index (DCPContentType const * c)
 vector<DCPContentType const *>
 DCPContentType::all ()
 {
-       return _dcp_content_types;
+       vector<DCPContentType const *> raw;
+       for (auto& type: _dcp_content_types) {
+               raw.push_back (&type);
+       }
+       return raw;
 }
index 03a52e57ce00053a0d122b2a9eee93566e22128a..117ff3b16d79a0b3029c3d7ac3a9656fef0ea831 100644 (file)
@@ -41,9 +41,6 @@ class DCPContentType
 public:
        DCPContentType (std::string, dcp::ContentKind, std::string);
 
-       DCPContentType (DCPContentType const&) = delete;
-       DCPContentType& operator= (DCPContentType const&) = delete;
-
        /** @return user-visible `pretty' name */
        std::string pretty_name () const {
                return _pretty_name;
@@ -70,7 +67,7 @@ private:
        std::string _isdcf_name;
 
        /** All available DCP content types */
-       static std::vector<DCPContentType const *> _dcp_content_types;
+       static std::vector<DCPContentType> _dcp_content_types;
 };
 
 
index bb48805e67b2f32d2e0e9e316857a60c49905f97..9158cba5c10b6741995433ea767c2a3899611920 100644 (file)
@@ -38,7 +38,7 @@ LIBDCP_ENABLE_WARNINGS
 using namespace std;
 
 
-vector<Filter const *> Filter::_filters;
+vector<Filter> Filter::_filters;
 
 
 /** @param i Our id.
@@ -60,7 +60,11 @@ Filter::Filter (string i, string n, string c, string f)
 vector<Filter const *>
 Filter::all ()
 {
-       return _filters;
+       vector<Filter const *> raw;
+       for (auto& filter: _filters) {
+               raw.push_back (&filter);
+       }
+       return raw;
 }
 
 
@@ -100,7 +104,7 @@ Filter::maybe_add (string i, string n, string c, string f)
        }
 
        if (avfilter_get_by_name(check_name.c_str())) {
-               _filters.push_back (new Filter(i, n, c, f));
+               _filters.push_back (Filter(i, n, c, f));
        }
 }
 
@@ -131,7 +135,7 @@ Filter const *
 Filter::from_id (string d)
 {
        auto i = _filters.begin ();
-       while (i != _filters.end() && (*i)->id() != d) {
+       while (i != _filters.end() && i->id() != d) {
                ++i;
        }
 
@@ -139,5 +143,5 @@ Filter::from_id (string d)
                return nullptr;
        }
 
-       return *i;
+       return &(*i);
 }
index 3c2a49792d97ac197439b477164304e162eac94c..f73a954538350d18a287582eddc643996baa96d5 100644 (file)
@@ -44,9 +44,6 @@ class Filter
 public:
        Filter (std::string i, std::string n, std::string c, std::string f);
 
-       Filter (Filter const&) = delete;
-       Filter& operator= (Filter const&) = delete;
-
        /** @return our id */
        std::string id () const {
                return _id;
@@ -82,7 +79,7 @@ private:
        std::string _ffmpeg;
 
        /** all available filters */
-       static std::vector<Filter const *> _filters;
+       static std::vector<Filter> _filters;
        static void maybe_add (std::string, std::string, std::string, std::string);
 };
 
index 5ba79c28b7a8f48ad826a4f33ba608fc98dc4e69..5f1a3aa63d31a98a9b6afa441e86d84140b6f455 100644 (file)
@@ -33,22 +33,36 @@ using std::vector;
 using boost::optional;
 
 
-vector<Ratio const *> Ratio::_ratios;
+vector<Ratio> Ratio::_ratios;
 
 
 void
 Ratio::setup_ratios ()
 {
-       _ratios.push_back (new Ratio(float(1290) / 1080, "119", _("1.19"),              optional<string>(),      "119"));
-       _ratios.push_back (new Ratio(float(1440) / 1080, "133", _("1.33 (4:3)"),        optional<string>(),      "133"));
-       _ratios.push_back (new Ratio(float(1485) / 1080, "138", _("1.38 (Academy)"),    optional<string>(),      "137"));
-       _ratios.push_back (new Ratio(float(1544) / 1080, "143", _("1.43 (IMAX)"),       optional<string>(),      "143"));
-       _ratios.push_back (new Ratio(float(1800) / 1080, "166", _("1.66"),              optional<string>(),      "166"));
-       _ratios.push_back (new Ratio(float(1920) / 1080, "178", _("1.78 (16:9 or HD)"), optional<string>(),      "178"));
-       _ratios.push_back (new Ratio(float(1998) / 1080, "185", _("1.85 (Flat)"),       string(_("DCI Flat")),   "F"));
-       _ratios.push_back (new Ratio(float(2048) /  872, "235", _("2.35 (35mm Scope)"), optional<string>(),      "S"));
-       _ratios.push_back (new Ratio(float(2048) /  858, "239", _("2.39 (Scope)"),      string(_("DCI Scope")),  "S"));
-       _ratios.push_back (new Ratio(float(2048) / 1080, "190", _("1.90 (Full frame)"), string(_("Full frame")), "C"));
+       /* This must only be called once as we rely on the addresses of objects in _ratios staying the same */
+       DCPOMATIC_ASSERT (_ratios.empty());
+
+       _ratios.push_back (Ratio(float(1290) / 1080, "119", _("1.19"),              {},                      "119"));
+       _ratios.push_back (Ratio(float(1440) / 1080, "133", _("1.33 (4:3)"),        {},                      "133"));
+       _ratios.push_back (Ratio(float(1485) / 1080, "138", _("1.38 (Academy)"),    {},                      "137"));
+       _ratios.push_back (Ratio(float(1544) / 1080, "143", _("1.43 (IMAX)"),       {},                      "143"));
+       _ratios.push_back (Ratio(float(1800) / 1080, "166", _("1.66"),              {},                      "166"));
+       _ratios.push_back (Ratio(float(1920) / 1080, "178", _("1.78 (16:9 or HD)"), {},                      "178"));
+       _ratios.push_back (Ratio(float(1998) / 1080, "185", _("1.85 (Flat)"),       string(_("DCI Flat")),   "F"));
+       _ratios.push_back (Ratio(float(2048) /  872, "235", _("2.35 (35mm Scope)"), {},                      "S"));
+       _ratios.push_back (Ratio(float(2048) /  858, "239", _("2.39 (Scope)"),      string(_("DCI Scope")),  "S"));
+       _ratios.push_back (Ratio(float(2048) / 1080, "190", _("1.90 (Full frame)"), string(_("Full frame")), "C"));
+}
+
+
+vector<Ratio const *>
+Ratio::all ()
+{
+       vector<Ratio const *> pointers;
+       for (Ratio& ratio: _ratios) {
+               pointers.push_back (&ratio);
+       }
+       return pointers;
 }
 
 
@@ -61,15 +75,15 @@ Ratio::from_id (string i)
        }
 
        auto j = _ratios.begin ();
-       while (j != _ratios.end() && (*j)->id() != i) {
+       while (j != _ratios.end() && j->id() != i) {
                ++j;
        }
 
-       if (j == _ratios.end ()) {
-               return 0;
+       if (j == _ratios.end()) {
+               return nullptr;
        }
 
-       return *j;
+       return &(*j);
 }
 
 
@@ -78,7 +92,7 @@ Ratio const *
 Ratio::from_ratio (float r)
 {
        auto j = _ratios.begin ();
-       while (j != _ratios.end() && fabs((*j)->ratio() - r) > 0.01) {
+       while (j != _ratios.end() && fabs(j->ratio() - r) > 0.01) {
                ++j;
        }
 
@@ -86,32 +100,34 @@ Ratio::from_ratio (float r)
                return nullptr;
        }
 
-       return *j;
+       return &(*j);
 }
 
 
 Ratio const *
 Ratio::nearest_from_ratio (float r)
 {
-       Ratio const * nearest = nullptr;
+       vector<Ratio>::const_iterator nearest = _ratios.end();
        float distance = FLT_MAX;
 
        for (auto i = _ratios.begin(); i != _ratios.end(); ++i) {
-               float const d = fabs((*i)->ratio() - r);
+               float const d = fabs(i->ratio() - r);
                if (d < distance) {
                        distance = d;
-                       nearest = *i;
+                       nearest = i;
                }
        }
 
-       return nearest;
+       DCPOMATIC_ASSERT (nearest != _ratios.end());
+
+       return &(*nearest);
 }
 
 vector<Ratio const *>
 Ratio::containers ()
 {
        if (Config::instance()->allow_any_container()) {
-               return _ratios;
+               return all();
        }
 
        vector<Ratio const *> r;
index 016a22edca438460a13ccdb8e249ebb33b9cadcb..31ff0935896c4f40a1e82a37e4852263d0055a13 100644 (file)
@@ -42,9 +42,6 @@ public:
                , _isdcf_name (d)
        {}
 
-       Ratio (Ratio const&) = delete;
-       Ratio& operator= (Ratio const&) = delete;
-
        std::string id () const {
                return _id;
        }
@@ -72,9 +69,7 @@ public:
        static Ratio const * from_ratio (float r);
        static Ratio const * nearest_from_ratio (float r);
 
-       static std::vector<Ratio const *> all () {
-               return _ratios;
-       }
+       static std::vector<Ratio const *> all ();
 
        static std::vector<Ratio const *> containers ();
 
@@ -88,7 +83,7 @@ private:
        boost::optional<std::string> _container_nickname;
        std::string _isdcf_name;
 
-       static std::vector<Ratio const *> _ratios;
+       static std::vector<Ratio> _ratios;
 };
 
 
index 1e8d5433358db19dca2015ca2ff22735b61e4171..a21859049823cb9cc07db48ed223b4d0c53a8623 100644 (file)
@@ -34,8 +34,6 @@ using std::ostream;
 
 BOOST_AUTO_TEST_CASE (ratio_test)
 {
-       Ratio::setup_ratios ();
-
        Ratio const * r = Ratio::from_id ("119");
        BOOST_CHECK (r);
        BOOST_CHECK_EQUAL (fit_ratio_within (r->ratio(), dcp::Size (2048, 1080)), dcp::Size (1290, 1080));
@@ -68,3 +66,10 @@ BOOST_AUTO_TEST_CASE (ratio_test)
        BOOST_CHECK (r);
        BOOST_CHECK_EQUAL (fit_ratio_within (r->ratio(), dcp::Size (2048, 1080)), dcp::Size (2048, 1080));
 }
+
+
+BOOST_AUTO_TEST_CASE (ratios_use_same_pointers_test)
+{
+       auto const test = Ratio::from_id ("119");
+       BOOST_CHECK_EQUAL (test, Ratio::from_id("119"));
+}