summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2012-10-24 23:27:23 +0100
committerCarl Hetherington <cth@carlh.net>2012-10-24 23:27:23 +0100
commit165edfe3bb8afd0531729f732701756d711dde16 (patch)
tree548b2b263704dcb3ebfd62af76fc27d5a4ffcce6 /src/lib
parentabd57c6c2e8526eac93e9d0c9bd0b6080de1e6fa (diff)
Try to clean up source length handling.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/check_hashes_job.cc9
-rw-r--r--src/lib/decoder.cc18
-rw-r--r--src/lib/film.cc41
-rw-r--r--src/lib/film.h17
-rw-r--r--src/lib/make_dcp_job.cc6
-rw-r--r--src/lib/transcode_job.cc3
6 files changed, 62 insertions, 32 deletions
diff --git a/src/lib/check_hashes_job.cc b/src/lib/check_hashes_job.cc
index 88233ab66..a9f8ac90b 100644
--- a/src/lib/check_hashes_job.cc
+++ b/src/lib/check_hashes_job.cc
@@ -27,6 +27,7 @@
#include "ab_transcode_job.h"
#include "transcode_job.h"
#include "film.h"
+#include "exceptions.h"
using std::string;
using std::stringstream;
@@ -52,7 +53,11 @@ CheckHashesJob::run ()
{
_bad = 0;
- int const N = _film->dcp_length ();
+ if (!_film->dcp_length()) {
+ throw EncodeError ("cannot check hashes of a DCP with unknown length");
+ }
+
+ int const N = _film->dcp_length().get();
for (int i = 0; i < N; ++i) {
string const j2k_file = _opt->frame_out_path (i, false);
@@ -78,7 +83,7 @@ CheckHashesJob::run ()
}
}
- set_progress (float (i) / _film->length());
+ set_progress (float (i) / N);
}
if (_bad) {
diff --git a/src/lib/decoder.cc b/src/lib/decoder.cc
index a78652010..eee288341 100644
--- a/src/lib/decoder.cc
+++ b/src/lib/decoder.cc
@@ -75,8 +75,8 @@ Decoder::Decoder (boost::shared_ptr<Film> f, boost::shared_ptr<const Options> o,
, _delay_in_bytes (0)
, _audio_frames_processed (0)
{
- if (_opt->decode_video_frequency != 0 && _film->length() == 0) {
- throw DecodeError ("cannot do a partial decode if length == 0");
+ if (_opt->decode_video_frequency != 0 && !_film->length()) {
+ throw DecodeError ("cannot do a partial decode if length is unknown");
}
}
@@ -111,19 +111,19 @@ Decoder::process_end ()
in to get it to the right length.
*/
- int64_t const video_length_in_audio_frames = ((int64_t) _film->dcp_length() * audio_sample_rate() / frames_per_second());
+ int64_t const video_length_in_audio_frames = ((int64_t) last_video_frame() * audio_sample_rate() / frames_per_second());
int64_t const audio_short_by_frames = video_length_in_audio_frames - _audio_frames_processed;
_log->log (
String::compose ("DCP length is %1 (%2 audio frames); %3 frames of audio processed.",
- _film->dcp_length(),
+ last_video_frame(),
video_length_in_audio_frames,
_audio_frames_processed)
);
if (audio_short_by_frames >= 0 && _opt->decode_audio) {
- _log->log (String::compose ("DCP length is %1; %2 frames of audio processed.", _film->dcp_length(), _audio_frames_processed));
+ _log->log (String::compose ("DCP length is %1; %2 frames of audio processed.", last_video_frame(), _audio_frames_processed));
_log->log (String::compose ("Adding %1 frames of silence to the end.", audio_short_by_frames));
/* XXX: this is slightly questionable; does memset () give silence with all
@@ -150,13 +150,13 @@ Decoder::go ()
{
process_begin ();
- if (_job && _ignore_length) {
+ if (_job && !_film->dcp_length()) {
_job->set_progress_unknown ();
}
while (pass () == false) {
- if (_job && !_ignore_length) {
- _job->set_progress (float (_video_frame) / _film->dcp_length());
+ if (_job && _film->dcp_length()) {
+ _job->set_progress (float (_video_frame) / _film->dcp_length().get());
}
}
@@ -286,7 +286,7 @@ Decoder::process_video (AVFrame* frame)
int gap = 0;
if (_opt->decode_video_frequency != 0) {
- gap = _film->length() / _opt->decode_video_frequency;
+ gap = _film->length().get() / _opt->decode_video_frequency;
}
if (_opt->decode_video_frequency != 0 && gap != 0 && (_video_frame % gap) != 0) {
diff --git a/src/lib/film.cc b/src/lib/film.cc
index 8750ab442..0104f5a16 100644
--- a/src/lib/film.cc
+++ b/src/lib/film.cc
@@ -62,6 +62,7 @@ using std::vector;
using std::ifstream;
using std::ofstream;
using std::setfill;
+using std::min;
using boost::shared_ptr;
using boost::lexical_cast;
using boost::to_upper_copy;
@@ -81,7 +82,6 @@ Film::Film (string d, bool must_exist)
, _dcp_content_type (0)
, _format (0)
, _scaler (Scaler::from_id ("bicubic"))
- , _dcp_frames (0)
, _dcp_trim_action (CUT)
, _dcp_ab (false)
, _audio_stream (-1)
@@ -92,7 +92,6 @@ Film::Film (string d, bool must_exist)
, _with_subtitles (false)
, _subtitle_offset (0)
, _subtitle_scale (1)
- , _length (0)
, _audio_sample_rate (0)
, _has_subtitles (false)
, _frames_per_second (0)
@@ -252,7 +251,7 @@ Film::make_dcp (bool transcode)
shared_ptr<Options> o (new Options (j2k_dir(), ".j2c", dir ("wavs")));
o->out_size = format()->dcp_size ();
- if (dcp_frames() == 0) {
+ if (!dcp_frames()) {
/* Decode the whole film, no blacking */
o->black_after = 0;
} else {
@@ -263,7 +262,7 @@ Film::make_dcp (bool transcode)
break;
case BLACK_OUT:
/* Decode the whole film, but black some frames out */
- o->black_after = dcp_frames ();
+ o->black_after = dcp_frames().get ();
}
}
@@ -417,7 +416,7 @@ Film::write_metadata () const
f << "filter " << (*i)->id () << "\n";
}
f << "scaler " << _scaler->id () << "\n";
- f << "dcp_frames " << _dcp_frames << "\n";
+ f << "dcp_frames " << _dcp_frames.get_value_or(0) << "\n";
f << "dcp_trim_action ";
switch (_dcp_trim_action) {
@@ -454,7 +453,7 @@ Film::write_metadata () const
}
f << "width " << _size.width << "\n";
f << "height " << _size.height << "\n";
- f << "length " << _length << "\n";
+ f << "length " << _length.get_value_or(0) << "\n";
f << "audio_sample_rate " << _audio_sample_rate << "\n";
f << "content_digest " << _content_digest << "\n";
f << "has_subtitles " << _has_subtitles << "\n";
@@ -508,7 +507,10 @@ Film::read_metadata ()
} else if (k == "scaler") {
_scaler = Scaler::from_id (v);
} else if (k == "dcp_frames") {
- _dcp_frames = atoi (v.c_str ());
+ int const vv = atoi (v.c_str ());
+ if (vv) {
+ _dcp_frames = vv;
+ }
} else if (k == "dcp_trim_action") {
if (v == "cut") {
_dcp_trim_action = CUT;
@@ -561,7 +563,10 @@ Film::read_metadata ()
} else if (k == "height") {
_size.height = atoi (v.c_str ());
} else if (k == "length") {
- _length = atof (v.c_str ());
+ int const vv = atoi (v.c_str ());
+ if (vv) {
+ _length = vv;
+ }
} else if (k == "audio_sample_rate") {
_audio_sample_rate = atoi (v.c_str ());
} else if (k == "content_digest") {
@@ -738,11 +743,15 @@ Film::target_audio_sample_rate () const
return rint (t);
}
-int
+boost::optional<int>
Film::dcp_length () const
{
+ if (!length()) {
+ return boost::optional<int> ();
+ }
+
if (dcp_frames()) {
- return dcp_frames();
+ return min (dcp_frames().get(), length().get());
}
return length();
@@ -914,7 +923,7 @@ Film::set_content (string c)
o->out_size = Size (1024, 1024);
shared_ptr<Decoder> d = decoder_factory (shared_from_this(), o, 0, 0);
-
+
set_size (d->native_size ());
set_frames_per_second (d->frames_per_second ());
set_audio_sample_rate (d->audio_sample_rate ());
@@ -1247,6 +1256,16 @@ Film::set_length (int l)
}
void
+Film::unset_length ()
+{
+ {
+ boost::mutex::scoped_lock lm (_state_mutex);
+ _length = boost::none;
+ }
+ signal_changed (LENGTH);
+}
+
+void
Film::set_audio_sample_rate (int r)
{
{
diff --git a/src/lib/film.h b/src/lib/film.h
index 27be4331c..131891706 100644
--- a/src/lib/film.h
+++ b/src/lib/film.h
@@ -95,7 +95,7 @@ public:
void read_metadata ();
Size cropped_size (Size) const;
- int dcp_length () const;
+ boost::optional<int> dcp_length () const;
std::string dci_name () const;
std::string dcp_name () const;
@@ -185,7 +185,7 @@ public:
return _scaler;
}
- int dcp_frames () const {
+ boost::optional<int> dcp_frames () const {
boost::mutex::scoped_lock lm (_state_mutex);
return _dcp_frames;
}
@@ -297,11 +297,11 @@ public:
return _size;
}
- int length () const {
+ boost::optional<int> length () const {
boost::mutex::scoped_lock lm (_state_mutex);
return _length;
}
-
+
int audio_sample_rate () const {
boost::mutex::scoped_lock lm (_state_mutex);
return _audio_sample_rate;
@@ -369,6 +369,7 @@ public:
void set_thumbs (std::vector<int>);
void set_size (Size);
void set_length (int);
+ void unset_length ();
void set_audio_sample_rate (int);
void set_content_digest (std::string);
void set_has_subtitles (bool);
@@ -418,8 +419,8 @@ private:
std::vector<Filter const *> _filters;
/** Scaler algorithm to use */
Scaler const * _scaler;
- /** Number of frames to put in the DCP, or 0 for all */
- int _dcp_frames;
+ /** Maximum number of frames to put in the DCP, if applicable */
+ boost::optional<int> _dcp_frames;
/** What to do with audio when trimming DCPs */
TrimAction _dcp_trim_action;
/** true to create an A/B comparison DCP, where the left half of the image
@@ -461,8 +462,8 @@ private:
std::vector<int> _thumbs;
/** Size, in pixels, of the source (ignoring cropping) */
Size _size;
- /** Length of the source in frames */
- int _length;
+ /** Actual length of the source (in video frames) from examining it */
+ boost::optional<int> _length;
/** Sample rate of the source audio, in Hz */
int _audio_sample_rate;
/** MD5 digest of our content file */
diff --git a/src/lib/make_dcp_job.cc b/src/lib/make_dcp_job.cc
index e2c90a854..2bb0e1ba0 100644
--- a/src/lib/make_dcp_job.cc
+++ b/src/lib/make_dcp_job.cc
@@ -70,6 +70,10 @@ 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");
+ }
+
string const dcp_path = _film->dir (_film->dcp_name());
/* Remove any old DCP */
@@ -78,7 +82,7 @@ MakeDCPJob::run ()
int frames = 0;
switch (_film->content_type ()) {
case VIDEO:
- frames = _film->dcp_length ();
+ frames = _film->dcp_length().get();
break;
case STILL:
frames = _film->still_duration() * ImageMagickDecoder::static_frames_per_second ();
diff --git a/src/lib/transcode_job.cc b/src/lib/transcode_job.cc
index cf16b8ab6..877214316 100644
--- a/src/lib/transcode_job.cc
+++ b/src/lib/transcode_job.cc
@@ -109,5 +109,6 @@ TranscodeJob::remaining_time () const
return 0;
}
- return ((_film->dcp_length() - _encoder->last_frame()) / fps);
+ /* We assume that dcp_length() is valid */
+ return ((_film->dcp_length().get() - _encoder->last_frame()) / fps);
}