Hand-apply 6a3cd511559433554ab40ed72ff94b7d8dc2c5bd from master;
authorCarl Hetherington <cth@carlh.net>
Wed, 3 Dec 2014 10:12:35 +0000 (10:12 +0000)
committerCarl Hetherington <cth@carlh.net>
Wed, 3 Dec 2014 10:12:35 +0000 (10:12 +0000)
Basics of an image sequence dialog that asks about frame rate and
digest calculation.

57 files changed:
src/lib/content.cc
src/lib/content.h
src/lib/dcp_content.cc
src/lib/dcp_content.h
src/lib/dcp_examiner.h
src/lib/dcp_subtitle_content.cc
src/lib/dcp_subtitle_content.h
src/lib/examine_content_job.cc
src/lib/examine_content_job.h
src/lib/ffmpeg_content.cc
src/lib/ffmpeg_content.h
src/lib/ffmpeg_examiner.cc
src/lib/ffmpeg_examiner.h
src/lib/film.cc
src/lib/film.h
src/lib/image_content.cc
src/lib/image_content.h
src/lib/image_examiner.cc
src/lib/image_examiner.h
src/lib/sndfile_content.cc
src/lib/sndfile_content.h
src/lib/subrip_content.cc
src/lib/subrip_content.h
src/lib/video_content.cc
src/lib/video_examiner.h
src/tools/dcpomatic.cc
src/tools/dcpomatic_create.cc
src/wx/content_menu.cc
src/wx/content_panel.cc
src/wx/image_sequence_dialog.cc [new file with mode: 0644]
src/wx/image_sequence_dialog.h [new file with mode: 0644]
src/wx/wscript
test/4k_test.cc
test/audio_analysis_test.cc
test/audio_delay_test.cc
test/black_fill_test.cc
test/burnt_subtitle_test.cc
test/dcp_subtitle_test.cc
test/ffmpeg_audio_test.cc
test/ffmpeg_dcp_test.cc
test/ffmpeg_decoder_seek_test.cc
test/ffmpeg_decoder_sequential_test.cc
test/frame_rate_test.cc
test/import_dcp_test.cc
test/isdcf_name_test.cc
test/play_test.cc
test/player_test.cc
test/recover_test.cc
test/repeat_frame_test.cc
test/scaling_test.cc
test/seek_zero_test.cc
test/silence_padding_test.cc
test/skip_frame_test.cc
test/subrip_test.cc
test/threed_test.cc
test/upmixer_a_test.cc
test/xml_subtitle_test.cc

index 21e49a2c955ae7e74091ec5c1a43f4e9e238b857..6e02183233da9f6f288794d61de2835bc439c8d1 100644 (file)
@@ -32,6 +32,7 @@
 #include "exceptions.h"
 #include "film.h"
 #include "safe_stringstream.h"
+#include "job.h"
 
 #include "i18n.h"
 
@@ -131,8 +132,14 @@ Content::as_xml (xmlpp::Node* node) const
 }
 
 void
-Content::examine (shared_ptr<Job> job)
+Content::examine (shared_ptr<Job> job, bool calculate_digest)
 {
+       if (!calculate_digest) {
+               return;
+       }
+
+       job->sub (_("Computing digest"));
+       
        boost::mutex::scoped_lock lm (_mutex);
        vector<boost::filesystem::path> p = _paths;
        lm.unlock ();
index f7e97feac9a3489d1083f96278a4eea3e491d367..0b72ada9c52a55d7b822829dce94ceeac134f24c 100644 (file)
@@ -67,8 +67,9 @@ public:
        /** Examine the content to establish digest, frame rates and any other
         *  useful metadata.
         *  @param job Job to use to report progress, or 0.
+        *  @param calculate_digest True to calculate a digest for the content's file(s).
         */
-       virtual void examine (boost::shared_ptr<Job> job);
+       virtual void examine (boost::shared_ptr<Job> job, bool calculate_digest);
        
        /** @return Quick one-line summary of the content, as will be presented in the
         *  film editor.
index a5b5f37e13f967a9c4845d707000f19049c140cb..28b7ac8620138ebda61caaac00c4d6b364046b6c 100644 (file)
@@ -77,12 +77,12 @@ DCPContent::read_directory (boost::filesystem::path p)
 }
 
 void
-DCPContent::examine (shared_ptr<Job> job)
+DCPContent::examine (shared_ptr<Job> job, bool calculate_digest)
 {
        bool const could_be_played = can_be_played ();
                
        job->set_progress_unknown ();
-       Content::examine (job);
+       Content::examine (job, calculate_digest);
        
        shared_ptr<DCPExaminer> examiner (new DCPExaminer (shared_from_this ()));
        take_from_video_examiner (examiner);
index da78e6d72a5cc0bd22f7f111c875013d41609ee3..d6fe8c8207a237223a07e8d708d66d68c8613d7a 100644 (file)
@@ -52,7 +52,7 @@ public:
 
        DCPTime full_length () const;
        
-       void examine (boost::shared_ptr<Job>);
+       void examine (boost::shared_ptr<Job>, bool calculate_digest);
        std::string summary () const;
        std::string technical_summary () const;
        void as_xml (xmlpp::Node *) const;
index 03d43d0f6c9f7a270ab2f2b16d147c4389ec289d..ef780dc3e9876d124493109315f5e1b3a9214bfd 100644 (file)
@@ -27,8 +27,8 @@ class DCPExaminer : public VideoExaminer, public AudioExaminer
 public:
        DCPExaminer (boost::shared_ptr<const DCPContent>);
        
-       float video_frame_rate () const {
-               return _video_frame_rate.get_value_or (24);
+       boost::optional<float> video_frame_rate () const {
+               return _video_frame_rate;
        }
        
        dcp::Size video_size () const {
index 83b0d200cee33146c6f92b33a1de1bd0b34df0da..1935a874f7870dadfd8a6517d9acb13f9b6d09cf 100644 (file)
@@ -44,9 +44,9 @@ DCPSubtitleContent::DCPSubtitleContent (shared_ptr<const Film> film, cxml::Const
 }
 
 void
-DCPSubtitleContent::examine (shared_ptr<Job> job)
+DCPSubtitleContent::examine (shared_ptr<Job> job, bool calculate_digest)
 {
-       Content::examine (job);
+       Content::examine (job, calculate_digest);
        dcp::SubtitleContent sc (path (0), false);
        _length = DCPTime::from_seconds (sc.latest_subtitle_out().to_seconds ());
 }
index 5794b59516e6767f586cc5d0a33663b2ed9ef376..551dafd15e5f5ed25ff23d64976eac626b8ef2a9 100644 (file)
@@ -26,7 +26,7 @@ public:
        DCPSubtitleContent (boost::shared_ptr<const Film>, cxml::ConstNodePtr, int);
 
        /* Content */
-       void examine (boost::shared_ptr<Job>);
+       void examine (boost::shared_ptr<Job>, bool calculate_digest);
        std::string summary () const;
        std::string technical_summary () const;
        std::string information () const;
index cbf180ffcb3bf451379e410039d5d28dfed75d80..ee887271fd7ffbb8690cc86bc579aabec39749d9 100644 (file)
@@ -29,9 +29,10 @@ using std::string;
 using std::cout;
 using boost::shared_ptr;
 
-ExamineContentJob::ExamineContentJob (shared_ptr<const Film> f, shared_ptr<Content> c)
+ExamineContentJob::ExamineContentJob (shared_ptr<const Film> f, shared_ptr<Content> c, bool calculate_digest)
        : Job (f)
        , _content (c)
+       , _calculate_digest (calculate_digest)
 {
 
 }
@@ -49,7 +50,7 @@ ExamineContentJob::name () const
 void
 ExamineContentJob::run ()
 {
-       _content->examine (shared_from_this ());
+       _content->examine (shared_from_this (), _calculate_digest);
        set_progress (1);
        set_state (FINISHED_OK);
 }
index b6903b86bebf0ed9e80970a7382c0f07628301cc..f0d9eae930c9ce6d8ef7ef6ac8d876240ca793d0 100644 (file)
@@ -26,7 +26,7 @@ class Log;
 class ExamineContentJob : public Job
 {
 public:
-       ExamineContentJob (boost::shared_ptr<const Film>, boost::shared_ptr<Content>);
+       ExamineContentJob (boost::shared_ptr<const Film>, boost::shared_ptr<Content>, bool calculate_digest);
        ~ExamineContentJob ();
 
        std::string name () const;
@@ -34,5 +34,6 @@ public:
 
 private:
        boost::shared_ptr<Content> _content;
+       bool _calculate_digest;
 };
 
index bb4e022308dc9882dff57d5a0959d0a014cf9cab..a186db48eaecff51d6f0f1b6fa59f508378ab5ed 100644 (file)
@@ -163,11 +163,11 @@ FFmpegContent::as_xml (xmlpp::Node* node) const
 }
 
 void
-FFmpegContent::examine (shared_ptr<Job> job)
+FFmpegContent::examine (shared_ptr<Job> job, bool calculate_digest)
 {
        job->set_progress_unknown ();
 
-       Content::examine (job);
+       Content::examine (job, calculate_digest);
 
        shared_ptr<FFmpegExaminer> examiner (new FFmpegExaminer (shared_from_this ()));
        take_from_video_examiner (examiner);
index da8152c0d92816de44a576f718a15f9f94c5db24..fca3bf8beb3e52afff2494b0b5addbdfd198c2fd 100644 (file)
@@ -56,7 +56,7 @@ public:
                return boost::dynamic_pointer_cast<FFmpegContent> (Content::shared_from_this ());
        }
        
-       void examine (boost::shared_ptr<Job>);
+       void examine (boost::shared_ptr<Job>, bool calculate_digest);
        std::string summary () const;
        std::string technical_summary () const;
        std::string information () const;
index 5ca05dd55e780080b421b24c44a49cc694604e5f..1d01981f60c80dd55dc19f185bc8fda2b3e0dfe0 100644 (file)
@@ -156,7 +156,7 @@ FFmpegExaminer::frame_time (AVStream* s) const
        return t;
 }
 
-float
+optional<float>
 FFmpegExaminer::video_frame_rate () const
 {
        /* This use of r_frame_rate is debateable; there's a few different
index 59c3299b26c7325313eb7f1b791821babc6ff73c..4378e241b973e53aa541d46da6afda1491e0e5f5 100644 (file)
@@ -29,7 +29,7 @@ class FFmpegExaminer : public FFmpeg, public VideoExaminer
 public:
        FFmpegExaminer (boost::shared_ptr<const FFmpegContent>);
        
-       float video_frame_rate () const;
+       boost::optional<float> video_frame_rate () const;
        dcp::Size video_size () const;
        ContentTime video_length () const;
        boost::optional<float> sample_aspect_ratio () const;
index 8144759b662da603eed2b1e6f7bef91b24a8324e..22dc0ca90ef2e176d6bc9672d6baa608e16824f4 100644 (file)
@@ -948,20 +948,20 @@ Film::content () const
 }
 
 void
-Film::examine_content (shared_ptr<Content> c)
+Film::examine_content (shared_ptr<Content> c, bool calculate_digest)
 {
-       shared_ptr<Job> j (new ExamineContentJob (shared_from_this(), c));
+       shared_ptr<Job> j (new ExamineContentJob (shared_from_this(), c, calculate_digest));
        JobManager::instance()->add (j);
 }
 
 void
-Film::examine_and_add_content (shared_ptr<Content> c)
+Film::examine_and_add_content (shared_ptr<Content> c, bool calculate_digest)
 {
        if (dynamic_pointer_cast<FFmpegContent> (c)) {
                run_ffprobe (c->path(0), file ("ffprobe.log"), _log);
        }
                        
-       shared_ptr<Job> j (new ExamineContentJob (shared_from_this(), c));
+       shared_ptr<Job> j (new ExamineContentJob (shared_from_this(), c, calculate_digest));
        j->Finished.connect (bind (&Film::maybe_add_content, this, boost::weak_ptr<Job> (j), boost::weak_ptr<Content> (c)));
        JobManager::instance()->add (j);
 }
index 8a0823094e4c0ddf7b272ee05fae332ba631cc25..1906de91b19bc94674c86b6b5e0612687791046d 100644 (file)
@@ -250,8 +250,8 @@ public:
        void set_directory (boost::filesystem::path);
        void set_name (std::string);
        void set_use_isdcf_name (bool);
-       void examine_content (boost::shared_ptr<Content>);
-       void examine_and_add_content (boost::shared_ptr<Content>);
+       void examine_content (boost::shared_ptr<Content>, bool calculate_digest);
+       void examine_and_add_content (boost::shared_ptr<Content>, bool calculate_digest);
        void add_content (boost::shared_ptr<Content>);
        void remove_content (boost::shared_ptr<Content>);
        void move_content_earlier (boost::shared_ptr<Content>);
index 84b0b75c9732a4cd47dc30e1698ee1a82335c675..132b261446120e469207018d2a9a8ebbf3728f36 100644 (file)
@@ -100,10 +100,9 @@ ImageContent::as_xml (xmlpp::Node* node) const
 }
 
 void
-ImageContent::examine (shared_ptr<Job> job)
+ImageContent::examine (shared_ptr<Job> job, bool calculate_digest)
 {
-       job->sub (_("Computing digest"));
-       Content::examine (job);
+       Content::examine (job, calculate_digest);
 
        shared_ptr<const Film> film = _film.lock ();
        assert (film);
index a1b1437c811fb391154b222466b7fa22a27b5258..6b70d578988eae42cf1ca5d0478f480af78eee54 100644 (file)
@@ -37,7 +37,7 @@ public:
                return boost::dynamic_pointer_cast<ImageContent> (Content::shared_from_this ());
        };
 
-       void examine (boost::shared_ptr<Job>);
+       void examine (boost::shared_ptr<Job>, bool calculate_digest);
        std::string summary () const;
        std::string technical_summary () const;
        void as_xml (xmlpp::Node *) const;
index ef9c13c5a1c1e8b33500d72531bba395372d7563..d6c7d0502cebffb1f0be88e7770d0bfc683d1789 100644 (file)
@@ -34,6 +34,7 @@ using std::cout;
 using std::list;
 using std::sort;
 using boost::shared_ptr;
+using boost::optional;
 
 ImageExaminer::ImageExaminer (shared_ptr<const Film> film, shared_ptr<const ImageContent> content, shared_ptr<Job>)
        : _film (film)
@@ -63,7 +64,9 @@ ImageExaminer::ImageExaminer (shared_ptr<const Film> film, shared_ptr<const Imag
        if (content->still ()) {
                _video_length = ContentTime::from_seconds (Config::instance()->default_still_length());
        } else {
-               _video_length = ContentTime::from_frames (_image_content->number_of_paths (), video_frame_rate ());
+               _video_length = ContentTime::from_frames (
+                       _image_content->number_of_paths (), video_frame_rate().get_value_or (0)
+                       );
        }
 }
 
@@ -73,13 +76,9 @@ ImageExaminer::video_size () const
        return _video_size.get ();
 }
 
-float
+optional<float>
 ImageExaminer::video_frame_rate () const
 {
-       boost::shared_ptr<const Film> f = _film.lock ();
-       if (!f) {
-               return 24;
-       }
-
-       return f->video_frame_rate ();
+       /* Don't know */
+       return optional<float> ();
 }
index 6ae0422cbbd4477f8ac7878e05a2430b251711b0..1917a23f399da90a47763d56b174c0008abf5586 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -30,7 +30,7 @@ class ImageExaminer : public VideoExaminer
 public:
        ImageExaminer (boost::shared_ptr<const Film>, boost::shared_ptr<const ImageContent>, boost::shared_ptr<Job>);
 
-       float video_frame_rate () const;
+       boost::optional<float> video_frame_rate () const;
        dcp::Size video_size () const;
        ContentTime video_length () const {
                return _video_length;
index 1a17976657c42759a10566aaec00559de94e1ba9..cdc9734bffcad0fe1d561ecdd1df6e6c68df19c7 100644 (file)
@@ -101,10 +101,10 @@ SndfileContent::valid_file (boost::filesystem::path f)
 }
 
 void
-SndfileContent::examine (shared_ptr<Job> job)
+SndfileContent::examine (shared_ptr<Job> job, bool calculate_digest)
 {
        job->set_progress_unknown ();
-       Content::examine (job);
+       Content::examine (job, calculate_digest);
        shared_ptr<AudioExaminer> dec (new SndfileDecoder (shared_from_this()));
        take_from_audio_examiner (dec);
 }
index 75c723518ea61ebf48ed6e06163b2894e71fe53b..cb255fd745a16fbd345e351ae4d8ecce91f7a22d 100644 (file)
@@ -41,7 +41,7 @@ public:
        
        DCPTime full_length () const;
        
-       void examine (boost::shared_ptr<Job>);
+       void examine (boost::shared_ptr<Job>, bool calculate_digest);
        std::string summary () const;
        std::string technical_summary () const;
        std::string information () const;
index 14cb50b86718eb3a25e0a3516a5cea9f823261e1..7a336f88af632d3770eeed3beb3f9cd82b0915e7 100644 (file)
@@ -47,9 +47,9 @@ SubRipContent::SubRipContent (shared_ptr<const Film> film, cxml::ConstNodePtr no
 }
 
 void
-SubRipContent::examine (boost::shared_ptr<Job> job)
+SubRipContent::examine (boost::shared_ptr<Job> job, bool calculate_digest)
 {
-       Content::examine (job);
+       Content::examine (job, calculate_digest);
        SubRip s (shared_from_this ());
 
        shared_ptr<const Film> film = _film.lock ();
index d2dcdee00b09cce5e1b014dba924fd0b09bea8ff..243032691b76b0179205f5614098e51cc8e25bb7 100644 (file)
@@ -30,7 +30,7 @@ public:
        }
        
        /* Content */
-       void examine (boost::shared_ptr<Job>);
+       void examine (boost::shared_ptr<Job>, bool calculate_digest);
        std::string summary () const;
        std::string technical_summary () const;
        std::string information () const;
index 8e07174e34016b3b7a008d4958a2bbd55046365d..ca0c687a791d9a1b15996cb0cf2f488b64d05a48 100644 (file)
@@ -221,14 +221,16 @@ VideoContent::take_from_video_examiner (shared_ptr<VideoExaminer> d)
 {
        /* These examiner calls could call other content methods which take a lock on the mutex */
        dcp::Size const vs = d->video_size ();
-       float const vfr = d->video_frame_rate ();
+       optional<float> const vfr = d->video_frame_rate ();
        ContentTime vl = d->video_length ();
        optional<float> const ar = d->sample_aspect_ratio ();
 
        {
                boost::mutex::scoped_lock lm (_mutex);
                _video_size = vs;
-               _video_frame_rate = vfr;
+               if (vfr) {
+                       _video_frame_rate = vfr.get ();
+               }
                _video_length = vl;
                _sample_aspect_ratio = ar;
 
index de79665074d3b93520f38e6fe1933a0f587d7347..55b27ac94832f42397b7a96425ee9dd22ba65d94 100644 (file)
@@ -32,7 +32,7 @@ class VideoExaminer
 {
 public:
        virtual ~VideoExaminer () {}
-       virtual float video_frame_rate () const = 0;
+       virtual boost::optional<float> video_frame_rate () const = 0;
        virtual dcp::Size video_size () const = 0;
        virtual ContentTime video_length () const = 0;
        virtual boost::optional<float> sample_aspect_ratio () const {
index 58cb32c53e3e77f449b17007c5d4509e86526964..b0df7b32c9d5d7c52be5a2c38cb388457a6cf242 100644 (file)
@@ -786,7 +786,7 @@ class App : public wxApp
                if (!_film_to_create.empty ()) {
                        _frame->new_film (_film_to_create);
                        if (!_content_to_add.empty ()) {
-                               _frame->film()->examine_and_add_content (content_factory (_frame->film(), _content_to_add));
+                               _frame->film()->examine_and_add_content (content_factory (_frame->film(), _content_to_add), true);
                        }
                }
 
index 304f4f697ab6e8a031c44dd2a74c3b896f2c448a..6e8f1688843f48bb160c244c4b23db76ddccb704 100644 (file)
@@ -178,7 +178,7 @@ main (int argc, char* argv[])
                        if (vc) {
                                vc->set_scale (VideoContentScale (content_ratio));
                        }
-                       film->examine_and_add_content (c);
+                       film->examine_and_add_content (c, true);
                }
                
                JobManager* jm = JobManager::instance ();
index 3e3c462b2e6981267283186ae2ecc0566db72210..c528447ac4721298fc0c39b2744ec0ec59e797ab 100644 (file)
@@ -207,7 +207,7 @@ ContentMenu::find_missing ()
                return;
        }
 
-       shared_ptr<Job> j (new ExamineContentJob (film, content));
+       shared_ptr<Job> j (new ExamineContentJob (film, content, true));
        
        j->Finished.connect (
                bind (
@@ -231,7 +231,7 @@ ContentMenu::re_examine ()
        }
 
        for (ContentList::iterator i = _content.begin(); i != _content.end(); ++i) {
-               film->examine_content (*i);
+               film->examine_content (*i, true);
        }
 }
 
@@ -269,7 +269,7 @@ ContentMenu::kdm ()
                dcp->add_kdm (dcp::EncryptedKDM (dcp::file_to_string (wx_to_std (d->GetPath ()))));
                shared_ptr<Film> film = _film.lock ();
                assert (film);
-               film->examine_content (dcp);
+               film->examine_content (dcp, true);
        }
        
        d->Destroy ();
index 2932ee7c58bca7cd6da585f47b7fb5bb435f6a63..4d73a608dcb2b329f7c262c95d2561f02b9265a9 100644 (file)
@@ -35,6 +35,7 @@
 #include "subtitle_panel.h"
 #include "timing_panel.h"
 #include "timeline_dialog.h"
+#include "image_sequence_dialog.h"
 
 using std::list;
 using std::string;
@@ -247,7 +248,7 @@ ContentPanel::add_file_clicked ()
        /* XXX: check for lots of files here and do something */
 
        for (unsigned int i = 0; i < paths.GetCount(); ++i) {
-               _film->examine_and_add_content (content_factory (_film, wx_to_std (paths[i])));
+               _film->examine_and_add_content (content_factory (_film, wx_to_std (paths[i])), true);
        }
 
        d->Destroy ();
@@ -257,7 +258,7 @@ void
 ContentPanel::add_folder_clicked ()
 {
        wxDirDialog* d = new wxDirDialog (_panel, _("Choose a folder"), wxT (""), wxDD_DIR_MUST_EXIST);
-       int const r = d->ShowModal ();
+       int r = d->ShowModal ();
        boost::filesystem::path const path (wx_to_std (d->GetPath ()));
        d->Destroy ();
        
@@ -265,21 +266,47 @@ ContentPanel::add_folder_clicked ()
                return;
        }
 
-       shared_ptr<Content> content;
-       
-       try {
-               content.reset (new ImageContent (_film, path));
-       } catch (...) {
+       /* Guess if this is a DCP or a set of images: read the first ten filenames and if they
+          are all valid image files we assume it is a set of images.
+       */
+
+       bool is_dcp = false;
+       int read = 0;
+       for (boost::filesystem::directory_iterator i(path); i != boost::filesystem::directory_iterator() && read < 10; ++i, ++read) {
+               if (!boost::filesystem::is_regular_file (i->path()) || !valid_image_file (i->path())) {
+                       is_dcp = true;
+               }
+       }
+
+       if (is_dcp) {
                try {
-                       content.reset (new DCPContent (_film, path));
+                       shared_ptr<DCPContent> content (new DCPContent (_film, path));
+                       _film->examine_and_add_content (content, true);
                } catch (...) {
-                       error_dialog (_panel, _("Could not find any images nor a DCP in that folder"));
+                       error_dialog (_panel, _("Could not find a DCP in that folder."));
+               }
+       } else {
+               
+               ImageSequenceDialog* e = new ImageSequenceDialog (_panel);
+               r = e->ShowModal ();
+               float const frame_rate = e->frame_rate ();
+               bool const digest = e->digest ();
+               e->Destroy ();
+
+               if (r != wxID_OK) {
                        return;
                }
-       }
 
-       if (content) {
-               _film->examine_and_add_content (content);
+               shared_ptr<Content> content;
+               
+               try {
+                       shared_ptr<ImageContent> content (new ImageContent (_film, path));
+                       content->set_video_frame_rate (frame_rate);
+                       _film->examine_and_add_content (content, digest);
+               } catch (...) {
+                       error_dialog (_panel, _("Could not find any images in that folder"));
+                       return;
+               }
        }
 }
 
@@ -464,6 +491,6 @@ ContentPanel::files_dropped (wxDropFilesEvent& event)
        
        wxString* paths = event.GetFiles ();
        for (int i = 0; i < event.GetNumberOfFiles(); i++) {
-               _film->examine_and_add_content (content_factory (_film, wx_to_std (paths[i])));
+               _film->examine_and_add_content (content_factory (_film, wx_to_std (paths[i])), true);
        }
 }
diff --git a/src/wx/image_sequence_dialog.cc b/src/wx/image_sequence_dialog.cc
new file mode 100644 (file)
index 0000000..930ef8b
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+    Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
+
+    This program 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.
+
+    This program 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 this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <libdcp/raw_convert.h>
+#include "wx_util.h"
+#include "image_sequence_dialog.h"
+
+using libdcp::raw_convert;
+
+ImageSequenceDialog::ImageSequenceDialog (wxWindow* parent)
+       : TableDialog (parent, _("Add image sequence"), 2, true)
+{
+       add (_("Frame rate"), true);
+       _frame_rate = add (new wxTextCtrl (this, wxID_ANY, N_("24")));
+       _digest = new wxCheckBox (this, wxID_ANY, _("Calculate digests"));
+       _digest->SetValue (true);
+       _digest->SetToolTip (_("By default DCP-o-matic will calculate digests (hashes) of your image files so that it knows if they change.  Turning this off will speed up import but you must not alter the image files after import or strange things may happen."));
+       add (_digest);
+
+       layout ();
+}
+
+float
+ImageSequenceDialog::frame_rate () const
+{
+       try {
+               return raw_convert<float> (wx_to_std (_frame_rate->GetValue ()));
+       } catch (...) {
+
+       }
+
+       return 0;
+}
+
+bool
+ImageSequenceDialog::digest () const
+{
+       return _digest->GetValue ();
+}
diff --git a/src/wx/image_sequence_dialog.h b/src/wx/image_sequence_dialog.h
new file mode 100644 (file)
index 0000000..d3658b7
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+    Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
+
+    This program 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.
+
+    This program 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 this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <wx/wx.h>
+#include "table_dialog.h"
+
+class ImageSequenceDialog : public TableDialog
+{
+public:
+       ImageSequenceDialog (wxWindow* parent);
+
+       float frame_rate () const;
+       bool digest () const;
+
+private:
+       wxTextCtrl* _frame_rate;
+       wxCheckBox* _digest;
+};
index 6a6021c22d6671c7a35aa089e969d8d6e0e4dae3..6a72f858d31ba83c63118a094d45b3df631c91e5 100644 (file)
@@ -18,6 +18,7 @@ sources = """
           content_panel.cc
           content_sub_panel.cc
           dcp_panel.cc
+          image_sequence_dialog.cc
           isdcf_metadata_dialog.cc
           dir_picker_ctrl.cc
           dolby_certificate_dialog.cc
index fa5b33bb921feb348e4a0d6ad83fda54c40411b7..63c5f543588b5bc3e1ebfdc67d7bf6e873376091 100644 (file)
@@ -41,7 +41,7 @@ BOOST_AUTO_TEST_CASE (fourk_test)
        film->set_resolution (RESOLUTION_4K);
        film->set_dcp_content_type (DCPContentType::from_isdcf_name ("FTR"));
        film->set_container (Ratio::from_id ("185"));
-       film->examine_and_add_content (c);
+       film->examine_and_add_content (c, true);
        wait_for_jobs ();
 
        film->make_dcp ();
index 2799449191575571a55e3c2694a9032265608fee..2da38f45566d5d4ebec68d9f47a1d42a89f21b96 100644 (file)
@@ -84,7 +84,7 @@ BOOST_AUTO_TEST_CASE (audio_analysis_test)
        boost::filesystem::path p = private_data / "betty_L.wav";
 
        shared_ptr<SndfileContent> c (new SndfileContent (film, p));
-       film->examine_and_add_content (c);
+       film->examine_and_add_content (c, true);
        wait_for_jobs ();
 
        c->analyse_audio (boost::bind (&finished));
index 68e14ff3ca353f470d9f09f8c14112f6713b34a4..0127cc644e0929c0c34ac55551abc101c4e1df2e 100644 (file)
@@ -51,7 +51,7 @@ void test_audio_delay (int delay_in_ms)
 
        shared_ptr<SndfileContent> content (new SndfileContent (film, "test/data/staircase.wav"));
        content->set_audio_delay (delay_in_ms);
-       film->examine_and_add_content (content);
+       film->examine_and_add_content (content, true);
        wait_for_jobs ();
 
        film->make_dcp ();
index 5981552d128e6c3f9f0ead28bacfc772ee2fd718..99e0870b17c59801d64810fbacf00889e007d1f7 100644 (file)
@@ -40,8 +40,8 @@ BOOST_AUTO_TEST_CASE (black_fill_test)
        shared_ptr<ImageContent> contentA (new ImageContent (film, "test/data/simple_testcard_640x480.png"));
        shared_ptr<ImageContent> contentB (new ImageContent (film, "test/data/simple_testcard_640x480.png"));
 
-       film->examine_and_add_content (contentA);
-       film->examine_and_add_content (contentB);
+       film->examine_and_add_content (contentA, true);
+       film->examine_and_add_content (contentB, true);
        wait_for_jobs ();
 
        contentA->set_scale (VideoContentScale (Ratio::from_id ("185")));
index d10d1ed25239e54dac342c0bce6bcef40d0a94d6..9bb772f4a263eb02e7087dae5a6e85286c5ce04f 100644 (file)
@@ -42,7 +42,7 @@ BOOST_AUTO_TEST_CASE (burnt_subtitle_test_subrip)
        film->set_burn_subtitles (true);
        shared_ptr<SubRipContent> content (new SubRipContent (film, "test/data/subrip2.srt"));
        content->set_use_subtitles (true);
-       film->examine_and_add_content (content);
+       film->examine_and_add_content (content, true);
        wait_for_jobs ();
        film->make_dcp ();
        wait_for_jobs ();
@@ -60,7 +60,7 @@ BOOST_AUTO_TEST_CASE (burnt_subtitle_test_dcp)
        film->set_burn_subtitles (true);
        shared_ptr<DCPSubtitleContent> content (new DCPSubtitleContent (film, "test/data/dcp_sub.xml"));
        content->set_use_subtitles (true);
-       film->examine_and_add_content (content);
+       film->examine_and_add_content (content, true);
        wait_for_jobs ();
        film->make_dcp ();
        wait_for_jobs ();
index 95fa7d1ec7eaf2d6844892ac9b9d1ddf1d8ed258..12d9a7a1e4bf93dd9904132e9454197ce3d5a309 100644 (file)
@@ -39,7 +39,7 @@ BOOST_AUTO_TEST_CASE (dcp_subtitle_test)
        film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
        film->set_name ("frobozz");
        shared_ptr<DCPSubtitleContent> content (new DCPSubtitleContent (film, "test/data/dcp_sub.xml"));
-       film->examine_and_add_content (content);
+       film->examine_and_add_content (content, true);
        wait_for_jobs ();
 
        BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (2));
index 444b0869b7dc52fd2928dec6444a408315265642..5117cf412a3aba7b16343a4409c4071e2d47566a 100644 (file)
@@ -44,7 +44,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_audio_test)
        shared_ptr<Film> film = new_test_film ("ffmpeg_audio_test");
        film->set_name ("ffmpeg_audio_test");
        shared_ptr<FFmpegContent> c (new FFmpegContent (film, "test/data/staircase.mov"));
-       film->examine_and_add_content (c);
+       film->examine_and_add_content (c, true);
 
        wait_for_jobs ();
        
index 559277e511a4ba14e59f4f2b329eea6d4b77224b..8b441db98578f7573ba6845298c29a869ea4915b 100644 (file)
@@ -38,7 +38,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_dcp_test)
        shared_ptr<Film> film = new_test_film ("ffmpeg_dcp_test");
        film->set_name ("test_film2");
        shared_ptr<FFmpegContent> c (new FFmpegContent (film, "test/data/test.mp4"));
-       film->examine_and_add_content (c);
+       film->examine_and_add_content (c, true);
 
        wait_for_jobs ();
        
index 968c3bdf910eb0265441739ae4b07a7783cfb172..3274fd8a907054a477665b24ce616d4a2180d6f5 100644 (file)
@@ -60,7 +60,7 @@ test (boost::filesystem::path file, vector<int> frames)
 
        shared_ptr<Film> film = new_test_film ("ffmpeg_decoder_seek_test_" + file.string());
        shared_ptr<FFmpegContent> content (new FFmpegContent (film, path)); 
-       film->examine_and_add_content (content);
+       film->examine_and_add_content (content, true);
        wait_for_jobs ();
        shared_ptr<Log> log (new NullLog);
        FFmpegDecoder decoder (content, log);
index c6af70c2c3c138a95fe973714be15b969f878d30..e4968dedaaaa787e2f35a32605cb48fbc773485f 100644 (file)
@@ -47,7 +47,7 @@ test (boost::filesystem::path file, float fps, int gaps)
 
        shared_ptr<Film> film = new_test_film ("ffmpeg_decoder_seek_test_" + file.string());
        shared_ptr<FFmpegContent> content (new FFmpegContent (film, path)); 
-       film->examine_and_add_content (content);
+       film->examine_and_add_content (content, true);
        wait_for_jobs ();
        shared_ptr<Log> log (new NullLog);
        FFmpegDecoder decoder (content, log);
index e8ebcea3b959833ccb1009c561c7b99f4394bbf5..0ed5a64a7400f4f2aef00de00c6dc06be6ed9097 100644 (file)
@@ -243,7 +243,7 @@ BOOST_AUTO_TEST_CASE (audio_sampling_rate_test)
        shared_ptr<Film> film = new_test_film ("audio_sampling_rate_test");
        /* Get any piece of content, it doesn't matter what */
        shared_ptr<FFmpegContent> content (new FFmpegContent (film, "test/data/test.mp4"));
-       film->examine_and_add_content (content);
+       film->examine_and_add_content (content, true);
        wait_for_jobs ();
        
        std::list<int> afr;
index 80cd9c3df35d200873a8b86907ab11908ae47eb2..b2420b1fe490c585ff0741f8f677bf1492aebf1e 100644 (file)
@@ -39,7 +39,7 @@ BOOST_AUTO_TEST_CASE (import_dcp_test)
        A->set_name ("frobozz");
 
        shared_ptr<FFmpegContent> c (new FFmpegContent (A, "test/data/test.mp4"));
-       A->examine_and_add_content (c);
+       A->examine_and_add_content (c, true);
        A->set_encrypted (true);
        wait_for_jobs ();
 
@@ -64,7 +64,7 @@ BOOST_AUTO_TEST_CASE (import_dcp_test)
 
        shared_ptr<DCPContent> d (new DCPContent (B, "build/test/import_dcp_test/" + A->dcp_name()));
        d->add_kdm (kdm);
-       B->examine_and_add_content (d);
+       B->examine_and_add_content (d, true);
        wait_for_jobs ();
 
        B->make_dcp ();
index c2ea833bd859c13e7f6cf7136d1f89f1f12de314..b0b83de44948d28712a65ab7bece6d5af1d3f859 100644 (file)
@@ -73,7 +73,7 @@ BOOST_AUTO_TEST_CASE (isdcf_name_test)
        /* Test interior aspect ratio: shouldn't be shown with trailers */
 
        shared_ptr<ImageContent> content (new ImageContent (film, "test/data/simple_testcard_640x480.png"));
-       film->examine_and_add_content (content);
+       film->examine_and_add_content (content, true);
        wait_for_jobs ();
        content->set_scale (VideoContentScale (Ratio::from_id ("133")));
        film->set_container (Ratio::from_id ("185"));
index bbf70781a87d4600526428055228fc54809c1c62..f7aa52d6f539f18102a3f68080c59f70d6cc75e7 100644 (file)
@@ -87,13 +87,13 @@ BOOST_AUTO_TEST_CASE (play_test)
        film->set_name ("play_test");
 
        shared_ptr<FFmpegContent> A (new FFmpegContent (film, "test/data/red_24.mp4"));
-       film->examine_and_add_content (A);
+       film->examine_and_add_content (A, true);
        wait_for_jobs ();
 
        BOOST_CHECK_EQUAL (A->video_length_after_3d_combine(), 16);
 
        shared_ptr<FFmpegContent> B (new FFmpegContent (film, "test/data/red_30.mp4"));
-       film->examine_and_add_content (B);
+       film->examine_and_add_content (B, true);
        wait_for_jobs ();
 
        BOOST_CHECK_EQUAL (B->video_length_after_3d_combine(), 16);
index b6f864f8250e9762f0975eb16e6e79b38af8e360..d7a55b57a065d89d34b4de743ddd7a0319e4dfac 100644 (file)
@@ -44,9 +44,9 @@ BOOST_AUTO_TEST_CASE (player_overlaps_test)
        shared_ptr<FFmpegContent> B (new FFmpegContent (film, "test/data/test.mp4"));
        shared_ptr<FFmpegContent> C (new FFmpegContent (film, "test/data/test.mp4"));
 
-       film->examine_and_add_content (A);
-       film->examine_and_add_content (B);
-       film->examine_and_add_content (C);
+       film->examine_and_add_content (A, true);
+       film->examine_and_add_content (B, true);
+       film->examine_and_add_content (C, true);
        wait_for_jobs ();
 
        BOOST_CHECK_EQUAL (A->full_length(), DCPTime (288000));
@@ -87,7 +87,7 @@ BOOST_AUTO_TEST_CASE (player_silence_padding_test)
        film->set_container (Ratio::from_id ("185"));
        film->set_audio_channels (6);
        
-       film->examine_and_add_content (c);
+       film->examine_and_add_content (c, true);
        wait_for_jobs ();
 
        shared_ptr<Player> player = film->make_player ();
index fd9290f9e7e3635538682ffd8b0f122ba859aeee..cb5c26858192fa09b45b419b02f76e061c371cfe 100644 (file)
@@ -51,7 +51,7 @@ BOOST_AUTO_TEST_CASE (recover_test)
 
        shared_ptr<ImageContent> content (new ImageContent (film, "test/data/3d_test"));
        content->set_video_frame_type (VIDEO_FRAME_TYPE_3D_LEFT_RIGHT);
-       film->examine_and_add_content (content);
+       film->examine_and_add_content (content, true);
        wait_for_jobs ();
 
        film->make_dcp ();
index 1d19d269e314b2a448ab31dbbfcf73ceea9eaf1c..d312ae7edeaa6e9b85448f9d7f7a4ef0a1fc4f57 100644 (file)
@@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE (repeat_frame_test)
        film->set_container (Ratio::from_id ("185"));
        film->set_dcp_content_type (DCPContentType::from_pretty_name ("Test"));
        shared_ptr<FFmpegContent> c (new FFmpegContent (film, "test/data/red_24.mp4"));
-       film->examine_and_add_content (c);
+       film->examine_and_add_content (c, true);
 
        wait_for_jobs ();
 
index 441af6bf30514ecb2eaaafa58ae7deea3ffdaa16..d642271c27088bb39254e0bc6a1031e4e51d5541 100644 (file)
@@ -60,7 +60,7 @@ BOOST_AUTO_TEST_CASE (scaling_test)
        film->set_name ("scaling_test");
        shared_ptr<ImageContent> imc (new ImageContent (film, "test/data/simple_testcard_640x480.png"));
 
-       film->examine_and_add_content (imc);
+       film->examine_and_add_content (imc, true);
 
        wait_for_jobs ();
        
index 2a1a061360e328fefc6721aeb09f1c9d3b7fedbc..7abe7fa2623f290ebae98409cbf689551c971391 100644 (file)
@@ -45,7 +45,7 @@ BOOST_AUTO_TEST_CASE (seek_zero_test)
        film->set_container (Ratio::from_id ("185"));
        film->set_dcp_content_type (DCPContentType::from_pretty_name ("Test"));
        shared_ptr<FFmpegContent> content (new FFmpegContent (film, "test/data/count300bd48.m2ts"));
-       film->examine_and_add_content (content);
+       film->examine_and_add_content (content, true);
        wait_for_jobs ();
        content->set_scale (VideoContentScale (Ratio::from_id ("185")));
        
index d876a0228d7acafa9cd7ab0bb8319097c127869d..25f2d80c94d1c1e7a9446b6476ccde0349a669ef 100644 (file)
@@ -48,7 +48,7 @@ test_silence_padding (int channels)
        film->set_name (film_name);
 
        shared_ptr<SndfileContent> content (new SndfileContent (film, "test/data/staircase.wav"));
-       film->examine_and_add_content (content);
+       film->examine_and_add_content (content, true);
        wait_for_jobs ();
 
        film->set_audio_channels (channels);
index 79be6d0f6f709af5a7f43982ef7d60b60f59a7ef..3e4f895c55a013e61ad5be8ad59591ac915615c9 100644 (file)
@@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE (skip_frame_test)
        film->set_container (Ratio::from_id ("185"));
        film->set_dcp_content_type (DCPContentType::from_pretty_name ("Test"));
        shared_ptr<FFmpegContent> c (new FFmpegContent (film, "test/data/count300bd48.m2ts"));
-       film->examine_and_add_content (c);
+       film->examine_and_add_content (c, true);
 
        wait_for_jobs ();
 
index e18ee2ea564d20c19988659771b96dd4fbc68aea..cd517cfe9492026a9d88fe345e21d0ab0d09e8ff 100644 (file)
@@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE (subrip_render_test)
 {
        shared_ptr<Film> film = new_test_film ("subrip_render_test");
        shared_ptr<SubRipContent> content (new SubRipContent (film, "test/data/subrip.srt"));
-       content->examine (shared_ptr<Job> ());
+       content->examine (shared_ptr<Job> (), true);
        BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds ((3 * 60) + 56.471));
 
        shared_ptr<SubRipDecoder> decoder (new SubRipDecoder (content));
index fb021d169c033422ad35a856950e1119b28ee03f..0553d4c0f606d13733be55d6c6c1551438eb76d4 100644 (file)
@@ -37,7 +37,7 @@ BOOST_AUTO_TEST_CASE (threed_test)
        film->set_name ("test_film2");
        shared_ptr<FFmpegContent> c (new FFmpegContent (film, "test/data/test.mp4"));
        c->set_video_frame_type (VIDEO_FRAME_TYPE_3D_LEFT_RIGHT);
-       film->examine_and_add_content (c);
+       film->examine_and_add_content (c, true);
 
        wait_for_jobs ();
 
index b115db21bff72fe96a3fcddeafc74ef08cddbf3b..bdca521a22ccaedd40f9ebf9625ace55d26d6739 100644 (file)
@@ -38,7 +38,7 @@ BOOST_AUTO_TEST_CASE (upmixer_a_test)
        film->set_name ("frobozz");
        shared_ptr<SndfileContent> content (new SndfileContent (film, "test/data/white.wav"));
        content->set_audio_processor (AudioProcessor::from_id ("stereo-5.1-upmix-a"));
-       film->examine_and_add_content (content);
+       film->examine_and_add_content (content, true);
 
        wait_for_jobs ();
 
index 561b1021fc6013462f1268364b3f0bac7ecf0bb2..f6452c788f381f125d61188fcaa830e5d45753d0 100644 (file)
@@ -41,7 +41,7 @@ BOOST_AUTO_TEST_CASE (xml_subtitle_test)
        film->set_burn_subtitles (false);
        shared_ptr<SubRipContent> content (new SubRipContent (film, "test/data/subrip2.srt"));
        content->set_use_subtitles (true);
-       film->examine_and_add_content (content);
+       film->examine_and_add_content (content, true);
        wait_for_jobs ();
        film->make_dcp ();
        wait_for_jobs ();