From c008066160d85b9ec9e5485375d7baaa5d27bda2 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 3 Dec 2014 10:12:35 +0000 Subject: [PATCH] Hand-apply 6a3cd511559433554ab40ed72ff94b7d8dc2c5bd from master; Basics of an image sequence dialog that asks about frame rate and digest calculation. --- src/lib/content.cc | 9 ++++- src/lib/content.h | 3 +- src/lib/dcp_content.cc | 4 +- src/lib/dcp_content.h | 2 +- src/lib/dcp_examiner.h | 4 +- src/lib/dcp_subtitle_content.cc | 4 +- src/lib/dcp_subtitle_content.h | 2 +- src/lib/examine_content_job.cc | 5 ++- src/lib/examine_content_job.h | 3 +- src/lib/ffmpeg_content.cc | 4 +- src/lib/ffmpeg_content.h | 2 +- src/lib/ffmpeg_examiner.cc | 2 +- src/lib/ffmpeg_examiner.h | 2 +- src/lib/film.cc | 8 ++-- src/lib/film.h | 4 +- src/lib/image_content.cc | 5 +-- src/lib/image_content.h | 2 +- src/lib/image_examiner.cc | 15 ++++--- src/lib/image_examiner.h | 4 +- src/lib/sndfile_content.cc | 4 +- src/lib/sndfile_content.h | 2 +- src/lib/subrip_content.cc | 4 +- src/lib/subrip_content.h | 2 +- src/lib/video_content.cc | 6 ++- src/lib/video_examiner.h | 2 +- src/tools/dcpomatic.cc | 2 +- src/tools/dcpomatic_create.cc | 2 +- src/wx/content_menu.cc | 6 +-- src/wx/content_panel.cc | 53 +++++++++++++++++++------ src/wx/image_sequence_dialog.cc | 55 ++++++++++++++++++++++++++ src/wx/image_sequence_dialog.h | 34 ++++++++++++++++ src/wx/wscript | 1 + test/4k_test.cc | 2 +- test/audio_analysis_test.cc | 2 +- test/audio_delay_test.cc | 2 +- test/black_fill_test.cc | 4 +- test/burnt_subtitle_test.cc | 4 +- test/dcp_subtitle_test.cc | 2 +- test/ffmpeg_audio_test.cc | 2 +- test/ffmpeg_dcp_test.cc | 2 +- test/ffmpeg_decoder_seek_test.cc | 2 +- test/ffmpeg_decoder_sequential_test.cc | 2 +- test/frame_rate_test.cc | 2 +- test/import_dcp_test.cc | 4 +- test/isdcf_name_test.cc | 2 +- test/play_test.cc | 4 +- test/player_test.cc | 8 ++-- test/recover_test.cc | 2 +- test/repeat_frame_test.cc | 2 +- test/scaling_test.cc | 2 +- test/seek_zero_test.cc | 2 +- test/silence_padding_test.cc | 2 +- test/skip_frame_test.cc | 2 +- test/subrip_test.cc | 2 +- test/threed_test.cc | 2 +- test/upmixer_a_test.cc | 2 +- test/xml_subtitle_test.cc | 2 +- 57 files changed, 224 insertions(+), 97 deletions(-) create mode 100644 src/wx/image_sequence_dialog.cc create mode 100644 src/wx/image_sequence_dialog.h diff --git a/src/lib/content.cc b/src/lib/content.cc index 21e49a2c9..6e0218323 100644 --- a/src/lib/content.cc +++ b/src/lib/content.cc @@ -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) +Content::examine (shared_ptr job, bool calculate_digest) { + if (!calculate_digest) { + return; + } + + job->sub (_("Computing digest")); + boost::mutex::scoped_lock lm (_mutex); vector p = _paths; lm.unlock (); diff --git a/src/lib/content.h b/src/lib/content.h index f7e97feac..0b72ada9c 100644 --- a/src/lib/content.h +++ b/src/lib/content.h @@ -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); + virtual void examine (boost::shared_ptr job, bool calculate_digest); /** @return Quick one-line summary of the content, as will be presented in the * film editor. diff --git a/src/lib/dcp_content.cc b/src/lib/dcp_content.cc index a5b5f37e1..28b7ac862 100644 --- a/src/lib/dcp_content.cc +++ b/src/lib/dcp_content.cc @@ -77,12 +77,12 @@ DCPContent::read_directory (boost::filesystem::path p) } void -DCPContent::examine (shared_ptr job) +DCPContent::examine (shared_ptr 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 examiner (new DCPExaminer (shared_from_this ())); take_from_video_examiner (examiner); diff --git a/src/lib/dcp_content.h b/src/lib/dcp_content.h index da78e6d72..d6fe8c820 100644 --- a/src/lib/dcp_content.h +++ b/src/lib/dcp_content.h @@ -52,7 +52,7 @@ public: DCPTime full_length () const; - void examine (boost::shared_ptr); + void examine (boost::shared_ptr, bool calculate_digest); std::string summary () const; std::string technical_summary () const; void as_xml (xmlpp::Node *) const; diff --git a/src/lib/dcp_examiner.h b/src/lib/dcp_examiner.h index 03d43d0f6..ef780dc3e 100644 --- a/src/lib/dcp_examiner.h +++ b/src/lib/dcp_examiner.h @@ -27,8 +27,8 @@ class DCPExaminer : public VideoExaminer, public AudioExaminer public: DCPExaminer (boost::shared_ptr); - float video_frame_rate () const { - return _video_frame_rate.get_value_or (24); + boost::optional video_frame_rate () const { + return _video_frame_rate; } dcp::Size video_size () const { diff --git a/src/lib/dcp_subtitle_content.cc b/src/lib/dcp_subtitle_content.cc index 83b0d200c..1935a874f 100644 --- a/src/lib/dcp_subtitle_content.cc +++ b/src/lib/dcp_subtitle_content.cc @@ -44,9 +44,9 @@ DCPSubtitleContent::DCPSubtitleContent (shared_ptr film, cxml::Const } void -DCPSubtitleContent::examine (shared_ptr job) +DCPSubtitleContent::examine (shared_ptr 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 ()); } diff --git a/src/lib/dcp_subtitle_content.h b/src/lib/dcp_subtitle_content.h index 5794b5951..551dafd15 100644 --- a/src/lib/dcp_subtitle_content.h +++ b/src/lib/dcp_subtitle_content.h @@ -26,7 +26,7 @@ public: DCPSubtitleContent (boost::shared_ptr, cxml::ConstNodePtr, int); /* Content */ - void examine (boost::shared_ptr); + void examine (boost::shared_ptr, bool calculate_digest); std::string summary () const; std::string technical_summary () const; std::string information () const; diff --git a/src/lib/examine_content_job.cc b/src/lib/examine_content_job.cc index cbf180ffc..ee887271f 100644 --- a/src/lib/examine_content_job.cc +++ b/src/lib/examine_content_job.cc @@ -29,9 +29,10 @@ using std::string; using std::cout; using boost::shared_ptr; -ExamineContentJob::ExamineContentJob (shared_ptr f, shared_ptr c) +ExamineContentJob::ExamineContentJob (shared_ptr f, shared_ptr 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); } diff --git a/src/lib/examine_content_job.h b/src/lib/examine_content_job.h index b6903b86b..f0d9eae93 100644 --- a/src/lib/examine_content_job.h +++ b/src/lib/examine_content_job.h @@ -26,7 +26,7 @@ class Log; class ExamineContentJob : public Job { public: - ExamineContentJob (boost::shared_ptr, boost::shared_ptr); + ExamineContentJob (boost::shared_ptr, boost::shared_ptr, bool calculate_digest); ~ExamineContentJob (); std::string name () const; @@ -34,5 +34,6 @@ public: private: boost::shared_ptr _content; + bool _calculate_digest; }; diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index bb4e02230..a186db48e 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -163,11 +163,11 @@ FFmpegContent::as_xml (xmlpp::Node* node) const } void -FFmpegContent::examine (shared_ptr job) +FFmpegContent::examine (shared_ptr job, bool calculate_digest) { job->set_progress_unknown (); - Content::examine (job); + Content::examine (job, calculate_digest); shared_ptr examiner (new FFmpegExaminer (shared_from_this ())); take_from_video_examiner (examiner); diff --git a/src/lib/ffmpeg_content.h b/src/lib/ffmpeg_content.h index da8152c0d..fca3bf8be 100644 --- a/src/lib/ffmpeg_content.h +++ b/src/lib/ffmpeg_content.h @@ -56,7 +56,7 @@ public: return boost::dynamic_pointer_cast (Content::shared_from_this ()); } - void examine (boost::shared_ptr); + void examine (boost::shared_ptr, bool calculate_digest); std::string summary () const; std::string technical_summary () const; std::string information () const; diff --git a/src/lib/ffmpeg_examiner.cc b/src/lib/ffmpeg_examiner.cc index 5ca05dd55..1d01981f6 100644 --- a/src/lib/ffmpeg_examiner.cc +++ b/src/lib/ffmpeg_examiner.cc @@ -156,7 +156,7 @@ FFmpegExaminer::frame_time (AVStream* s) const return t; } -float +optional FFmpegExaminer::video_frame_rate () const { /* This use of r_frame_rate is debateable; there's a few different diff --git a/src/lib/ffmpeg_examiner.h b/src/lib/ffmpeg_examiner.h index 59c3299b2..4378e241b 100644 --- a/src/lib/ffmpeg_examiner.h +++ b/src/lib/ffmpeg_examiner.h @@ -29,7 +29,7 @@ class FFmpegExaminer : public FFmpeg, public VideoExaminer public: FFmpegExaminer (boost::shared_ptr); - float video_frame_rate () const; + boost::optional video_frame_rate () const; dcp::Size video_size () const; ContentTime video_length () const; boost::optional sample_aspect_ratio () const; diff --git a/src/lib/film.cc b/src/lib/film.cc index 8144759b6..22dc0ca90 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -948,20 +948,20 @@ Film::content () const } void -Film::examine_content (shared_ptr c) +Film::examine_content (shared_ptr c, bool calculate_digest) { - shared_ptr j (new ExamineContentJob (shared_from_this(), c)); + shared_ptr j (new ExamineContentJob (shared_from_this(), c, calculate_digest)); JobManager::instance()->add (j); } void -Film::examine_and_add_content (shared_ptr c) +Film::examine_and_add_content (shared_ptr c, bool calculate_digest) { if (dynamic_pointer_cast (c)) { run_ffprobe (c->path(0), file ("ffprobe.log"), _log); } - shared_ptr j (new ExamineContentJob (shared_from_this(), c)); + shared_ptr j (new ExamineContentJob (shared_from_this(), c, calculate_digest)); j->Finished.connect (bind (&Film::maybe_add_content, this, boost::weak_ptr (j), boost::weak_ptr (c))); JobManager::instance()->add (j); } diff --git a/src/lib/film.h b/src/lib/film.h index 8a0823094..1906de91b 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -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); - void examine_and_add_content (boost::shared_ptr); + void examine_content (boost::shared_ptr, bool calculate_digest); + void examine_and_add_content (boost::shared_ptr, bool calculate_digest); void add_content (boost::shared_ptr); void remove_content (boost::shared_ptr); void move_content_earlier (boost::shared_ptr); diff --git a/src/lib/image_content.cc b/src/lib/image_content.cc index 84b0b75c9..132b26144 100644 --- a/src/lib/image_content.cc +++ b/src/lib/image_content.cc @@ -100,10 +100,9 @@ ImageContent::as_xml (xmlpp::Node* node) const } void -ImageContent::examine (shared_ptr job) +ImageContent::examine (shared_ptr job, bool calculate_digest) { - job->sub (_("Computing digest")); - Content::examine (job); + Content::examine (job, calculate_digest); shared_ptr film = _film.lock (); assert (film); diff --git a/src/lib/image_content.h b/src/lib/image_content.h index a1b1437c8..6b70d5789 100644 --- a/src/lib/image_content.h +++ b/src/lib/image_content.h @@ -37,7 +37,7 @@ public: return boost::dynamic_pointer_cast (Content::shared_from_this ()); }; - void examine (boost::shared_ptr); + void examine (boost::shared_ptr, bool calculate_digest); std::string summary () const; std::string technical_summary () const; void as_xml (xmlpp::Node *) const; diff --git a/src/lib/image_examiner.cc b/src/lib/image_examiner.cc index ef9c13c5a..d6c7d0502 100644 --- a/src/lib/image_examiner.cc +++ b/src/lib/image_examiner.cc @@ -34,6 +34,7 @@ using std::cout; using std::list; using std::sort; using boost::shared_ptr; +using boost::optional; ImageExaminer::ImageExaminer (shared_ptr film, shared_ptr content, shared_ptr) : _film (film) @@ -63,7 +64,9 @@ ImageExaminer::ImageExaminer (shared_ptr film, shared_ptrstill ()) { _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 ImageExaminer::video_frame_rate () const { - boost::shared_ptr f = _film.lock (); - if (!f) { - return 24; - } - - return f->video_frame_rate (); + /* Don't know */ + return optional (); } diff --git a/src/lib/image_examiner.h b/src/lib/image_examiner.h index 6ae0422cb..1917a23f3 100644 --- a/src/lib/image_examiner.h +++ b/src/lib/image_examiner.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Carl Hetherington + Copyright (C) 2013-2014 Carl Hetherington 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, boost::shared_ptr, boost::shared_ptr); - float video_frame_rate () const; + boost::optional video_frame_rate () const; dcp::Size video_size () const; ContentTime video_length () const { return _video_length; diff --git a/src/lib/sndfile_content.cc b/src/lib/sndfile_content.cc index 1a1797665..cdc9734bf 100644 --- a/src/lib/sndfile_content.cc +++ b/src/lib/sndfile_content.cc @@ -101,10 +101,10 @@ SndfileContent::valid_file (boost::filesystem::path f) } void -SndfileContent::examine (shared_ptr job) +SndfileContent::examine (shared_ptr job, bool calculate_digest) { job->set_progress_unknown (); - Content::examine (job); + Content::examine (job, calculate_digest); shared_ptr dec (new SndfileDecoder (shared_from_this())); take_from_audio_examiner (dec); } diff --git a/src/lib/sndfile_content.h b/src/lib/sndfile_content.h index 75c723518..cb255fd74 100644 --- a/src/lib/sndfile_content.h +++ b/src/lib/sndfile_content.h @@ -41,7 +41,7 @@ public: DCPTime full_length () const; - void examine (boost::shared_ptr); + void examine (boost::shared_ptr, bool calculate_digest); std::string summary () const; std::string technical_summary () const; std::string information () const; diff --git a/src/lib/subrip_content.cc b/src/lib/subrip_content.cc index 14cb50b86..7a336f88a 100644 --- a/src/lib/subrip_content.cc +++ b/src/lib/subrip_content.cc @@ -47,9 +47,9 @@ SubRipContent::SubRipContent (shared_ptr film, cxml::ConstNodePtr no } void -SubRipContent::examine (boost::shared_ptr job) +SubRipContent::examine (boost::shared_ptr job, bool calculate_digest) { - Content::examine (job); + Content::examine (job, calculate_digest); SubRip s (shared_from_this ()); shared_ptr film = _film.lock (); diff --git a/src/lib/subrip_content.h b/src/lib/subrip_content.h index d2dcdee00..243032691 100644 --- a/src/lib/subrip_content.h +++ b/src/lib/subrip_content.h @@ -30,7 +30,7 @@ public: } /* Content */ - void examine (boost::shared_ptr); + void examine (boost::shared_ptr, bool calculate_digest); std::string summary () const; std::string technical_summary () const; std::string information () const; diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc index 8e07174e3..ca0c687a7 100644 --- a/src/lib/video_content.cc +++ b/src/lib/video_content.cc @@ -221,14 +221,16 @@ VideoContent::take_from_video_examiner (shared_ptr 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 const vfr = d->video_frame_rate (); ContentTime vl = d->video_length (); optional 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; diff --git a/src/lib/video_examiner.h b/src/lib/video_examiner.h index de7966507..55b27ac94 100644 --- a/src/lib/video_examiner.h +++ b/src/lib/video_examiner.h @@ -32,7 +32,7 @@ class VideoExaminer { public: virtual ~VideoExaminer () {} - virtual float video_frame_rate () const = 0; + virtual boost::optional video_frame_rate () const = 0; virtual dcp::Size video_size () const = 0; virtual ContentTime video_length () const = 0; virtual boost::optional sample_aspect_ratio () const { diff --git a/src/tools/dcpomatic.cc b/src/tools/dcpomatic.cc index 58cb32c53..b0df7b32c 100644 --- a/src/tools/dcpomatic.cc +++ b/src/tools/dcpomatic.cc @@ -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); } } diff --git a/src/tools/dcpomatic_create.cc b/src/tools/dcpomatic_create.cc index 304f4f697..6e8f16888 100644 --- a/src/tools/dcpomatic_create.cc +++ b/src/tools/dcpomatic_create.cc @@ -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 (); diff --git a/src/wx/content_menu.cc b/src/wx/content_menu.cc index 3e3c462b2..c528447ac 100644 --- a/src/wx/content_menu.cc +++ b/src/wx/content_menu.cc @@ -207,7 +207,7 @@ ContentMenu::find_missing () return; } - shared_ptr j (new ExamineContentJob (film, content)); + shared_ptr 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.lock (); assert (film); - film->examine_content (dcp); + film->examine_content (dcp, true); } d->Destroy (); diff --git a/src/wx/content_panel.cc b/src/wx/content_panel.cc index 2932ee7c5..4d73a608d 100644 --- a/src/wx/content_panel.cc +++ b/src/wx/content_panel.cc @@ -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; - - 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 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; + + try { + shared_ptr 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 index 000000000..930ef8b67 --- /dev/null +++ b/src/wx/image_sequence_dialog.cc @@ -0,0 +1,55 @@ +/* + Copyright (C) 2014 Carl Hetherington + + 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 +#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 (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 index 000000000..d3658b7b8 --- /dev/null +++ b/src/wx/image_sequence_dialog.h @@ -0,0 +1,34 @@ +/* + Copyright (C) 2014 Carl Hetherington + + 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 +#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; +}; diff --git a/src/wx/wscript b/src/wx/wscript index 6a6021c22..6a72f858d 100644 --- a/src/wx/wscript +++ b/src/wx/wscript @@ -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 diff --git a/test/4k_test.cc b/test/4k_test.cc index fa5b33bb9..63c5f5435 100644 --- a/test/4k_test.cc +++ b/test/4k_test.cc @@ -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 (); diff --git a/test/audio_analysis_test.cc b/test/audio_analysis_test.cc index 279944919..2da38f455 100644 --- a/test/audio_analysis_test.cc +++ b/test/audio_analysis_test.cc @@ -84,7 +84,7 @@ BOOST_AUTO_TEST_CASE (audio_analysis_test) boost::filesystem::path p = private_data / "betty_L.wav"; shared_ptr 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)); diff --git a/test/audio_delay_test.cc b/test/audio_delay_test.cc index 68e14ff3c..0127cc644 100644 --- a/test/audio_delay_test.cc +++ b/test/audio_delay_test.cc @@ -51,7 +51,7 @@ void test_audio_delay (int delay_in_ms) shared_ptr 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 (); diff --git a/test/black_fill_test.cc b/test/black_fill_test.cc index 5981552d1..99e0870b1 100644 --- a/test/black_fill_test.cc +++ b/test/black_fill_test.cc @@ -40,8 +40,8 @@ BOOST_AUTO_TEST_CASE (black_fill_test) shared_ptr contentA (new ImageContent (film, "test/data/simple_testcard_640x480.png")); shared_ptr 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"))); diff --git a/test/burnt_subtitle_test.cc b/test/burnt_subtitle_test.cc index d10d1ed25..9bb772f4a 100644 --- a/test/burnt_subtitle_test.cc +++ b/test/burnt_subtitle_test.cc @@ -42,7 +42,7 @@ BOOST_AUTO_TEST_CASE (burnt_subtitle_test_subrip) film->set_burn_subtitles (true); shared_ptr 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 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 (); diff --git a/test/dcp_subtitle_test.cc b/test/dcp_subtitle_test.cc index 95fa7d1ec..12d9a7a1e 100644 --- a/test/dcp_subtitle_test.cc +++ b/test/dcp_subtitle_test.cc @@ -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 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)); diff --git a/test/ffmpeg_audio_test.cc b/test/ffmpeg_audio_test.cc index 444b0869b..5117cf412 100644 --- a/test/ffmpeg_audio_test.cc +++ b/test/ffmpeg_audio_test.cc @@ -44,7 +44,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_audio_test) shared_ptr film = new_test_film ("ffmpeg_audio_test"); film->set_name ("ffmpeg_audio_test"); shared_ptr c (new FFmpegContent (film, "test/data/staircase.mov")); - film->examine_and_add_content (c); + film->examine_and_add_content (c, true); wait_for_jobs (); diff --git a/test/ffmpeg_dcp_test.cc b/test/ffmpeg_dcp_test.cc index 559277e51..8b441db98 100644 --- a/test/ffmpeg_dcp_test.cc +++ b/test/ffmpeg_dcp_test.cc @@ -38,7 +38,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_dcp_test) shared_ptr film = new_test_film ("ffmpeg_dcp_test"); film->set_name ("test_film2"); shared_ptr c (new FFmpegContent (film, "test/data/test.mp4")); - film->examine_and_add_content (c); + film->examine_and_add_content (c, true); wait_for_jobs (); diff --git a/test/ffmpeg_decoder_seek_test.cc b/test/ffmpeg_decoder_seek_test.cc index 968c3bdf9..3274fd8a9 100644 --- a/test/ffmpeg_decoder_seek_test.cc +++ b/test/ffmpeg_decoder_seek_test.cc @@ -60,7 +60,7 @@ test (boost::filesystem::path file, vector frames) shared_ptr film = new_test_film ("ffmpeg_decoder_seek_test_" + file.string()); shared_ptr content (new FFmpegContent (film, path)); - film->examine_and_add_content (content); + film->examine_and_add_content (content, true); wait_for_jobs (); shared_ptr log (new NullLog); FFmpegDecoder decoder (content, log); diff --git a/test/ffmpeg_decoder_sequential_test.cc b/test/ffmpeg_decoder_sequential_test.cc index c6af70c2c..e4968deda 100644 --- a/test/ffmpeg_decoder_sequential_test.cc +++ b/test/ffmpeg_decoder_sequential_test.cc @@ -47,7 +47,7 @@ test (boost::filesystem::path file, float fps, int gaps) shared_ptr film = new_test_film ("ffmpeg_decoder_seek_test_" + file.string()); shared_ptr content (new FFmpegContent (film, path)); - film->examine_and_add_content (content); + film->examine_and_add_content (content, true); wait_for_jobs (); shared_ptr log (new NullLog); FFmpegDecoder decoder (content, log); diff --git a/test/frame_rate_test.cc b/test/frame_rate_test.cc index e8ebcea3b..0ed5a64a7 100644 --- a/test/frame_rate_test.cc +++ b/test/frame_rate_test.cc @@ -243,7 +243,7 @@ BOOST_AUTO_TEST_CASE (audio_sampling_rate_test) shared_ptr film = new_test_film ("audio_sampling_rate_test"); /* Get any piece of content, it doesn't matter what */ shared_ptr 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 afr; diff --git a/test/import_dcp_test.cc b/test/import_dcp_test.cc index 80cd9c3df..b2420b1fe 100644 --- a/test/import_dcp_test.cc +++ b/test/import_dcp_test.cc @@ -39,7 +39,7 @@ BOOST_AUTO_TEST_CASE (import_dcp_test) A->set_name ("frobozz"); shared_ptr 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 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 (); diff --git a/test/isdcf_name_test.cc b/test/isdcf_name_test.cc index c2ea833bd..b0b83de44 100644 --- a/test/isdcf_name_test.cc +++ b/test/isdcf_name_test.cc @@ -73,7 +73,7 @@ BOOST_AUTO_TEST_CASE (isdcf_name_test) /* Test interior aspect ratio: shouldn't be shown with trailers */ shared_ptr 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")); diff --git a/test/play_test.cc b/test/play_test.cc index bbf70781a..f7aa52d6f 100644 --- a/test/play_test.cc +++ b/test/play_test.cc @@ -87,13 +87,13 @@ BOOST_AUTO_TEST_CASE (play_test) film->set_name ("play_test"); shared_ptr 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 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); diff --git a/test/player_test.cc b/test/player_test.cc index b6f864f82..d7a55b57a 100644 --- a/test/player_test.cc +++ b/test/player_test.cc @@ -44,9 +44,9 @@ BOOST_AUTO_TEST_CASE (player_overlaps_test) shared_ptr B (new FFmpegContent (film, "test/data/test.mp4")); shared_ptr 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 = film->make_player (); diff --git a/test/recover_test.cc b/test/recover_test.cc index fd9290f9e..cb5c26858 100644 --- a/test/recover_test.cc +++ b/test/recover_test.cc @@ -51,7 +51,7 @@ BOOST_AUTO_TEST_CASE (recover_test) shared_ptr 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 (); diff --git a/test/repeat_frame_test.cc b/test/repeat_frame_test.cc index 1d19d269e..d312ae7ed 100644 --- a/test/repeat_frame_test.cc +++ b/test/repeat_frame_test.cc @@ -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 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 (); diff --git a/test/scaling_test.cc b/test/scaling_test.cc index 441af6bf3..d642271c2 100644 --- a/test/scaling_test.cc +++ b/test/scaling_test.cc @@ -60,7 +60,7 @@ BOOST_AUTO_TEST_CASE (scaling_test) film->set_name ("scaling_test"); shared_ptr 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 (); diff --git a/test/seek_zero_test.cc b/test/seek_zero_test.cc index 2a1a06136..7abe7fa26 100644 --- a/test/seek_zero_test.cc +++ b/test/seek_zero_test.cc @@ -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 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"))); diff --git a/test/silence_padding_test.cc b/test/silence_padding_test.cc index d876a0228..25f2d80c9 100644 --- a/test/silence_padding_test.cc +++ b/test/silence_padding_test.cc @@ -48,7 +48,7 @@ test_silence_padding (int channels) film->set_name (film_name); shared_ptr 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); diff --git a/test/skip_frame_test.cc b/test/skip_frame_test.cc index 79be6d0f6..3e4f895c5 100644 --- a/test/skip_frame_test.cc +++ b/test/skip_frame_test.cc @@ -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 c (new FFmpegContent (film, "test/data/count300bd48.m2ts")); - film->examine_and_add_content (c); + film->examine_and_add_content (c, true); wait_for_jobs (); diff --git a/test/subrip_test.cc b/test/subrip_test.cc index e18ee2ea5..cd517cfe9 100644 --- a/test/subrip_test.cc +++ b/test/subrip_test.cc @@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE (subrip_render_test) { shared_ptr film = new_test_film ("subrip_render_test"); shared_ptr content (new SubRipContent (film, "test/data/subrip.srt")); - content->examine (shared_ptr ()); + content->examine (shared_ptr (), true); BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds ((3 * 60) + 56.471)); shared_ptr decoder (new SubRipDecoder (content)); diff --git a/test/threed_test.cc b/test/threed_test.cc index fb021d169..0553d4c0f 100644 --- a/test/threed_test.cc +++ b/test/threed_test.cc @@ -37,7 +37,7 @@ BOOST_AUTO_TEST_CASE (threed_test) film->set_name ("test_film2"); shared_ptr 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 (); diff --git a/test/upmixer_a_test.cc b/test/upmixer_a_test.cc index b115db21b..bdca521a2 100644 --- a/test/upmixer_a_test.cc +++ b/test/upmixer_a_test.cc @@ -38,7 +38,7 @@ BOOST_AUTO_TEST_CASE (upmixer_a_test) film->set_name ("frobozz"); shared_ptr 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 (); diff --git a/test/xml_subtitle_test.cc b/test/xml_subtitle_test.cc index 561b1021f..f6452c788 100644 --- a/test/xml_subtitle_test.cc +++ b/test/xml_subtitle_test.cc @@ -41,7 +41,7 @@ BOOST_AUTO_TEST_CASE (xml_subtitle_test) film->set_burn_subtitles (false); shared_ptr 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 (); -- 2.30.2