summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2012-11-04 14:52:43 +0000
committerCarl Hetherington <cth@carlh.net>2012-11-04 14:52:43 +0000
commitd9f9938c2ca2a1f9b27a85bf64a50d7f480f969b (patch)
tree5a3c0abf1813983324e57c896deff490055d311e /src/lib
parentb4dd5979b6c1d48b0af4fefd9d1df4e9947da402 (diff)
parentc366d41af080b9ac37117a9b27a249722c77f74e (diff)
Merge master.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/check_hashes_job.cc3
-rw-r--r--src/lib/dcp_video_frame.cc3
-rw-r--r--src/lib/decoder.cc15
-rw-r--r--src/lib/examine_content_job.cc6
-rw-r--r--src/lib/film.cc7
-rw-r--r--src/lib/make_dcp_job.cc14
-rw-r--r--src/lib/options.h5
-rw-r--r--src/lib/tiff_decoder.cc2
-rw-r--r--src/lib/util.cc18
-rw-r--r--src/lib/util.h8
10 files changed, 55 insertions, 26 deletions
diff --git a/src/lib/check_hashes_job.cc b/src/lib/check_hashes_job.cc
index a9f8ac90b..d1483933d 100644
--- a/src/lib/check_hashes_job.cc
+++ b/src/lib/check_hashes_job.cc
@@ -58,8 +58,9 @@ CheckHashesJob::run ()
}
int const N = _film->dcp_length().get();
+ DCPFrameRate const dfr = dcp_frame_rate (_film->frames_per_second ());
- for (int i = 0; i < N; ++i) {
+ for (int i = 0; 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 9d6022efa..1dcc81f0d 100644
--- a/src/lib/dcp_video_frame.cc
+++ b/src/lib/dcp_video_frame.cc
@@ -86,8 +86,7 @@ DCPVideoFrame::DCPVideoFrame (
, _subtitle_scale (subtitle_scale)
, _scaler (s)
, _frame (f)
- /* we round here; not sure if this is right */
- , _frames_per_second (rint (fps))
+ , _frames_per_second (dcp_frame_rate(fps).frames_per_second)
, _post_process (pp)
, _colour_lut_index (clut)
, _j2k_bandwidth (bw)
diff --git a/src/lib/decoder.cc b/src/lib/decoder.cc
index 783d54010..a8da1ae67 100644
--- a/src/lib/decoder.cc
+++ b/src/lib/decoder.cc
@@ -61,9 +61,7 @@ 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()) {
- throw DecodeError ("cannot do a partial decode if length is unknown");
- }
+
}
Decoder::~Decoder ()
@@ -101,7 +99,7 @@ Decoder::process_end ()
int64_t const audio_short_by_frames = video_length_in_audio_frames - _audio_frames_processed;
_film->log()->log (
- String::compose ("DCP length is %1 (%2 audio frames); %3 frames of audio processed.",
+ String::compose ("Source length is %1 (%2 audio frames); %3 frames of audio processed.",
video_frame_index(),
video_length_in_audio_frames,
_audio_frames_processed)
@@ -109,7 +107,7 @@ Decoder::process_end ()
if (audio_short_by_frames >= 0 && _opt->decode_audio) {
- _film->log()->log (String::compose ("DCP length is %1; %2 frames of audio processed.", video_frame_index(), _audio_frames_processed));
+ _film->log()->log (String::compose ("Source length is %1; %2 frames of audio processed.", video_frame_index(), _audio_frames_processed));
_film->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
@@ -260,12 +258,7 @@ Decoder::process_video (AVFrame* frame)
/* Use Film::length here as our one may be wrong */
- int gap = 0;
- if (_opt->decode_video_frequency != 0) {
- gap = _film->length().get() / _opt->decode_video_frequency;
- }
-
- if (_opt->decode_video_frequency != 0 && gap != 0 && (_video_frame_index % gap) != 0) {
+ if (_opt->decode_video_skip != 0 && (_video_frame_index % _opt->decode_video_skip) != 0) {
++_video_frame_index;
return;
}
diff --git a/src/lib/examine_content_job.cc b/src/lib/examine_content_job.cc
index 943e9fbf7..6d1233a8c 100644
--- a/src/lib/examine_content_job.cc
+++ b/src/lib/examine_content_job.cc
@@ -84,7 +84,11 @@ ExamineContentJob::run ()
o->out_size = _film->size ();
o->apply_crop = false;
o->decode_audio = false;
- o->decode_video_frequency = 128;
+ if (_film->length() > 0) {
+ o->decode_video_skip = _film->length().get() / 128;
+ } else {
+ o->decode_video_skip = 0;
+ }
o->decode_subtitles = true;
shared_ptr<ImageMagickEncoder> e (new ImageMagickEncoder (_film, o));
Transcoder w (_film, o, this, e);
diff --git a/src/lib/film.cc b/src/lib/film.cc
index b2abe4759..da664a5a5 100644
--- a/src/lib/film.cc
+++ b/src/lib/film.cc
@@ -258,6 +258,7 @@ Film::make_dcp (bool transcode)
o->padding = format()->dcp_padding (shared_from_this ());
o->ratio = format()->ratio_as_float (shared_from_this ());
o->decode_subtitles = with_subtitles ();
+ o->decode_video_skip = dcp_frame_rate (frames_per_second()).skip;
shared_ptr<Job> r;
@@ -685,11 +686,13 @@ 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);
diff --git a/src/lib/make_dcp_job.cc b/src/lib/make_dcp_job.cc
index bf01119e4..4102f8384 100644
--- a/src/lib/make_dcp_job.cc
+++ b/src/lib/make_dcp_job.cc
@@ -58,7 +58,7 @@ MakeDCPJob::name () const
string
MakeDCPJob::j2c_path (int f) const
{
- return _opt->frame_out_path (f, false);
+ return _opt->frame_out_path (f * dcp_frame_rate(_film->frames_per_second()).skip, false);
}
string
@@ -79,21 +79,23 @@ MakeDCPJob::run ()
/* Remove any old DCP */
boost::filesystem::remove_all (dcp_path);
+ DCPFrameRate const dfr = dcp_frame_rate (_film->frames_per_second ());
+
int frames = 0;
switch (_film->content_type ()) {
case VIDEO:
- frames = _film->dcp_length().get();
+ frames = _film->dcp_length().get() / dfr.skip;
break;
case STILL:
frames = _film->still_duration() * ImageMagickDecoder::static_frames_per_second ();
break;
}
-
+
libdcp::DCP dcp (_film->dir (_film->dcp_name()));
dcp.Progress.connect (boost::bind (&MakeDCPJob::dcp_progress, this, _1));
shared_ptr<libdcp::CPL> cpl (
- new libdcp::CPL (_film->dir (_film->dcp_name()), _film->dcp_name(), _film->dcp_content_type()->libdcp_kind (), frames, rint (_film->frames_per_second()))
+ new libdcp::CPL (_film->dir (_film->dcp_name()), _film->dcp_name(), _film->dcp_content_type()->libdcp_kind (), frames, dfr.frames_per_second)
);
dcp.add_cpl (cpl);
@@ -105,7 +107,7 @@ MakeDCPJob::run ()
_film->dir (_film->dcp_name()),
"video.mxf",
&dcp.Progress,
- rint (_film->frames_per_second()),
+ dfr.frames_per_second,
frames,
_opt->out_size.width,
_opt->out_size.height
@@ -124,7 +126,7 @@ MakeDCPJob::run ()
_film->dir (_film->dcp_name()),
"audio.mxf",
&dcp.Progress,
- rint (_film->frames_per_second()),
+ dfr.frames_per_second,
frames,
_film->audio_channels()
)
diff --git a/src/lib/options.h b/src/lib/options.h
index d8b99815d..aef9ca112 100644
--- a/src/lib/options.h
+++ b/src/lib/options.h
@@ -39,7 +39,7 @@ public:
Options (std::string f, std::string e, std::string m)
: padding (0)
, apply_crop (true)
- , decode_video_frequency (0)
+ , decode_video_skip (0)
, decode_audio (true)
, decode_subtitles (false)
, _frame_out_path (f)
@@ -96,7 +96,8 @@ 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_frequency; ///< skip frames so that this many are decoded in all (or 0) (for generating thumbnails)
+ 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.
bool decode_audio; ///< true to decode audio, otherwise false
bool decode_subtitles;
diff --git a/src/lib/tiff_decoder.cc b/src/lib/tiff_decoder.cc
index e75f2c482..7d8559a7c 100644
--- a/src/lib/tiff_decoder.cc
+++ b/src/lib/tiff_decoder.cc
@@ -198,7 +198,7 @@ TIFFDecoder::pixel_format () const
int
TIFFDecoder::time_base_numerator () const
{
- return rint (_film->frames_per_second());
+ return dcp_frame_rate(_film->frames_per_second()).frames_per_second;
}
diff --git a/src/lib/util.cc b/src/lib/util.cc
index b68f7e392..d89ebd0d5 100644
--- a/src/lib/util.cc
+++ b/src/lib/util.cc
@@ -374,6 +374,24 @@ md5_digest (string file)
return s.str ();
}
+DCPFrameRate
+dcp_frame_rate (float fps)
+{
+ DCPFrameRate dfr;
+
+ dfr.run_fast = (fps != rint (fps));
+ dfr.frames_per_second = rint (fps);
+ dfr.skip = 1;
+
+ /* XXX: somewhat arbitrary */
+ if (fps == 50) {
+ dfr.frames_per_second = 25;
+ dfr.skip = 2;
+ }
+
+ return dfr;
+}
+
/** @param An arbitrary sampling rate.
* @return The appropriate DCP-approved sampling rate (48kHz or 96kHz).
*/
diff --git a/src/lib/util.h b/src/lib/util.h
index 1af650085..26c6ed9fa 100644
--- a/src/lib/util.h
+++ b/src/lib/util.h
@@ -54,6 +54,13 @@ extern std::string md5_digest (std::string);
extern std::string md5_digest (void const *, int);
extern void ensure_ui_thread ();
+struct DCPFrameRate
+{
+ int frames_per_second;
+ int skip;
+ bool run_fast;
+};
+
enum ContentType {
STILL,
VIDEO
@@ -157,6 +164,7 @@ struct Rect
extern std::string crop_string (Position, Size);
extern int dcp_audio_sample_rate (int);
+extern DCPFrameRate dcp_frame_rate (float);
extern std::string colour_lut_index_to_name (int index);
extern int round_up (int, int);
extern std::multimap<std::string, std::string> read_key_value (std::istream& s);