Bump libdcp for better verification, and make API adjustments.
authorCarl Hetherington <cth@carlh.net>
Wed, 20 Jan 2021 22:42:28 +0000 (23:42 +0100)
committerCarl Hetherington <cth@carlh.net>
Wed, 20 Jan 2021 22:42:28 +0000 (23:42 +0100)
25 files changed:
cscript
src/lib/dcp.cc
src/lib/dcp_decoder.cc
src/lib/dcp_decoder.h
src/lib/dcp_examiner.cc
src/lib/dcp_subtitle_decoder.cc
src/lib/dcp_subtitle_decoder.h
src/lib/hints.cc
src/lib/reel_writer.cc
src/lib/types.cc
src/lib/types.h
src/lib/verify_dcp_job.h
src/tools/dcpomatic_player.cc
src/wx/content_menu.cc
src/wx/kdm_cpl_panel.cc
src/wx/markers_dialog.cc
src/wx/verify_dcp_dialog.cc
src/wx/verify_dcp_dialog.h
test/closed_caption_test.cc
test/dcp_decoder_test.cc
test/digest_test.cc
test/import_dcp_test.cc
test/reels_test.cc
test/subtitle_reel_test.cc
test/torture_test.cc

diff --git a/cscript b/cscript
index 5fb075c5e6463ad558483ad6df03dbf630134579..302fad69f08d43486d7ab9e30aea7cff513c127f 100644 (file)
--- a/cscript
+++ b/cscript
@@ -370,8 +370,8 @@ def dependencies(target, options):
         # Use distro-provided FFmpeg on Arch
         deps = []
 
-    deps.append(('libdcp', 'b221efe'))
-    deps.append(('libsub', '6a05977'))
+    deps.append(('libdcp', '6c3db78'))
+    deps.append(('libsub', '5b0e2db'))
     deps.append(('leqm-nrt', '131f971'))
     deps.append(('rtaudio', 'f619b76'))
     # We get our OpenSSL libraries from the environment, but we
index 421dbbf83b605fd23efa3aa4278e467af9a69a55..05b71557e42c600f50b9e1d3dc48dc8bfd8acf26 100644 (file)
 using std::list;
 using std::string;
 using std::shared_ptr;
+using std::make_shared;
 using std::dynamic_pointer_cast;
+using std::vector;
 
 
 /** Find all the CPLs in our directories, cross-add assets and return the CPLs */
 list<shared_ptr<dcp::CPL> >
 DCP::cpls () const
 {
-       list<shared_ptr<dcp::DCP> > dcps;
-       list<shared_ptr<dcp::CPL> > cpls;
+       list<shared_ptr<dcp::DCP>> dcps;
+       list<shared_ptr<dcp::CPL>> cpls;
 
        LOG_GENERAL ("Reading %1 DCP directories", _dcp_content->directories().size());
        for (auto i: _dcp_content->directories()) {
-               shared_ptr<dcp::DCP> dcp (new dcp::DCP (i));
-               list<dcp::VerificationNote> notes;
+               auto dcp = make_shared<dcp::DCP>(i);
+               vector<dcp::VerificationNote> notes;
                dcp->read (&notes, true);
                if (!_tolerant) {
                        /** We accept and ignore EMPTY_ASSET_PATH and EXTERNAL_ASSET but everything else is bad */
index 71eb0bae0b04503fe23935d915cb4be39d3e05b1..4bc090bf4981c622c8a124fe596e57cc3f80c2c0 100644 (file)
@@ -280,7 +280,7 @@ DCPDecoder::pass_texts (
        int64_t const frame = next.frames_round (vfr);
 
        if (_decode_referenced || !reference) {
-               list<shared_ptr<dcp::Subtitle> > subs = asset->subtitles_during (
+               auto subs = asset->subtitles_during (
                        dcp::Time (entry_point + frame, vfr, vfr),
                        dcp::Time (entry_point + frame + 1, vfr, vfr),
                        true
@@ -289,10 +289,10 @@ DCPDecoder::pass_texts (
                list<dcp::SubtitleString> strings;
 
                for (auto i: subs) {
-                       shared_ptr<dcp::SubtitleString> is = dynamic_pointer_cast<dcp::SubtitleString> (i);
+                       auto is = dynamic_pointer_cast<const dcp::SubtitleString>(i);
                        if (is) {
                                if (!strings.empty() && (strings.back().in() != is->in() || strings.back().out() != is->out())) {
-                                       dcp::SubtitleString b = strings.back();
+                                       auto b = strings.back();
                                        decoder->emit_plain (
                                                ContentTimePeriod (
                                                        ContentTime::from_frames(_offset - entry_point, vfr) + ContentTime::from_seconds(b.in().as_seconds()),
@@ -310,7 +310,7 @@ DCPDecoder::pass_texts (
                           this would need to be done both here and in DCPSubtitleDecoder.
                        */
 
-                       shared_ptr<dcp::SubtitleImage> ii = dynamic_pointer_cast<dcp::SubtitleImage> (i);
+                       auto ii = dynamic_pointer_cast<const dcp::SubtitleImage>(i);
                        if (ii) {
                                emit_subtitle_image (
                                        ContentTimePeriod (
@@ -325,7 +325,7 @@ DCPDecoder::pass_texts (
                }
 
                if (!strings.empty()) {
-                       dcp::SubtitleString b = strings.back();
+                       auto b = strings.back();
                        decoder->emit_plain (
                                ContentTimePeriod (
                                        ContentTime::from_frames(_offset - entry_point, vfr) + ContentTime::from_seconds(b.in().as_seconds()),
index 553f05aedc433610b4c41f189a728c7cc5f65fdf..887f8ad5ccaa2a4bbb0ad217bc33a53ea94d4027 100644 (file)
@@ -49,7 +49,7 @@ public:
                std::shared_ptr<DCPDecoder> old
                );
 
-       std::list<std::shared_ptr<dcp::Reel> > reels () const {
+       std::vector<std::shared_ptr<dcp::Reel>> reels () const {
                return _reels;
        }
 
@@ -85,9 +85,9 @@ private:
 
        /** Time of next thing to return from pass relative to the start of _reel */
        dcpomatic::ContentTime _next;
-       std::list<std::shared_ptr<dcp::Reel> > _reels;
+       std::vector<std::shared_ptr<dcp::Reel>> _reels;
 
-       std::list<std::shared_ptr<dcp::Reel> >::iterator _reel;
+       std::vector<std::shared_ptr<dcp::Reel>>::iterator _reel;
        /** Offset of _reel from the start of the content in frames */
        int64_t _offset;
        /** Reader for current mono picture asset, if applicable */
index 191022f1227666985eb3878b21937107153013d8..d0c3d1021eb1e5f4ee4f9ff95af596c4c32aa795 100644 (file)
@@ -219,7 +219,7 @@ DCPExaminer::DCPExaminer (shared_ptr<const DCPContent> content, bool tolerant)
                }
        }
 
-       _encrypted = cpl->encrypted ();
+       _encrypted = cpl->any_encrypted ();
        _kdm_valid = true;
 
        /* Check that we can read the first picture, sound and subtitle frames of each reel */
index 5372df0a57ab3cb35a8bebd13278e0720b9a029c..1b144f20456bec9e3d928851632f70b958e85314 100644 (file)
@@ -67,7 +67,7 @@ DCPSubtitleDecoder::seek (ContentTime time, bool accurate)
        Decoder::seek (time, accurate);
 
        _next = _subtitles.begin ();
-       list<shared_ptr<dcp::Subtitle> >::const_iterator i = _subtitles.begin ();
+       auto i = _subtitles.begin ();
        while (i != _subtitles.end() && ContentTime::from_seconds ((*_next)->in().as_seconds()) < time) {
                ++i;
        }
@@ -92,7 +92,7 @@ DCPSubtitleDecoder::pass ()
        ContentTimePeriod const p = content_time_period (*_next);
 
        while (_next != _subtitles.end () && content_time_period (*_next) == p) {
-               shared_ptr<dcp::SubtitleString> ns = dynamic_pointer_cast<dcp::SubtitleString>(*_next);
+               auto ns = dynamic_pointer_cast<const dcp::SubtitleString>(*_next);
                if (ns) {
                        s.push_back (*ns);
                        ++_next;
@@ -101,7 +101,7 @@ DCPSubtitleDecoder::pass ()
                           this would need to be done both here and in DCPDecoder.
                        */
 
-                       shared_ptr<dcp::SubtitleImage> ni = dynamic_pointer_cast<dcp::SubtitleImage>(*_next);
+                       auto ni = dynamic_pointer_cast<const dcp::SubtitleImage>(*_next);
                        if (ni) {
                                emit_subtitle_image (p, *ni, film()->frame_size(), only_text());
                                ++_next;
@@ -114,12 +114,12 @@ DCPSubtitleDecoder::pass ()
 }
 
 ContentTimePeriod
-DCPSubtitleDecoder::content_time_period (shared_ptr<dcp::Subtitle> s) const
+DCPSubtitleDecoder::content_time_period (shared_ptr<const dcp::Subtitle> s) const
 {
-       return ContentTimePeriod (
-               ContentTime::from_seconds (s->in().as_seconds ()),
-               ContentTime::from_seconds (s->out().as_seconds ())
-               );
+       return {
+               ContentTime::from_seconds(s->in().as_seconds()),
+               ContentTime::from_seconds(s->out().as_seconds())
+       };
 }
 
 
index 31b8e6a8e557656e040ab4746a22855074b54869..a9540c3cf05e6896901683d1eaf5c9a20f770889 100644 (file)
@@ -35,10 +35,10 @@ public:
        std::vector<dcpomatic::FontData> fonts () const;
 
 private:
-       dcpomatic::ContentTimePeriod content_time_period (std::shared_ptr<dcp::Subtitle> s) const;
+       dcpomatic::ContentTimePeriod content_time_period (std::shared_ptr<const dcp::Subtitle> s) const;
 
-       std::list<std::shared_ptr<dcp::Subtitle> > _subtitles;
-       std::list<std::shared_ptr<dcp::Subtitle> >::const_iterator _next;
+       std::vector<std::shared_ptr<const dcp::Subtitle>> _subtitles;
+       std::vector<std::shared_ptr<const dcp::Subtitle>>::const_iterator _next;
 
        std::vector<dcpomatic::FontData> _fonts;
 };
index ca697ad74a8fc8abbaebe3b17521463b4ab1f68c..58d33204c3b25bde24964b58fd35a447ea2a8321 100644 (file)
@@ -534,7 +534,7 @@ void
 Hints::check_ffec_and_ffmc_in_smpte_feature ()
 {
        shared_ptr<const Film> f = film();
-       if (!f->interop() && f->dcp_content_type()->libdcp_kind() == dcp::FEATURE && (!f->marker(dcp::FFEC) || !f->marker(dcp::FFMC))) {
+       if (!f->interop() && f->dcp_content_type()->libdcp_kind() == dcp::FEATURE && (!f->marker(dcp::Marker::FFEC) || !f->marker(dcp::Marker::FFMC))) {
                hint (_("SMPTE DCPs with the type FTR (feature) should have markers for the first frame of end credits (FFEC) and the first frame of moving credits (FFMC).  You should add these markers using the 'Markers' button in the DCP tab."));
        }
 }
index b81c225c276517ee0e6e7b17c2cc255684f4d381..8be31d09b9e4183d3f77f77b6a4e0cb62e4fdb00 100644 (file)
@@ -62,6 +62,7 @@ using std::map;
 using std::set;
 using std::vector;
 using std::shared_ptr;
+using std::make_shared;
 using boost::optional;
 using std::dynamic_pointer_cast;
 #if BOOST_VERSION >= 106100
@@ -690,7 +691,7 @@ ReelWriter::create_reel_markers (shared_ptr<dcp::Reel> reel) const
        }
 
        if (!reel_markers.empty ()) {
-               shared_ptr<dcp::ReelMarkersAsset> ma (new dcp::ReelMarkersAsset(dcp::Fraction(film()->video_frame_rate(), 1), 0));
+               auto ma = make_shared<dcp::ReelMarkersAsset>(dcp::Fraction(film()->video_frame_rate(), 1), reel->duration(), 0);
                for (map<dcp::Marker, DCPTime>::const_iterator i = reel_markers.begin(); i != reel_markers.end(); ++i) {
                        int h, m, s, f;
                        DCPTime relative = i->second - _period.from;
index 68d97b8ff614b84617fc1779e9747da5ebf54b47..9aba915e80f56b8976abe566c0a823d6be531e72 100644 (file)
@@ -39,6 +39,7 @@ using std::min;
 using std::string;
 using std::list;
 using std::shared_ptr;
+using std::vector;
 using dcp::raw_convert;
 
 bool operator== (Crop const & a, Crop const & b)
@@ -197,7 +198,7 @@ CPLSummary::CPLSummary (boost::filesystem::path p)
 {
        dcp::DCP dcp (p);
 
-       list<dcp::VerificationNote> notes;
+       vector<dcp::VerificationNote> notes;
        dcp.read (&notes);
        for (auto i: notes) {
                if (i.code() != dcp::VerificationNote::EXTERNAL_ASSET) {
index 87b3fc753b36fcc19e3a05fbdadd218184afc56f..f8f23a300c87d2dc5a38ac6b27306e4724653b08 100644 (file)
@@ -236,7 +236,7 @@ struct CPLSummary
 
        std::string dcp_directory;
        std::string cpl_id;
-       std::string cpl_annotation_text;
+       boost::optional<std::string> cpl_annotation_text;
        boost::filesystem::path cpl_file;
        /** true if this CPL has any encrypted assets */
        bool encrypted;
index ab33b4f559dfd0b180ec19644e3ff3a95ff11c57..3372cd6023b57437f0d308789c1583d1133a1404 100644 (file)
@@ -33,7 +33,7 @@ public:
        std::string json_name () const;
        void run ();
 
-       std::list<dcp::VerificationNote> notes () const {
+       std::vector<dcp::VerificationNote> notes () const {
                return _notes;
        }
 
@@ -41,5 +41,5 @@ private:
        void update_stage (std::string s, boost::optional<boost::filesystem::path> path);
 
        std::vector<boost::filesystem::path> _directories;
-       std::list<dcp::VerificationNote> _notes;
+       std::vector<dcp::VerificationNote> _notes;
 };
index 0586db9755dc2d7577f84c105ceab053c694788f..c6c4c0878b346a5edf7bea27d65426758d8add27 100644 (file)
@@ -315,7 +315,7 @@ public:
                                        "playback-started %s %s %s",
                                        time.timecode(_film->video_frame_rate()).c_str(),
                                        dcp->directories().front().string().c_str(),
-                                       playing_cpl->annotation_text().c_str()
+                                       playing_cpl->annotation_text().get_value_or("").c_str()
                                        )
                                );
                }
@@ -455,7 +455,7 @@ public:
                                for (auto i: ex.cpls()) {
                                        wxMenuItem* j = _cpl_menu->AppendRadioItem(
                                                id,
-                                               wxString::Format("%s (%s)", std_to_wx(i->annotation_text()).data(), std_to_wx(i->id()).data())
+                                               wxString::Format("%s (%s)", std_to_wx(i->annotation_text().get_value_or("")).data(), std_to_wx(i->id()).data())
                                                );
                                        j->Check(!first->cpl() || i->id() == *first->cpl());
                                        ++id;
@@ -532,7 +532,7 @@ private:
                view->AppendRadioItem(ID_view_scale_quarter, _("Decode at quarter resolution"))->Check(c && c.get() == 2);
 
                wxMenu* tools = new wxMenu;
-               _tools_verify = tools->Append (ID_tools_verify, _("Verify DCP"));
+               _tools_verify = tools->Append (ID_tools_verify, _("Verify DCP..."));
                tools->AppendSeparator ();
                tools->Append (ID_tools_check_for_updates, _("Check for updates"));
                tools->Append (ID_tools_timing, _("Timing..."));
index d93fd31b2ce023c6730c7ba67d46389c711281ae..1ac13b143356b5fea68f7e8d101eb9f236df3c20 100644 (file)
@@ -142,7 +142,7 @@ ContentMenu::popup (weak_ptr<Film> film, ContentList c, TimelineContentViewList
                        _set_dcp_settings->Enable (static_cast<bool>(dcp));
                        try {
                                DCPExaminer ex (dcp, true);
-                               list<shared_ptr<dcp::CPL> > cpls = ex.cpls ();
+                               auto cpls = ex.cpls ();
                                _choose_cpl->Enable (cpls.size() > 1);
                                /* We can't have 0 as a menu item ID on OS X */
                                int id = 1;
@@ -151,7 +151,7 @@ ContentMenu::popup (weak_ptr<Film> film, ContentList c, TimelineContentViewList
                                                id++,
                                                wxString::Format (
                                                        "%s (%s)",
-                                                       std_to_wx(i->annotation_text()).data(),
+                                                       std_to_wx(i->annotation_text().get_value_or("")).data(),
                                                        std_to_wx(i->id()).data()
                                                        )
                                                );
index be5e42dd8b9458a490b967027928c9982ffd5d6d..8bb73f783a473346a84463355eef96eabb182a00 100644 (file)
@@ -92,7 +92,7 @@ KDMCPLPanel::update_cpl_summary ()
 
        _dcp_directory->SetLabel (std_to_wx (_cpls[n].dcp_directory));
        _cpl_id->SetLabel (std_to_wx (_cpls[n].cpl_id));
-       _cpl_annotation_text->SetLabel (std_to_wx (_cpls[n].cpl_annotation_text));
+       _cpl_annotation_text->SetLabel (std_to_wx(_cpls[n].cpl_annotation_text.get_value_or("")));
 }
 
 void
index 31789af2cca675bf190f746cce83afe7f33dba33..7f675f2150e6efdce66080609227800f5574cafa 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2019 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2019-2021 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
 #include <iostream>
 
 using std::cout;
-using boost::bind;
 using std::shared_ptr;
 using std::weak_ptr;
+using std::make_shared;
 using boost::optional;
+using boost::bind;
 using dcpomatic::DCPTime;
 
 class Marker
@@ -113,16 +114,16 @@ MarkersDialog::MarkersDialog (wxWindow* parent, weak_ptr<Film> film, weak_ptr<Fi
        wxGridBagSizer* grid = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
 
        int r = 0;
-       _markers.push_back (shared_ptr<Marker>(new Marker(this, grid, r++, film, viewer, _("First frame of composition"), dcp::FFOC)));
-       _markers.push_back (shared_ptr<Marker>(new Marker(this, grid, r++, film, viewer, _("Last frame of composition"), dcp::LFOC)));
-       _markers.push_back (shared_ptr<Marker>(new Marker(this, grid, r++, film, viewer, _("First frame of title credits"), dcp::FFTC)));
-       _markers.push_back (shared_ptr<Marker>(new Marker(this, grid, r++, film, viewer, _("Last frame of title credits"), dcp::LFTC)));
-       _markers.push_back (shared_ptr<Marker>(new Marker(this, grid, r++, film, viewer, _("First frame of intermission"), dcp::FFOI)));
-       _markers.push_back (shared_ptr<Marker>(new Marker(this, grid, r++, film, viewer, _("Last frame of intermission"), dcp::LFOI)));
-       _markers.push_back (shared_ptr<Marker>(new Marker(this, grid, r++, film, viewer, _("First frame of end credits"), dcp::FFEC)));
-       _markers.push_back (shared_ptr<Marker>(new Marker(this, grid, r++, film, viewer, _("Last frame of end credits"), dcp::LFEC)));
-       _markers.push_back (shared_ptr<Marker>(new Marker(this, grid, r++, film, viewer, _("First frame of moving credits"), dcp::FFMC)));
-       _markers.push_back (shared_ptr<Marker>(new Marker(this, grid, r++, film, viewer, _("Last frame of moving credits"), dcp::LFMC)));
+       _markers.push_back (make_shared<Marker>(this, grid, r++, film, viewer, _("First frame of composition"), dcp::Marker::FFOC));
+       _markers.push_back (make_shared<Marker>(this, grid, r++, film, viewer, _("Last frame of composition"), dcp::Marker::LFOC));
+       _markers.push_back (make_shared<Marker>(this, grid, r++, film, viewer, _("First frame of title credits"), dcp::Marker::FFTC));
+       _markers.push_back (make_shared<Marker>(this, grid, r++, film, viewer, _("Last frame of title credits"), dcp::Marker::LFTC));
+       _markers.push_back (make_shared<Marker>(this, grid, r++, film, viewer, _("First frame of intermission"), dcp::Marker::FFOI));
+       _markers.push_back (make_shared<Marker>(this, grid, r++, film, viewer, _("Last frame of intermission"), dcp::Marker::LFOI));
+       _markers.push_back (make_shared<Marker>(this, grid, r++, film, viewer, _("First frame of end credits"), dcp::Marker::FFEC));
+       _markers.push_back (make_shared<Marker>(this, grid, r++, film, viewer, _("Last frame of end credits"), dcp::Marker::LFEC));
+       _markers.push_back (make_shared<Marker>(this, grid, r++, film, viewer, _("First frame of moving credits"), dcp::Marker::FFMC));
+       _markers.push_back (make_shared<Marker>(this, grid, r++, film, viewer, _("Last frame of moving credits"), dcp::Marker::LFMC));
 
        sizer->Add (grid, 0, wxALL, 8);
        SetSizerAndFit (sizer);
index 55360dc39353f8cfe61cc3ff62178b6aaf390cdc..50fd4be0cbac32a03774e390e611a5cd1bb3e933 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2018-2021 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
 #include "lib/verify_dcp_job.h"
 #include "lib/warnings.h"
 #include <dcp/verify.h>
+#include <dcp/raw_convert.h>
 DCPOMATIC_DISABLE_WARNINGS
 #include <wx/richtext/richtextctrl.h>
+#include <wx/notebook.h>
 DCPOMATIC_ENABLE_WARNINGS
 
 using std::list;
+using std::map;
 using std::shared_ptr;
+using std::string;
 
 VerifyDCPDialog::VerifyDCPDialog (wxWindow* parent, shared_ptr<VerifyDCPJob> job)
-       : wxDialog (parent, wxID_ANY, _("DCP verification"))
+       : wxDialog (parent, wxID_ANY, _("DCP verification"), wxDefaultPosition, {600, 400})
 {
-       wxBoxSizer* sizer = new wxBoxSizer (wxVERTICAL);
-       _text = new wxRichTextCtrl (this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (400, 300), wxRE_READONLY);
-       sizer->Add (_text, 1, wxEXPAND | wxALL, 6);
+       auto sizer = new wxBoxSizer (wxVERTICAL);
+       auto notebook = new wxNotebook (this, wxID_ANY);
+       sizer->Add (notebook, 1, wxEXPAND | wxALL, DCPOMATIC_DIALOG_BORDER);
 
-       wxStdDialogButtonSizer* buttons = CreateStdDialogButtonSizer (0);
+       map<dcp::VerificationNote::Type, wxRichTextCtrl*> pages;
+       pages[dcp::VerificationNote::VERIFY_ERROR] = new wxRichTextCtrl (notebook, wxID_ANY, wxEmptyString, wxDefaultPosition, {400, 300}, wxRE_READONLY);
+       notebook->AddPage (pages[dcp::VerificationNote::VERIFY_ERROR], _("Errors"));
+       pages[dcp::VerificationNote::VERIFY_BV21_ERROR] = new wxRichTextCtrl (notebook, wxID_ANY, wxEmptyString, wxDefaultPosition, {400, 300}, wxRE_READONLY);
+       notebook->AddPage (pages[dcp::VerificationNote::VERIFY_BV21_ERROR], _("SMPTE Bv2.1 errors"));
+       pages[dcp::VerificationNote::VERIFY_WARNING] = new wxRichTextCtrl (notebook, wxID_ANY, wxEmptyString, wxDefaultPosition, {400, 300}, wxRE_READONLY);
+       notebook->AddPage (pages[dcp::VerificationNote::VERIFY_WARNING], _("Warnings"));
+
+       auto summary = new wxStaticText (this, wxID_ANY, wxT(""));
+       sizer->Add (summary, 0, wxALL, DCPOMATIC_DIALOG_BORDER);
+
+       auto buttons = CreateStdDialogButtonSizer (0);
        sizer->Add (CreateSeparatedSizer(buttons), wxSizerFlags().Expand().DoubleBorder());
        buttons->SetAffirmativeButton (new wxButton (this, wxID_OK));
        buttons->Realize ();
@@ -46,114 +61,281 @@ VerifyDCPDialog::VerifyDCPDialog (wxWindow* parent, shared_ptr<VerifyDCPJob> job
        sizer->Layout ();
        sizer->SetSizeHints (this);
 
-       _text->GetCaret()->Hide ();
+       for (auto const& i: pages) {
+               i.second->GetCaret()->Hide();
+       }
 
        if (job->finished_ok() && job->notes().empty()) {
-               _text->BeginStandardBullet (N_("standard/circle"), 1, 50);
-               _text->WriteText (_("DCP validates OK."));
-               _text->EndStandardBullet ();
+               summary->SetLabel (_("DCP validates OK."));
                return;
        }
 
-       /* We might have an error that did not come from dcp::verify; report it if so */
+       map<dcp::VerificationNote::Type, int> counts;
+       counts[dcp::VerificationNote::VERIFY_WARNING] = 0;
+       counts[dcp::VerificationNote::VERIFY_BV21_ERROR] = 0;
+       counts[dcp::VerificationNote::VERIFY_ERROR] = 0;
+
+       auto add_bullet = [&pages](dcp::VerificationNote::Type type, wxString message) {
+               pages[type]->BeginStandardBullet(N_("standard/diamond"), 1, 50);
+               pages[type]->WriteText (message);
+               pages[type]->Newline ();
+               pages[type]->EndStandardBullet ();
+       };
+
+       auto add = [&counts, &add_bullet](dcp::VerificationNote note, wxString message) {
+               if (note.note()) {
+                       message.Replace("%n", std_to_wx(note.note().get()));
+               }
+               if (note.file()) {
+                       message.Replace("%f", std_to_wx(note.file()->filename().string()));
+               }
+               if (note.line()) {
+                       message.Replace("%l", std_to_wx(dcp::raw_convert<string>(note.line().get())));
+               }
+               add_bullet (note.type(), message);
+               counts[note.type()]++;
+       };
+
        if (job->finished_in_error() && job->error_summary() != "") {
-               _text->BeginSymbolBullet (N_("!"), 1, 50);
-               _text->WriteText(std_to_wx(job->error_summary()));
-               _text->Newline();
+               /* We have an error that did not come from dcp::verify */
+               add_bullet (dcp::VerificationNote::VERIFY_ERROR, std_to_wx(job->error_summary()));
        }
 
        for (auto i: job->notes()) {
-               switch (i.type()) {
-               case dcp::VerificationNote::VERIFY_WARNING:
-                       _text->BeginStandardBullet (N_("standard/diamond"), 1, 50);
-                       break;
-               case dcp::VerificationNote::VERIFY_ERROR:
-                       _text->BeginSymbolBullet (N_("!"), 1, 50);
-                       break;
-               }
-
-               wxString text;
                switch (i.code()) {
-               case dcp::VerificationNote::GENERAL_READ:
-                       text = std_to_wx(*i.note());
+               case dcp::VerificationNote::FAILED_READ:
+                       add (i, std_to_wx(*i.note()));
                        break;
-               case dcp::VerificationNote::CPL_HASH_INCORRECT:
-                       text = _("The hash of the CPL in the PKL does not agree with the CPL file.  This probably means that the CPL file is corrupt.");
+               case dcp::VerificationNote::MISMATCHED_CPL_HASHES:
+                       add(i, _("The hash of the CPL %n in the PKL does not agree with the CPL file.  This probably means that the CPL file is corrupt."));
                        break;
                case dcp::VerificationNote::INVALID_PICTURE_FRAME_RATE:
-                       text = _("The picture in a reel has an invalid frame rate");
+                       add(i, _("The picture in a reel has a frame rate of %n, which is not valid."));
                        break;
-               case dcp::VerificationNote::PICTURE_HASH_INCORRECT:
-                       text = wxString::Format(
-                               _("The hash of the picture asset %s does not agree with the PKL file.  This probably means that the asset file is corrupt."),
-                               std_to_wx(i.file()->filename().string())
-                               );
+               case dcp::VerificationNote::INCORRECT_PICTURE_HASH:
+                       add(i, _("The hash of the picture asset %f does not agree with the PKL file.  This probably means that the asset file is corrupt."));
                        break;
-               case dcp::VerificationNote::PKL_CPL_PICTURE_HASHES_DISAGREE:
-                       text = _("The PKL and CPL hashes disagree for a picture asset.");
+               case dcp::VerificationNote::MISMATCHED_PICTURE_HASHES:
+                       add(i, _("The PKL and CPL hashes disagree for picture asset %f."));
                        break;
-               case dcp::VerificationNote::SOUND_HASH_INCORRECT:
-                       text = wxString::Format(
-                               _("The hash of the sound asset %s does not agree with the PKL file.  This probably means that the asset file is corrupt."),
-                               std_to_wx(i.file()->filename().string())
-                               );
+               case dcp::VerificationNote::INCORRECT_SOUND_HASH:
+                       add(i, _("The hash of the sound asset %f does not agree with the PKL file.  This probably means that the asset file is corrupt."));
                        break;
-               case dcp::VerificationNote::PKL_CPL_SOUND_HASHES_DISAGREE:
-                       text = _("The PKL and CPL hashes disagree for a sound asset.");
+               case dcp::VerificationNote::MISMATCHED_SOUND_HASHES:
+                       add(i, _("The PKL and CPL hashes disagree for sound asset %f."));
                        break;
                case dcp::VerificationNote::EMPTY_ASSET_PATH:
-                       text = _("An asset has an empty path in the ASSETMAP.");
+                       add(i, _("An asset has an empty path in the ASSETMAP."));
                        break;
                case dcp::VerificationNote::MISSING_ASSET:
-                       text = _("An asset is missing.");
+                       add(i, _("The asset %f is missing."));
                        break;
                case dcp::VerificationNote::MISMATCHED_STANDARD:
-                       text = _("Parts of the DCP are written according to the Interop standard and parts according to SMPTE.");
+                       add(i, _("Parts of the DCP are written according to the Interop standard and parts according to SMPTE."));
                        break;
-               case dcp::VerificationNote::XML_VALIDATION_ERROR:
+               case dcp::VerificationNote::INVALID_XML:
                        if (i.line()) {
-                               text = wxString::Format(
-                                       _("The XML in %s is malformed on line %" PRIu64 "."),
-                                       std_to_wx(i.file()->filename().string()),
-                                       i.line().get()
-                                       );
+                               add(i, _("The XML in %f is malformed on line %l (%n)."));
                        } else {
-                               text = wxString::Format(
-                                       _("The XML in %s is malformed."),
-                                       std_to_wx(i.file()->filename().string())
-                                       );
+                               add(i, _("The XML in %f is malformed (%n)."));
                        }
                        break;
                case dcp::VerificationNote::MISSING_ASSETMAP:
-                       text = _("No ASSETMAP or ASSETMAP.xml file was found.");
+                       add(i, _("No ASSETMAP or ASSETMAP.xml file was found."));
                        break;
-               case dcp::VerificationNote::INTRINSIC_DURATION_TOO_SMALL:
-                       text = _("An asset has an instrinsic duration of less than 1 second, which is invalid.");
+               case dcp::VerificationNote::INVALID_INTRINSIC_DURATION:
+                       add(i, _("The asset %n has an instrinsic duration of less than 1 second, which is invalid."));
                        break;
-               case dcp::VerificationNote::DURATION_TOO_SMALL:
-                       text = _("An asset has a duration of less than 1 second, which is invalid.");
+               case dcp::VerificationNote::INVALID_DURATION:
+                       add(i, _("The asset %n has a duration of less than 1 second, which is invalid."));
                        break;
-               case dcp::VerificationNote::PICTURE_FRAME_TOO_LARGE:
-                       text = _("At least one frame of the video data is over the limit of 250Mbit/s.");
+               case dcp::VerificationNote::INVALID_PICTURE_FRAME_SIZE_IN_BYTES:
+                       add(i, _("At least one frame of the video asset %f is over the limit of 250Mbit/s."));
                        break;
-               case dcp::VerificationNote::PICTURE_FRAME_NEARLY_TOO_LARGE:
-                       text = _("At least one frame of the video data is close to the limit of 250MBit/s.");
+               case dcp::VerificationNote::NEARLY_INVALID_PICTURE_FRAME_SIZE_IN_BYTES:
+                       add(i, _("At least one frame of the video asset %f is close to the limit of 250MBit/s."));
                        break;
                case dcp::VerificationNote::EXTERNAL_ASSET:
-                       text = _("This DCP refers to at least one asset in another DCP, so it is a \"version file\" (VF)");
+                       add(i, _("This DCP refers to at the asset %n in another DCP (and perhaps others), so it is a \"version file\" (VF)"));
                        break;
-               }
-
-               _text->WriteText (text);
-               _text->Newline ();
-
-               switch (i.type()) {
-               case dcp::VerificationNote::VERIFY_WARNING:
-                       _text->EndStandardBullet ();
+               case dcp::VerificationNote::INVALID_STANDARD:
+                       add(i, _("This DCP uses the Interop standard, but it should be made with SMPTE."));
+                       break;
+               case dcp::VerificationNote::INVALID_LANGUAGE:
+                       add(i, _("The invalid language tag %n is used."));
+                       break;
+               case dcp::VerificationNote::INVALID_PICTURE_SIZE_IN_PIXELS:
+                       add(i, _("The video asset %f uses the invalid image size %n."));
+                       break;
+               case dcp::VerificationNote::INVALID_PICTURE_FRAME_RATE_FOR_2K:
+                       add(i, _("The video asset %f uses the invalid frame rate %n."));
+                       break;
+               case dcp::VerificationNote::INVALID_PICTURE_FRAME_RATE_FOR_4K:
+                       add(i, _("The video asset %f uses the frame rate %n which is invalid for 4K video."));
+                       break;
+               case dcp::VerificationNote::INVALID_PICTURE_ASSET_RESOLUTION_FOR_3D:
+                       add(i, _("The video asset %f uses the frame rate %n which is invalid for 3D video."));
+                       break;
+               case dcp::VerificationNote::INVALID_CLOSED_CAPTION_XML_SIZE_IN_BYTES:
+                       add(i, _("The XML in the closed caption asset %f takes up %n bytes which is over the 256KB limit."));
+                       break;
+               case dcp::VerificationNote::INVALID_TIMED_TEXT_SIZE_IN_BYTES:
+                       add(i, _("The timed text asset %f takes up %n bytes which is over the 115MB limit."));
+                       break;
+               case dcp::VerificationNote::INVALID_TIMED_TEXT_FONT_SIZE_IN_BYTES:
+                       add(i, _("The fonts in the timed text asset %f take up %n bytes which is over the 10MB limit."));
+                       break;
+               case dcp::VerificationNote::MISSING_SUBTITLE_LANGUAGE:
+                       add(i, _("The subtitle asset %f contains no <Language> tag."));
+                       break;
+               case dcp::VerificationNote::MISMATCHED_SUBTITLE_LANGUAGES:
+                       add(i, _("Not all subtitle assets specify the same <Language> tag."));
+                       break;
+               case dcp::VerificationNote::MISSING_SUBTITLE_START_TIME:
+                       add(i, _("The subtitle asset %f contains no <StartTime> tag."));
+                       break;
+               case dcp::VerificationNote::INVALID_SUBTITLE_START_TIME:
+                       add(i, _("The subtitle asset %f has a <StartTime> which is not zero."));
+                       break;
+               case dcp::VerificationNote::INVALID_SUBTITLE_FIRST_TEXT_TIME:
+                       add(i, _("The first subtitle or closed caption happens before 4s into the first reel."));
+                       break;
+               case dcp::VerificationNote::INVALID_SUBTITLE_DURATION:
+                       add(i, _("At least one subtitle lasts less than 15 frames."));
+                       break;
+               case dcp::VerificationNote::INVALID_SUBTITLE_SPACING:
+                       add(i, _("At least one pair of subtitles is separated by less than 2 frames."));
+                       break;
+               case dcp::VerificationNote::INVALID_SUBTITLE_LINE_COUNT:
+                       add(i, _("There are more than 3 subtitle lines in at least one place."));
+                       break;
+               case dcp::VerificationNote::NEARLY_INVALID_SUBTITLE_LINE_LENGTH:
+                       add(i, _("There are more than 52 characters in at least one subtitle line."));
+                       break;
+               case dcp::VerificationNote::INVALID_SUBTITLE_LINE_LENGTH:
+                       add(i, _("There are more than 79 characters in at least one subtitle line."));
+                       break;
+               case dcp::VerificationNote::INVALID_CLOSED_CAPTION_LINE_COUNT:
+                       add(i, _("There are more than 3 closed caption lines in at least one place."));
+                       break;
+               case dcp::VerificationNote::INVALID_CLOSED_CAPTION_LINE_LENGTH:
+                       add(i, _("There are more than 32 characters in at least one closed caption line."));
+                       break;
+               case dcp::VerificationNote::INVALID_SOUND_FRAME_RATE:
+                       add(i, _("The sound asset %f has an invalid frame rate of %n."));
                        break;
-               case dcp::VerificationNote::VERIFY_ERROR:
-                       _text->EndSymbolBullet ();
+               case dcp::VerificationNote::MISSING_CPL_ANNOTATION_TEXT:
+                       add(i, _("The CPL %n has no <AnnotationText> tag."));
+                       break;
+               case dcp::VerificationNote::MISMATCHED_CPL_ANNOTATION_TEXT:
+                       add(i, _("The CPL %n has an <AnnotationText> which is not the same as its <ContentTitleText>."));
+                       break;
+               case dcp::VerificationNote::MISMATCHED_ASSET_DURATION:
+                       add(i, _("At least one asset in a reel does not have the same duration as the others."));
+                       break;
+               case dcp::VerificationNote::MISSING_MAIN_SUBTITLE_FROM_SOME_REELS:
+                       add(i, _("The DCP has subtitles but at least one reel has no subtitle asset."));
+                       break;
+               case dcp::VerificationNote::MISMATCHED_CLOSED_CAPTION_ASSET_COUNTS:
+                       add(i, _("The DCP has closed captions but not every reel has the same number of closed caption assets."));
+                       break;
+               case dcp::VerificationNote::MISSING_SUBTITLE_ENTRY_POINT:
+                       add(i, _("The subtitle asset %n has no <EntryPoint> tag."));
+                       break;
+               case dcp::VerificationNote::INCORRECT_SUBTITLE_ENTRY_POINT:
+                       add(i, _("Subtitle asset %n has a non-zero <EntryPoint>."));
+                       break;
+               case dcp::VerificationNote::MISSING_CLOSED_CAPTION_ENTRY_POINT:
+                       add(i, _("The closed caption asset %n has no <EntryPoint> tag."));
+                       break;
+               case dcp::VerificationNote::INCORRECT_CLOSED_CAPTION_ENTRY_POINT:
+                       add(i, _("Closed caption asset %n has a non-zero <EntryPoint>."));
+                       break;
+               case dcp::VerificationNote::MISSING_HASH:
+                       add(i, _("The asset %n has no <Hash> in the CPL."));
+                       break;
+               case dcp::VerificationNote::MISSING_FFEC_IN_FEATURE:
+                       add(i, _("The DCP is a feature but has no FFEC (first frame of end credits) marker."));
+                       break;
+               case dcp::VerificationNote::MISSING_FFMC_IN_FEATURE:
+                       add(i, _("The DCP is a feature but has no FFMC (first frame of moving credits) marker."));
+                       break;
+               case dcp::VerificationNote::MISSING_FFOC:
+                       add(i, _("The DCP has no FFOC (first frame of content) marker."));
+                       break;
+               case dcp::VerificationNote::MISSING_LFOC:
+                       add(i, _("The DCP has no LFOC (last frame of content) marker."));
+                       break;
+               case dcp::VerificationNote::INCORRECT_FFOC:
+                       add(i, _("The DCP has a FFOC of %n instead of 1."));
+                       break;
+               case dcp::VerificationNote::INCORRECT_LFOC:
+                       add(i, _("The DCP has a LFOC of %n instead of the reel duration minus one."));
+                       break;
+               case dcp::VerificationNote::MISSING_CPL_METADATA:
+                       add(i, _("The CPL %n has no CPL metadata tag."));
+                       break;
+               case dcp::VerificationNote::MISSING_CPL_METADATA_VERSION_NUMBER:
+                       add(i, _("The CPL %n has no CPL metadata version number tag."));
+                       break;
+               case dcp::VerificationNote::MISSING_EXTENSION_METADATA:
+                       add(i, _("The CPL %n has no CPL extension metadata tag."));
+                       break;
+               case dcp::VerificationNote::INVALID_EXTENSION_METADATA:
+                       add(i, _("The CPL %f has an invalid CPL extension metadata tag (%n)"));
+                       break;
+               case dcp::VerificationNote::UNSIGNED_CPL_WITH_ENCRYPTED_CONTENT:
+                       add(i, _("The CPL %n has encrypted content but is not signed."));
+                       break;
+               case dcp::VerificationNote::UNSIGNED_PKL_WITH_ENCRYPTED_CONTENT:
+                       add(i, _("The PKL %n has encrypted content but is not signed."));
+                       break;
+               case dcp::VerificationNote::MISMATCHED_PKL_ANNOTATION_TEXT_WITH_CPL:
+                       add(i, _("The PKL %n has an <AnnotationText> which does not match its CPL's <ContentTitleText>."));
+                       break;
+               case dcp::VerificationNote::PARTIALLY_ENCRYPTED:
+                       add(i, _("The DCP has encrypted content, but not all its assets are encrypted."));
                        break;
                }
        }
+
+       wxString summary_text;
+
+       if (counts[dcp::VerificationNote::VERIFY_ERROR] == 1) {
+               /// TRANSLATORS: this will be used at the start of a string like "1 error, 2 Bv2.1 errors and 3 warnings."
+               summary_text = _("1 error, ");
+       } else {
+               /// TRANSLATORS: this will be used at the start of a string like "1 error, 2 Bv2.1 errors and 3 warnings."
+               summary_text = wxString::Format("%d errors, ", counts[dcp::VerificationNote::VERIFY_ERROR]);
+       }
+
+       if (counts[dcp::VerificationNote::VERIFY_BV21_ERROR] == 1) {
+               /// TRANSLATORS: this will be used in the middle of a string like "1 error, 2 Bv2.1 errors and 3 warnings."
+               summary_text += _("1 Bv2.1 error, ");
+       } else {
+               /// TRANSLATORS: this will be used in the middle of a string like "1 error, 2 Bv2.1 errors and 3 warnings."
+               summary_text += wxString::Format("%d Bv2.1 errors, ", counts[dcp::VerificationNote::VERIFY_BV21_ERROR]);
+       }
+
+       if (counts[dcp::VerificationNote::VERIFY_WARNING] == 1) {
+               /// TRANSLATORS: this will be used at the end of a string like "1 error, 2 Bv2.1 errors and 3 warnings."
+               summary_text += _("and 1 warning.");
+       } else {
+               /// TRANSLATORS: this will be used at the end of a string like "1 error, 2 Bv2.1 errors and 3 warnings."
+               summary_text += wxString::Format("and %d warnings.", counts[dcp::VerificationNote::VERIFY_WARNING]);
+       }
+
+       summary->SetLabel(summary_text);
+
+       if (counts[dcp::VerificationNote::VERIFY_ERROR] == 0) {
+               add_bullet (dcp::VerificationNote::VERIFY_ERROR, _("No errors found."));
+       }
+
+       if (counts[dcp::VerificationNote::VERIFY_BV21_ERROR] == 0) {
+               add_bullet (dcp::VerificationNote::VERIFY_BV21_ERROR, _("No SMPTE Bv2.1 errors found."));
+       }
+
+       if (counts[dcp::VerificationNote::VERIFY_WARNING] == 0) {
+               add_bullet (dcp::VerificationNote::VERIFY_WARNING, _("No warnings found."));
+       }
 }
index 2d3bac24f0018ede440815dded526802cccc644a..ecc7d22775b6da91202ae93b09314925322b7f60 100644 (file)
@@ -34,5 +34,6 @@ public:
        VerifyDCPDialog (wxWindow* parent, std::shared_ptr<VerifyDCPJob> job);
 
 private:
-       wxRichTextCtrl* _text;
+       wxStaticText* _summary;
+       std::map<dcp::VerificationNote::Type, wxRichTextCtrl*> _pages;
 };
index 4c59be72b497a9ae01ca7155c43322b6a079250b..48fc8e05c91a1a52893ade569dc9477d65bae3a2 100644 (file)
@@ -83,10 +83,10 @@ BOOST_AUTO_TEST_CASE (closed_caption_test2)
 
        BOOST_REQUIRE_EQUAL (check.cpls().size(), 1U);
        BOOST_REQUIRE_EQUAL (check.cpls().front()->reels().size(), 1U);
-       list<shared_ptr<dcp::ReelClosedCaptionAsset> > ccaps = check.cpls().front()->reels().front()->closed_captions();
+       auto ccaps = check.cpls().front()->reels().front()->closed_captions();
        BOOST_REQUIRE_EQUAL (ccaps.size(), 3U);
 
-       list<shared_ptr<dcp::ReelClosedCaptionAsset> >::const_iterator i = ccaps.begin ();
+       auto i = ccaps.begin ();
        BOOST_CHECK_EQUAL ((*i)->annotation_text(), "First track");
        BOOST_REQUIRE (static_cast<bool>((*i)->language()));
        BOOST_CHECK_EQUAL ((*i)->language().get(), "fr-FR");
index 0cd9722498696107c5ead99eaefb79a5916bd758..28538a2819dd3b845d78069f083275c4a563ec9b 100644 (file)
@@ -39,6 +39,7 @@
 using std::list;
 using std::string;
 using std::vector;
+using std::make_shared;
 using std::shared_ptr;
 
 /* Check that DCPDecoder reuses old data when it should */
@@ -46,14 +47,14 @@ BOOST_AUTO_TEST_CASE (check_reuse_old_data_test)
 {
        /* Make some DCPs */
 
-       shared_ptr<Film> ov = new_test_film2 ("check_reuse_old_data_ov");
+       auto ov = new_test_film2 ("check_reuse_old_data_ov");
        ov->examine_and_add_content (content_factory("test/data/flat_red.png").front());
        BOOST_REQUIRE (!wait_for_jobs());
        ov->make_dcp ();
        BOOST_REQUIRE (!wait_for_jobs());
 
-       shared_ptr<Film> vf = new_test_film2 ("check_reuse_old_data_vf");
-       shared_ptr<DCPContent> ov_content(new DCPContent(ov->dir(ov->dcp_name(false))));
+       auto vf = new_test_film2 ("check_reuse_old_data_vf");
+       auto ov_content = make_shared<DCPContent>(ov->dir(ov->dcp_name(false)));
        vf->examine_and_add_content (ov_content);
        vf->examine_and_add_content (content_factory("test/data/L.wav").front());
        BOOST_REQUIRE (!wait_for_jobs());
@@ -61,7 +62,7 @@ BOOST_AUTO_TEST_CASE (check_reuse_old_data_test)
        vf->make_dcp ();
        BOOST_REQUIRE (!wait_for_jobs());
 
-       shared_ptr<Film> encrypted = new_test_film2 ("check_reuse_old_data_decrypted");
+       auto encrypted = new_test_film2 ("check_reuse_old_data_decrypted");
        encrypted->examine_and_add_content (content_factory("test/data/flat_red.png").front());
        BOOST_REQUIRE (!wait_for_jobs());
        encrypted->set_encrypted (true);
@@ -71,7 +72,7 @@ BOOST_AUTO_TEST_CASE (check_reuse_old_data_test)
        dcp::DCP encrypted_dcp (encrypted->dir(encrypted->dcp_name()));
        encrypted_dcp.read ();
 
-       dcp::EncryptedKDM kdm = encrypted->make_kdm (
+       auto kdm = encrypted->make_kdm (
                Config::instance()->decryption_chain()->leaf(),
                vector<string>(),
                encrypted_dcp.cpls().front()->file().get(),
@@ -85,15 +86,15 @@ BOOST_AUTO_TEST_CASE (check_reuse_old_data_test)
        /* Add just the OV to a new project, move it around a bit and check that
           the _reels get reused.
        */
-       shared_ptr<Film> test = new_test_film2 ("check_reuse_old_data_test1");
-       ov_content.reset (new DCPContent(ov->dir(ov->dcp_name(false))));
+       auto test = new_test_film2 ("check_reuse_old_data_test1");
+       ov_content = make_shared<DCPContent>(ov->dir(ov->dcp_name(false)));
        test->examine_and_add_content (ov_content);
        BOOST_REQUIRE (!wait_for_jobs());
-       shared_ptr<Player> player (new Player(test));
+       auto player = make_shared<Player>(test);
 
-       shared_ptr<DCPDecoder> decoder = std::dynamic_pointer_cast<DCPDecoder>(player->_pieces.front()->decoder);
+       auto decoder = std::dynamic_pointer_cast<DCPDecoder>(player->_pieces.front()->decoder);
        BOOST_REQUIRE (decoder);
-       list<shared_ptr<dcp::Reel> > reels = decoder->reels();
+       auto reels = decoder->reels();
 
        ov_content->set_position (test, dcpomatic::DCPTime(96000));
        decoder = std::dynamic_pointer_cast<DCPDecoder>(player->_pieces.front()->decoder);
@@ -104,7 +105,7 @@ BOOST_AUTO_TEST_CASE (check_reuse_old_data_test)
           _reels did not get reused.
        */
        test = new_test_film2 ("check_reuse_old_data_test2");
-       shared_ptr<DCPContent> vf_content (new DCPContent(vf->dir(vf->dcp_name(false))));
+       auto vf_content = make_shared<DCPContent>(vf->dir(vf->dcp_name(false)));
        test->examine_and_add_content (vf_content);
        BOOST_REQUIRE (!wait_for_jobs());
        player.reset (new Player(test));
@@ -114,7 +115,7 @@ BOOST_AUTO_TEST_CASE (check_reuse_old_data_test)
        reels = decoder->reels();
 
        vf_content->add_ov (ov->dir(ov->dcp_name(false)));
-       JobManager::instance()->add (shared_ptr<Job>(new ExamineContentJob(test, vf_content)));
+       JobManager::instance()->add (make_shared<ExamineContentJob>(test, vf_content));
        BOOST_REQUIRE (!wait_for_jobs());
        decoder = std::dynamic_pointer_cast<DCPDecoder>(player->_pieces.front()->decoder);
        BOOST_REQUIRE (decoder);
@@ -122,17 +123,17 @@ BOOST_AUTO_TEST_CASE (check_reuse_old_data_test)
 
        /* Add a KDM to an encrypted DCP and check that the _reels did not get reused */
        test = new_test_film2 ("check_reuse_old_data_test3");
-       shared_ptr<DCPContent> encrypted_content (new DCPContent(encrypted->dir(encrypted->dcp_name(false))));
+       auto encrypted_content = make_shared<DCPContent>(encrypted->dir(encrypted->dcp_name(false)));
        test->examine_and_add_content (encrypted_content);
        BOOST_REQUIRE (!wait_for_jobs());
-       player.reset (new Player(test));
+       player = make_shared<Player>(test);
 
        decoder = std::dynamic_pointer_cast<DCPDecoder>(player->_pieces.front()->decoder);
        BOOST_REQUIRE (decoder);
        reels = decoder->reels();
 
        encrypted_content->add_kdm (kdm);
-       JobManager::instance()->add (shared_ptr<Job>(new ExamineContentJob(test, encrypted_content)));
+       JobManager::instance()->add (make_shared<ExamineContentJob>(test, encrypted_content));
        BOOST_REQUIRE (!wait_for_jobs());
        decoder = std::dynamic_pointer_cast<DCPDecoder>(player->_pieces.front()->decoder);
        BOOST_REQUIRE (decoder);
index 5145ee7e370a47b6f13578437b409a6b7b431cb8..ba73461bf1b8d4719f5b8d28ea969767dfe18123 100644 (file)
@@ -79,9 +79,9 @@ BOOST_AUTO_TEST_CASE (digest_test)
        dcp::DCP dcp (film->dir (film->dcp_name ()));
        dcp.read ();
        BOOST_CHECK_EQUAL (dcp.cpls().size(), 1U);
-       list<shared_ptr<dcp::Reel> > reels = dcp.cpls().front()->reels ();
+       auto reels = dcp.cpls()[0]->reels();
 
-       list<shared_ptr<dcp::Reel> >::const_iterator i = reels.begin ();
+       auto i = reels.begin ();
        BOOST_REQUIRE (i != reels.end ());
        BOOST_REQUIRE ((*i)->main_picture()->hash());
        BOOST_REQUIRE ((*i)->main_picture()->asset()->file());
index 05b020e1c1240a6b7ceacac7799fd2db386603dc..7ecb6c822171a19c22094a4443556c5e7250d0ab 100644 (file)
@@ -111,9 +111,9 @@ BOOST_AUTO_TEST_CASE (import_dcp_markers_test)
 
        content->video->set_length (24 * 60 * 10);
 
-       film->set_marker(dcp::FFOC, dcpomatic::DCPTime::from_seconds(1.91));
-       film->set_marker(dcp::FFMC, dcpomatic::DCPTime::from_seconds(9.4));
-       film->set_marker(dcp::LFMC, dcpomatic::DCPTime::from_seconds(9.99));
+       film->set_marker(dcp::Marker::FFOC, dcpomatic::DCPTime::from_seconds(1.91));
+       film->set_marker(dcp::Marker::FFMC, dcpomatic::DCPTime::from_seconds(9.4));
+       film->set_marker(dcp::Marker::LFMC, dcpomatic::DCPTime::from_seconds(9.99));
 
        film->make_dcp ();
        BOOST_REQUIRE (!wait_for_jobs());
@@ -131,12 +131,12 @@ BOOST_AUTO_TEST_CASE (import_dcp_markers_test)
        BOOST_CHECK_EQUAL (imported->markers().size(), 4U);
 
        map<dcp::Marker, dcpomatic::ContentTime> markers = imported->markers();
-       BOOST_REQUIRE(markers.find(dcp::FFOC) != markers.end());
-       BOOST_CHECK(markers[dcp::FFOC] == dcpomatic::ContentTime(184000));
-       BOOST_REQUIRE(markers.find(dcp::FFMC) != markers.end());
-       BOOST_CHECK(markers[dcp::FFMC] == dcpomatic::ContentTime(904000));
-       BOOST_REQUIRE(markers.find(dcp::LFMC) != markers.end());
-       BOOST_CHECK(markers[dcp::LFMC] == dcpomatic::ContentTime(960000));
+       BOOST_REQUIRE(markers.find(dcp::Marker::FFOC) != markers.end());
+       BOOST_CHECK(markers[dcp::Marker::FFOC] == dcpomatic::ContentTime(184000));
+       BOOST_REQUIRE(markers.find(dcp::Marker::FFMC) != markers.end());
+       BOOST_CHECK(markers[dcp::Marker::FFMC] == dcpomatic::ContentTime(904000));
+       BOOST_REQUIRE(markers.find(dcp::Marker::LFMC) != markers.end());
+       BOOST_CHECK(markers[dcp::Marker::LFMC] == dcpomatic::ContentTime(960000));
 
        /* Load that film and check that the markers have been loaded */
        shared_ptr<Film> film3(new Film(boost::filesystem::path("build/test/import_dcp_markers_test2")));
@@ -148,12 +148,12 @@ BOOST_AUTO_TEST_CASE (import_dcp_markers_test)
        BOOST_CHECK_EQUAL (reloaded->markers().size(), 4U);
 
        markers = reloaded->markers();
-       BOOST_REQUIRE(markers.find(dcp::FFOC) != markers.end());
-       BOOST_CHECK(markers[dcp::FFOC] == dcpomatic::ContentTime(184000));
-       BOOST_REQUIRE(markers.find(dcp::FFMC) != markers.end());
-       BOOST_CHECK(markers[dcp::FFMC] == dcpomatic::ContentTime(904000));
-       BOOST_REQUIRE(markers.find(dcp::LFMC) != markers.end());
-       BOOST_CHECK(markers[dcp::LFMC] == dcpomatic::ContentTime(960000));
+       BOOST_REQUIRE(markers.find(dcp::Marker::FFOC) != markers.end());
+       BOOST_CHECK(markers[dcp::Marker::FFOC] == dcpomatic::ContentTime(184000));
+       BOOST_REQUIRE(markers.find(dcp::Marker::FFMC) != markers.end());
+       BOOST_CHECK(markers[dcp::Marker::FFMC] == dcpomatic::ContentTime(904000));
+       BOOST_REQUIRE(markers.find(dcp::Marker::LFMC) != markers.end());
+       BOOST_CHECK(markers[dcp::Marker::LFMC] == dcpomatic::ContentTime(960000));
 }
 
 
index c7b33d39417a81b3c03e85abf701ea54e918d5fb..cf8dc3e2ea5d8e3cdfe7c44e6eb35eb460f371a4 100644 (file)
@@ -493,7 +493,7 @@ no_op ()
 }
 
 static void
-dump_notes (list<dcp::VerificationNote> const & notes)
+dump_notes (vector<dcp::VerificationNote> const & notes)
 {
        for (auto i: notes) {
                std::cout << dcp::note_to_string(i) << "\n";
@@ -525,7 +525,7 @@ BOOST_AUTO_TEST_CASE (reels_should_not_be_short1)
 
        vector<boost::filesystem::path> dirs;
        dirs.push_back (film->dir(film->dcp_name(false)));
-       list<dcp::VerificationNote> const notes = dcp::verify(dirs, boost::bind(&no_op), boost::bind(&no_op), TestPaths::xsd());
+       auto notes = dcp::verify(dirs, boost::bind(&no_op), boost::bind(&no_op), TestPaths::xsd());
        dump_notes (notes);
        BOOST_REQUIRE (notes.empty());
 }
@@ -555,7 +555,7 @@ BOOST_AUTO_TEST_CASE (reels_should_not_be_short2)
 
        vector<boost::filesystem::path> dirs;
        dirs.push_back (film->dir(film->dcp_name(false)));
-       list<dcp::VerificationNote> const notes = dcp::verify(dirs, boost::bind(&no_op), boost::bind(&no_op), TestPaths::xsd());
+       auto const notes = dcp::verify(dirs, boost::bind(&no_op), boost::bind(&no_op), TestPaths::xsd());
        dump_notes (notes);
        BOOST_REQUIRE (notes.empty());
 }
@@ -579,7 +579,7 @@ BOOST_AUTO_TEST_CASE (reels_should_not_be_short3)
        BOOST_REQUIRE (!wait_for_jobs());
 
        vector<boost::filesystem::path> dirs;
-       list<dcp::VerificationNote> const notes = dcp::verify(dirs, boost::bind(&no_op), boost::bind(&no_op), TestPaths::xsd());
+       auto const notes = dcp::verify(dirs, boost::bind(&no_op), boost::bind(&no_op), TestPaths::xsd());
        dump_notes (notes);
        BOOST_REQUIRE (notes.empty());
 }
@@ -609,7 +609,7 @@ BOOST_AUTO_TEST_CASE (reels_should_not_be_short4)
 
        vector<boost::filesystem::path> dirs;
        dirs.push_back (film->dir(film->dcp_name(false)));
-       list<dcp::VerificationNote> const notes = dcp::verify(dirs, boost::bind(&no_op), boost::bind(&no_op), TestPaths::xsd());
+       auto const notes = dcp::verify(dirs, boost::bind(&no_op), boost::bind(&no_op), TestPaths::xsd());
        dump_notes (notes);
        BOOST_REQUIRE (notes.empty());
 }
index 2eee36ffa3b463fa1899ce519fb3f41e435fc2d8..906477963fa318a71cca9f26414ef6214e4748fc 100644 (file)
@@ -74,17 +74,17 @@ BOOST_AUTO_TEST_CASE (subtitle_reel_test)
        BOOST_REQUIRE_EQUAL (dcp.cpls().size(), 1U);
        shared_ptr<dcp::CPL> cpl = dcp.cpls().front();
 
-       list<shared_ptr<dcp::Reel> > reels = cpl->reels ();
+       auto reels = cpl->reels ();
        BOOST_REQUIRE_EQUAL (reels.size(), 2U);
-       list<shared_ptr<dcp::Reel> >::const_iterator i = reels.begin ();
+       auto i = reels.begin ();
        BOOST_REQUIRE ((*i)->main_subtitle());
        BOOST_REQUIRE ((*i)->main_subtitle()->asset());
-       shared_ptr<dcp::InteropSubtitleAsset> A = std::dynamic_pointer_cast<dcp::InteropSubtitleAsset>((*i)->main_subtitle()->asset());
+       auto A = std::dynamic_pointer_cast<dcp::InteropSubtitleAsset>((*i)->main_subtitle()->asset());
        BOOST_REQUIRE (A);
        ++i;
        BOOST_REQUIRE ((*i)->main_subtitle());
        BOOST_REQUIRE ((*i)->main_subtitle()->asset());
-       shared_ptr<dcp::InteropSubtitleAsset> B = std::dynamic_pointer_cast<dcp::InteropSubtitleAsset>((*i)->main_subtitle()->asset());
+       auto B = std::dynamic_pointer_cast<dcp::InteropSubtitleAsset>((*i)->main_subtitle()->asset());
        BOOST_REQUIRE (B);
 
        BOOST_REQUIRE_EQUAL (A->subtitles().size(), 1U);
index 23eb3ca8e66fafbb2163d42978fbb29fd4824b4c..232435363171187dc01f92d94bfbab85e6a93eda 100644 (file)
@@ -89,23 +89,23 @@ BOOST_AUTO_TEST_CASE (torture_test1)
        dcp::DCP dcp ("build/test/torture_test1/" + film->dcp_name(false));
        dcp.read ();
 
-       list<shared_ptr<dcp::CPL> > cpls = dcp.cpls ();
+       auto cpls = dcp.cpls ();
        BOOST_REQUIRE_EQUAL (cpls.size(), 1U);
-       list<shared_ptr<dcp::Reel> > reels = cpls.front()->reels ();
+       auto reels = cpls.front()->reels ();
        BOOST_REQUIRE_EQUAL (reels.size(), 1U);
 
        /* Check sound */
 
-       shared_ptr<dcp::ReelSoundAsset> reel_sound = reels.front()->main_sound();
+       auto reel_sound = reels.front()->main_sound();
        BOOST_REQUIRE (reel_sound);
-       shared_ptr<dcp::SoundAsset> sound = reel_sound->asset();
+       auto sound = reel_sound->asset();
        BOOST_REQUIRE (sound);
        BOOST_CHECK_EQUAL (sound->intrinsic_duration(), 144);
 
        shared_ptr<dcp::SoundAssetReader> sound_reader = sound->start_read ();
 
        /* First frame silent */
-       shared_ptr<const dcp::SoundFrame> fr = sound_reader->get_frame (0);
+       auto fr = sound_reader->get_frame (0);
        for (int i = 0; i < fr->samples(); ++i) {
                for (int j = 0; j < 6; ++j) {
                        BOOST_CHECK_EQUAL (fr->get(j, i), 0);