Name audio analyses with stream ID so that you can see analyses
[dcpomatic.git] / src / lib / film.cc
index 1290cbda21fc67f44b924d323607262c1799bff4..da48bc9b2656184a004dd3193e84d32fe6e9c8b2 100644 (file)
@@ -83,15 +83,19 @@ using libdcp::Signer;
 
 /* 5 -> 6
  * AudioMapping XML changed.
+ * 6 -> 7
+ * Subtitle offset changed to subtitle y offset, and subtitle x offset added.
+ * 7 -> 8
+ * Use <Scale> tag in <VideoContent> rather than <Ratio>.
  */
-int const Film::state_version = 6;
+int const Film::current_state_version = 8;
 
 /** Construct a Film object in a given directory.
  *
  *  @param dir Film directory.
  */
 
-Film::Film (boost::filesystem::path dir)
+Film::Film (boost::filesystem::path dir, bool log)
        : _playlist (new Playlist)
        , _use_dci_name (true)
        , _dcp_content_type (Config::instance()->default_dcp_content_type ())
@@ -104,10 +108,11 @@ Film::Film (boost::filesystem::path dir)
        , _j2k_bandwidth (Config::instance()->default_j2k_bandwidth ())
        , _dci_metadata (Config::instance()->default_dci_metadata ())
        , _video_frame_rate (24)
-       , _audio_channels (MAX_AUDIO_CHANNELS)
+       , _audio_channels (6)
        , _three_d (false)
        , _sequence_video (true)
        , _interop (false)
+       , _state_version (current_state_version)
        , _dirty (false)
 {
        set_dci_date_today ();
@@ -134,7 +139,11 @@ Film::Film (boost::filesystem::path dir)
        }
 
        set_directory (result);
-       _log.reset (new FileLog (file ("log")));
+       if (log) {
+               _log.reset (new FileLog (file ("log")));
+       } else {
+               _log.reset (new NullLog);
+       }
 
        _playlist->set_sequence_video (_sequence_video);
 }
@@ -223,11 +232,9 @@ Film::filename_safe_name () const
 }
 
 boost::filesystem::path
-Film::audio_analysis_path (shared_ptr<const AudioContent> c) const
+Film::audio_analysis_dir () const
 {
-       boost::filesystem::path p = dir ("analysis");
-       p /= c->digest();
-       return p;
+       return dir ("analysis");
 }
 
 /** Add suitable Jobs to the JobManager to create a DCP for this Film */
@@ -325,22 +332,15 @@ Film::encoded_frames () const
        return N;
 }
 
-/** Write state to our `metadata' file */
-void
-Film::write_metadata () const
+shared_ptr<xmlpp::Document>
+Film::metadata () const
 {
-       if (!boost::filesystem::exists (directory ())) {
-               boost::filesystem::create_directory (directory ());
-       }
-       
        LocaleGuard lg;
 
-       boost::filesystem::create_directories (directory ());
-
-       xmlpp::Document doc;
-       xmlpp::Element* root = doc.create_root_node ("Metadata");
+       shared_ptr<xmlpp::Document> doc (new xmlpp::Document);
+       xmlpp::Element* root = doc->create_root_node ("Metadata");
 
-       root->add_child("Version")->add_child_text (lexical_cast<string> (state_version));
+       root->add_child("Version")->add_child_text (lexical_cast<string> (current_state_version));
        root->add_child("Name")->add_child_text (_name);
        root->add_child("UseDCIName")->add_child_text (_use_dci_name ? "1" : "0");
 
@@ -368,8 +368,16 @@ Film::write_metadata () const
        root->add_child("Key")->add_child_text (_key.hex ());
        _playlist->as_xml (root->add_child ("Playlist"));
 
-       doc.write_to_file_formatted (file("metadata.xml").string ());
-       
+       return doc;
+}
+
+/** Write state to our `metadata' file */
+void
+Film::write_metadata () const
+{
+       boost::filesystem::create_directories (directory ());
+       shared_ptr<xmlpp::Document> doc = metadata ();
+       doc->write_to_file_formatted (file("metadata.xml").string ());
        _dirty = false;
 }
 
@@ -386,7 +394,10 @@ Film::read_metadata ()
        cxml::Document f ("Metadata");
        f.read_file (file ("metadata.xml"));
 
-       int const version = f.number_child<int> ("Version");
+       _state_version = f.number_child<int> ("Version");
+       if (_state_version > current_state_version) {
+               throw StringError (_("This film was created with a newer version of DCP-o-matic, and it cannot be loaded into this version.  Sorry!"));
+       }
        
        _name = f.string_child ("Name");
        _use_dci_name = f.bool_child ("UseDCIName");
@@ -419,7 +430,7 @@ Film::read_metadata ()
        _three_d = f.bool_child ("ThreeD");
        _interop = f.bool_child ("Interop");
        _key = libdcp::Key (f.string_child ("Key"));
-       _playlist->set_from_xml (shared_from_this(), f.node_child ("Playlist"), version);
+       _playlist->set_from_xml (shared_from_this(), f.node_child ("Playlist"), _state_version);
 
        _dirty = false;
 }
@@ -892,25 +903,25 @@ Film::playlist_changed ()
 OutputAudioFrame
 Film::time_to_audio_frames (Time t) const
 {
-       return t * audio_frame_rate () / TIME_HZ;
+       return divide_with_round (t * audio_frame_rate (), TIME_HZ);
 }
 
 OutputVideoFrame
 Film::time_to_video_frames (Time t) const
 {
-       return t * video_frame_rate () / TIME_HZ;
+       return divide_with_round (t * video_frame_rate (), TIME_HZ);
 }
 
 Time
 Film::audio_frames_to_time (OutputAudioFrame f) const
 {
-       return f * TIME_HZ / audio_frame_rate ();
+       return divide_with_round (f * TIME_HZ, audio_frame_rate ());
 }
 
 Time
 Film::video_frames_to_time (OutputVideoFrame f) const
 {
-       return f * TIME_HZ / video_frame_rate ();
+       return divide_with_round (f * TIME_HZ, video_frame_rate ());
 }
 
 OutputAudioFrame