summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2012-11-04 15:58:22 +0000
committerCarl Hetherington <cth@carlh.net>2012-11-04 15:58:22 +0000
commit4fb0a5ab9eebc0f07981edc3a6813102520b8233 (patch)
tree4651bda7e99e3214ce5af2a21e33141d7f308e4a /src
parentc4362a7aa94d9340e38021a67a85635fc6cd4f7d (diff)
Various work on range setting.
Diffstat (limited to 'src')
-rw-r--r--src/lib/ab_transcoder.cc2
-rw-r--r--src/lib/ab_transcoder.h5
-rw-r--r--src/lib/check_hashes_job.cc4
-rw-r--r--src/lib/dcp_video_frame.cc4
-rw-r--r--src/lib/dcp_video_frame.h12
-rw-r--r--src/lib/decoder.cc3
-rw-r--r--src/lib/decoder.h8
-rw-r--r--src/lib/encoder.cc6
-rw-r--r--src/lib/encoder.h13
-rw-r--r--src/lib/examine_content_job.cc2
-rw-r--r--src/lib/film.cc26
-rw-r--r--src/lib/film.h28
-rw-r--r--src/lib/imagemagick_encoder.cc2
-rw-r--r--src/lib/imagemagick_encoder.h2
-rw-r--r--src/lib/j2k_still_encoder.cc2
-rw-r--r--src/lib/j2k_still_encoder.h2
-rw-r--r--src/lib/j2k_wav_encoder.cc2
-rw-r--r--src/lib/j2k_wav_encoder.h2
-rw-r--r--src/lib/make_dcp_job.cc5
-rw-r--r--src/lib/options.h10
-rw-r--r--src/lib/transcode_job.cc3
-rw-r--r--src/lib/util.h2
-rw-r--r--src/wx/dcp_range_dialog.cc5
23 files changed, 86 insertions, 64 deletions
diff --git a/src/lib/ab_transcoder.cc b/src/lib/ab_transcoder.cc
index beedd478f..0579aa4ff 100644
--- a/src/lib/ab_transcoder.cc
+++ b/src/lib/ab_transcoder.cc
@@ -66,7 +66,7 @@ ABTranscoder::~ABTranscoder ()
}
void
-ABTranscoder::process_video (shared_ptr<Image> yuv, int frame, shared_ptr<Subtitle> sub, int index)
+ABTranscoder::process_video (shared_ptr<Image> yuv, SourceFrame frame, shared_ptr<Subtitle> sub, int index)
{
if (index == 0) {
/* Keep this image around until we get the other half */
diff --git a/src/lib/ab_transcoder.h b/src/lib/ab_transcoder.h
index 7bf5dd4a1..a136fd270 100644
--- a/src/lib/ab_transcoder.h
+++ b/src/lib/ab_transcoder.h
@@ -24,6 +24,7 @@
#include <boost/shared_ptr.hpp>
#include <stdint.h>
+#include "util.h"
class Job;
class Encoder;
@@ -54,7 +55,7 @@ public:
void go ();
private:
- void process_video (boost::shared_ptr<Image>, int, boost::shared_ptr<Subtitle>, int);
+ void process_video (boost::shared_ptr<Image>, SourceFrame, boost::shared_ptr<Subtitle>, int);
boost::shared_ptr<Film> _film_a;
boost::shared_ptr<Film> _film_b;
@@ -63,6 +64,6 @@ private:
boost::shared_ptr<Encoder> _encoder;
boost::shared_ptr<Decoder> _da;
boost::shared_ptr<Decoder> _db;
- int _last_frame;
+ SourceFrame _last_frame;
boost::shared_ptr<Image> _image;
};
diff --git a/src/lib/check_hashes_job.cc b/src/lib/check_hashes_job.cc
index d1483933d..3967d0d70 100644
--- a/src/lib/check_hashes_job.cc
+++ b/src/lib/check_hashes_job.cc
@@ -57,10 +57,10 @@ CheckHashesJob::run ()
throw EncodeError ("cannot check hashes of a DCP with unknown length");
}
- int const N = _film->dcp_length().get();
+ SourceFrame const N = _film->dcp_trim_start() + _film->dcp_length().get();
DCPFrameRate const dfr = dcp_frame_rate (_film->frames_per_second ());
- for (int i = 0; i < N; i += dfr.skip) {
+ for (SourceFrame i = _film->dcp_trim_start(); i < N; i += dfr.skip) {
string const j2k_file = _opt->frame_out_path (i, false);
string const hash_file = j2k_file + ".md5";
diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc
index 1dcc81f0d..c185de0f4 100644
--- a/src/lib/dcp_video_frame.cc
+++ b/src/lib/dcp_video_frame.cc
@@ -76,7 +76,7 @@ using boost::shared_ptr;
DCPVideoFrame::DCPVideoFrame (
shared_ptr<const Image> yuv, shared_ptr<Subtitle> sub,
Size out, int p, int subtitle_offset, float subtitle_scale,
- Scaler const * s, int f, float fps, string pp, int clut, int bw, Log* l
+ Scaler const * s, SourceFrame f, float fps, string pp, int clut, int bw, Log* l
)
: _input (yuv)
, _subtitle (sub)
@@ -376,7 +376,7 @@ DCPVideoFrame::encode_remotely (ServerDescription const * serv)
* @param frame Frame index.
*/
void
-EncodedData::write (shared_ptr<const Options> opt, int frame)
+EncodedData::write (shared_ptr<const Options> opt, SourceFrame frame)
{
string const tmp_j2k = opt->frame_out_path (frame, true);
diff --git a/src/lib/dcp_video_frame.h b/src/lib/dcp_video_frame.h
index 0ff29f7bf..5ae53f1e8 100644
--- a/src/lib/dcp_video_frame.h
+++ b/src/lib/dcp_video_frame.h
@@ -50,7 +50,7 @@ public:
virtual ~EncodedData () {}
void send (boost::shared_ptr<Socket> socket);
- void write (boost::shared_ptr<const Options>, int);
+ void write (boost::shared_ptr<const Options>, SourceFrame);
/** @return data */
uint8_t* data () const {
@@ -106,13 +106,17 @@ public:
class DCPVideoFrame
{
public:
- DCPVideoFrame (boost::shared_ptr<const Image>, boost::shared_ptr<Subtitle>, Size, int, int, float, Scaler const *, int, float, std::string, int, int, Log *);
+ DCPVideoFrame (
+ boost::shared_ptr<const Image>, boost::shared_ptr<Subtitle>, Size,
+ int, int, float, Scaler const *, SourceFrame, float, std::string, int, int, Log *
+ );
+
virtual ~DCPVideoFrame ();
boost::shared_ptr<EncodedData> encode_locally ();
boost::shared_ptr<EncodedData> encode_remotely (ServerDescription const *);
- int frame () const {
+ SourceFrame frame () const {
return _frame;
}
@@ -127,7 +131,7 @@ private:
int _subtitle_offset;
float _subtitle_scale;
Scaler const * _scaler; ///< scaler to use
- int _frame; ///< frame index within the Film
+ SourceFrame _frame; ///< frame index within the Film's source
int _frames_per_second; ///< Frames per second that we will use for the DCP (rounded)
std::string _post_process; ///< FFmpeg post-processing string to use
int _colour_lut_index; ///< Colour look-up table to use (see Config::colour_lut_index ())
diff --git a/src/lib/decoder.cc b/src/lib/decoder.cc
index a8da1ae67..3e210c9cc 100644
--- a/src/lib/decoder.cc
+++ b/src/lib/decoder.cc
@@ -140,7 +140,8 @@ Decoder::go ()
while (pass () == false) {
if (_job && _film->dcp_length()) {
- _job->set_progress (float ((_video_frame_index - _film->dcp_trim_start())) / _film->dcp_length().get());
+ SourceFrame const p = _video_frame_index - _film->dcp_trim_start();
+ _job->set_progress (float (p) / _film->dcp_length().get());
}
}
diff --git a/src/lib/decoder.h b/src/lib/decoder.h
index e8e73cc9f..0741c4f54 100644
--- a/src/lib/decoder.h
+++ b/src/lib/decoder.h
@@ -81,7 +81,7 @@ public:
void go ();
/** @return the index of the last video frame to be processed */
- int video_frame_index () const {
+ SourceFrame video_frame_index () const {
return _video_frame_index;
}
@@ -94,11 +94,11 @@ public:
}
/** Emitted when a video frame is ready.
- * First parameter is the frame.
+ * First parameter is the frame within the source.
* Second parameter is its index within the content.
* Third parameter is either 0 or a subtitle that should be on this frame.
*/
- boost::signals2::signal<void (boost::shared_ptr<Image>, int, boost::shared_ptr<Subtitle>)> Video;
+ boost::signals2::signal<void (boost::shared_ptr<Image>, SourceFrame, boost::shared_ptr<Subtitle>)> Video;
/** Emitted when some audio data is ready */
boost::signals2::signal<void (boost::shared_ptr<AudioBuffers>)> Audio;
@@ -133,7 +133,7 @@ private:
void emit_audio (uint8_t* data, int size);
/** last video frame to be processed */
- int _video_frame_index;
+ SourceFrame _video_frame_index;
std::list<boost::shared_ptr<FilterGraph> > _filter_graphs;
diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc
index 7352dcfb1..bb23c9e59 100644
--- a/src/lib/encoder.cc
+++ b/src/lib/encoder.cc
@@ -67,7 +67,7 @@ Encoder::skipping () const
}
/** @return Index of last frame to be successfully encoded */
-int
+SourceFrame
Encoder::last_frame () const
{
boost::mutex::scoped_lock (_history_mutex);
@@ -75,10 +75,10 @@ Encoder::last_frame () const
}
/** Should be called when a frame has been encoded successfully.
- * @param n Frame index.
+ * @param n Source frame index.
*/
void
-Encoder::frame_done (int n)
+Encoder::frame_done (SourceFrame n)
{
boost::mutex::scoped_lock lock (_history_mutex);
_just_skipped = false;
diff --git a/src/lib/encoder.h b/src/lib/encoder.h
index 590b8aaa9..704b55e46 100644
--- a/src/lib/encoder.h
+++ b/src/lib/encoder.h
@@ -31,6 +31,7 @@
extern "C" {
#include <libavutil/samplefmt.h>
}
+#include "util.h"
class Options;
class Image;
@@ -58,10 +59,10 @@ public:
/** Called with a frame of video.
* @param i Video frame image.
- * @param f Frame number within the film.
+ * @param f Frame number within the film's source.
* @param s A subtitle that should be on this frame, or 0.
*/
- virtual void process_video (boost::shared_ptr<const Image> i, int f, boost::shared_ptr<Subtitle> s) = 0;
+ virtual void process_video (boost::shared_ptr<const Image> i, SourceFrame f, boost::shared_ptr<Subtitle> s) = 0;
/** Called with some audio data.
* @param d Array of pointers to floating point sample data for each channel.
@@ -74,10 +75,10 @@ public:
float current_frames_per_second () const;
bool skipping () const;
- int last_frame () const;
+ SourceFrame last_frame () const;
protected:
- void frame_done (int n);
+ void frame_done (SourceFrame n);
void frame_skipped ();
/** Film that we are encoding */
@@ -95,8 +96,8 @@ protected:
static int const _history_size;
/** true if the last frame we processed was skipped (because it was already done) */
bool _just_skipped;
- /** Index of the last frame to be processed */
- int _last_frame;
+ /** Source index of the last frame to be processed */
+ SourceFrame _last_frame;
};
#endif
diff --git a/src/lib/examine_content_job.cc b/src/lib/examine_content_job.cc
index 6d1233a8c..58b9282b8 100644
--- a/src/lib/examine_content_job.cc
+++ b/src/lib/examine_content_job.cc
@@ -105,7 +105,7 @@ ExamineContentJob::run ()
}
string const tdir = _film->dir ("thumbs");
- vector<int> thumbs;
+ vector<SourceFrame> thumbs;
for (boost::filesystem::directory_iterator i = boost::filesystem::directory_iterator (tdir); i != boost::filesystem::directory_iterator(); ++i) {
diff --git a/src/lib/film.cc b/src/lib/film.cc
index da664a5a5..cacd30764 100644
--- a/src/lib/film.cc
+++ b/src/lib/film.cc
@@ -282,7 +282,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 */
@@ -428,7 +428,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";
@@ -567,17 +567,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
{
@@ -585,7 +587,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);
@@ -599,11 +601,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);
@@ -698,11 +700,11 @@ Film::target_audio_sample_rate () const
return rint (t);
}
-boost::optional<int>
+boost::optional<SourceFrame>
Film::dcp_length () const
{
if (!length()) {
- return boost::optional<int> ();
+ return boost::optional<SourceFrame> ();
}
return length().get() - dcp_trim_start() - dcp_trim_end();
@@ -1194,7 +1196,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);
@@ -1214,7 +1216,7 @@ Film::set_size (Size s)
}
void
-Film::set_length (int l)
+Film::set_length (SourceFrame l)
{
{
boost::mutex::scoped_lock lm (_state_mutex);
diff --git a/src/lib/film.h b/src/lib/film.h
index eeaae2acd..06ebba3ce 100644
--- a/src/lib/film.h
+++ b/src/lib/film.h
@@ -87,7 +87,7 @@ public:
std::string thumb_file (int) const;
std::string thumb_base (int) const;
- int thumb_frame (int) const;
+ SourceFrame thumb_frame (int) const;
int target_audio_sample_rate () const;
@@ -95,7 +95,7 @@ public:
void read_metadata ();
Size cropped_size (Size) const;
- boost::optional<int> dcp_length () const;
+ boost::optional<SourceFrame> dcp_length () const;
std::string dci_name () const;
std::string dcp_name () const;
@@ -187,12 +187,12 @@ public:
return _scaler;
}
- int dcp_trim_start () const {
+ SourceFrame dcp_trim_start () const {
boost::mutex::scoped_lock lm (_state_mutex);
return _dcp_trim_start;
}
- int dcp_trim_end () const {
+ SourceFrame dcp_trim_end () const {
boost::mutex::scoped_lock lm (_state_mutex);
return _dcp_trim_end;
}
@@ -289,7 +289,7 @@ public:
return _package_type;
}
- std::vector<int> thumbs () const {
+ std::vector<SourceFrame> thumbs () const {
boost::mutex::scoped_lock lm (_state_mutex);
return _thumbs;
}
@@ -299,7 +299,7 @@ public:
return _size;
}
- boost::optional<int> length () const {
+ boost::optional<SourceFrame> length () const {
boost::mutex::scoped_lock lm (_state_mutex);
return _length;
}
@@ -368,9 +368,9 @@ public:
void set_studio (std::string);
void set_facility (std::string);
void set_package_type (std::string);
- void set_thumbs (std::vector<int>);
+ void set_thumbs (std::vector<SourceFrame>);
void set_size (Size);
- void set_length (int);
+ void set_length (SourceFrame);
void unset_length ();
void set_audio_sample_rate (int);
void set_content_digest (std::string);
@@ -392,8 +392,8 @@ private:
boost::gregorian::date _dci_date;
- std::string thumb_file_for_frame (int) const;
- std::string thumb_base_for_frame (int) const;
+ std::string thumb_file_for_frame (SourceFrame) const;
+ std::string thumb_base_for_frame (SourceFrame) const;
void signal_changed (Property);
void examine_content_finished ();
@@ -422,8 +422,8 @@ private:
std::vector<Filter const *> _filters;
/** Scaler algorithm to use */
Scaler const * _scaler;
- int _dcp_trim_start;
- int _dcp_trim_end;
+ SourceFrame _dcp_trim_start;
+ SourceFrame _dcp_trim_end;
/** true to create an A/B comparison DCP, where the left half of the image
is the video without any filters or post-processing, and the right half
has the specified filters and post-processing.
@@ -460,11 +460,11 @@ private:
/* Data which are cached to speed things up */
/** Vector of frame indices for each of our `thumbnails' */
- std::vector<int> _thumbs;
+ std::vector<SourceFrame> _thumbs;
/** Size, in pixels, of the source (ignoring cropping) */
Size _size;
/** Actual length of the source (in video frames) from examining it */
- boost::optional<int> _length;
+ boost::optional<SourceFrame> _length;
/** Sample rate of the source audio, in Hz */
int _audio_sample_rate;
/** MD5 digest of our content file */
diff --git a/src/lib/imagemagick_encoder.cc b/src/lib/imagemagick_encoder.cc
index e8b060997..e0e2d1cdc 100644
--- a/src/lib/imagemagick_encoder.cc
+++ b/src/lib/imagemagick_encoder.cc
@@ -50,7 +50,7 @@ ImageMagickEncoder::ImageMagickEncoder (shared_ptr<const Film> f, shared_ptr<con
}
void
-ImageMagickEncoder::process_video (shared_ptr<const Image> image, int frame, shared_ptr<Subtitle> sub)
+ImageMagickEncoder::process_video (shared_ptr<const Image> image, SourceFrame frame, shared_ptr<Subtitle> sub)
{
shared_ptr<Image> scaled = image->scale_and_convert_to_rgb (_opt->out_size, _opt->padding, _film->scaler());
shared_ptr<Image> compact (new CompactImage (scaled));
diff --git a/src/lib/imagemagick_encoder.h b/src/lib/imagemagick_encoder.h
index c112300e3..3d8edd25e 100644
--- a/src/lib/imagemagick_encoder.h
+++ b/src/lib/imagemagick_encoder.h
@@ -37,7 +37,7 @@ public:
ImageMagickEncoder (boost::shared_ptr<const Film> f, boost::shared_ptr<const Options> o);
void process_begin (int64_t audio_channel_layout) {}
- void process_video (boost::shared_ptr<const Image>, int, boost::shared_ptr<Subtitle>);
+ void process_video (boost::shared_ptr<const Image>, SourceFrame, boost::shared_ptr<Subtitle>);
void process_audio (boost::shared_ptr<const AudioBuffers>) {}
void process_end () {}
};
diff --git a/src/lib/j2k_still_encoder.cc b/src/lib/j2k_still_encoder.cc
index edcf0de89..aab686417 100644
--- a/src/lib/j2k_still_encoder.cc
+++ b/src/lib/j2k_still_encoder.cc
@@ -49,7 +49,7 @@ J2KStillEncoder::J2KStillEncoder (shared_ptr<const Film> f, shared_ptr<const Opt
}
void
-J2KStillEncoder::process_video (shared_ptr<const Image> yuv, int frame, shared_ptr<Subtitle> sub)
+J2KStillEncoder::process_video (shared_ptr<const Image> yuv, SourceFrame frame, shared_ptr<Subtitle> sub)
{
pair<string, string> const s = Filter::ffmpeg_strings (_film->filters());
DCPVideoFrame* f = new DCPVideoFrame (
diff --git a/src/lib/j2k_still_encoder.h b/src/lib/j2k_still_encoder.h
index 86bebc0d2..89222ce18 100644
--- a/src/lib/j2k_still_encoder.h
+++ b/src/lib/j2k_still_encoder.h
@@ -37,7 +37,7 @@ public:
J2KStillEncoder (boost::shared_ptr<const Film>, boost::shared_ptr<const Options>);
void process_begin (int64_t audio_channel_layout) {}
- void process_video (boost::shared_ptr<const Image>, int, boost::shared_ptr<Subtitle>);
+ void process_video (boost::shared_ptr<const Image>, SourceFrame, boost::shared_ptr<Subtitle>);
void process_audio (boost::shared_ptr<const AudioBuffers>) {}
void process_end () {}
};
diff --git a/src/lib/j2k_wav_encoder.cc b/src/lib/j2k_wav_encoder.cc
index bac7d5f35..f93fd9460 100644
--- a/src/lib/j2k_wav_encoder.cc
+++ b/src/lib/j2k_wav_encoder.cc
@@ -106,7 +106,7 @@ J2KWAVEncoder::close_sound_files ()
}
void
-J2KWAVEncoder::process_video (shared_ptr<const Image> yuv, int frame, shared_ptr<Subtitle> sub)
+J2KWAVEncoder::process_video (shared_ptr<const Image> yuv, SourceFrame frame, shared_ptr<Subtitle> sub)
{
boost::mutex::scoped_lock lock (_worker_mutex);
diff --git a/src/lib/j2k_wav_encoder.h b/src/lib/j2k_wav_encoder.h
index 99924829d..2272d7f49 100644
--- a/src/lib/j2k_wav_encoder.h
+++ b/src/lib/j2k_wav_encoder.h
@@ -51,7 +51,7 @@ public:
~J2KWAVEncoder ();
void process_begin (int64_t audio_channel_layout);
- void process_video (boost::shared_ptr<const Image>, int, boost::shared_ptr<Subtitle>);
+ void process_video (boost::shared_ptr<const Image>, SourceFrame, boost::shared_ptr<Subtitle>);
void process_audio (boost::shared_ptr<const AudioBuffers>);
void process_end ();
diff --git a/src/lib/make_dcp_job.cc b/src/lib/make_dcp_job.cc
index 4102f8384..a1ffd9672 100644
--- a/src/lib/make_dcp_job.cc
+++ b/src/lib/make_dcp_job.cc
@@ -55,10 +55,12 @@ MakeDCPJob::name () const
return String::compose ("Make DCP for %1", _film->name());
}
+/** @param f DCP frame index */
string
MakeDCPJob::j2c_path (int f) const
{
- return _opt->frame_out_path (f * dcp_frame_rate(_film->frames_per_second()).skip, false);
+ SourceFrame const s = (f * dcp_frame_rate(_film->frames_per_second()).skip) + _film->dcp_trim_start();
+ return _opt->frame_out_path (s, false);
}
string
@@ -84,6 +86,7 @@ MakeDCPJob::run ()
int frames = 0;
switch (_film->content_type ()) {
case VIDEO:
+ /* Source frames -> DCP frames */
frames = _film->dcp_length().get() / dfr.skip;
break;
case STILL:
diff --git a/src/lib/options.h b/src/lib/options.h
index aef9ca112..043e3692f 100644
--- a/src/lib/options.h
+++ b/src/lib/options.h
@@ -52,11 +52,11 @@ public:
return _frame_out_path;
}
- /** @param f Frame index.
+ /** @param f Source frame index.
* @param t true to return a temporary file path, otherwise a permanent one.
* @return The path to write this video frame to.
*/
- std::string frame_out_path (int f, bool t, std::string e = "") const {
+ std::string frame_out_path (SourceFrame f, bool t, std::string e = "") const {
if (e.empty ()) {
e = _frame_out_extension;
}
@@ -96,8 +96,10 @@ public:
float ratio; ///< ratio of the wanted output image (not considering padding)
int padding; ///< number of pixels of padding (in terms of the output size) each side of the image
bool apply_crop; ///< true to apply cropping
- int decode_video_skip; ///< skip frames such that we don't decode any frame where (index % decode_video_skip) != 0; e.g.
- ///< 1 for every frame, 2 for every other frame, etc.
+ /** Skip frames such that we don't decode any frame where (index % decode_video_skip) != 0; e.g.
+ * 1 for every frame, 2 for every other frame, etc.
+ */
+ SourceFrame decode_video_skip;
bool decode_audio; ///< true to decode audio, otherwise false
bool decode_subtitles;
diff --git a/src/lib/transcode_job.cc b/src/lib/transcode_job.cc
index 877214316..31808c103 100644
--- a/src/lib/transcode_job.cc
+++ b/src/lib/transcode_job.cc
@@ -110,5 +110,6 @@ TranscodeJob::remaining_time () const
}
/* We assume that dcp_length() is valid */
- return ((_film->dcp_length().get() - _encoder->last_frame()) / fps);
+ SourceFrame const left = _film->dcp_length().get() - _encoder->last_frame() - _film->dcp_trim_start();
+ return left / fps;
}
diff --git a/src/lib/util.h b/src/lib/util.h
index 26c6ed9fa..f87328dba 100644
--- a/src/lib/util.h
+++ b/src/lib/util.h
@@ -54,6 +54,8 @@ extern std::string md5_digest (std::string);
extern std::string md5_digest (void const *, int);
extern void ensure_ui_thread ();
+typedef int SourceFrame;
+
struct DCPFrameRate
{
int frames_per_second;
diff --git a/src/wx/dcp_range_dialog.cc b/src/wx/dcp_range_dialog.cc
index e249f6fc6..9eced92d6 100644
--- a/src/wx/dcp_range_dialog.cc
+++ b/src/wx/dcp_range_dialog.cc
@@ -39,6 +39,11 @@ DCPRangeDialog::DCPRangeDialog (wxWindow* p, shared_ptr<Film> f)
table->Add (_trim_end, 1);
add_label_to_sizer (table, this, "frames");
+ if (_film->length()) {
+ _trim_start->SetRange (0, _film->length().get());
+ _trim_end->SetRange (0, _film->length().get());
+ }
+
_trim_start->SetValue (_film->dcp_trim_start());
_trim_end->SetValue (_film->dcp_trim_end());