Fix combining when two DCPs both contain copies of the same asset.
authorCarl Hetherington <cth@carlh.net>
Wed, 17 Mar 2021 21:38:08 +0000 (22:38 +0100)
committerCarl Hetherington <cth@carlh.net>
Wed, 17 Mar 2021 21:38:08 +0000 (22:38 +0100)
src/combine.cc
test/combine_test.cc

index dd8a145c7c6e8f3ce8b0e4e2e985d8fbb8d5fec5..da893cb73d5738cfcb6485e5c157671d720f78ab 100644 (file)
@@ -140,10 +140,6 @@ dcp::combine (
                                continue;
                        }
 
-                       auto file = j->file();
-                       DCP_ASSERT (file);
-                       path new_path = make_unique(output / file->filename());
-
                        auto sub = dynamic_pointer_cast<dcp::InteropSubtitleAsset>(j);
                        if (sub) {
                                /* Interop fonts are really fiddly.  The font files are assets (in the ASSETMAP)
@@ -155,16 +151,10 @@ dcp::combine (
                                for (auto const& k: fonts) {
                                        sub->set_font_file (k.first, make_unique(output / k.second.filename()));
                                }
-                               sub->write (new_path);
-                       } else if (!dynamic_pointer_cast<dcp::FontAsset>(j)) {
-                               /* Take care of everything else that's not a Interop subtitle asset, Interop font file
-                                * or CPL.
-                                */
-                               auto file = j->file();
+                               auto file = sub->file();
                                DCP_ASSERT (file);
                                path new_path = make_unique(output / file->filename());
-                               create_hard_link_or_copy (*file, new_path);
-                               j->set_file (new_path);
+                               sub->write (new_path);
                        }
 
                        assets.push_back (j);
@@ -172,5 +162,16 @@ dcp::combine (
        }
 
        output_dcp.resolve_refs (assets);
+
+       for (auto i: output_dcp.assets()) {
+               if (!dynamic_pointer_cast<dcp::FontAsset>(i) && !dynamic_pointer_cast<dcp::CPL>(i)) {
+                       auto file = i->file();
+                       DCP_ASSERT (file);
+                       path new_path = make_unique(output / file->filename());
+                       create_hard_link_or_copy (*file, new_path);
+                       i->set_file (new_path);
+               }
+       }
+
        output_dcp.write_xml (*standard, issuer, creator, issue_date, annotation_text, signer);
 }
index 09a4577021ea314f09dbf909960b762e040688ea..59931be7b41611a0d143dc839c9a15ab4ea7c2c2 100644 (file)
@@ -348,5 +348,56 @@ BOOST_AUTO_TEST_CASE (combine_two_dcps_with_shared_asset)
 }
 
 
+/** Two DCPs each with a copy of the exact same asset */
+BOOST_AUTO_TEST_CASE (combine_two_dcps_with_duplicated_asset)
+{
+       using namespace boost::filesystem;
+       boost::filesystem::path const out = "build/test/combine_two_dcps_with_duplicated_asset";
+
+       auto first = make_simple ("build/test/combine_input1", 1);
+       first->write_xml (dcp::Standard::SMPTE);
+
+       remove_all ("build/test/combine_input2");
+       auto second = make_shared<dcp::DCP>("build/test/combine_input2");
+
+       dcp::MXFMetadata mxf_meta;
+       mxf_meta.company_name = "OpenDCP";
+       mxf_meta.product_version = "0.0.25";
+
+       auto cpl = make_shared<dcp::CPL>("A Test DCP", dcp::ContentKind::TRAILER);
+       cpl->set_content_version (
+               dcp::ContentVersion("urn:uuid:75ac29aa-42ac-1234-ecae-49251abefd11","content-version-label-text")
+               );
+       cpl->set_main_sound_configuration ("L,C,R,Lfe,-,-");
+       cpl->set_main_sound_sample_rate (48000);
+       cpl->set_main_picture_stored_area (dcp::Size(1998, 1080));
+       cpl->set_main_picture_active_area (dcp::Size(1440, 1080));
+       cpl->set_version_number(1);
+
+       auto pic = make_shared<dcp::ReelMonoPictureAsset>(simple_picture("build/test/combine_input2", ""), 0);
+       auto first_sound_asset = first->cpls()[0]->reels()[0]->main_sound()->asset()->file();
+       BOOST_REQUIRE (first_sound_asset);
+       boost::filesystem::path second_sound_asset = "build/test/combine_input2/my_great_audio.mxf";
+       boost::filesystem::copy_file (*first_sound_asset, second_sound_asset);
+       auto sound = make_shared<dcp::ReelSoundAsset>(make_shared<dcp::SoundAsset>(second_sound_asset), 0);
+       auto reel = make_shared<dcp::Reel>(pic, sound);
+       reel->add (simple_markers());
+       cpl->add (reel);
+       second->add (cpl);
+       second->write_xml (dcp::Standard::SMPTE);
+
+       remove_all (out);
+       vector<path> inputs;
+       inputs.push_back ("build/test/combine_input1");
+       inputs.push_back ("build/test/combine_input2");
+       dcp::combine (inputs, out);
+
+       check_no_errors (out);
+       check_combined (inputs, out);
+
+       BOOST_REQUIRE (!boost::filesystem::exists(out / "my_great_audio.mxf"));
+}
+
+
 /* XXX: same CPL names */
 /* XXX: Interop PNG subs */