Remove film player, DVD ripping, alignment, screen configs; never finished and not...
[dcpomatic.git] / src / lib / film.cc
index 70c8f7db2e66457e9e408bb0a019385bb17e3163..902306fb84f277c34de864a7c30eb892506139e7 100644 (file)
@@ -40,7 +40,6 @@
 #include "ab_transcode_job.h"
 #include "transcode_job.h"
 #include "scp_dcp_job.h"
-#include "copy_from_dvd_job.h"
 #include "make_dcp_job.h"
 #include "log.h"
 #include "options.h"
@@ -63,6 +62,7 @@ using std::ifstream;
 using std::ofstream;
 using std::setfill;
 using std::min;
+using std::make_pair;
 using boost::shared_ptr;
 using boost::lexical_cast;
 using boost::to_upper_copy;
@@ -82,6 +82,8 @@ Film::Film (string d, bool must_exist)
        , _dcp_content_type (0)
        , _format (0)
        , _scaler (Scaler::from_id ("bicubic"))
+       , _dcp_trim_start (0)
+       , _dcp_trim_end (0)
        , _dcp_ab (false)
        , _audio_stream (-1)
        , _audio_gain (0)
@@ -141,7 +143,8 @@ Film::Film (Film const & o)
        , _crop              (o._crop)
        , _filters           (o._filters)
        , _scaler            (o._scaler)
-       , _dcp_frames        (o._dcp_frames)
+       , _dcp_trim_start    (o._dcp_trim_start)
+       , _dcp_trim_end      (o._dcp_trim_end)
        , _dcp_ab            (o._dcp_ab)
        , _audio_stream      (o._audio_stream)
        , _audio_gain        (o._audio_gain)
@@ -254,7 +257,16 @@ Film::make_dcp (bool transcode)
        o->out_size = format()->dcp_size ();
        o->padding = format()->dcp_padding (shared_from_this ());
        o->ratio = format()->ratio_as_float (shared_from_this ());
+       if (dcp_length ()) {
+               o->video_decode_range = make_pair (dcp_trim_start(), dcp_trim_start() + dcp_length().get());
+               o->audio_decode_range = make_pair (
+                       video_frames_to_audio_frames (o->video_decode_range.get().first, audio_sample_rate(), frames_per_second()),
+                       video_frames_to_audio_frames (o->video_decode_range.get().second, audio_sample_rate(), frames_per_second())
+                       );
+                       
+       }
        o->decode_subtitles = with_subtitles ();
+       o->decode_video_skip = dcp_frame_rate (frames_per_second()).skip;
 
        shared_ptr<Job> r;
 
@@ -278,7 +290,7 @@ Film::examine_content ()
                return;
        }
 
-       set_thumbs (vector<int> ());
+       set_thumbs (vector<SourceFrame> ());
        boost::filesystem::remove_all (dir ("thumbs"));
 
        /* This call will recreate the directory */
@@ -315,13 +327,6 @@ Film::send_dcp_to_tms ()
        JobManager::instance()->add (j);
 }
 
-void
-Film::copy_from_dvd ()
-{
-       shared_ptr<Job> j (new CopyFromDVDJob (shared_from_this(), shared_ptr<Job> ()));
-       JobManager::instance()->add (j);
-}
-
 /** Count the number of frames that have been encoded for this film.
  *  @return frame count.
  */
@@ -402,7 +407,8 @@ Film::write_metadata () const
                f << "filter " << (*i)->id () << "\n";
        }
        f << "scaler " << _scaler->id () << "\n";
-       f << "dcp_frames " << _dcp_frames.get_value_or(0) << "\n";
+       f << "dcp_trim_start " << _dcp_trim_start << "\n";
+       f << "dcp_trim_end " << _dcp_trim_end << "\n";
        f << "dcp_ab " << (_dcp_ab ? "1" : "0") << "\n";
        f << "selected_audio_stream " << _audio_stream << "\n";
        f << "audio_gain " << _audio_gain << "\n";
@@ -423,7 +429,7 @@ Film::write_metadata () const
        /* Cached stuff; this is information about our content; we could
           look it up each time, but that's slow.
        */
-       for (vector<int>::const_iterator i = _thumbs.begin(); i != _thumbs.end(); ++i) {
+       for (vector<SourceFrame>::const_iterator i = _thumbs.begin(); i != _thumbs.end(); ++i) {
                f << "thumb " << *i << "\n";
        }
        f << "width " << _size.width << "\n";
@@ -481,11 +487,10 @@ Film::read_metadata ()
                        _filters.push_back (Filter::from_id (v));
                } else if (k == "scaler") {
                        _scaler = Scaler::from_id (v);
-               } else if (k == "dcp_frames") {
-                       int const vv = atoi (v.c_str ());
-                       if (vv) {
-                               _dcp_frames = vv;
-                       }
+               } else if (k == "dcp_trim_start") {
+                       _dcp_trim_start = atoi (v.c_str ());
+               } else if (k == "dcp_trim_end") {
+                       _dcp_trim_end = atoi (v.c_str ());
                } else if (k == "dcp_ab") {
                        _dcp_ab = (v == "1");
                } else if (k == "selected_audio_stream") {
@@ -563,17 +568,19 @@ Film::thumb_file (int n) const
        return thumb_file_for_frame (thumb_frame (n));
 }
 
-/** @param n A frame index within the Film.
+/** @param n A frame index within the Film's source.
  *  @return The path to the thumb's image file for this frame;
  *  we assume that it exists.
  */
 string
-Film::thumb_file_for_frame (int n) const
+Film::thumb_file_for_frame (SourceFrame n) const
 {
        return thumb_base_for_frame(n) + ".png";
 }
 
-/** Must not be called with the _state_mutex locked */
+/** @param n Thumb index.
+ *  Must not be called with the _state_mutex locked.
+ */
 string
 Film::thumb_base (int n) const
 {
@@ -581,7 +588,7 @@ Film::thumb_base (int n) const
 }
 
 string
-Film::thumb_base_for_frame (int n) const
+Film::thumb_base_for_frame (SourceFrame n) const
 {
        stringstream s;
        s.width (8);
@@ -595,11 +602,11 @@ Film::thumb_base_for_frame (int n) const
 }
 
 /** @param n A thumb index.
- *  @return The frame within the Film that it is for.
+ *  @return The frame within the Film's source that it is for.
  *
  *  Must not be called with the _state_mutex locked.
  */
-int
+SourceFrame
 Film::thumb_frame (int n) const
 {
        boost::mutex::scoped_lock lm (_state_mutex);
@@ -682,28 +689,26 @@ Film::target_audio_sample_rate () const
        /* Resample to a DCI-approved sample rate */
        double t = dcp_audio_sample_rate (audio_sample_rate());
 
+       DCPFrameRate dfr = dcp_frame_rate (frames_per_second ());
+
        /* Compensate for the fact that video will be rounded to the
           nearest integer number of frames per second.
        */
-       if (rint (frames_per_second()) != frames_per_second()) {
-               t *= _frames_per_second / rint (frames_per_second());
+       if (dfr.run_fast) {
+               t *= _frames_per_second * dfr.skip / dfr.frames_per_second;
        }
 
        return rint (t);
 }
 
-boost::optional<int>
+boost::optional<SourceFrame>
 Film::dcp_length () const
 {
        if (!length()) {
-               return boost::optional<int> ();
+               return boost::optional<SourceFrame> ();
        }
 
-       if (dcp_frames()) {
-               return min (dcp_frames().get(), length().get());
-       }
-
-       return length();
+       return length().get() - dcp_trim_start() - dcp_trim_end();
 }
 
 /** @return a DCI-compliant name for a DCP of this film */
@@ -755,19 +760,21 @@ Film::dci_name () const
                d << "_";
        }
 
-       switch (_audio_streams[_audio_stream].channels()) {
-       case 1:
-               d << "10_";
-               break;
-       case 2:
-               d << "20_";
-               break;
-       case 6:
-               d << "51_";
-               break;
-       case 8:
-               d << "71_";
-               break;
+       if (_audio_stream != -1) {
+               switch (_audio_streams[_audio_stream].channels()) {
+               case 1:
+                       d << "10_";
+                       break;
+               case 2:
+                       d << "20_";
+                       break;
+               case 6:
+                       d << "51_";
+                       break;
+               case 8:
+                       d << "71_";
+                       break;
+               }
        }
 
        d << "2K_";
@@ -873,7 +880,7 @@ Film::set_content (string c)
                shared_ptr<Options> o (new Options ("", "", ""));
                o->out_size = Size (1024, 1024);
                
-               shared_ptr<Decoder> d = decoder_factory (shared_from_this(), o, 0, 0);
+               shared_ptr<Decoder> d = decoder_factory (shared_from_this(), o, 0);
                
                set_size (d->native_size ());
                set_frames_per_second (d->frames_per_second ());
@@ -1012,23 +1019,23 @@ Film::set_scaler (Scaler const * s)
 }
 
 void
-Film::set_dcp_frames (int f)
+Film::set_dcp_trim_start (int t)
 {
        {
                boost::mutex::scoped_lock lm (_state_mutex);
-               _dcp_frames = f;
+               _dcp_trim_start = t;
        }
-       signal_changed (DCP_FRAMES);
+       signal_changed (DCP_TRIM_START);
 }
 
 void
-Film::unset_dcp_frames ()
+Film::set_dcp_trim_end (int t)
 {
        {
                boost::mutex::scoped_lock lm (_state_mutex);
-               _dcp_frames = boost::none;
+               _dcp_trim_end = t;
        }
-       signal_changed (DCP_FRAMES);
+       signal_changed (DCP_TRIM_END);
 }
 
 void
@@ -1192,7 +1199,7 @@ Film::set_package_type (string p)
 }
 
 void
-Film::set_thumbs (vector<int> t)
+Film::set_thumbs (vector<SourceFrame> t)
 {
        {
                boost::mutex::scoped_lock lm (_state_mutex);
@@ -1212,7 +1219,7 @@ Film::set_size (Size s)
 }
 
 void
-Film::set_length (int l)
+Film::set_length (SourceFrame l)
 {
        {
                boost::mutex::scoped_lock lm (_state_mutex);
@@ -1320,3 +1327,4 @@ Film::set_dci_date_today ()
 {
        _dci_date = boost::gregorian::day_clock::local_day ();
 }
+