summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-01-17 21:30:16 +0000
committerCarl Hetherington <cth@carlh.net>2013-01-17 21:30:16 +0000
commit39c65e47432c76a4e34aaea5317bd7362409aed0 (patch)
tree5bacc1d631de0a2b7f0aa492ddaf05a65e06d97c /src/lib
parent3882d34aed9dee417ceed93bf0bf5372b3970ff6 (diff)
Try to tidy up frame indexing; use DCP length obtained from the transcode to make the DCP.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/check_hashes_job.cc12
-rw-r--r--src/lib/dcp_video_frame.cc9
-rw-r--r--src/lib/dcp_video_frame.h12
-rw-r--r--src/lib/encoder.cc39
-rw-r--r--src/lib/encoder.h12
-rw-r--r--src/lib/ffmpeg_decoder.cc1
-rw-r--r--src/lib/ffmpeg_decoder.h2
-rw-r--r--src/lib/film.cc40
-rw-r--r--src/lib/film.h26
-rw-r--r--src/lib/filter_graph.cc1
-rw-r--r--src/lib/filter_graph.h6
-rw-r--r--src/lib/format.cc1
-rw-r--r--src/lib/format.h10
-rw-r--r--src/lib/image.cc1
-rw-r--r--src/lib/image.h14
-rw-r--r--src/lib/imagemagick_decoder.cc3
-rw-r--r--src/lib/imagemagick_decoder.h2
-rw-r--r--src/lib/make_dcp_job.cc32
-rw-r--r--src/lib/matcher.h2
-rw-r--r--src/lib/server.cc1
-rw-r--r--src/lib/subtitle.cc1
-rw-r--r--src/lib/transcode_job.cc15
-rw-r--r--src/lib/util.cc11
-rw-r--r--src/lib/util.h34
-rw-r--r--src/lib/video_decoder.h2
25 files changed, 141 insertions, 148 deletions
diff --git a/src/lib/check_hashes_job.cc b/src/lib/check_hashes_job.cc
index cf4e86b79..55a744552 100644
--- a/src/lib/check_hashes_job.cc
+++ b/src/lib/check_hashes_job.cc
@@ -53,16 +53,12 @@ CheckHashesJob::run ()
{
_bad = 0;
- if (!_film->dcp_length()) {
- throw EncodeError ("cannot check hashes of a DCP with unknown length");
+ if (!_film->dcp_intrinsic_duration()) {
+ throw EncodeError ("cannot check hashes of a DCP with unknown intrinsic duration");
}
- SourceFrame const N = _film->trim_start() + _film->dcp_length().get();
- DCPFrameRate const dfr (_film->frames_per_second ());
-
- int const inc = dfr.skip ? 2 : 1;
-
- for (SourceFrame i = _film->trim_start(); i < N; i += inc) {
+ int const N = _film->dcp_intrinsic_duration().get();
+ for (int i = 0; i < N; ++i) {
string const j2k_file = _film->frame_out_path (i, false);
string const hash_file = _film->hash_out_path (i, false);
diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc
index c00ed9b88..427d447ef 100644
--- a/src/lib/dcp_video_frame.cc
+++ b/src/lib/dcp_video_frame.cc
@@ -60,13 +60,14 @@ using std::string;
using std::stringstream;
using std::ofstream;
using boost::shared_ptr;
+using libdcp::Size;
/** Construct a DCP video frame.
* @param input Input image.
* @param out Required size of output, in pixels (including any padding).
* @param s Scaler to use.
* @param p Number of pixels of padding either side of the image.
- * @param f Index of the frame within the Film's source.
+ * @param f Index of the frame within the DCP's intrinsic duration.
* @param fps Frames per second of the Film's source.
* @param pp FFmpeg post-processing string to use.
* @param clut Colour look-up table to use (see Config::colour_lut_index ())
@@ -76,7 +77,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, SourceFrame f, float fps, string pp, int clut, int bw, Log* l
+ Scaler const * s, int f, float fps, string pp, int clut, int bw, Log* l
)
: _input (yuv)
, _subtitle (sub)
@@ -373,10 +374,10 @@ DCPVideoFrame::encode_remotely (ServerDescription const * serv)
/** Write this data to a J2K file.
* @param opt Options.
- * @param frame Frame index.
+ * @param frame DCP Frame index.
*/
void
-EncodedData::write (shared_ptr<const Film> film, SourceFrame frame)
+EncodedData::write (shared_ptr<const Film> film, int frame)
{
string const tmp_j2k = film->frame_out_path (frame, true);
diff --git a/src/lib/dcp_video_frame.h b/src/lib/dcp_video_frame.h
index 1b75cb207..4271ebb28 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 Film>, SourceFrame);
+ void write (boost::shared_ptr<const Film>, int);
/** @return data */
uint8_t* data () const {
@@ -107,8 +107,8 @@ class DCPVideoFrame
{
public:
DCPVideoFrame (
- boost::shared_ptr<const Image>, boost::shared_ptr<Subtitle>, Size,
- int, int, float, Scaler const *, SourceFrame, float, std::string, int, int, Log *
+ boost::shared_ptr<const Image>, boost::shared_ptr<Subtitle>, libdcp::Size,
+ int, int, float, Scaler const *, int, float, std::string, int, int, Log *
);
virtual ~DCPVideoFrame ();
@@ -116,7 +116,7 @@ public:
boost::shared_ptr<EncodedData> encode_locally ();
boost::shared_ptr<EncodedData> encode_remotely (ServerDescription const *);
- SourceFrame frame () const {
+ int frame () const {
return _frame;
}
@@ -125,12 +125,12 @@ private:
boost::shared_ptr<const Image> _input; ///< the input image
boost::shared_ptr<Subtitle> _subtitle; ///< any subtitle that should be on the image
- Size _out_size; ///< the required size of the output, in pixels
+ libdcp::Size _out_size; ///< the required size of the output, in pixels
int _padding;
int _subtitle_offset;
float _subtitle_scale;
Scaler const * _scaler; ///< scaler to use
- SourceFrame _frame; ///< frame index within the Film's source
+ int _frame; ///< frame index within the DCP's intrinsic duration
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; ///< Colour look-up table to use
diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc
index c32d68834..6df7c85a1 100644
--- a/src/lib/encoder.cc
+++ b/src/lib/encoder.cc
@@ -54,12 +54,13 @@ int const Encoder::_history_size = 25;
Encoder::Encoder (shared_ptr<const Film> f)
: _film (f)
, _just_skipped (false)
- , _video_frame (0)
- , _audio_frame (0)
+ , _video_frames_in (0)
+ , _audio_frames_in (0)
+ , _video_frames_out (0)
+ , _audio_frames_out (0)
#ifdef HAVE_SWRESAMPLE
, _swr_context (0)
#endif
- , _audio_frames_written (0)
, _process_end (false)
{
if (_film->audio_stream()) {
@@ -241,12 +242,12 @@ Encoder::skipping () const
return _just_skipped;
}
-/** @return Number of video frames that have been received */
-SourceFrame
-Encoder::video_frame () const
+/** @return Number of video frames that have been sent out */
+int
+Encoder::video_frames_out () const
{
boost::mutex::scoped_lock (_history_mutex);
- return _video_frame;
+ return _video_frames_out;
}
/** Should be called when a frame has been encoded successfully.
@@ -281,8 +282,8 @@ Encoder::process_video (shared_ptr<Image> image, bool same, boost::shared_ptr<Su
{
DCPFrameRate dfr (_film->frames_per_second ());
- if (dfr.skip && (_video_frame % 2)) {
- ++_video_frame;
+ if (dfr.skip && (_video_frames_in % 2)) {
+ ++_video_frames_in;
return;
}
@@ -300,7 +301,7 @@ Encoder::process_video (shared_ptr<Image> image, bool same, boost::shared_ptr<Su
}
/* Only do the processing if we don't already have a file for this frame */
- if (boost::filesystem::exists (_film->frame_out_path (_video_frame, false))) {
+ if (boost::filesystem::exists (_film->frame_out_path (_video_frames_out, false))) {
frame_skipped ();
return;
}
@@ -310,7 +311,7 @@ Encoder::process_video (shared_ptr<Image> image, bool same, boost::shared_ptr<Su
as on windows the link is really a copy and the reference frame might not have
finished encoding yet.
*/
- _links_required.push_back (make_pair (_last_real_frame.get(), _video_frame));
+ _links_required.push_back (make_pair (_last_real_frame.get(), _video_frames_out));
} else {
/* Queue this new frame for encoding */
pair<string, string> const s = Filter::ffmpeg_strings (_film->filters());
@@ -319,17 +320,23 @@ Encoder::process_video (shared_ptr<Image> image, bool same, boost::shared_ptr<Su
new DCPVideoFrame (
image, sub, _film->format()->dcp_size(), _film->format()->dcp_padding (_film),
_film->subtitle_offset(), _film->subtitle_scale(),
- _film->scaler(), _video_frame, _film->frames_per_second(), s.second,
+ _film->scaler(), _video_frames_out, _film->frames_per_second(), s.second,
_film->colour_lut(), _film->j2k_bandwidth(),
_film->log()
)
));
_worker_condition.notify_all ();
- _last_real_frame = _video_frame;
+ _last_real_frame = _video_frames_out;
}
- ++_video_frame;
+ ++_video_frames_in;
+ ++_video_frames_out;
+
+ if (dfr.repeat) {
+ _links_required.push_back (make_pair (_video_frames_out, _video_frames_out - 1));
+ ++_video_frames_out;
+ }
}
void
@@ -378,7 +385,7 @@ Encoder::process_audio (shared_ptr<AudioBuffers> data)
write_audio (data);
- _audio_frame += data->frames ();
+ _audio_frames_in += data->frames ();
}
void
@@ -388,7 +395,7 @@ Encoder::write_audio (shared_ptr<const AudioBuffers> audio)
sf_write_float (_sound_files[i], audio->data(i), audio->frames());
}
- _audio_frames_written += audio->frames ();
+ _audio_frames_out += audio->frames ();
}
void
diff --git a/src/lib/encoder.h b/src/lib/encoder.h
index d8edf9b26..20255cca9 100644
--- a/src/lib/encoder.h
+++ b/src/lib/encoder.h
@@ -82,7 +82,7 @@ public:
float current_frames_per_second () const;
bool skipping () const;
- SourceFrame video_frame () const;
+ int video_frames_out () const;
private:
@@ -111,9 +111,13 @@ private:
bool _just_skipped;
/** Number of video frames received so far */
- SourceFrame _video_frame;
+ SourceFrame _video_frames_in;
/** Number of audio frames received so far */
- int64_t _audio_frame;
+ int64_t _audio_frames_in;
+ /** Number of video frames written for the DCP so far */
+ int _video_frames_out;
+ /** Number of audio frames written for the DCP so far */
+ int64_t _audio_frames_out;
#if HAVE_SWRESAMPLE
SwrContext* _swr_context;
@@ -122,11 +126,11 @@ private:
/** List of links that we need to create when all frames have been processed;
* such that we need to call link (first, second) for each member of this list.
* In other words, `first' is a `real' frame and `second' should be a link to `first'.
+ * Frames are DCP frames.
*/
std::list<std::pair<int, int> > _links_required;
std::vector<SNDFILE*> _sound_files;
- int64_t _audio_frames_written;
boost::optional<int> _last_real_frame;
bool _process_end;
diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc
index 9e5cda889..e7dfc206b 100644
--- a/src/lib/ffmpeg_decoder.cc
+++ b/src/lib/ffmpeg_decoder.cc
@@ -58,6 +58,7 @@ using std::list;
using boost::shared_ptr;
using boost::optional;
using boost::dynamic_pointer_cast;
+using libdcp::Size;
FFmpegDecoder::FFmpegDecoder (shared_ptr<Film> f, DecodeOptions o, Job* j)
: Decoder (f, o, j)
diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h
index 51b88a24a..9a4e65ebc 100644
--- a/src/lib/ffmpeg_decoder.h
+++ b/src/lib/ffmpeg_decoder.h
@@ -90,7 +90,7 @@ public:
~FFmpegDecoder ();
float frames_per_second () const;
- Size native_size () const;
+ libdcp::Size native_size () const;
SourceFrame length () const;
int time_base_numerator () const;
int time_base_denominator () const;
diff --git a/src/lib/film.cc b/src/lib/film.cc
index 2af8d3c14..1741d49e6 100644
--- a/src/lib/film.cc
+++ b/src/lib/film.cc
@@ -72,6 +72,7 @@ using boost::to_upper_copy;
using boost::ends_with;
using boost::starts_with;
using boost::optional;
+using libdcp::Size;
int const Film::state_version = 2;
@@ -180,6 +181,7 @@ Film::Film (Film const & o)
, _package_type (o._package_type)
, _size (o._size)
, _length (o._length)
+ , _dcp_intrinsic_duration (o._dcp_intrinsic_duration)
, _content_digest (o._content_digest)
, _content_audio_streams (o._content_audio_streams)
, _external_audio_stream (o._external_audio_stream)
@@ -423,6 +425,7 @@ Film::write_metadata () const
f << "width " << _size.width << "\n";
f << "height " << _size.height << "\n";
f << "length " << _length.get_value_or(0) << "\n";
+ f << "dcp_intrinsic_duration " << _dcp_intrinsic_duration.get_value_or(0) << "\n";
f << "content_digest " << _content_digest << "\n";
for (vector<shared_ptr<AudioStream> >::const_iterator i = _content_audio_streams.begin(); i != _content_audio_streams.end(); ++i) {
@@ -569,6 +572,11 @@ Film::read_metadata ()
if (vv) {
_length = vv;
}
+ } else if (k == "dcp_intrinsic_duration") {
+ int const vv = atoi (v.c_str ());
+ if (vv) {
+ _dcp_intrinsic_duration = vv;
+ }
} else if (k == "content_digest") {
_content_digest = v;
} else if (k == "content_audio_stream" || (!version && k == "audio_stream")) {
@@ -695,18 +703,10 @@ Film::target_audio_sample_rate () const
return rint (t);
}
-boost::optional<int>
-Film::dcp_length () const
+int
+Film::still_duration_in_frames () const
{
- if (content_type() == STILL) {
- return _still_duration * frames_per_second();
- }
-
- if (!length()) {
- return boost::optional<int> ();
- }
-
- return length().get() - trim_start() - trim_end();
+ return still_duration() * frames_per_second();
}
/** @return a DCI-compliant name for a DCP of this film */
@@ -1327,7 +1327,17 @@ Film::unset_length ()
_length = boost::none;
}
signal_changed (LENGTH);
-}
+}
+
+void
+Film::set_dcp_intrinsic_duration (int d)
+{
+ {
+ boost::mutex::scoped_lock lm (_state_mutex);
+ _dcp_intrinsic_duration = d;
+ }
+ signal_changed (DCP_INTRINSIC_DURATION);
+}
void
Film::set_content_digest (string d)
@@ -1409,12 +1419,12 @@ Film::audio_stream () const
return _external_audio_stream;
}
-/** @param f Source frame index.
+/** @param f DCP frame index.
* @param t true to return a temporary file path, otherwise a permanent one.
* @return The path to write this video frame to.
*/
string
-Film::frame_out_path (SourceFrame f, bool t) const
+Film::frame_out_path (int f, bool t) const
{
stringstream s;
s << j2k_dir() << "/";
@@ -1429,7 +1439,7 @@ Film::frame_out_path (SourceFrame f, bool t) const
}
string
-Film::hash_out_path (SourceFrame f, bool t) const
+Film::hash_out_path (int f, bool t) const
{
return frame_out_path (f, t) + ".md5";
}
diff --git a/src/lib/film.h b/src/lib/film.h
index b03d84920..e10abfa4b 100644
--- a/src/lib/film.h
+++ b/src/lib/film.h
@@ -78,8 +78,8 @@ public:
std::string file (std::string f) const;
std::string dir (std::string d) const;
- std::string frame_out_path (SourceFrame f, bool t) const;
- std::string hash_out_path (SourceFrame f, bool t) const;
+ std::string frame_out_path (int f, bool t) const;
+ std::string hash_out_path (int f, bool t) const;
std::string multichannel_audio_out_path (int c, bool t) const;
std::string content_path () const;
@@ -90,11 +90,14 @@ public:
void write_metadata () const;
void read_metadata ();
- Size cropped_size (Size) const;
- boost::optional<int> dcp_length () const;
+ libdcp::Size cropped_size (libdcp::Size) const;
std::string dci_name () const;
std::string dcp_name () const;
+ boost::optional<int> dcp_intrinsic_duration () const {
+ return _dcp_intrinsic_duration;
+ }
+
/** @return true if our state has changed since we last saved it */
bool dirty () const {
return _dirty;
@@ -137,6 +140,7 @@ public:
DCI_METADATA,
SIZE,
LENGTH,
+ DCP_INTRINSIC_DURATION,
CONTENT_AUDIO_STREAMS,
SUBTITLE_STREAMS,
FRAMES_PER_SECOND,
@@ -195,12 +199,12 @@ public:
return _scaler;
}
- SourceFrame trim_start () const {
+ int trim_start () const {
boost::mutex::scoped_lock lm (_state_mutex);
return _trim_start;
}
- SourceFrame trim_end () const {
+ int trim_end () const {
boost::mutex::scoped_lock lm (_state_mutex);
return _trim_end;
}
@@ -245,6 +249,8 @@ public:
return _still_duration;
}
+ int still_duration_in_frames () const;
+
boost::shared_ptr<SubtitleStream> subtitle_stream () const {
boost::mutex::scoped_lock lm (_state_mutex);
return _subtitle_stream;
@@ -310,7 +316,7 @@ public:
return _package_type;
}
- Size size () const {
+ libdcp::Size size () const {
boost::mutex::scoped_lock lm (_state_mutex);
return _size;
}
@@ -387,9 +393,10 @@ public:
void set_studio (std::string);
void set_facility (std::string);
void set_package_type (std::string);
- void set_size (Size);
+ void set_size (libdcp::Size);
void set_length (SourceFrame);
void unset_length ();
+ void set_dcp_intrinsic_duration (int);
void set_content_digest (std::string);
void set_content_audio_streams (std::vector<boost::shared_ptr<AudioStream> >);
void set_subtitle_streams (std::vector<boost::shared_ptr<SubtitleStream> >);
@@ -499,9 +506,10 @@ private:
/* Data which are cached to speed things up */
/** Size, in pixels, of the source (ignoring cropping) */
- Size _size;
+ libdcp::Size _size;
/** The length of the source, in video frames (as far as we know) */
boost::optional<SourceFrame> _length;
+ boost::optional<int> _dcp_intrinsic_duration;
/** MD5 digest of our content file */
std::string _content_digest;
/** The audio streams in our content */
diff --git a/src/lib/filter_graph.cc b/src/lib/filter_graph.cc
index 376ab404f..86864a762 100644
--- a/src/lib/filter_graph.cc
+++ b/src/lib/filter_graph.cc
@@ -47,6 +47,7 @@ using std::stringstream;
using std::string;
using std::list;
using boost::shared_ptr;
+using libdcp::Size;
/** Construct a FilterGraph for the settings in a film.
* @param film Film.
diff --git a/src/lib/filter_graph.h b/src/lib/filter_graph.h
index 9e6ac6252..7e4e8422b 100644
--- a/src/lib/filter_graph.h
+++ b/src/lib/filter_graph.h
@@ -37,15 +37,15 @@ class FFmpegDecoder;
class FilterGraph
{
public:
- FilterGraph (boost::shared_ptr<Film> film, FFmpegDecoder* decoder, Size s, AVPixelFormat p);
+ FilterGraph (boost::shared_ptr<Film> film, FFmpegDecoder* decoder, libdcp::Size s, AVPixelFormat p);
- bool can_process (Size s, AVPixelFormat p) const;
+ bool can_process (libdcp::Size s, AVPixelFormat p) const;
std::list<boost::shared_ptr<Image> > process (AVFrame const * frame);
private:
AVFilterContext* _buffer_src_context;
AVFilterContext* _buffer_sink_context;
- Size _size; ///< size of the images that this chain can process
+ libdcp::Size _size; ///< size of the images that this chain can process
AVPixelFormat _pixel_format; ///< pixel format of the images that this chain can process
};
diff --git a/src/lib/format.cc b/src/lib/format.cc
index 975862411..a80fab619 100644
--- a/src/lib/format.cc
+++ b/src/lib/format.cc
@@ -35,6 +35,7 @@ using std::setprecision;
using std::stringstream;
using std::vector;
using boost::shared_ptr;
+using libdcp::Size;
vector<Format const *> Format::_formats;
diff --git a/src/lib/format.h b/src/lib/format.h
index 2118237a4..48a000480 100644
--- a/src/lib/format.h
+++ b/src/lib/format.h
@@ -31,7 +31,7 @@ class Film;
class Format
{
public:
- Format (Size dcp, std::string id, std::string n, std::string d)
+ Format (libdcp::Size dcp, std::string id, std::string n, std::string d)
: _dcp_size (dcp)
, _id (id)
, _nickname (n)
@@ -52,7 +52,7 @@ public:
* put in a DCP for this ratio. This size will not correspond
* to the ratio when we are doing things like 16:9 in a Flat frame.
*/
- Size dcp_size () const {
+ libdcp::Size dcp_size () const {
return _dcp_size;
}
@@ -85,7 +85,7 @@ protected:
* put in a DCP for this ratio. This size will not correspond
* to the ratio when we are doing things like 16:9 in a Flat frame.
*/
- Size _dcp_size;
+ libdcp::Size _dcp_size;
/** id for use in metadata */
std::string _id;
/** nickname (e.g. Flat, Scope) */
@@ -104,7 +104,7 @@ private:
class FixedFormat : public Format
{
public:
- FixedFormat (int, Size, std::string, std::string, std::string);
+ FixedFormat (int, libdcp::Size, std::string, std::string, std::string);
int ratio_as_integer (boost::shared_ptr<const Film>) const {
return _ratio;
@@ -125,7 +125,7 @@ private:
class VariableFormat : public Format
{
public:
- VariableFormat (Size, std::string, std::string, std::string);
+ VariableFormat (libdcp::Size, std::string, std::string, std::string);
int ratio_as_integer (boost::shared_ptr<const Film> f) const;
float ratio_as_float (boost::shared_ptr<const Film> f) const;
diff --git a/src/lib/image.cc b/src/lib/image.cc
index f774f476f..c41558f02 100644
--- a/src/lib/image.cc
+++ b/src/lib/image.cc
@@ -42,6 +42,7 @@ extern "C" {
using namespace std;
using namespace boost;
+using libdcp::Size;
void
Image::swap (Image& other)
diff --git a/src/lib/image.h b/src/lib/image.h
index e19c6f54b..5ca3f337c 100644
--- a/src/lib/image.h
+++ b/src/lib/image.h
@@ -66,13 +66,13 @@ public:
virtual int * stride () const = 0;
/** @return Size of the image, in pixels */
- virtual Size size () const = 0;
+ virtual libdcp::Size size () const = 0;
int components () const;
int lines (int) const;
- boost::shared_ptr<Image> scale_and_convert_to_rgb (Size out_size, int padding, Scaler const * scaler, bool aligned) const;
- boost::shared_ptr<Image> scale (Size, Scaler const *, bool aligned) const;
+ boost::shared_ptr<Image> scale_and_convert_to_rgb (libdcp::Size out_size, int padding, Scaler const * scaler, bool aligned) const;
+ boost::shared_ptr<Image> scale (libdcp::Size, Scaler const *, bool aligned) const;
boost::shared_ptr<Image> post_process (std::string, bool aligned) const;
void alpha_blend (boost::shared_ptr<const Image> image, Position pos);
boost::shared_ptr<Image> crop (Crop c, bool aligned) const;
@@ -106,7 +106,7 @@ public:
uint8_t ** data () const;
int * line_size () const;
int * stride () const;
- Size size () const;
+ libdcp::Size size () const;
private:
/* Not allowed */
@@ -122,7 +122,7 @@ private:
class SimpleImage : public Image
{
public:
- SimpleImage (AVPixelFormat, Size, bool);
+ SimpleImage (AVPixelFormat, libdcp::Size, bool);
SimpleImage (SimpleImage const &);
SimpleImage& operator= (SimpleImage const &);
~SimpleImage ();
@@ -130,14 +130,14 @@ public:
uint8_t ** data () const;
int * line_size () const;
int * stride () const;
- Size size () const;
+ libdcp::Size size () const;
protected:
void allocate ();
void swap (SimpleImage &);
private:
- Size _size; ///< size in pixels
+ libdcp::Size _size; ///< size in pixels
uint8_t** _data; ///< array of pointers to components
int* _line_size; ///< array of sizes of the data in each line, in pixels (without any alignment padding bytes)
int* _stride; ///< array of strides for each line (including any alignment padding bytes)
diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc
index 063730540..bab4f2f07 100644
--- a/src/lib/imagemagick_decoder.cc
+++ b/src/lib/imagemagick_decoder.cc
@@ -27,6 +27,7 @@
using std::cout;
using boost::shared_ptr;
+using libdcp::Size;
ImageMagickDecoder::ImageMagickDecoder (
boost::shared_ptr<Film> f, DecodeOptions o, Job* j)
@@ -70,7 +71,7 @@ bool
ImageMagickDecoder::pass ()
{
if (_iter == _files.end()) {
- if (!_film->dcp_length() || video_frame() >= _film->dcp_length().get()) {
+ if (video_frame() >= _film->still_duration_in_frames()) {
return true;
}
diff --git a/src/lib/imagemagick_decoder.h b/src/lib/imagemagick_decoder.h
index 5dfcab6f0..84a6f15f9 100644
--- a/src/lib/imagemagick_decoder.h
+++ b/src/lib/imagemagick_decoder.h
@@ -33,7 +33,7 @@ public:
return 0;
}
- Size native_size () const;
+ libdcp::Size native_size () const;
SourceFrame length () const {
/* We don't know */
diff --git a/src/lib/make_dcp_job.cc b/src/lib/make_dcp_job.cc
index 3603298d9..6877e5e88 100644
--- a/src/lib/make_dcp_job.cc
+++ b/src/lib/make_dcp_job.cc
@@ -61,10 +61,7 @@ MakeDCPJob::name () const
string
MakeDCPJob::j2c_path (int f, int offset) const
{
- DCPFrameRate dfr (_film->frames_per_second());
- int const mult = dfr.skip ? 2 : 1;
- SourceFrame const s = ((f + offset) * mult) + _film->trim_start();
- return _film->frame_out_path (s, false);
+ return _film->frame_out_path (f, false);
}
string
@@ -76,8 +73,8 @@ MakeDCPJob::wav_path (libdcp::Channel c) const
void
MakeDCPJob::run ()
{
- if (!_film->dcp_length()) {
- throw EncodeError ("cannot make a DCP when the source length is not known");
+ if (!_film->dcp_intrinsic_duration()) {
+ throw EncodeError ("cannot make a DCP when its intrinsic duration is not known");
}
descend (0.9);
@@ -87,22 +84,10 @@ MakeDCPJob::run ()
/* Remove any old DCP */
boost::filesystem::remove_all (dcp_path);
+ int const frames = _film->dcp_intrinsic_duration().get();
+ int const duration = frames - _film->trim_start() - _film->trim_end();
DCPFrameRate const dfr (_film->frames_per_second ());
- int frames = 0;
- switch (_film->content_type ()) {
- case VIDEO:
- /* Source frames -> DCP frames */
- frames = _film->dcp_length().get();
- if (dfr.skip) {
- frames /= 2;
- }
- break;
- case STILL:
- frames = _film->still_duration() * 24;
- break;
- }
-
libdcp::DCP dcp (_film->dir (_film->dcp_name()));
dcp.Progress.connect (boost::bind (&MakeDCPJob::dcp_progress, this, _1));
@@ -138,13 +123,12 @@ MakeDCPJob::run ()
&dcp.Progress,
dfr.frames_per_second,
this_time,
- _film->format()->dcp_size().width,
- _film->format()->dcp_size().height
+ _film->format()->dcp_size()
)
);
pa->set_entry_point (_film->trim_start ());
- pa->set_duration (_film->duration ());
+ pa->set_duration (duration);
ascend ();
@@ -166,7 +150,7 @@ MakeDCPJob::run ()
);
sa->set_entry_point (_film->trim_start ());
- sa->set_duration (_film->duration ());
+ sa->set_duration (duration);
ascend ();
}
diff --git a/src/lib/matcher.h b/src/lib/matcher.h
index b94c28446..60bb87432 100644
--- a/src/lib/matcher.h
+++ b/src/lib/matcher.h
@@ -35,6 +35,6 @@ private:
int _video_frames;
int64_t _audio_frames;
boost::optional<AVPixelFormat> _pixel_format;
- boost::optional<Size> _size;
+ boost::optional<libdcp::Size> _size;
boost::optional<int> _channels;
};
diff --git a/src/lib/server.cc b/src/lib/server.cc
index bea75cff8..134cb65a0 100644
--- a/src/lib/server.cc
+++ b/src/lib/server.cc
@@ -45,6 +45,7 @@ using boost::algorithm::is_any_of;
using boost::algorithm::split;
using boost::thread;
using boost::bind;
+using libdcp::Size;
/** Create a server description from a string of metadata returned from as_metadata().
* @param v Metadata.
diff --git a/src/lib/subtitle.cc b/src/lib/subtitle.cc
index c52d3ac66..a7aa7cd21 100644
--- a/src/lib/subtitle.cc
+++ b/src/lib/subtitle.cc
@@ -27,6 +27,7 @@
using namespace std;
using namespace boost;
+using libdcp::Size;
/** Construct a TimedSubtitle. This is a subtitle image, position,
* and a range of time over which it should be shown.
diff --git a/src/lib/transcode_job.cc b/src/lib/transcode_job.cc
index c9792ed2e..6dd74c36c 100644
--- a/src/lib/transcode_job.cc
+++ b/src/lib/transcode_job.cc
@@ -67,7 +67,10 @@ TranscodeJob::run ()
set_progress (1);
set_state (FINISHED_OK);
+ _film->set_dcp_intrinsic_duration (_encoder->video_frames_out ());
+
_film->log()->log ("Transcode job completed successfully");
+ _film->log()->log (String::compose ("DCP intrinsic duration is %1", _encoder->video_frames_out()));
} catch (std::exception& e) {
@@ -115,11 +118,19 @@ TranscodeJob::remaining_time () const
return 0;
}
- if (!_film->dcp_length()) {
+ if (!_film->length()) {
return 0;
}
+ /* Compute approximate proposed length here, as it's only here that we need it */
+ int length = _film->length().get();
+ DCPFrameRate const dfr (_film->frames_per_second ());
+ if (dfr.skip) {
+ length /= 2;
+ }
+ /* If we are repeating it shouldn't affect transcode time, so don't take it into account */
+
/* We assume that dcp_length() is valid, if it is set */
- SourceFrame const left = _film->trim_start() + _film->dcp_length().get() - _encoder->video_frame();
+ int const left = length - _encoder->video_frames_out();
return left / fps;
}
diff --git a/src/lib/util.cc b/src/lib/util.cc
index b500ddc2f..0e250bb08 100644
--- a/src/lib/util.cc
+++ b/src/lib/util.cc
@@ -63,6 +63,7 @@ extern "C" {
using namespace std;
using namespace boost;
+using libdcp::Size;
thread::id ui_thread;
@@ -455,16 +456,6 @@ dcp_audio_channels (int f)
}
-bool operator== (Size const & a, Size const & b)
-{
- return (a.width == b.width && a.height == b.height);
-}
-
-bool operator!= (Size const & a, Size const & b)
-{
- return !(a == b);
-}
-
bool operator== (Crop const & a, Crop const & b)
{
return (a.left == b.left && a.right == b.right && a.top == b.top && a.bottom == b.bottom);
diff --git a/src/lib/util.h b/src/lib/util.h
index 1fd2c0150..c4940a5d7 100644
--- a/src/lib/util.h
+++ b/src/lib/util.h
@@ -29,6 +29,7 @@
#include <vector>
#include <boost/shared_ptr.hpp>
#include <boost/asio.hpp>
+#include <libdcp/util.h>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavfilter/avfilter.h>
@@ -99,33 +100,6 @@ enum ContentType {
VIDEO ///< content is a video
};
-/** @class Size
- * @brief Representation of the size of something */
-struct Size
-{
- /** Construct a zero Size */
- Size ()
- : width (0)
- , height (0)
- {}
-
- /** @param w Width.
- * @param h Height.
- */
- Size (int w, int h)
- : width (w)
- , height (h)
- {}
-
- /** width */
- int width;
- /** height */
- int height;
-};
-
-extern bool operator== (Size const & a, Size const & b);
-extern bool operator!= (Size const & a, Size const & b);
-
/** @struct Crop
* @brief A description of the crop of an image or video.
*/
@@ -195,14 +169,14 @@ struct Rect
return Position (x, y);
}
- Size size () const {
- return Size (width, height);
+ libdcp::Size size () const {
+ return libdcp::Size (width, height);
}
Rect intersection (Rect const & other) const;
};
-extern std::string crop_string (Position, Size);
+extern std::string crop_string (Position, libdcp::Size);
extern int dcp_audio_sample_rate (int);
extern int dcp_audio_channels (int);
extern std::string colour_lut_index_to_name (int index);
diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h
index c0eab2140..ef1ab041a 100644
--- a/src/lib/video_decoder.h
+++ b/src/lib/video_decoder.h
@@ -32,7 +32,7 @@ public:
/** @return video frames per second, or 0 if unknown */
virtual float frames_per_second () const = 0;
/** @return native size in pixels */
- virtual Size native_size () const = 0;
+ virtual libdcp::Size native_size () const = 0;
/** @return length (in source video frames), according to our content's header */
virtual SourceFrame length () const = 0;