Stop player analysing audio even if it is configured automatically to happen.
[dcpomatic.git] / src / lib / film.cc
index 218dc58efcc31e080eb4400ad0ef26f2d17cc729..0c6a553861d1ea2d09e272aa2f1fe84b8f6e7852 100644 (file)
@@ -19,7 +19,7 @@
 */
 
 /** @file  src/film.cc
- *  @brief A representation of some audio and video content, and details of
+ *  @brief A representation of some audio, video and subtitle content, and details of
  *  how they should be presented in a DCP.
  */
 
@@ -27,6 +27,7 @@
 #include "job.h"
 #include "util.h"
 #include "job_manager.h"
+#include "dcp_encoder.h"
 #include "transcode_job.h"
 #include "upload_job.h"
 #include "null_log.h"
@@ -98,6 +99,8 @@ using dcp::raw_convert;
 #define LOG_GENERAL(...) log()->log (String::compose (__VA_ARGS__), LogEntry::TYPE_GENERAL);
 #define LOG_GENERAL_NC(...) log()->log (__VA_ARGS__, LogEntry::TYPE_GENERAL);
 
+string const Film::metadata_file = "metadata.xml";
+
 /* 5 -> 6
  * AudioMapping XML changed.
  * 6 -> 7
@@ -306,7 +309,7 @@ Film::make_dcp ()
        }
 
        if (name().empty()) {
-               throw MissingSettingError (_("name"));
+               set_name ("DCP");
        }
 
        BOOST_FOREACH (shared_ptr<const Content> i, content ()) {
@@ -339,7 +342,9 @@ Film::make_dcp ()
        }
        LOG_GENERAL ("J2K bandwidth %1", j2k_bandwidth());
 
-       JobManager::instance()->add (shared_ptr<Job> (new TranscodeJob (shared_from_this())));
+       shared_ptr<TranscodeJob> tj (new TranscodeJob (shared_from_this()));
+       tj->set_encoder (shared_ptr<Encoder> (new DCPEncoder (shared_from_this(), tj)));
+       JobManager::instance()->add (tj);
 }
 
 /** Start a job to send our DCP to the configured TMS */
@@ -399,7 +404,7 @@ Film::write_metadata () const
        DCPOMATIC_ASSERT (directory());
        boost::filesystem::create_directories (directory().get());
        shared_ptr<xmlpp::Document> doc = metadata ();
-       doc->write_to_file_formatted (file("metadata.xml").string ());
+       doc->write_to_file_formatted (file(metadata_file).string ());
        _dirty = false;
 }
 
@@ -419,11 +424,11 @@ list<string>
 Film::read_metadata (optional<boost::filesystem::path> path)
 {
        if (!path) {
-               if (boost::filesystem::exists (file ("metadata")) && !boost::filesystem::exists (file ("metadata.xml"))) {
+               if (boost::filesystem::exists (file ("metadata")) && !boost::filesystem::exists (file (metadata_file))) {
                        throw runtime_error (_("This film was created with an older version of DCP-o-matic, and unfortunately it cannot be loaded into this version.  You will need to create a new Film, re-add your content and set it up again.  Sorry!"));
                }
 
-               path = file ("metadata.xml");
+               path = file (metadata_file);
        }
 
        cxml::Document f ("Metadata");
@@ -509,7 +514,7 @@ Film::read_metadata (optional<boost::filesystem::path> path)
 }
 
 /** Given a directory name, return its full path within the Film's directory.
- *  @param d directory name within the Filn's directory.
+ *  @param d directory name within the Film's directory.
  *  @param create true to create the directory (and its parents) if they do not exist.
  */
 boost::filesystem::path
@@ -723,24 +728,9 @@ Film::isdcf_name (bool if_created_now) const
 
        /* Count mapped audio channels */
 
-       int non_lfe = 0;
-       int lfe = 0;
-
-       BOOST_FOREACH (int i, mapped_audio_channels ()) {
-               if (i >= audio_channels()) {
-                       /* This channel is mapped but is not included in the DCP */
-                       continue;
-               }
-
-               if (static_cast<dcp::Channel> (i) == dcp::LFE) {
-                       ++lfe;
-               } else {
-                       ++non_lfe;
-               }
-       }
-
-       if (non_lfe) {
-               d += String::compose("_%1%2", non_lfe, lfe);
+       pair<int, int> ch = audio_channel_types (mapped_audio_channels(), audio_channels());
+       if (ch.first) {
+               d += String::compose("_%1%2", ch.first, ch.second);
        }
 
        /* XXX: HI/VI */
@@ -1037,24 +1027,27 @@ Film::content () const
        return _playlist->content ();
 }
 
+/** @param content Content to add.
+ *  @param disable_audio_analysis true to never do automatic audio analysis, even if it is enabled in configuration.
+ */
 void
-Film::examine_and_add_content (shared_ptr<Content> c)
+Film::examine_and_add_content (shared_ptr<Content> content, bool disable_audio_analysis)
 {
-       if (dynamic_pointer_cast<FFmpegContent> (c) && _directory) {
-               run_ffprobe (c->path(0), file ("ffprobe.log"), _log);
+       if (dynamic_pointer_cast<FFmpegContent> (content) && _directory) {
+               run_ffprobe (content->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(), content));
 
        _job_connections.push_back (
-               j->Finished.connect (bind (&Film::maybe_add_content, this, weak_ptr<Job> (j), weak_ptr<Content> (c)))
+               j->Finished.connect (bind (&Film::maybe_add_content, this, weak_ptr<Job>(j), weak_ptr<Content>(content), disable_audio_analysis))
                );
 
        JobManager::instance()->add (j);
 }
 
 void
-Film::maybe_add_content (weak_ptr<Job> j, weak_ptr<Content> c)
+Film::maybe_add_content (weak_ptr<Job> j, weak_ptr<Content> c, bool disable_audio_analysis)
 {
        shared_ptr<Job> job = j.lock ();
        if (!job || !job->finished_ok ()) {
@@ -1068,7 +1061,7 @@ Film::maybe_add_content (weak_ptr<Job> j, weak_ptr<Content> c)
 
        add_content (content);
 
-       if (Config::instance()->automatic_audio_analysis() && content->audio) {
+       if (Config::instance()->automatic_audio_analysis() && content->audio && !disable_audio_analysis) {
                shared_ptr<Playlist> playlist (new Playlist);
                playlist->add (content);
                boost::signals2::connection c;
@@ -1123,7 +1116,7 @@ Film::move_content_later (shared_ptr<Content> c)
 DCPTime
 Film::length () const
 {
-       return _playlist->length ();
+       return _playlist->length().ceil(video_frame_rate());
 }
 
 int
@@ -1466,7 +1459,7 @@ list<DCPTimePeriod>
 Film::reels () const
 {
        list<DCPTimePeriod> p;
-       DCPTime const len = length().ceil (video_frame_rate ());
+       DCPTime const len = length();
 
        switch (reel_type ()) {
        case REELTYPE_SINGLE:
@@ -1584,3 +1577,15 @@ Film::use_template (string name)
        _reel_length = _template_film->_reel_length;
        _upload_after_make_dcp = _template_film->_upload_after_make_dcp;
 }
+
+pair<double, double>
+Film::speed_up_range (int dcp_frame_rate) const
+{
+       return _playlist->speed_up_range (dcp_frame_rate);
+}
+
+void
+Film::copy_from (shared_ptr<const Film> film)
+{
+       read_metadata (film->file (metadata_file));
+}