Fix bug causing failure to decrypt SMPTE subtitles.
authorCarl Hetherington <cth@carlh.net>
Thu, 27 May 2021 12:19:40 +0000 (14:19 +0200)
committerCarl Hetherington <cth@carlh.net>
Thu, 27 May 2021 12:25:17 +0000 (14:25 +0200)
src/reel.cc
test/decryption_test.cc

index e99f7140d809cb568befc96467da0daadb7e0bc4..daa1067c80c3dacb4ba4229cabeabebabf28b616 100644 (file)
@@ -322,7 +322,7 @@ Reel::add (DecryptedKDM const & kdm)
                        _main_sound->asset()->set_key (i.key());
                }
                if (_main_subtitle) {
-                       auto smpte = dynamic_pointer_cast<ReelSMPTESubtitleAsset>(_main_picture);
+                       auto smpte = dynamic_pointer_cast<ReelSMPTESubtitleAsset>(_main_subtitle);
                        if (smpte && i.id() == smpte->key_id()) {
                                smpte->smpte_asset()->set_key(i.key());
                        }
index 26005d1200d6a7c60c753c40304df692a8a9150c..708f222bb899ddc6dbed562a3c37355ef3cf011b 100644 (file)
@@ -86,7 +86,7 @@ get_frame (dcp::DCP const & dcp)
 }
 
 /** Decrypt an encrypted test DCP and check that its first frame is the same as the unencrypted version */
-BOOST_AUTO_TEST_CASE (decryption_test)
+BOOST_AUTO_TEST_CASE (decryption_test1)
 {
        boost::filesystem::path plaintext_path = private_test;
        plaintext_path /= "TONEPLATES-SMPTE-PLAINTEXT_TST_F_XX-XX_ITL-TD_51-XX_2K_WOE_20111001_WOE_OV";
@@ -137,3 +137,104 @@ BOOST_AUTO_TEST_CASE (failing_kdm_test)
                dcp::file_to_string ("test/data/private.key")
                );
 }
+
+
+/** Make an encrypted SMPTE DCP with picture, sound and subs and check that the keys get distributed to the assets
+ *  when we read it back in.
+ */
+BOOST_AUTO_TEST_CASE (decryption_test2)
+{
+       boost::filesystem::path dir = "build/test/decryption_test2";
+       boost::filesystem::create_directory(dir);
+
+       auto context_id = dcp::make_uuid();
+       dcp::Key key;
+
+       auto picture_asset = make_shared<dcp::MonoPictureAsset>(dcp::Fraction(24, 1), dcp::Standard::SMPTE);
+       picture_asset->set_key (key);
+       picture_asset->set_context_id (context_id);
+       auto picture_writer = picture_asset->start_write(dir / "picture.mxf", false);
+       dcp::ArrayData picture("test/data/flat_red.j2c");
+       for (int i = 0; i < 24; ++i) {
+               picture_writer->write(picture);
+       }
+       picture_writer->finalize();
+
+       auto sound_asset = make_shared<dcp::SoundAsset>(dcp::Fraction(24, 1), 48000, 2, dcp::LanguageTag("en-GB"), dcp::Standard::SMPTE);
+       sound_asset->set_key (key);
+       sound_asset->set_context_id (context_id);
+       auto sound_writer = sound_asset->start_write(dir / "sound.mxf");
+       std::array<float, 48000> left;
+       std::array<float, 48000> right;
+       for (int i = 0; i < 48000; ++i) {
+               left[i] = sin (2 * M_PI * i * 440 / 48000) * 0.25;
+               right[i] = sin (2 * M_PI * i * 880 / 48000) * 0.25;
+       }
+       std::array<float*, 2> audio;
+       audio[0] = left.data();
+       audio[1] = right.data();
+       sound_writer->write (audio.data(), 48000);
+       sound_writer->finalize ();
+
+       auto subs_asset = make_shared<dcp::SMPTESubtitleAsset>();
+       subs_asset->set_key (key);
+       subs_asset->set_context_id (context_id);
+       subs_asset->add(make_shared<dcp::SubtitleString>(
+               optional<string>(),
+               false, false, false,
+               dcp::Colour(255, 255, 255),
+               42,
+               1,
+               dcp::Time(),
+               dcp::Time(0, 0, 5, 0, 24),
+               0.5, dcp::HAlign::CENTER,
+               0.5, dcp::VAlign::CENTER,
+               dcp::Direction::LTR,
+               "Hello world",
+               dcp::Effect::NONE,
+               dcp::Colour(0, 0, 0),
+               dcp::Time(), dcp::Time()
+               ));
+       subs_asset->write (dir / "subs.mxf");
+
+       auto reel = make_shared<dcp::Reel>();
+       auto reel_picture_asset = make_shared<dcp::ReelMonoPictureAsset>(picture_asset, 0);
+       auto reel_sound_asset = make_shared<dcp::ReelSoundAsset>(sound_asset, 0);
+       auto reel_subs_asset = make_shared<dcp::ReelSMPTESubtitleAsset>(subs_asset, dcp::Fraction(24, 1), 120, 0);
+       reel->add(reel_picture_asset);
+       reel->add(reel_sound_asset);
+       reel->add(reel_subs_asset);
+
+       auto cpl = std::make_shared<dcp::CPL>("My film", dcp::ContentKind::FEATURE, dcp::Standard::SMPTE);
+       cpl->add(reel);
+
+       dcp::DCP dcp (dir);
+       dcp.add (cpl);
+       dcp.write_xml ();
+
+       map<shared_ptr<const dcp::ReelFileAsset>, dcp::Key> keys;
+       keys[reel_picture_asset] = key;
+       keys[reel_sound_asset] = key;
+       keys[reel_subs_asset] = key;
+
+       dcp::DecryptedKDM kdm (cpl->id(), keys, dcp::LocalTime(), dcp::LocalTime(), "foo", "bar", "baz");
+
+       dcp::DCP dcp_read (dir);
+       dcp_read.read ();
+       dcp_read.add (kdm);
+
+       BOOST_REQUIRE_EQUAL (dcp_read.cpls().size(), 1U);
+       auto cpl_read = dcp_read.cpls()[0];
+       BOOST_REQUIRE_EQUAL (cpl_read->reels().size(), 1U);
+       auto reel_read = cpl_read->reels()[0];
+
+       BOOST_REQUIRE (reel_read->main_picture());
+       BOOST_CHECK (reel_read->main_picture()->asset()->key());
+       BOOST_REQUIRE (reel_read->main_sound());
+       BOOST_CHECK (reel_read->main_sound()->asset()->key());
+       BOOST_REQUIRE (reel_read->main_subtitle());
+       auto smpte_sub = dynamic_pointer_cast<dcp::SMPTESubtitleAsset>(reel_read->main_subtitle()->asset());
+       BOOST_REQUIRE (smpte_sub);
+       BOOST_CHECK (smpte_sub->key());
+}
+