Allow content factory to return multiple content.
authorCarl Hetherington <cth@carlh.net>
Tue, 20 Dec 2016 16:18:24 +0000 (16:18 +0000)
committerCarl Hetherington <cth@carlh.net>
Tue, 20 Dec 2016 16:18:24 +0000 (16:18 +0000)
12 files changed:
src/lib/content_factory.cc
src/lib/content_factory.h
src/tools/dcpomatic.cc
src/tools/dcpomatic_create.cc
src/wx/content_menu.cc
src/wx/content_panel.cc
test/audio_analysis_test.cc
test/audio_decoder_test.cc
test/burnt_subtitle_test.cc
test/required_disk_space_test.cc
test/vf_test.cc
test/video_mxf_content_test.cc

index d3905e4e7c443a2d0c59bb06947f57b669c09f46..9dd04203790e5d3abf8b03cd4780e9001ab287f6 100644 (file)
@@ -100,22 +100,22 @@ content_factory (shared_ptr<const Film> film, cxml::NodePtr node, int version, l
        return content;
 }
 
-/** Create a Content object from a file or directory.
+/** Create some Content objects from a file or directory.
  *  @param film Film that the content will be in.
  *  @param path File or directory.
- *  @return Content object.
+ *  @return Content objects.
  */
-shared_ptr<Content>
+list<shared_ptr<Content> >
 content_factory (shared_ptr<const Film> film, boost::filesystem::path path)
 {
-       shared_ptr<Content> content;
+       list<shared_ptr<Content> > content;
 
        if (boost::filesystem::is_directory (path)) {
 
                LOG_GENERAL ("Look in directory %1", path);
 
                if (boost::filesystem::is_empty (path)) {
-                       return shared_ptr<Content> ();
+                       return content;
                }
 
                /* Guess if this is a DCP or a set of images: read the first ten filenames and if they
@@ -152,33 +152,37 @@ content_factory (shared_ptr<const Film> film, boost::filesystem::path path)
                }
 
                if (is_dcp) {
-                       content.reset (new DCPContent (film, path));
+                       content.push_back (shared_ptr<Content> (new DCPContent (film, path)));
                } else {
-                       content.reset (new ImageContent (film, path));
+                       content.push_back (shared_ptr<Content> (new ImageContent (film, path)));
                }
 
        } else {
 
+               shared_ptr<Content> single;
+
                string ext = path.extension().string ();
                transform (ext.begin(), ext.end(), ext.begin(), ::tolower);
 
                if (valid_image_file (path)) {
-                       content.reset (new ImageContent (film, path));
+                       single.reset (new ImageContent (film, path));
                } else if (ext == ".srt" || ext == ".ssa" || ext == ".ass") {
-                       content.reset (new TextSubtitleContent (film, path));
+                       single.reset (new TextSubtitleContent (film, path));
                } else if (ext == ".xml") {
-                       content.reset (new DCPSubtitleContent (film, path));
+                       single.reset (new DCPSubtitleContent (film, path));
                } else if (ext == ".mxf" && dcp::SMPTESubtitleAsset::valid_mxf (path)) {
-                       content.reset (new DCPSubtitleContent (film, path));
+                       single.reset (new DCPSubtitleContent (film, path));
                } else if (ext == ".mxf" && VideoMXFContent::valid_mxf (path)) {
-                       content.reset (new VideoMXFContent (film, path));
+                       single.reset (new VideoMXFContent (film, path));
                } else if (ext == ".mxf" && AtmosMXFContent::valid_mxf (path)) {
-                       content.reset (new AtmosMXFContent (film, path));
+                       single.reset (new AtmosMXFContent (film, path));
                }
 
-               if (!content) {
-                       content.reset (new FFmpegContent (film, path));
+               if (!single) {
+                       single.reset (new FFmpegContent (film, path));
                }
+
+               content.push_back (single);
        }
 
        return content;
index b319febfcbec5cc301a835b69d2a54b8a173d660..9c090c690e3f2bc2ebf31442246723c9e0d5830f 100644 (file)
@@ -29,4 +29,4 @@ class Film;
 class Content;
 
 extern boost::shared_ptr<Content> content_factory (boost::shared_ptr<const Film>, cxml::NodePtr, int, std::list<std::string> &);
-extern boost::shared_ptr<Content> content_factory (boost::shared_ptr<const Film>, boost::filesystem::path);
+extern std::list<boost::shared_ptr<Content> > content_factory (boost::shared_ptr<const Film>, boost::filesystem::path);
index aa37f2fb7d81b37099ef0765f43b2a56ec8e8533..097b7905a79beefa84a04827f163333c2427c788 100644 (file)
@@ -76,6 +76,7 @@
 #endif
 #include <boost/filesystem.hpp>
 #include <boost/noncopyable.hpp>
+#include <boost/foreach.hpp>
 #include <iostream>
 #include <fstream>
 /* This is OK as it's only used with DCPOMATIC_WINDOWS */
@@ -1094,7 +1095,9 @@ private:
                if (!_film_to_create.empty ()) {
                        _frame->new_film (_film_to_create, optional<string> ());
                        if (!_content_to_add.empty ()) {
-                               _frame->film()->examine_and_add_content (content_factory (_frame->film(), _content_to_add));
+                               BOOST_FOREACH (shared_ptr<Content> i, content_factory (_frame->film(), _content_to_add)) {
+                                       _frame->film()->examine_and_add_content (i);
+                               }
                        }
                }
 
index c14522a02ed50c77ffdd15c8346842f22843d8ed..0582f5cac0d5701ac2912faccf675355ecd9ff84 100644 (file)
@@ -32,6 +32,7 @@
 #include "lib/cross.h"
 #include <libxml++/libxml++.h>
 #include <boost/filesystem.hpp>
+#include <boost/foreach.hpp>
 #include <getopt.h>
 #include <string>
 #include <iostream>
@@ -227,11 +228,12 @@ main (int argc, char* argv[])
                film->set_signed (sign);
 
                for (int i = optind; i < argc; ++i) {
-                       shared_ptr<Content> c = content_factory (film, boost::filesystem::canonical (argv[i]));
-                       if (c->video) {
-                               c->video->set_scale (VideoContentScale (content_ratio));
+                       BOOST_FOREACH (shared_ptr<Content> j, content_factory (film, boost::filesystem::canonical (argv[i]))) {
+                               if (j->video) {
+                                       j->video->set_scale (VideoContentScale (content_ratio));
+                               }
+                               film->examine_and_add_content (j);
                        }
-                       film->examine_and_add_content (c);
                }
 
                JobManager* jm = JobManager::instance ();
index 0240a8c3372e2789821fb5db0e23fca8be4e2db5..42969995643eb2d94ffa9c0066574720e53f063c 100644 (file)
@@ -278,8 +278,6 @@ ContentMenu::find_missing ()
                return;
        }
 
-       shared_ptr<Content> content;
-
        /* XXX: a bit nasty */
        shared_ptr<ImageContent> ic = dynamic_pointer_cast<ImageContent> (_content.front ());
        shared_ptr<DCPContent> dc = dynamic_pointer_cast<DCPContent> (_content.front ());
@@ -299,27 +297,31 @@ ContentMenu::find_missing ()
                d->Destroy ();
        }
 
+       list<shared_ptr<Content> > content;
+
        if (r == wxID_OK) {
                content = content_factory (film, path);
        }
 
-       if (!content) {
+       if (content.empty ()) {
                return;
        }
 
-       shared_ptr<Job> j (new ExamineContentJob (film, content));
+       BOOST_FOREACH (shared_ptr<Content> i, content) {
+               shared_ptr<Job> j (new ExamineContentJob (film, i));
 
-       j->Finished.connect (
-               bind (
-                       &ContentMenu::maybe_found_missing,
-                       this,
-                       boost::weak_ptr<Job> (j),
-                       boost::weak_ptr<Content> (_content.front ()),
-                       boost::weak_ptr<Content> (content)
-                       )
-               );
+               j->Finished.connect (
+                       bind (
+                               &ContentMenu::maybe_found_missing,
+                               this,
+                               boost::weak_ptr<Job> (j),
+                               boost::weak_ptr<Content> (_content.front ()),
+                               boost::weak_ptr<Content> (i)
+                               )
+                       );
 
-       JobManager::instance()->add (j);
+               JobManager::instance()->add (j);
+       }
 }
 
 void
index b67bdb4eb77ad612e384be062a16c24cf07854cc..816512fb6f1ab8507fc3fe6f52be4f5addadf4f2 100644 (file)
@@ -310,7 +310,7 @@ ContentPanel::add_folder_clicked ()
                return;
        }
 
-       shared_ptr<Content> content;
+       list<shared_ptr<Content> > content;
 
        try {
                content = content_factory (_film, path);
@@ -319,26 +319,28 @@ ContentPanel::add_folder_clicked ()
                return;
        }
 
-       if (!content) {
+       if (content.empty ()) {
                error_dialog (_parent, _("No content found in this folder."));
                return;
        }
 
-       shared_ptr<ImageContent> ic = dynamic_pointer_cast<ImageContent> (content);
-       if (ic) {
-               ImageSequenceDialog* e = new ImageSequenceDialog (_panel);
-               r = e->ShowModal ();
-               float const frame_rate = e->frame_rate ();
-               e->Destroy ();
-
-               if (r != wxID_OK) {
-                       return;
+       BOOST_FOREACH (shared_ptr<Content> i, content) {
+               shared_ptr<ImageContent> ic = dynamic_pointer_cast<ImageContent> (i);
+               if (ic) {
+                       ImageSequenceDialog* e = new ImageSequenceDialog (_panel);
+                       r = e->ShowModal ();
+                       float const frame_rate = e->frame_rate ();
+                       e->Destroy ();
+
+                       if (r != wxID_OK) {
+                               return;
+                       }
+
+                       ic->set_video_frame_rate (frame_rate);
                }
 
-               ic->set_video_frame_rate (frame_rate);
+               _film->examine_and_add_content (i);
        }
-
-       _film->examine_and_add_content (content);
 }
 
 /** @return true if this remove "click" should be ignored */
@@ -583,7 +585,9 @@ ContentPanel::add_files (list<boost::filesystem::path> paths)
 
        /* XXX: check for lots of files here and do something */
 
-       for (list<boost::filesystem::path>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
-               _film->examine_and_add_content (content_factory (_film, *i));
+       BOOST_FOREACH (boost::filesystem::path i, paths) {
+               BOOST_FOREACH (shared_ptr<Content> j, content_factory (_film, i)) {
+                       _film->examine_and_add_content (j);
+               }
        }
 }
index 8328c7cd25d9cb03b62d84c83589af69de497b79..ae5fd08344017f1291e0d7bc60e900ec55d6b716 100644 (file)
@@ -182,7 +182,7 @@ BOOST_AUTO_TEST_CASE (analyse_audio_test4)
        film->set_container (Ratio::from_id ("185"));
        film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
        film->set_name ("frobozz");
-       shared_ptr<Content> content = content_factory (film, private_data / "20 The Wedding Convoy Song.m4a");
+       shared_ptr<Content> content = content_factory(film, private_data / "20 The Wedding Convoy Song.m4a").front();
        film->examine_and_add_content (content);
        wait_for_jobs ();
 
index 273d04344d79b23f7ac449747a8480629cda6e6f..57852dcb981b57070a4dc3a0f372a68c76899956 100644 (file)
@@ -159,7 +159,7 @@ BOOST_AUTO_TEST_CASE (audio_decoder_test)
        film->set_container (Ratio::from_id ("185"));
        film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
        film->set_name ("frobozz");
-       shared_ptr<Content> content = content_factory (film, private_data / "20 The Wedding Convoy Song.m4a");
+       shared_ptr<Content> content = content_factory(film, private_data / "20 The Wedding Convoy Song.m4a").front();
        film->examine_and_add_content (content);
        wait_for_jobs ();
 
index 01e80c783c49b4e56e87fbb08bb238621119ec0c..e8c3f359763027a2526582565a90c56cc3ff0016 100644 (file)
@@ -91,7 +91,7 @@ BOOST_AUTO_TEST_CASE (burnt_subtitle_test_onto_dcp)
        film->set_container (Ratio::from_id ("185"));
        film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
        film->set_name ("frobozz");
-       film->examine_and_add_content (content_factory (film, "test/data/flat_white.png"));
+       film->examine_and_add_content (content_factory(film, "test/data/flat_white.png").front());
        wait_for_jobs ();
        film->make_dcp ();
        wait_for_jobs ();
@@ -100,7 +100,7 @@ BOOST_AUTO_TEST_CASE (burnt_subtitle_test_onto_dcp)
        film2->set_container (Ratio::from_id ("185"));
        film2->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
        film2->set_name ("frobozz");
-       film2->examine_and_add_content (content_factory (film2, film->dir (film->dcp_name ())));
+       film2->examine_and_add_content (content_factory(film2, film->dir (film->dcp_name ())).front());
        shared_ptr<TextSubtitleContent> sub = dynamic_pointer_cast<TextSubtitleContent> (
                content_factory (film2, "test/data/subrip2.srt")
                );
index 29e8ad05ce7c8021f7b3f57cbe5e21b4a704d074..24ca4cac4921cbaa8e6e0d0a4cf28506803b0d72 100644 (file)
@@ -38,9 +38,9 @@ BOOST_AUTO_TEST_CASE (required_disk_space_test)
        shared_ptr<Film> film = new_test_film ("required_disk_space_test");
        film->set_j2k_bandwidth (100000000);
        film->set_audio_channels (6);
-       shared_ptr<Content> content_a = content_factory (film, "test/data/flat_blue.png");
+       shared_ptr<Content> content_a = content_factory(film, "test/data/flat_blue.png").front();
        film->examine_and_add_content (content_a);
-       shared_ptr<DCPContent> content_b = dynamic_pointer_cast<DCPContent> (content_factory (film, "test/data/burnt_subtitle_test_dcp"));
+       shared_ptr<DCPContent> content_b = dynamic_pointer_cast<DCPContent> (content_factory(film, "test/data/burnt_subtitle_test_dcp").front());
        film->examine_and_add_content (content_b);
        wait_for_jobs ();
        film->write_metadata ();
index 8fbb9b9d427e0ecde7013cb90bdc69c01617a522..f4f8fb2a68f55e702dd34309877adf18db121ffc 100644 (file)
@@ -84,11 +84,11 @@ BOOST_AUTO_TEST_CASE (vf_test2)
        shared_ptr<Film> ov = new_test_film ("vf_test2_ov");
        ov->set_dcp_content_type (DCPContentType::from_isdcf_name ("TST"));
        ov->set_name ("vf_test2_ov");
-       shared_ptr<Content> video = content_factory (ov, "test/data/flat_red.png");
+       shared_ptr<Content> video = content_factory (ov, "test/data/flat_red.png").front();
        ov->examine_and_add_content (video);
        wait_for_jobs ();
        video->video->set_length (24 * 5);
-       shared_ptr<Content> audio = content_factory (ov, "test/data/white.wav");
+       shared_ptr<Content> audio = content_factory(ov, "test/data/white.wav").front();
        ov->examine_and_add_content (audio);
        wait_for_jobs ();
        ov->make_dcp ();
@@ -99,13 +99,13 @@ BOOST_AUTO_TEST_CASE (vf_test2)
        vf->set_name ("vf_test2_vf");
        vf->set_dcp_content_type (DCPContentType::from_isdcf_name ("TST"));
        vf->set_reel_type (REELTYPE_BY_VIDEO_CONTENT);
-       shared_ptr<DCPContent> dcp = dynamic_pointer_cast<DCPContent> (content_factory (vf, ov->dir (ov->dcp_name ())));
+       shared_ptr<DCPContent> dcp = dynamic_pointer_cast<DCPContent> (content_factory (vf, ov->dir (ov->dcp_name ())).front());
        BOOST_REQUIRE (dcp);
        vf->examine_and_add_content (dcp);
        wait_for_jobs ();
        dcp->set_reference_video (true);
        dcp->set_reference_audio (true);
-       shared_ptr<Content> sub = content_factory (vf, "test/data/subrip4.srt");
+       shared_ptr<Content> sub = content_factory(vf, "test/data/subrip4.srt").front();
        vf->examine_and_add_content (sub);
        vf->make_dcp ();
        wait_for_jobs ();
@@ -141,11 +141,11 @@ BOOST_AUTO_TEST_CASE (vf_test3)
        shared_ptr<Film> ov = new_test_film ("vf_test3_ov");
        ov->set_dcp_content_type (DCPContentType::from_isdcf_name ("TST"));
        ov->set_name ("vf_test3_ov");
-       shared_ptr<Content> video = content_factory (ov, "test/data/flat_red.png");
+       shared_ptr<Content> video = content_factory(ov, "test/data/flat_red.png").front();
        ov->examine_and_add_content (video);
        wait_for_jobs ();
        video->video->set_length (24 * 5);
-       shared_ptr<Content> audio = content_factory (ov, "test/data/white.wav");
+       shared_ptr<Content> audio = content_factory(ov, "test/data/white.wav").front();
        ov->examine_and_add_content (audio);
        wait_for_jobs ();
        ov->make_dcp ();
@@ -156,7 +156,7 @@ BOOST_AUTO_TEST_CASE (vf_test3)
        vf->set_name ("vf_test3_vf");
        vf->set_dcp_content_type (DCPContentType::from_isdcf_name ("TST"));
        vf->set_reel_type (REELTYPE_BY_VIDEO_CONTENT);
-       shared_ptr<DCPContent> dcp = dynamic_pointer_cast<DCPContent> (content_factory (vf, ov->dir (ov->dcp_name ())));
+       shared_ptr<DCPContent> dcp = dynamic_pointer_cast<DCPContent> (content_factory(vf, ov->dir (ov->dcp_name ())).front());
        BOOST_REQUIRE (dcp);
        dcp->set_trim_start (ContentTime::from_seconds (1));
        dcp->set_trim_end (ContentTime::from_seconds (1));
index 953e9b7b705641b581c35c34de8b1048c86fd0b1..bdd35713c7329232f5c645af07acd2b166cd9136 100644 (file)
@@ -45,7 +45,7 @@ BOOST_AUTO_TEST_CASE (video_mxf_content_test)
        film->set_container (Ratio::from_id ("185"));
        film->set_name ("video_mxf_content_test");
 
-       shared_ptr<Content> content = content_factory (film, ref_mxf);
+       shared_ptr<Content> content = content_factory(film, ref_mxf).front();
        shared_ptr<VideoMXFContent> check = dynamic_pointer_cast<VideoMXFContent> (content);
        BOOST_REQUIRE (check);
        film->examine_and_add_content (content);