summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2014-12-03 10:12:35 +0000
committerCarl Hetherington <cth@carlh.net>2014-12-03 10:12:35 +0000
commitc008066160d85b9ec9e5485375d7baaa5d27bda2 (patch)
treecf2876d69549119bf22761c5f6eccb568242b647
parent996fa2194581bf95113b9778849654893c414889 (diff)
Hand-apply 6a3cd511559433554ab40ed72ff94b7d8dc2c5bd from master;
Basics of an image sequence dialog that asks about frame rate and digest calculation.
-rw-r--r--src/lib/content.cc9
-rw-r--r--src/lib/content.h3
-rw-r--r--src/lib/dcp_content.cc4
-rw-r--r--src/lib/dcp_content.h2
-rw-r--r--src/lib/dcp_examiner.h4
-rw-r--r--src/lib/dcp_subtitle_content.cc4
-rw-r--r--src/lib/dcp_subtitle_content.h2
-rw-r--r--src/lib/examine_content_job.cc5
-rw-r--r--src/lib/examine_content_job.h3
-rw-r--r--src/lib/ffmpeg_content.cc4
-rw-r--r--src/lib/ffmpeg_content.h2
-rw-r--r--src/lib/ffmpeg_examiner.cc2
-rw-r--r--src/lib/ffmpeg_examiner.h2
-rw-r--r--src/lib/film.cc8
-rw-r--r--src/lib/film.h4
-rw-r--r--src/lib/image_content.cc5
-rw-r--r--src/lib/image_content.h2
-rw-r--r--src/lib/image_examiner.cc15
-rw-r--r--src/lib/image_examiner.h4
-rw-r--r--src/lib/sndfile_content.cc4
-rw-r--r--src/lib/sndfile_content.h2
-rw-r--r--src/lib/subrip_content.cc4
-rw-r--r--src/lib/subrip_content.h2
-rw-r--r--src/lib/video_content.cc6
-rw-r--r--src/lib/video_examiner.h2
-rw-r--r--src/tools/dcpomatic.cc2
-rw-r--r--src/tools/dcpomatic_create.cc2
-rw-r--r--src/wx/content_menu.cc6
-rw-r--r--src/wx/content_panel.cc53
-rw-r--r--src/wx/image_sequence_dialog.cc55
-rw-r--r--src/wx/image_sequence_dialog.h34
-rw-r--r--src/wx/wscript1
-rw-r--r--test/4k_test.cc2
-rw-r--r--test/audio_analysis_test.cc2
-rw-r--r--test/audio_delay_test.cc2
-rw-r--r--test/black_fill_test.cc4
-rw-r--r--test/burnt_subtitle_test.cc4
-rw-r--r--test/dcp_subtitle_test.cc2
-rw-r--r--test/ffmpeg_audio_test.cc2
-rw-r--r--test/ffmpeg_dcp_test.cc2
-rw-r--r--test/ffmpeg_decoder_seek_test.cc2
-rw-r--r--test/ffmpeg_decoder_sequential_test.cc2
-rw-r--r--test/frame_rate_test.cc2
-rw-r--r--test/import_dcp_test.cc4
-rw-r--r--test/isdcf_name_test.cc2
-rw-r--r--test/play_test.cc4
-rw-r--r--test/player_test.cc8
-rw-r--r--test/recover_test.cc2
-rw-r--r--test/repeat_frame_test.cc2
-rw-r--r--test/scaling_test.cc2
-rw-r--r--test/seek_zero_test.cc2
-rw-r--r--test/silence_padding_test.cc2
-rw-r--r--test/skip_frame_test.cc2
-rw-r--r--test/subrip_test.cc2
-rw-r--r--test/threed_test.cc2
-rw-r--r--test/upmixer_a_test.cc2
-rw-r--r--test/xml_subtitle_test.cc2
57 files changed, 224 insertions, 97 deletions
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> 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 ();
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> 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.
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> 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);
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<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;
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<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 {
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<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 ());
}
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<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;
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<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);
}
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<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;
};
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> 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);
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<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;
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<float>
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<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;
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<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);
}
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<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>);
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> 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);
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<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;
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<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> ();
}
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 <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;
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> 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);
}
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<Job>);
+ void examine (boost::shared_ptr<Job>, 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<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 ();
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<Job>);
+ void examine (boost::shared_ptr<Job>, 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<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;
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<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 {
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<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 ();
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> 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
index 000000000..930ef8b67
--- /dev/null
+++ b/src/wx/image_sequence_dialog.cc
@@ -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
index 000000000..d3658b7b8
--- /dev/null
+++ b/src/wx/image_sequence_dialog.h
@@ -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;
+};
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<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));
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<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 ();
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<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")));
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<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 ();
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<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));
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> 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 ();
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> 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 ();
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<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);
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> 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);
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> 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;
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<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 ();
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<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"));
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<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);
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<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 ();
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<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 ();
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<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 ();
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<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 ();
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<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")));
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<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);
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<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 ();
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> 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));
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<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 ();
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<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 ();
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<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 ();