Add support for no-scale of the input video.
[dcpomatic.git] / src / lib / film.cc
index edd47c6d056df916df4793e63d7fe965774a8865..00beb870f6e0ead188a1c013cc4f32b23e8594bb 100644 (file)
@@ -81,14 +81,21 @@ using boost::optional;
 using libdcp::Size;
 using libdcp::Signer;
 
-int const Film::state_version = 5;
+/* 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::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 ())
@@ -101,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 ();
@@ -131,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);
 }
@@ -262,6 +274,14 @@ Film::make_dcp ()
 #else
        log()->log ("libdcp built in optimised mode.");
 #endif
+
+#ifdef DCPOMATIC_WINDOWS
+       OSVERSIONINFO info;
+       info.dwOSVersionInfoSize = sizeof (info);
+       GetVersionEx (&info);
+       log()->log (String::compose ("Windows version %1.%2.%3 SP %4", info.dwMajorVersion, info.dwMinorVersion, info.dwBuildNumber, info.szCSDVersion));
+#endif 
+       
        log()->log (String::compose ("CPU: %1, %2 processors", cpu_info(), boost::thread::hardware_concurrency ()));
        list<pair<string, string> > const m = mount_info ();
        for (list<pair<string, string> >::const_iterator i = m.begin(); i != m.end(); ++i) {
@@ -314,22 +334,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");
 
@@ -357,8 +370,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;
 }
 
@@ -375,7 +396,7 @@ 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");
        
        _name = f.string_child ("Name");
        _use_dci_name = f.bool_child ("UseDCIName");
@@ -408,7 +429,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;
 }
@@ -881,25 +902,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