diff options
| author | Carl Hetherington <cth@carlh.net> | 2019-10-14 11:24:48 +0200 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2019-10-14 11:24:48 +0200 |
| commit | 96f7dd41a2c8627bc1ea0d24d84142eb04b4ffef (patch) | |
| tree | 27c4f6a5355a0496e960e1769632d00c41ad4816 | |
| parent | 95bd2d068f67f7c0e611c720c95bfd6781329d86 (diff) | |
| parent | a9dde34b8772ef8b985af067e2ff709be4e3cab6 (diff) | |
Merge branch 'v2.15.x' of ssh://localhost:2222/home/carl/git/dcpomatic into v2.15.x
| -rw-r--r-- | src/lib/audio_processor.cc | 17 | ||||
| -rw-r--r-- | src/lib/audio_processor.h | 2 | ||||
| -rw-r--r-- | src/lib/config.cc | 4 | ||||
| -rw-r--r-- | src/lib/config.h | 11 | ||||
| -rw-r--r-- | src/lib/dcp_decoder.cc | 39 | ||||
| -rw-r--r-- | src/lib/dcp_decoder.h | 7 | ||||
| -rw-r--r-- | src/lib/film.cc | 8 | ||||
| -rw-r--r-- | src/lib/hints.cc | 2 | ||||
| -rw-r--r-- | src/lib/player.h | 1 | ||||
| -rw-r--r-- | src/wx/dcp_panel.cc | 27 | ||||
| -rw-r--r-- | src/wx/dcp_panel.h | 2 | ||||
| -rw-r--r-- | src/wx/full_config_dialog.cc | 13 | ||||
| -rw-r--r-- | test/dcp_decoder_test.cc | 140 | ||||
| -rw-r--r-- | test/wscript | 1 |
14 files changed, 255 insertions, 19 deletions
diff --git a/src/lib/audio_processor.cc b/src/lib/audio_processor.cc index 0d3f2b6d7..6cccbdc80 100644 --- a/src/lib/audio_processor.cc +++ b/src/lib/audio_processor.cc @@ -22,16 +22,21 @@ #include "mid_side_decoder.h" #include "upmixer_a.h" #include "upmixer_b.h" +#include "config.h" using std::string; using std::list; list<AudioProcessor const *> AudioProcessor::_all; +list<AudioProcessor const *> AudioProcessor::_non_experimental; void AudioProcessor::setup_audio_processors () { - _all.push_back (new MidSideDecoder ()); + AudioProcessor* mid_side = new MidSideDecoder (); + _all.push_back (mid_side); + _non_experimental.push_back (mid_side); + _all.push_back (new UpmixerA (48000)); _all.push_back (new UpmixerB (48000)); } @@ -49,6 +54,16 @@ AudioProcessor::from_id (string id) } list<AudioProcessor const *> +AudioProcessor::visible () +{ + if (Config::instance()->show_experimental_audio_processors()) { + return _all; + } + + return _non_experimental; +} + +list<AudioProcessor const *> AudioProcessor::all () { return _all; diff --git a/src/lib/audio_processor.h b/src/lib/audio_processor.h index e10df254c..78a3efb58 100644 --- a/src/lib/audio_processor.h +++ b/src/lib/audio_processor.h @@ -61,11 +61,13 @@ public: virtual std::vector<std::string> input_names () const = 0; static std::list<AudioProcessor const *> all (); + static std::list<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; }; #endif diff --git a/src/lib/config.cc b/src/lib/config.cc index 1d2ef1e40..581620f83 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -94,6 +94,7 @@ Config::set_defaults () _tms_password = ""; _allow_any_dcp_frame_rate = false; _allow_any_container = false; + _show_experimental_audio_processors = false; _language = optional<string> (); _default_still_length = 10; _default_container = Ratio::from_id ("185"); @@ -384,6 +385,7 @@ try _maximum_j2k_bandwidth = f.optional_number_child<int> ("MaximumJ2KBandwidth").get_value_or (250000000); _allow_any_dcp_frame_rate = f.optional_bool_child ("AllowAnyDCPFrameRate").get_value_or (false); _allow_any_container = f.optional_bool_child ("AllowAnyContainer").get_value_or (false); + _show_experimental_audio_processors = f.optional_bool_child ("ShowExperimentalAudioProcessors").get_value_or (false); _log_types = f.optional_number_child<int> ("LogTypes").get_value_or (LogEntry::TYPE_GENERAL | LogEntry::TYPE_WARNING | LogEntry::TYPE_ERROR); _analyse_ebur128 = f.optional_bool_child("AnalyseEBUR128").get_value_or (true); @@ -801,6 +803,8 @@ Config::write_config () const root->add_child("AllowAnyDCPFrameRate")->add_child_text (_allow_any_dcp_frame_rate ? "1" : "0"); /* [XML] AllowAnyContainer 1 to allow users to user any container ratio for their DCP, 0 to limit the GUI to standard containers. */ root->add_child("AllowAnyContainer")->add_child_text (_allow_any_container ? "1" : "0"); + /* [XML] ShowExperimentalAudioProcessors 1 to offer users the (experimental) audio upmixer processors, 0 to hide them */ + root->add_child("ShowExperimentalAudioProcessors")->add_child_text (_show_experimental_audio_processors ? "1" : "0"); /* [XML] LogTypes Types of logging to write; a bitfield where 1 is general notes, 2 warnings, 4 errors, 8 debug information related to encoding, 16 debug information related to encoding, 32 debug information for timing purposes, 64 debug information related to sending email. diff --git a/src/lib/config.h b/src/lib/config.h index 9a57b1b48..ff7a0fe39 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -82,6 +82,7 @@ public: PLAYER_PLAYLIST_DIRECTORY, PLAYER_DEBUG_LOG, HISTORY, + SHOW_EXPERIMENTAL_AUDIO_PROCESSORS, #ifdef DCPOMATIC_VARIANT_SWAROOP PLAYER_BACKGROUND_IMAGE, #endif @@ -157,6 +158,10 @@ public: return _allow_any_container; } + bool show_experimental_audio_processors () const { + return _show_experimental_audio_processors; + } + ISDCFMetadata default_isdcf_metadata () const { return _default_isdcf_metadata; } @@ -620,6 +625,10 @@ public: maybe_set (_allow_any_container, a); } + void set_show_experimental_audio_processors (bool e) { + maybe_set (_show_experimental_audio_processors, e, SHOW_EXPERIMENTAL_AUDIO_PROCESSORS); + } + void set_default_isdcf_metadata (ISDCFMetadata d) { maybe_set (_default_isdcf_metadata, d); } @@ -1177,6 +1186,8 @@ private: https://www.dcpomatic.com/forum/viewtopic.php?f=2&t=1119&p=4468 */ bool _allow_any_container; + /** Offer the upmixers in the audio processor settings */ + bool _show_experimental_audio_processors; /** Default ISDCF metadata for newly-created Films */ ISDCFMetadata _default_isdcf_metadata; boost::optional<std::string> _language; diff --git a/src/lib/dcp_decoder.cc b/src/lib/dcp_decoder.cc index 95cad9266..4b189189e 100644 --- a/src/lib/dcp_decoder.cc +++ b/src/lib/dcp_decoder.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2014-2018 Carl Hetherington <cth@carlh.net> + Copyright (C) 2014-2019 Carl Hetherington <cth@carlh.net> This file is part of DCP-o-matic. @@ -28,6 +28,7 @@ #include "ffmpeg_image_proxy.h" #include "image.h" #include "config.h" +#include "digester.h" #include <dcp/dcp.h> #include <dcp/cpl.h> #include <dcp/reel.h> @@ -52,6 +53,7 @@ using std::list; using std::cout; +using std::string; using boost::shared_ptr; using boost::dynamic_pointer_cast; using boost::optional; @@ -75,16 +77,18 @@ DCPDecoder::DCPDecoder (shared_ptr<const Film> film, shared_ptr<const DCPContent } } - if (old) { - _reels = old->_reels; + /* We try to avoid re-scanning the DCP's files every time we make a new DCPDecoder; we do this + by re-using the _reels list. Before we do this we need to check that nothing too serious + has changed in the DCPContent. - /* We might have gained a KDM since we made the Reel objects */ - if (_dcp_content->kdm ()) { - dcp::DecryptedKDM k = decrypted_kdm (); - BOOST_FOREACH (shared_ptr<dcp::Reel> i, _reels) { - i->add (k); - } - } + We do this by storing a digest of the important bits of the DCPContent and then checking that's + the same before we re-use _reels. + */ + + _lazy_digest = calculate_lazy_digest (c); + + if (old && old->lazy_digest() == _lazy_digest) { + _reels = old->_reels; } else { list<shared_ptr<dcp::CPL> > cpl_list = cpls (); @@ -425,3 +429,18 @@ DCPDecoder::set_forced_reduction (optional<int> reduction) { _forced_reduction = reduction; } + +string +DCPDecoder::calculate_lazy_digest (shared_ptr<const DCPContent> c) const +{ + Digester d; + BOOST_FOREACH (boost::filesystem::path i, c->paths()) { + d.add (i.string()); + } + d.add (static_cast<bool>(_dcp_content->kdm())); + d.add (static_cast<bool>(c->cpl())); + if (c->cpl()) { + d.add (c->cpl().get()); + } + return d.get (); +} diff --git a/src/lib/dcp_decoder.h b/src/lib/dcp_decoder.h index 2e63b24a2..496d95740 100644 --- a/src/lib/dcp_decoder.h +++ b/src/lib/dcp_decoder.h @@ -58,6 +58,10 @@ public: bool pass (); void seek (dcpomatic::ContentTime t, bool accurate); + std::string lazy_digest () const { + return _lazy_digest; + } + private: friend struct dcp_subtitle_within_dcp_test; @@ -72,6 +76,7 @@ private: boost::shared_ptr<TextDecoder> decoder, dcp::Size size ); + std::string calculate_lazy_digest (boost::shared_ptr<const DCPContent>) const; /** Time of next thing to return from pass relative to the start of _reel */ dcpomatic::ContentTime _next; @@ -89,4 +94,6 @@ private: bool _decode_referenced; boost::optional<int> _forced_reduction; + + std::string _lazy_digest; }; diff --git a/src/lib/film.cc b/src/lib/film.cc index e85543b80..93459661b 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -93,6 +93,7 @@ using std::copy; using std::back_inserter; using std::map; using std::exception; +using std::find; using boost::shared_ptr; using boost::weak_ptr; using boost::dynamic_pointer_cast; @@ -542,6 +543,13 @@ Film::read_metadata (optional<boost::filesystem::path> path) _audio_processor = 0; } + if (_audio_processor && !Config::instance()->show_experimental_audio_processors()) { + list<AudioProcessor const *> ap = AudioProcessor::visible(); + if (find(ap.begin(), ap.end(), _audio_processor) == ap.end()) { + Config::instance()->set_show_experimental_audio_processors(true); + } + } + _reel_type = static_cast<ReelType> (f.optional_number_child<int>("ReelType").get_value_or (static_cast<int>(REELTYPE_SINGLE))); _reel_length = f.optional_number_child<int64_t>("ReelLength").get_value_or (2000000000); _upload_after_make_dcp = f.optional_bool_child("UploadAfterMakeDCP").get_value_or (false); diff --git a/src/lib/hints.cc b/src/lib/hints.cc index a9b9d6f54..ad81e8d59 100644 --- a/src/lib/hints.cc +++ b/src/lib/hints.cc @@ -117,7 +117,7 @@ Hints::thread () } if (film->audio_channels() < 6) { - hint (_("Your DCP has fewer than 6 audio channels. This may cause problems on some projectors.")); + hint (_("Your DCP has fewer than 6 audio channels. This may cause problems on some projectors. You may want to set the DCP to have 6 channels. It does not matter if your content has fewer channels, as DCP-o-matic will fill the extras with silence.")); } AudioProcessor const * ap = film->audio_processor(); diff --git a/src/lib/player.h b/src/lib/player.h index 7558f6da0..e99c345bb 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -110,6 +110,7 @@ private: friend struct player_subframe_test; friend struct empty_test1; friend struct empty_test2; + friend struct check_reuse_old_data_test; void setup_pieces (); void setup_pieces_unlocked (); diff --git a/src/wx/dcp_panel.cc b/src/wx/dcp_panel.cc index a7f4f45e9..c4a14a58b 100644 --- a/src/wx/dcp_panel.cc +++ b/src/wx/dcp_panel.cc @@ -783,6 +783,12 @@ DCPPanel::config_changed (Config::Property p) _audio_grid->Clear (); add_audio_panel_to_grid (); _audio_grid->Layout (); + } else if (p == Config::SHOW_EXPERIMENTAL_AUDIO_PROCESSORS) { + _audio_processor->Clear (); + add_audio_processors (); + if (_film) { + film_changed (Film::AUDIO_PROCESSOR); + } } } @@ -931,10 +937,10 @@ wxPanel * DCPPanel::make_audio_panel () { wxPanel* panel = new wxPanel (_notebook); - wxSizer* sizer = new wxBoxSizer (wxVERTICAL); + _audio_panel_sizer = new wxBoxSizer (wxVERTICAL); _audio_grid = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); - sizer->Add (_audio_grid, 0, wxALL, 8); - panel->SetSizer (sizer); + _audio_panel_sizer->Add (_audio_grid, 0, wxALL, 8); + panel->SetSizer (_audio_panel_sizer); _channels_label = create_label (panel, _("Channels"), true); _audio_channels = new wxChoice (panel, wxID_ANY); @@ -942,10 +948,7 @@ DCPPanel::make_audio_panel () _processor_label = create_label (panel, _("Processor"), true); _audio_processor = new wxChoice (panel, wxID_ANY); - _audio_processor->Append (_("None"), new wxStringClientData (N_("none"))); - BOOST_FOREACH (AudioProcessor const * ap, AudioProcessor::all ()) { - _audio_processor->Append (std_to_wx (ap->name ()), new wxStringClientData (std_to_wx (ap->id ()))); - } + add_audio_processors (); _show_audio = new Button (panel, _("Show audio...")); @@ -1040,3 +1043,13 @@ DCPPanel::reel_length_changed () _film->set_reel_length (_reel_length->GetValue() * 1000000000LL); } + +void +DCPPanel::add_audio_processors () +{ + _audio_processor->Append (_("None"), new wxStringClientData (N_("none"))); + BOOST_FOREACH (AudioProcessor const * ap, AudioProcessor::visible()) { + _audio_processor->Append (std_to_wx(ap->name()), new wxStringClientData(std_to_wx(ap->id()))); + } + _audio_panel_sizer->Layout(); +} diff --git a/src/wx/dcp_panel.h b/src/wx/dcp_panel.h index f717e8327..887ae7c77 100644 --- a/src/wx/dcp_panel.h +++ b/src/wx/dcp_panel.h @@ -90,6 +90,7 @@ private: void add_to_grid (); void add_video_panel_to_grid (); void add_audio_panel_to_grid (); + void add_audio_processors (); int minimum_allowed_audio_channels () const; @@ -151,6 +152,7 @@ private: wxCheckBox* _upload_after_make_dcp; wxButton* _markers; wxButton* _metadata; + wxSizer* _audio_panel_sizer; AudioDialog* _audio_dialog; MarkersDialog* _markers_dialog; diff --git a/src/wx/full_config_dialog.cc b/src/wx/full_config_dialog.cc index ffe7b4749..f6dd783bd 100644 --- a/src/wx/full_config_dialog.cc +++ b/src/wx/full_config_dialog.cc @@ -1368,6 +1368,7 @@ public: , _maximum_j2k_bandwidth (0) , _allow_any_dcp_frame_rate (0) , _allow_any_container (0) + , _show_experimental_audio_processors (0) , _only_servers_encode (0) , _log_general (0) , _log_warning (0) @@ -1428,6 +1429,10 @@ private: restart->SetFont (font); table->AddSpacer (0); + _show_experimental_audio_processors = new CheckBox (_panel, _("Show experimental audio processors")); + table->Add (_show_experimental_audio_processors, 1, wxEXPAND | wxALL); + table->AddSpacer (0); + _only_servers_encode = new CheckBox (_panel, _("Only servers encode")); table->Add (_only_servers_encode, 1, wxEXPAND | wxALL); table->AddSpacer (0); @@ -1504,6 +1509,7 @@ private: _video_display_mode->Bind (wxEVT_CHOICE, boost::bind(&AdvancedPage::video_display_mode_changed, this)); _allow_any_dcp_frame_rate->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_dcp_frame_rate_changed, this)); _allow_any_container->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_container_changed, this)); + _show_experimental_audio_processors->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::show_experimental_audio_processors_changed, this)); _only_servers_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::only_servers_encode_changed, this)); _frames_in_memory_multiplier->Bind (wxEVT_SPINCTRL, boost::bind(&AdvancedPage::frames_in_memory_multiplier_changed, this)); _dcp_metadata_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_metadata_filename_format_changed, this)); @@ -1535,6 +1541,7 @@ private: } checked_set (_allow_any_dcp_frame_rate, config->allow_any_dcp_frame_rate ()); checked_set (_allow_any_container, config->allow_any_container ()); + checked_set (_show_experimental_audio_processors, config->show_experimental_audio_processors ()); checked_set (_only_servers_encode, config->only_servers_encode ()); checked_set (_log_general, config->log_types() & LogEntry::TYPE_GENERAL); checked_set (_log_warning, config->log_types() & LogEntry::TYPE_WARNING); @@ -1578,6 +1585,11 @@ private: Config::instance()->set_allow_any_container (_allow_any_container->GetValue ()); } + void show_experimental_audio_processors_changed () + { + Config::instance()->set_show_experimental_audio_processors (_show_experimental_audio_processors->GetValue ()); + } + void only_servers_encode_changed () { Config::instance()->set_only_servers_encode (_only_servers_encode->GetValue ()); @@ -1632,6 +1644,7 @@ private: wxSpinCtrl* _frames_in_memory_multiplier; wxCheckBox* _allow_any_dcp_frame_rate; wxCheckBox* _allow_any_container; + wxCheckBox* _show_experimental_audio_processors; wxCheckBox* _only_servers_encode; NameFormatEditor* _dcp_metadata_filename_format; NameFormatEditor* _dcp_asset_filename_format; diff --git a/test/dcp_decoder_test.cc b/test/dcp_decoder_test.cc new file mode 100644 index 000000000..64d35a2eb --- /dev/null +++ b/test/dcp_decoder_test.cc @@ -0,0 +1,140 @@ +/* + Copyright (C) 2019 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/>. + +*/ + +/** @file test/dcp_decoder_test.cc + * @brief Test DCPDecoder class. + * @ingroup selfcontained + */ + +#include "lib/film.h" +#include "lib/dcp_content.h" +#include "lib/dcp_decoder.h" +#include "lib/content_factory.h" +#include "lib/player.h" +#include "lib/examine_content_job.h" +#include "lib/job_manager.h" +#include "lib/config.h" +#include "test.h" +#include <dcp/dcp.h> +#include <boost/test/unit_test.hpp> +#include <iostream> + +using std::list; +using std::string; +using std::vector; +using boost::shared_ptr; + +/* Check that DCPDecoder reuses old data when it should */ +BOOST_AUTO_TEST_CASE (check_reuse_old_data_test) +{ + /* Make some DCPs */ + + shared_ptr<Film> 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)))); + vf->examine_and_add_content (ov_content); + vf->examine_and_add_content (content_factory("test/data/L.wav").front()); + BOOST_REQUIRE (!wait_for_jobs()); + ov_content->set_reference_video (true); + vf->make_dcp (); + BOOST_REQUIRE (!wait_for_jobs()); + + shared_ptr<Film> 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); + encrypted->make_dcp (); + BOOST_REQUIRE (!wait_for_jobs()); + + dcp::DCP encrypted_dcp (encrypted->dir(encrypted->dcp_name())); + encrypted_dcp.read (); + + dcp::EncryptedKDM kdm = encrypted->make_kdm ( + Config::instance()->decryption_chain()->leaf(), + vector<string>(), + encrypted_dcp.cpls().front()->file().get(), + dcp::LocalTime ("2014-07-21T00:00:00+00:00"), + dcp::LocalTime ("2024-07-21T00:00:00+00:00"), + dcp::MODIFIED_TRANSITIONAL_1, + true, 0 + ); + + + /* 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)))); + test->examine_and_add_content (ov_content); + BOOST_REQUIRE (!wait_for_jobs()); + shared_ptr<Player> player (new Player(test, test->playlist())); + + shared_ptr<DCPDecoder> decoder = boost::dynamic_pointer_cast<DCPDecoder>(player->_pieces.front()->decoder); + BOOST_REQUIRE (decoder); + list<shared_ptr<dcp::Reel> > reels = decoder->reels(); + + ov_content->set_position (test, dcpomatic::DCPTime(96000)); + decoder = boost::dynamic_pointer_cast<DCPDecoder>(player->_pieces.front()->decoder); + BOOST_REQUIRE (decoder); + BOOST_REQUIRE (reels == decoder->reels()); + + /* Add the VF to a new project, then add the OV and check that the + _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)))); + test->examine_and_add_content (vf_content); + BOOST_REQUIRE (!wait_for_jobs()); + player.reset (new Player(test, test->playlist())); + + decoder = boost::dynamic_pointer_cast<DCPDecoder>(player->_pieces.front()->decoder); + BOOST_REQUIRE (decoder); + reels = decoder->reels(); + + vf_content->add_ov (ov->dir(ov->dcp_name(false))); + JobManager::instance()->add (shared_ptr<Job>(new ExamineContentJob(test, vf_content))); + BOOST_REQUIRE (!wait_for_jobs()); + decoder = boost::dynamic_pointer_cast<DCPDecoder>(player->_pieces.front()->decoder); + BOOST_REQUIRE (decoder); + BOOST_REQUIRE (reels != decoder->reels()); + + /* 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)))); + test->examine_and_add_content (encrypted_content); + BOOST_REQUIRE (!wait_for_jobs()); + player.reset (new Player(test, test->playlist())); + + decoder = boost::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))); + BOOST_REQUIRE (!wait_for_jobs()); + decoder = boost::dynamic_pointer_cast<DCPDecoder>(player->_pieces.front()->decoder); + BOOST_REQUIRE (decoder); + BOOST_REQUIRE (reels != decoder->reels()); +} diff --git a/test/wscript b/test/wscript index 1d2fafc02..3c6170dcf 100644 --- a/test/wscript +++ b/test/wscript @@ -61,6 +61,7 @@ def build(bld): create_cli_test.cc crypto_test.cc dcpomatic_time_test.cc + dcp_decoder_test.cc dcp_playback_test.cc dcp_subtitle_test.cc digest_test.cc |
