summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-04-01 22:49:31 +0100
committerCarl Hetherington <cth@carlh.net>2013-04-01 22:49:31 +0100
commitdb468a15e50c8491d4b8462ad0676be905f49065 (patch)
tree4b6d93f0916264f9cf67d11440e5fe491ab58a3a /src/lib
parent623845efac0831aa1e2df6b79c4e879a7b901c69 (diff)
Various bits.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/ab_transcoder.cc24
-rw-r--r--src/lib/ab_transcoder.h6
-rw-r--r--src/lib/analyse_audio_job.cc16
-rw-r--r--src/lib/audio_decoder.cc2
-rw-r--r--src/lib/audio_decoder.h2
-rw-r--r--src/lib/encoder.cc31
-rw-r--r--src/lib/encoder.h4
-rw-r--r--src/lib/ffmpeg_decoder.cc6
-rw-r--r--src/lib/ffmpeg_decoder.h4
-rw-r--r--src/lib/film.cc73
-rw-r--r--src/lib/film.h15
-rw-r--r--src/lib/format.cc12
-rw-r--r--src/lib/format.h16
-rw-r--r--src/lib/imagemagick_decoder.cc4
-rw-r--r--src/lib/imagemagick_decoder.h4
-rw-r--r--src/lib/playlist.cc124
-rw-r--r--src/lib/playlist.h77
-rw-r--r--src/lib/sndfile_decoder.cc4
-rw-r--r--src/lib/sndfile_decoder.h4
-rw-r--r--src/lib/transcoder.cc22
-rw-r--r--src/lib/transcoder.h4
-rw-r--r--src/lib/video_decoder.cc9
-rw-r--r--src/lib/video_decoder.h2
-rw-r--r--src/lib/writer.cc7
-rw-r--r--src/lib/writer.h4
25 files changed, 304 insertions, 172 deletions
diff --git a/src/lib/ab_transcoder.cc b/src/lib/ab_transcoder.cc
index 6fc438ee8..6bf092fee 100644
--- a/src/lib/ab_transcoder.cc
+++ b/src/lib/ab_transcoder.cc
@@ -49,20 +49,20 @@ using boost::dynamic_pointer_cast;
ABTranscoder::ABTranscoder (shared_ptr<Film> a, shared_ptr<Film> b, shared_ptr<Job> j)
: _film_a (a)
, _film_b (b)
- , _playlist_a (_film_a->playlist ())
- , _playlist_b (_film_b->playlist ())
+ , _player_a (_film_a->player ())
+ , _player_b (_film_b->player ())
, _job (j)
- , _encoder (new Encoder (_film_a, _playlist_a))
+ , _encoder (new Encoder (_film_a))
, _combiner (new Combiner (a->log()))
{
- if (_playlist_a->has_audio ()) {
- _matcher.reset (new Matcher (_film_a->log(), _playlist_a->audio_frame_rate(), _playlist_a->video_frame_rate()));
- _delay_line.reset (new DelayLine (_film_a->log(), _playlist_a->audio_channels(), _film_a->audio_delay() * _playlist_a->audio_frame_rate() / 1000));
+ if (_film_a->has_audio ()) {
+ _matcher.reset (new Matcher (_film_a->log(), _film_a->audio_frame_rate(), _film_a->video_frame_rate()));
+ _delay_line.reset (new DelayLine (_film_a->log(), _film_a->audio_channels(), _film_a->audio_delay() * _film_a->audio_frame_rate() / 1000));
_gain.reset (new Gain (_film_a->log(), _film_a->audio_gain()));
}
- _playlist_a->Video.connect (bind (&Combiner::process_video, _combiner, _1, _2, _3));
- _playlist_b->Video.connect (bind (&Combiner::process_video_b, _combiner, _1, _2, _3));
+ _player_a->Video.connect (bind (&Combiner::process_video, _combiner, _1, _2, _3));
+ _player_b->Video.connect (bind (&Combiner::process_video_b, _combiner, _1, _2, _3));
if (_matcher) {
_combiner->connect_video (_matcher);
@@ -72,7 +72,7 @@ ABTranscoder::ABTranscoder (shared_ptr<Film> a, shared_ptr<Film> b, shared_ptr<J
}
if (_matcher && _delay_line) {
- _playlist_a->connect_audio (_delay_line);
+ _player_a->connect_audio (_delay_line);
_delay_line->connect_audio (_matcher);
_matcher->connect_audio (_gain);
_gain->connect_audio (_encoder);
@@ -87,11 +87,11 @@ ABTranscoder::go ()
bool done[2] = { false, false };
while (1) {
- done[0] = _playlist_a->pass ();
- done[1] = _playlist_b->pass ();
+ done[0] = _player_a->pass ();
+ done[1] = _player_b->pass ();
if (_job) {
- _playlist_a->set_progress (_job);
+ _player_a->set_progress (_job);
}
if (done[0] && done[1]) {
diff --git a/src/lib/ab_transcoder.h b/src/lib/ab_transcoder.h
index 5ce4a03da..b1b01d724 100644
--- a/src/lib/ab_transcoder.h
+++ b/src/lib/ab_transcoder.h
@@ -35,7 +35,7 @@ class Matcher;
class DelayLine;
class Gain;
class Combiner;
-class Playlist;
+class Player;
/** @class ABTranscoder
* @brief A transcoder which uses one Film for the left half of the screen, and a different one
@@ -55,8 +55,8 @@ public:
private:
boost::shared_ptr<Film> _film_a;
boost::shared_ptr<Film> _film_b;
- boost::shared_ptr<Playlist> _playlist_a;
- boost::shared_ptr<Playlist> _playlist_b;
+ boost::shared_ptr<Player> _player_a;
+ boost::shared_ptr<Player> _player_b;
boost::shared_ptr<Job> _job;
boost::shared_ptr<Encoder> _encoder;
boost::shared_ptr<Combiner> _combiner;
diff --git a/src/lib/analyse_audio_job.cc b/src/lib/analyse_audio_job.cc
index 6e6dda886..e2c9c5b18 100644
--- a/src/lib/analyse_audio_job.cc
+++ b/src/lib/analyse_audio_job.cc
@@ -50,18 +50,18 @@ AnalyseAudioJob::name () const
void
AnalyseAudioJob::run ()
{
- shared_ptr<Playlist> playlist = _film->playlist ();
- playlist->disable_video ();
+ shared_ptr<Player> player = _film->player ();
+ player->disable_video ();
- playlist->Audio.connect (bind (&AnalyseAudioJob::audio, this, _1));
+ player->Audio.connect (bind (&AnalyseAudioJob::audio, this, _1));
- _samples_per_point = max (int64_t (1), playlist->audio_length() / _num_points);
+ _samples_per_point = max (int64_t (1), _film->audio_length() / _num_points);
- _current.resize (playlist->audio_channels ());
- _analysis.reset (new AudioAnalysis (playlist->audio_channels()));
+ _current.resize (_film->audio_channels ());
+ _analysis.reset (new AudioAnalysis (_film->audio_channels()));
- while (!playlist->pass()) {
- set_progress (float (_done) / playlist->audio_length ());
+ while (!player->pass()) {
+ set_progress (float (_done) / _film->audio_length ());
}
_analysis->write (_film->audio_analysis_path ());
diff --git a/src/lib/audio_decoder.cc b/src/lib/audio_decoder.cc
index e2006a795..df13a984a 100644
--- a/src/lib/audio_decoder.cc
+++ b/src/lib/audio_decoder.cc
@@ -22,7 +22,7 @@
using boost::optional;
using boost::shared_ptr;
-AudioDecoder::AudioDecoder (shared_ptr<const Film> f, shared_ptr<AudioContent> c)
+AudioDecoder::AudioDecoder (shared_ptr<const Film> f)
: Decoder (f)
{
diff --git a/src/lib/audio_decoder.h b/src/lib/audio_decoder.h
index cbb84b52d..24e2796ae 100644
--- a/src/lib/audio_decoder.h
+++ b/src/lib/audio_decoder.h
@@ -35,7 +35,7 @@ class AudioContent;
class AudioDecoder : public AudioSource, public virtual Decoder
{
public:
- AudioDecoder (boost::shared_ptr<const Film>, boost::shared_ptr<AudioContent>);
+ AudioDecoder (boost::shared_ptr<const Film>);
};
#endif
diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc
index 00807f863..5c3e56709 100644
--- a/src/lib/encoder.cc
+++ b/src/lib/encoder.cc
@@ -53,9 +53,8 @@ using namespace boost;
int const Encoder::_history_size = 25;
/** @param f Film that we are encoding */
-Encoder::Encoder (shared_ptr<Film> f, shared_ptr<Playlist> p)
+Encoder::Encoder (shared_ptr<Film> f)
: _film (f)
- , _playlist (p)
, _video_frames_in (0)
, _video_frames_out (0)
#ifdef HAVE_SWRESAMPLE
@@ -78,22 +77,22 @@ Encoder::~Encoder ()
void
Encoder::process_begin ()
{
- if (_playlist->has_audio() && _playlist->audio_frame_rate() != _film->target_audio_sample_rate()) {
+ if (_film->has_audio() && _film->audio_frame_rate() != _film->target_audio_sample_rate()) {
#ifdef HAVE_SWRESAMPLE
stringstream s;
- s << String::compose (N_("Will resample audio from %1 to %2"), _playlist->audio_frame_rate(), _film->target_audio_sample_rate());
+ s << String::compose (N_("Will resample audio from %1 to %2"), _film->audio_frame_rate(), _film->target_audio_sample_rate());
_film->log()->log (s.str ());
/* We will be using planar float data when we call the resampler */
_swr_context = swr_alloc_set_opts (
0,
- _playlist->audio_channel_layout(),
+ _film->audio_channel_layout(),
AV_SAMPLE_FMT_FLTP,
_film->target_audio_sample_rate(),
- _playlist->audio_channel_layout(),
+ _film->audio_channel_layout(),
AV_SAMPLE_FMT_FLTP,
- _playlist->audio_frame_rate(),
+ _film->audio_frame_rate(),
0, 0
);
@@ -119,7 +118,7 @@ Encoder::process_begin ()
}
}
- _writer.reset (new Writer (_film, _playlist));
+ _writer.reset (new Writer (_film));
}
@@ -127,9 +126,9 @@ void
Encoder::process_end ()
{
#if HAVE_SWRESAMPLE
- if (_playlist->has_audio() && _playlist->audio_channels() && _swr_context) {
+ if (_film->has_audio() && _film->audio_channels() && _swr_context) {
- shared_ptr<AudioBuffers> out (new AudioBuffers (_playlist->audio_channels(), 256));
+ shared_ptr<AudioBuffers> out (new AudioBuffers (_film->audio_channels(), 256));
while (1) {
int const frames = swr_convert (_swr_context, (uint8_t **) out->data(), 256, 0, 0);
@@ -234,7 +233,7 @@ Encoder::frame_done ()
void
Encoder::process_video (shared_ptr<Image> image, bool same, boost::shared_ptr<Subtitle> sub)
{
- FrameRateConversion frc (_playlist->video_frame_rate(), _film->dcp_frame_rate());
+ FrameRateConversion frc (_film->video_frame_rate(), _film->dcp_frame_rate());
if (frc.skip && (_video_frames_in % 2)) {
++_video_frames_in;
@@ -272,7 +271,7 @@ Encoder::process_video (shared_ptr<Image> image, bool same, boost::shared_ptr<Su
TIMING ("adding to queue of %1", _queue.size ());
_queue.push_back (boost::shared_ptr<DCPVideoFrame> (
new DCPVideoFrame (
- image, sub, _film->format()->dcp_size(), _film->format()->dcp_padding (_playlist),
+ image, sub, _film->format()->dcp_size(), _film->format()->dcp_padding (_film),
_film->subtitle_offset(), _film->subtitle_scale(),
_film->scaler(), _video_frames_out, _film->dcp_frame_rate(), s.second,
_film->colour_lut(), _film->j2k_bandwidth(),
@@ -302,9 +301,9 @@ Encoder::process_audio (shared_ptr<AudioBuffers> data)
if (_swr_context) {
/* Compute the resampled frames count and add 32 for luck */
- int const max_resampled_frames = ceil ((int64_t) data->frames() * _film->target_audio_sample_rate() / _playlist->audio_frame_rate()) + 32;
+ int const max_resampled_frames = ceil ((int64_t) data->frames() * _film->target_audio_sample_rate() / _film->audio_frame_rate()) + 32;
- shared_ptr<AudioBuffers> resampled (new AudioBuffers (_playlist->audio_channels(), max_resampled_frames));
+ shared_ptr<AudioBuffers> resampled (new AudioBuffers (_film->audio_channels(), max_resampled_frames));
/* Resample audio */
int const resampled_frames = swr_convert (
@@ -426,8 +425,8 @@ Encoder::encoder_thread (ServerDescription* server)
void
Encoder::write_audio (shared_ptr<const AudioBuffers> data)
{
- AudioMapping m (_playlist->audio_channels ());
- if (m.dcp_channels() != _playlist->audio_channels()) {
+ AudioMapping m (_film->audio_channels ());
+ if (m.dcp_channels() != _film->audio_channels()) {
/* Remap (currently just for mono -> 5.1) */
diff --git a/src/lib/encoder.h b/src/lib/encoder.h
index c84ee027a..86880bc34 100644
--- a/src/lib/encoder.h
+++ b/src/lib/encoder.h
@@ -51,7 +51,6 @@ class ServerDescription;
class DCPVideoFrame;
class EncodedData;
class Writer;
-class Playlist;
/** @class Encoder
* @brief Encoder to J2K and WAV for DCP.
@@ -63,7 +62,7 @@ class Playlist;
class Encoder : public VideoSink, public AudioSink
{
public:
- Encoder (boost::shared_ptr<Film> f, boost::shared_ptr<Playlist>);
+ Encoder (boost::shared_ptr<Film> f);
virtual ~Encoder ();
/** Called to indicate that a processing run is about to begin */
@@ -96,7 +95,6 @@ private:
/** Film that we are encoding */
boost::shared_ptr<Film> _film;
- boost::shared_ptr<Playlist> _playlist;
/** Mutex for _time_history and _last_frame */
mutable boost::mutex _history_mutex;
diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc
index 7b56a5971..25ca9bb88 100644
--- a/src/lib/ffmpeg_decoder.cc
+++ b/src/lib/ffmpeg_decoder.cc
@@ -61,10 +61,10 @@ using boost::optional;
using boost::dynamic_pointer_cast;
using libdcp::Size;
-FFmpegDecoder::FFmpegDecoder (shared_ptr<const Film> f, shared_ptr<FFmpegContent> c, bool video, bool audio, bool subtitles, bool video_sync)
+FFmpegDecoder::FFmpegDecoder (shared_ptr<const Film> f, shared_ptr<const FFmpegContent> c, bool video, bool audio, bool subtitles, bool video_sync)
: Decoder (f)
- , VideoDecoder (f, c)
- , AudioDecoder (f, c)
+ , VideoDecoder (f)
+ , AudioDecoder (f)
, _ffmpeg_content (c)
, _format_context (0)
, _video_stream (-1)
diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h
index ef66f09d9..71ecf7906 100644
--- a/src/lib/ffmpeg_decoder.h
+++ b/src/lib/ffmpeg_decoder.h
@@ -57,7 +57,7 @@ class Log;
class FFmpegDecoder : public VideoDecoder, public AudioDecoder
{
public:
- FFmpegDecoder (boost::shared_ptr<const Film>, boost::shared_ptr<FFmpegContent>, bool video, bool audio, bool subtitles, bool video_sync);
+ FFmpegDecoder (boost::shared_ptr<const Film>, boost::shared_ptr<const FFmpegContent>, bool video, bool audio, bool subtitles, bool video_sync);
~FFmpegDecoder ();
float frames_per_second () const;
@@ -105,7 +105,7 @@ private:
std::string stream_name (AVStream* s) const;
- boost::shared_ptr<FFmpegContent> _ffmpeg_content;
+ boost::shared_ptr<const FFmpegContent> _ffmpeg_content;
AVFormatContext* _format_context;
int _video_stream;
diff --git a/src/lib/film.cc b/src/lib/film.cc
index f2c7a654a..fe16a65fa 100644
--- a/src/lib/film.cc
+++ b/src/lib/film.cc
@@ -91,7 +91,8 @@ int const Film::state_version = 4;
*/
Film::Film (string d, bool must_exist)
- : _use_dci_name (true)
+ : _playlist (new Playlist)
+ , _use_dci_name (true)
, _trust_content_headers (true)
, _dcp_content_type (0)
, _format (0)
@@ -151,6 +152,7 @@ Film::Film (Film const & o)
: boost::enable_shared_from_this<Film> (o)
/* note: the copied film shares the original's log */
, _log (o._log)
+ , _playlist (new Playlist)
, _directory (o._directory)
, _name (o._name)
, _use_dci_name (o._use_dci_name)
@@ -175,7 +177,7 @@ Film::Film (Film const & o)
, _dcp_frame_rate (o._dcp_frame_rate)
, _dirty (o._dirty)
{
-
+ _playlist->setup (_content);
}
Film::~Film ()
@@ -554,17 +556,14 @@ Film::file (string f) const
int
Film::target_audio_sample_rate () const
{
- /* XXX: how often is this method called? */
-
- boost::shared_ptr<Playlist> p = playlist ();
- if (p->has_audio ()) {
+ if (has_audio ()) {
return 0;
}
/* Resample to a DCI-approved sample rate */
- double t = dcp_audio_sample_rate (p->audio_frame_rate());
+ double t = dcp_audio_sample_rate (audio_frame_rate());
- FrameRateConversion frc (p->video_frame_rate(), dcp_frame_rate());
+ FrameRateConversion frc (video_frame_rate(), dcp_frame_rate());
/* Compensate if the DCP is being run at a different frame rate
to the source; that is, if the video is run such that it will
@@ -573,7 +572,7 @@ Film::target_audio_sample_rate () const
*/
if (frc.change_speed) {
- t *= p->video_frame_rate() * frc.factor() / dcp_frame_rate();
+ t *= video_frame_rate() * frc.factor() / dcp_frame_rate();
}
return rint (t);
@@ -1023,11 +1022,11 @@ Film::have_dcp () const
return true;
}
-shared_ptr<Playlist>
-Film::playlist () const
+shared_ptr<Player>
+Film::player () const
{
boost::mutex::scoped_lock lm (_state_mutex);
- return shared_ptr<Playlist> (new Playlist (shared_from_this (), _content));
+ return shared_ptr<Player> (new Player (shared_from_this (), _playlist));
}
void
@@ -1036,9 +1035,59 @@ Film::add_content (shared_ptr<Content> c)
{
boost::mutex::scoped_lock lm (_state_mutex);
_content.push_back (c);
+ _playlist->setup (_content);
}
signal_changed (CONTENT);
examine_content (c);
}
+
+ContentAudioFrame
+Film::audio_length () const
+{
+ return _playlist->audio_length ();
+}
+
+int
+Film::audio_channels () const
+{
+ return _playlist->audio_channels ();
+}
+
+int
+Film::audio_frame_rate () const
+{
+ return _playlist->audio_frame_rate ();
+}
+
+int64_t
+Film::audio_channel_layout () const
+{
+ return _playlist->audio_channel_layout ();
+}
+
+bool
+Film::has_audio () const
+{
+ return _playlist->has_audio ();
+}
+
+float
+Film::video_frame_rate () const
+{
+ return _playlist->video_frame_rate ();
+}
+
+libdcp::Size
+Film::video_size () const
+{
+ return _playlist->video_size ();
+}
+
+ContentVideoFrame
+Film::video_length () const
+{
+ return _playlist->video_length ();
+}
+
diff --git a/src/lib/film.h b/src/lib/film.h
index f5f944409..6e097d44e 100644
--- a/src/lib/film.h
+++ b/src/lib/film.h
@@ -47,6 +47,7 @@ class ExamineContentJob;
class AnalyseAudioJob;
class ExternalAudioStream;
class Content;
+class Player;
class Playlist;
/** @class Film
@@ -105,7 +106,17 @@ public:
bool have_dcp () const;
- boost::shared_ptr<Playlist> playlist () const;
+ boost::shared_ptr<Player> player () const;
+
+ ContentAudioFrame audio_length () const;
+ int audio_channels () const;
+ int audio_frame_rate () const;
+ int64_t audio_channel_layout () const;
+ bool has_audio () const;
+
+ float video_frame_rate () const;
+ libdcp::Size video_size () const;
+ ContentVideoFrame video_length () const;
/** Identifiers for the parts of our state;
used for signalling changes.
@@ -301,6 +312,8 @@ private:
void analyse_audio_finished ();
std::string video_state_identifier () const;
+ boost::shared_ptr<Playlist> _playlist;
+
/** Complete path to directory containing the film metadata;
* must not be relative.
*/
diff --git a/src/lib/format.cc b/src/lib/format.cc
index 05b71f2e5..538bf7953 100644
--- a/src/lib/format.cc
+++ b/src/lib/format.cc
@@ -207,9 +207,9 @@ FixedFormat::FixedFormat (int r, libdcp::Size dcp, string id, string n, string d
* (so there are dcp_padding() pixels on the left and dcp_padding() on the right)
*/
int
-Format::dcp_padding (shared_ptr<const Playlist> p) const
+Format::dcp_padding (shared_ptr<const Film> f) const
{
- int pad = rint ((_dcp_size.width - (_dcp_size.height * ratio_as_integer(p) / 100.0)) / 2.0);
+ int pad = rint ((_dcp_size.width - (_dcp_size.height * ratio_as_integer(f) / 100.0)) / 2.0);
/* This comes out -ve for Scope; bodge it */
if (pad < 0) {
@@ -232,15 +232,15 @@ VariableFormat::VariableFormat (libdcp::Size dcp, string id, string n, string d,
}
int
-VariableFormat::ratio_as_integer (shared_ptr<const Playlist> p) const
+VariableFormat::ratio_as_integer (shared_ptr<const Film> f) const
{
- return rint (ratio_as_float (p) * 100);
+ return rint (ratio_as_float (f) * 100);
}
float
-VariableFormat::ratio_as_float (shared_ptr<const Playlist> p) const
+VariableFormat::ratio_as_float (shared_ptr<const Film> f) const
{
- return float (p->video_size().width) / p->video_size().height;
+ return float (f->video_size().width) / f->video_size().height;
}
/** @return A name to be presented to the user */
diff --git a/src/lib/format.h b/src/lib/format.h
index 94c2253de..cc7502893 100644
--- a/src/lib/format.h
+++ b/src/lib/format.h
@@ -26,7 +26,7 @@
#include <vector>
#include "util.h"
-class Playlist;
+class Film;
class Format
{
@@ -42,15 +42,15 @@ public:
/** @return the aspect ratio multiplied by 100
* (e.g. 239 for Cinemascope 2.39:1)
*/
- virtual int ratio_as_integer (boost::shared_ptr<const Playlist> f) const = 0;
+ virtual int ratio_as_integer (boost::shared_ptr<const Film> f) const = 0;
/** @return the ratio as a floating point number */
- virtual float ratio_as_float (boost::shared_ptr<const Playlist> f) const = 0;
+ virtual float ratio_as_float (boost::shared_ptr<const Film> f) const = 0;
/** @return the ratio of the container (including any padding) as a floating point number */
float container_ratio_as_float () const;
- int dcp_padding (boost::shared_ptr<const Playlist>) const;
+ int dcp_padding (boost::shared_ptr<const Film>) const;
/** @return size in pixels of the images that we should
* put in a DCP for this ratio. This size will not correspond
@@ -115,11 +115,11 @@ class FixedFormat : public Format
public:
FixedFormat (int, libdcp::Size, std::string, std::string, std::string, std::string);
- int ratio_as_integer (boost::shared_ptr<const Playlist>) const {
+ int ratio_as_integer (boost::shared_ptr<const Film>) const {
return _ratio;
}
- float ratio_as_float (boost::shared_ptr<const Playlist>) const {
+ float ratio_as_float (boost::shared_ptr<const Film>) const {
return _ratio / 100.0;
}
@@ -136,8 +136,8 @@ class VariableFormat : public Format
public:
VariableFormat (libdcp::Size, std::string, std::string, std::string, std::string);
- int ratio_as_integer (boost::shared_ptr<const Playlist> f) const;
- float ratio_as_float (boost::shared_ptr<const Playlist> f) const;
+ int ratio_as_integer (boost::shared_ptr<const Film> f) const;
+ float ratio_as_float (boost::shared_ptr<const Film> f) const;
std::string name () const;
};
diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc
index c3723f610..279c8bf32 100644
--- a/src/lib/imagemagick_decoder.cc
+++ b/src/lib/imagemagick_decoder.cc
@@ -32,9 +32,9 @@ using std::cout;
using boost::shared_ptr;
using libdcp::Size;
-ImageMagickDecoder::ImageMagickDecoder (shared_ptr<const Film> f, shared_ptr<ImageMagickContent> c)
+ImageMagickDecoder::ImageMagickDecoder (shared_ptr<const Film> f, shared_ptr<const ImageMagickContent> c)
: Decoder (f)
- , VideoDecoder (f, c)
+ , VideoDecoder (f)
, _imagemagick_content (c)
, _position (0)
{
diff --git a/src/lib/imagemagick_decoder.h b/src/lib/imagemagick_decoder.h
index a26e283c0..7ad08df03 100644
--- a/src/lib/imagemagick_decoder.h
+++ b/src/lib/imagemagick_decoder.h
@@ -28,7 +28,7 @@ class ImageMagickContent;
class ImageMagickDecoder : public VideoDecoder
{
public:
- ImageMagickDecoder (boost::shared_ptr<const Film>, boost::shared_ptr<ImageMagickContent>);
+ ImageMagickDecoder (boost::shared_ptr<const Film>, boost::shared_ptr<const ImageMagickContent>);
float frames_per_second () const {
/* We don't know */
@@ -82,6 +82,6 @@ protected:
private:
void film_changed (Film::Property);
- boost::shared_ptr<ImageMagickContent> _imagemagick_content;
+ boost::shared_ptr<const ImageMagickContent> _imagemagick_content;
ContentVideoFrame _position;
};
diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc
index fc9edac48..d9bf8ac36 100644
--- a/src/lib/playlist.cc
+++ b/src/lib/playlist.cc
@@ -30,15 +30,20 @@ using std::list;
using boost::shared_ptr;
using boost::dynamic_pointer_cast;
-Playlist::Playlist (shared_ptr<const Film> f, list<shared_ptr<Content> > c)
- : _film (f)
- , _video_from (VIDEO_NONE)
+Playlist::Playlist ()
+ : _video_from (VIDEO_NONE)
, _audio_from (AUDIO_NONE)
- , _have_setup_decoders (false)
- , _ffmpeg_decoder_done (false)
- , _video_sync (true)
{
- for (list<shared_ptr<Content> >::const_iterator i = c.begin(); i != c.end(); ++i) {
+
+}
+
+void
+Playlist::setup (list<shared_ptr<Content> > content)
+{
+ _video_from = VIDEO_NONE;
+ _audio_from = AUDIO_NONE;
+
+ for (list<shared_ptr<Content> >::const_iterator i = content.begin(); i != content.end(); ++i) {
shared_ptr<FFmpegContent> fc = dynamic_pointer_cast<FFmpegContent> (*i);
if (fc) {
assert (!_ffmpeg);
@@ -76,7 +81,7 @@ Playlist::audio_length () const
case AUDIO_SNDFILE:
{
ContentAudioFrame l = 0;
- for (list<shared_ptr<SndfileContent> >::const_iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) {
+ for (list<shared_ptr<const SndfileContent> >::const_iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) {
l += (*i)->audio_length ();
}
return l;
@@ -97,7 +102,7 @@ Playlist::audio_channels () const
case AUDIO_SNDFILE:
{
int c = 0;
- for (list<shared_ptr<SndfileContent> >::const_iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) {
+ for (list<shared_ptr<const SndfileContent> >::const_iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) {
c += (*i)->audio_channels ();
}
return c;
@@ -180,7 +185,7 @@ Playlist::video_length () const
case VIDEO_IMAGEMAGICK:
{
ContentVideoFrame l = 0;
- for (list<shared_ptr<ImageMagickContent> >::const_iterator i = _imagemagick.begin(); i != _imagemagick.end(); ++i) {
+ for (list<shared_ptr<const ImageMagickContent> >::const_iterator i = _imagemagick.begin(); i != _imagemagick.end(); ++i) {
l += (*i)->video_length ();
}
return l;
@@ -195,27 +200,40 @@ Playlist::has_audio () const
{
return _audio_from != AUDIO_NONE;
}
+
+Player::Player (boost::shared_ptr<const Film> f, boost::shared_ptr<const Playlist> p)
+ : _film (f)
+ , _playlist (p)
+ , _video (true)
+ , _audio (true)
+ , _subtitles (true)
+ , _have_setup_decoders (false)
+ , _ffmpeg_decoder_done (false)
+ , _video_sync (true)
+{
+
+}
void
-Playlist::disable_video ()
+Player::disable_video ()
{
- _video_from = VIDEO_NONE;
+ _video = false;
}
void
-Playlist::disable_audio ()
+Player::disable_audio ()
{
- _audio_from = AUDIO_NONE;
+ _audio = false;
}
void
-Playlist::disable_subtitles ()
+Player::disable_subtitles ()
{
- /* XXX */
+ _subtitles = false;
}
bool
-Playlist::pass ()
+Player::pass ()
{
if (!_have_setup_decoders) {
setup_decoders ();
@@ -224,7 +242,7 @@ Playlist::pass ()
bool done = true;
- if (_video_from == VIDEO_FFMPEG || _audio_from == AUDIO_FFMPEG) {
+ if (_playlist->video_from() == Playlist::VIDEO_FFMPEG || _playlist->audio_from() == Playlist::AUDIO_FFMPEG) {
if (!_ffmpeg_decoder_done) {
if (_ffmpeg_decoder->pass ()) {
_ffmpeg_decoder_done = true;
@@ -234,7 +252,7 @@ Playlist::pass ()
}
}
- if (_video_from == VIDEO_IMAGEMAGICK) {
+ if (_playlist->video_from() == Playlist::VIDEO_IMAGEMAGICK) {
if (_imagemagick_decoder != _imagemagick_decoders.end ()) {
if ((*_imagemagick_decoder)->pass ()) {
_imagemagick_decoder++;
@@ -252,37 +270,37 @@ Playlist::pass ()
}
void
-Playlist::set_progress (shared_ptr<Job> job)
+Player::set_progress (shared_ptr<Job> job)
{
/* XXX */
}
void
-Playlist::process_video (shared_ptr<Image> i, bool same, shared_ptr<Subtitle> s)
+Player::process_video (shared_ptr<Image> i, bool same, shared_ptr<Subtitle> s)
{
Video (i, same, s);
}
void
-Playlist::process_audio (shared_ptr<AudioBuffers> b)
+Player::process_audio (shared_ptr<AudioBuffers> b)
{
Audio (b);
}
bool
-Playlist::seek (double t)
+Player::seek (double t)
{
bool r = false;
- switch (_video_from) {
- case VIDEO_NONE:
+ switch (_playlist->video_from()) {
+ case Playlist::VIDEO_NONE:
break;
- case VIDEO_FFMPEG:
+ case Playlist::VIDEO_FFMPEG:
if (_ffmpeg_decoder->seek (t)) {
r = true;
}
break;
- case VIDEO_IMAGEMAGICK:
+ case Playlist::VIDEO_IMAGEMAGICK:
if ((*_imagemagick_decoder)->seek (t)) {
r = true;
}
@@ -295,19 +313,19 @@ Playlist::seek (double t)
}
bool
-Playlist::seek_to_last ()
+Player::seek_to_last ()
{
bool r = false;
- switch (_video_from) {
- case VIDEO_NONE:
+ switch (_playlist->video_from ()) {
+ case Playlist::VIDEO_NONE:
break;
- case VIDEO_FFMPEG:
+ case Playlist::VIDEO_FFMPEG:
if (_ffmpeg_decoder->seek_to_last ()) {
r = true;
}
break;
- case VIDEO_IMAGEMAGICK:
+ case Playlist::VIDEO_IMAGEMAGICK:
if ((*_imagemagick_decoder)->seek_to_last ()) {
r = true;
}
@@ -320,26 +338,32 @@ Playlist::seek_to_last ()
}
void
-Playlist::setup_decoders ()
+Player::setup_decoders ()
{
- if (_video_from == VIDEO_FFMPEG || _audio_from == AUDIO_FFMPEG) {
+ if ((_video && _playlist->video_from() == Playlist::VIDEO_FFMPEG) || (_audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG)) {
_ffmpeg_decoder.reset (
new FFmpegDecoder (
- _film, _ffmpeg, _video_from == VIDEO_FFMPEG, _audio_from == AUDIO_FFMPEG, _film->with_subtitles(), _video_sync
+ _film,
+ _playlist->ffmpeg(),
+ _video && _playlist->video_from() == Playlist::VIDEO_FFMPEG,
+ _audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG,
+ _subtitles && _film->with_subtitles(),
+ _video_sync
)
);
}
- if (_video_from == VIDEO_FFMPEG) {
+ if (_video && _playlist->video_from() == Playlist::VIDEO_FFMPEG) {
_ffmpeg_decoder->connect_video (shared_from_this ());
}
- if (_audio_from == AUDIO_FFMPEG) {
+ if (_audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG) {
_ffmpeg_decoder->connect_audio (shared_from_this ());
}
- if (_video_from == VIDEO_IMAGEMAGICK) {
- for (list<shared_ptr<ImageMagickContent> >::iterator i = _imagemagick.begin(); i != _imagemagick.end(); ++i) {
+ if (_video && _playlist->video_from() == Playlist::VIDEO_IMAGEMAGICK) {
+ list<shared_ptr<const ImageMagickContent> > ic = _playlist->imagemagick ();
+ for (list<shared_ptr<const ImageMagickContent> >::iterator i = ic.begin(); i != ic.end(); ++i) {
shared_ptr<ImageMagickDecoder> d (new ImageMagickDecoder (_film, *i));
_imagemagick_decoders.push_back (d);
d->connect_video (shared_from_this ());
@@ -348,8 +372,9 @@ Playlist::setup_decoders ()
_imagemagick_decoder = _imagemagick_decoders.begin ();
}
- if (_audio_from == AUDIO_SNDFILE) {
- for (list<shared_ptr<SndfileContent> >::iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) {
+ if (_audio && _playlist->audio_from() == Playlist::AUDIO_SNDFILE) {
+ list<shared_ptr<const SndfileContent> > sc = _playlist->sndfile ();
+ for (list<shared_ptr<const SndfileContent> >::iterator i = sc.begin(); i != sc.end(); ++i) {
shared_ptr<SndfileDecoder> d (new SndfileDecoder (_film, *i));
_sndfile_decoders.push_back (d);
d->connect_audio (shared_from_this ());
@@ -358,7 +383,22 @@ Playlist::setup_decoders ()
}
void
-Playlist::disable_video_sync ()
+Player::disable_video_sync ()
{
_video_sync = false;
}
+
+double
+Player::last_video_time () const
+{
+ switch (_playlist->video_from ()) {
+ case Playlist::VIDEO_NONE:
+ return 0;
+ case Playlist::VIDEO_FFMPEG:
+ return _ffmpeg_decoder->last_source_time ();
+ case Playlist::VIDEO_IMAGEMAGICK:
+ return (*_imagemagick_decoder)->last_source_time ();
+ }
+
+ return 0;
+}
diff --git a/src/lib/playlist.h b/src/lib/playlist.h
index d374dc98c..827849049 100644
--- a/src/lib/playlist.h
+++ b/src/lib/playlist.h
@@ -35,10 +35,12 @@ class SndfileDecoder;
class Job;
class Film;
-class Playlist : public VideoSource, public AudioSource, public VideoSink, public AudioSink, public boost::enable_shared_from_this<Playlist>
+class Playlist
{
public:
- Playlist (boost::shared_ptr<const Film>, std::list<boost::shared_ptr<Content> >);
+ Playlist ();
+
+ void setup (std::list<boost::shared_ptr<Content> >);
ContentAudioFrame audio_length () const;
int audio_channels () const;
@@ -50,6 +52,52 @@ public:
libdcp::Size video_size () const;
ContentVideoFrame video_length () const;
+ enum VideoFrom {
+ VIDEO_NONE,
+ VIDEO_FFMPEG,
+ VIDEO_IMAGEMAGICK
+ };
+
+ enum AudioFrom {
+ AUDIO_NONE,
+ AUDIO_FFMPEG,
+ AUDIO_SNDFILE
+ };
+
+ VideoFrom video_from () const {
+ return _video_from;
+ }
+
+ AudioFrom audio_from () const {
+ return _audio_from;
+ }
+
+ boost::shared_ptr<const FFmpegContent> ffmpeg () const {
+ return _ffmpeg;
+ }
+
+ std::list<boost::shared_ptr<const ImageMagickContent> > imagemagick () const {
+ return _imagemagick;
+ }
+
+ std::list<boost::shared_ptr<const SndfileContent> > sndfile () const {
+ return _sndfile;
+ }
+
+private:
+ VideoFrom _video_from;
+ AudioFrom _audio_from;
+
+ boost::shared_ptr<const FFmpegContent> _ffmpeg;
+ std::list<boost::shared_ptr<const ImageMagickContent> > _imagemagick;
+ std::list<boost::shared_ptr<const SndfileContent> > _sndfile;
+};
+
+class Player : public VideoSource, public AudioSource, public VideoSink, public AudioSink, public boost::enable_shared_from_this<Player>
+{
+public:
+ Player (boost::shared_ptr<const Film>, boost::shared_ptr<const Playlist>);
+
void disable_video ();
void disable_audio ();
void disable_subtitles ();
@@ -60,29 +108,20 @@ public:
bool seek (double);
bool seek_to_last ();
+ double last_video_time () const;
+
private:
void process_video (boost::shared_ptr<Image> i, bool same, boost::shared_ptr<Subtitle> s);
void process_audio (boost::shared_ptr<AudioBuffers>);
void setup_decoders ();
-
- boost::shared_ptr<const Film> _film;
- enum {
- VIDEO_NONE,
- VIDEO_FFMPEG,
- VIDEO_IMAGEMAGICK
- } _video_from;
+ boost::shared_ptr<const Film> _film;
+ boost::shared_ptr<const Playlist> _playlist;
+
+ bool _video;
+ bool _audio;
+ bool _subtitles;
- enum {
- AUDIO_NONE,
- AUDIO_FFMPEG,
- AUDIO_SNDFILE
- } _audio_from;
-
- boost::shared_ptr<FFmpegContent> _ffmpeg;
- std::list<boost::shared_ptr<ImageMagickContent> > _imagemagick;
- std::list<boost::shared_ptr<SndfileContent> > _sndfile;
-
bool _have_setup_decoders;
boost::shared_ptr<FFmpegDecoder> _ffmpeg_decoder;
bool _ffmpeg_decoder_done;
diff --git a/src/lib/sndfile_decoder.cc b/src/lib/sndfile_decoder.cc
index daa363c5e..1f97e5c41 100644
--- a/src/lib/sndfile_decoder.cc
+++ b/src/lib/sndfile_decoder.cc
@@ -36,9 +36,9 @@ using boost::optional;
/* XXX */
-SndfileDecoder::SndfileDecoder (shared_ptr<const Film> f, shared_ptr<SndfileContent> c)
+SndfileDecoder::SndfileDecoder (shared_ptr<const Film> f, shared_ptr<const SndfileContent> c)
: Decoder (f)
- , AudioDecoder (f, c)
+ , AudioDecoder (f)
{
sf_count_t frames;
SNDFILE* sf = open_file (frames);
diff --git a/src/lib/sndfile_decoder.h b/src/lib/sndfile_decoder.h
index 9a3ef49b0..56fc3a9f0 100644
--- a/src/lib/sndfile_decoder.h
+++ b/src/lib/sndfile_decoder.h
@@ -26,7 +26,7 @@ class SndfileContent;
class SndfileDecoder : public AudioDecoder
{
public:
- SndfileDecoder (boost::shared_ptr<const Film>, boost::shared_ptr<SndfileContent>);
+ SndfileDecoder (boost::shared_ptr<const Film>, boost::shared_ptr<const SndfileContent>);
bool pass ();
@@ -34,5 +34,5 @@ private:
SNDFILE* open_file (sf_count_t &);
void close_file (SNDFILE*);
- boost::shared_ptr<SndfileContent> _sndfile_content;
+ boost::shared_ptr<const SndfileContent> _sndfile_content;
};
diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc
index 21944c5fc..0ee6f523f 100644
--- a/src/lib/transcoder.cc
+++ b/src/lib/transcoder.cc
@@ -47,24 +47,24 @@ using boost::dynamic_pointer_cast;
*/
Transcoder::Transcoder (shared_ptr<Film> f, shared_ptr<Job> j)
: _job (j)
- , _playlist (f->playlist ())
- , _encoder (new Encoder (f, _playlist))
+ , _player (f->player ())
+ , _encoder (new Encoder (f))
{
- if (_playlist->has_audio ()) {
- _matcher.reset (new Matcher (f->log(), _playlist->audio_frame_rate(), _playlist->video_frame_rate()));
- _delay_line.reset (new DelayLine (f->log(), _playlist->audio_channels(), f->audio_delay() * _playlist->audio_frame_rate() / 1000));
+ if (f->has_audio ()) {
+ _matcher.reset (new Matcher (f->log(), f->audio_frame_rate(), f->video_frame_rate()));
+ _delay_line.reset (new DelayLine (f->log(), f->audio_channels(), f->audio_delay() * f->audio_frame_rate() / 1000));
_gain.reset (new Gain (f->log(), f->audio_gain()));
}
if (_matcher) {
- _playlist->connect_video (_matcher);
+ _player->connect_video (_matcher);
_matcher->connect_video (_encoder);
} else {
- _playlist->connect_video (_encoder);
+ _player->connect_video (_encoder);
}
- if (_matcher && _delay_line && _playlist->has_audio ()) {
- _playlist->connect_audio (_delay_line);
+ if (_matcher && _delay_line && f->has_audio ()) {
+ _player->connect_audio (_delay_line);
_delay_line->connect_audio (_matcher);
_matcher->connect_audio (_gain);
_gain->connect_audio (_encoder);
@@ -77,10 +77,10 @@ Transcoder::go ()
_encoder->process_begin ();
try {
while (1) {
- if (_playlist->pass ()) {
+ if (_player->pass ()) {
break;
}
- _playlist->set_progress (_job);
+ _player->set_progress (_job);
}
} catch (...) {
diff --git a/src/lib/transcoder.h b/src/lib/transcoder.h
index 856b10f3a..2d032fcf6 100644
--- a/src/lib/transcoder.h
+++ b/src/lib/transcoder.h
@@ -30,7 +30,7 @@ class Matcher;
class VideoFilter;
class Gain;
class DelayLine;
-class Playlist;
+class Player;
/** @class Transcoder
*
@@ -50,7 +50,7 @@ public:
protected:
/** A Job that is running this Transcoder, or 0 */
boost::shared_ptr<Job> _job;
- boost::shared_ptr<Playlist> _playlist;
+ boost::shared_ptr<Player> _player;
boost::shared_ptr<Encoder> _encoder;
boost::shared_ptr<Matcher> _matcher;
boost::shared_ptr<DelayLine> _delay_line;
diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc
index 33dd433ea..32b06085f 100644
--- a/src/lib/video_decoder.cc
+++ b/src/lib/video_decoder.cc
@@ -29,7 +29,7 @@
using boost::shared_ptr;
using boost::optional;
-VideoDecoder::VideoDecoder (shared_ptr<const Film> f, shared_ptr<VideoContent> c)
+VideoDecoder::VideoDecoder (shared_ptr<const Film> f)
: Decoder (f)
, _video_frame (0)
, _last_source_time (0)
@@ -106,10 +106,7 @@ VideoDecoder::set_progress (Job* j) const
{
assert (j);
-#if 0
- XXX
- if (_film->length()) {
- j->set_progress (float (_video_frame) / _film->length().get());
+ if (_film->video_length()) {
+ j->set_progress (float (_video_frame) / _film->video_length());
}
-#endif
}
diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h
index 03dc4777a..a2fd5b651 100644
--- a/src/lib/video_decoder.h
+++ b/src/lib/video_decoder.h
@@ -28,7 +28,7 @@ class VideoContent;
class VideoDecoder : public VideoSource, public virtual Decoder
{
public:
- VideoDecoder (boost::shared_ptr<const Film>, boost::shared_ptr<VideoContent>);
+ VideoDecoder (boost::shared_ptr<const Film>);
/** @return video frames per second, or 0 if unknown */
virtual float frames_per_second () const = 0;
diff --git a/src/lib/writer.cc b/src/lib/writer.cc
index 5f5dae98f..b08b9caf1 100644
--- a/src/lib/writer.cc
+++ b/src/lib/writer.cc
@@ -42,9 +42,8 @@ using boost::shared_ptr;
int const Writer::_maximum_frames_in_memory = 8;
-Writer::Writer (shared_ptr<Film> f, shared_ptr<Playlist> p)
+Writer::Writer (shared_ptr<Film> f)
: _film (f)
- , _playlist (p)
, _first_nonexistant_frame (0)
, _thread (0)
, _finish (false)
@@ -76,7 +75,7 @@ Writer::Writer (shared_ptr<Film> f, shared_ptr<Playlist> p)
_picture_asset_writer = _picture_asset->start_write (_first_nonexistant_frame > 0);
- AudioMapping m (_playlist->audio_channels ());
+ AudioMapping m (_film->audio_channels ());
if (m.dcp_channels() > 0) {
_sound_asset.reset (
@@ -85,7 +84,7 @@ Writer::Writer (shared_ptr<Film> f, shared_ptr<Playlist> p)
N_("audio.mxf"),
_film->dcp_frame_rate (),
m.dcp_channels (),
- dcp_audio_sample_rate (_playlist->audio_frame_rate())
+ dcp_audio_sample_rate (_film->audio_frame_rate())
)
);
diff --git a/src/lib/writer.h b/src/lib/writer.h
index 920f592b6..beb16c7b9 100644
--- a/src/lib/writer.h
+++ b/src/lib/writer.h
@@ -26,7 +26,6 @@
class Film;
class EncodedData;
class AudioBuffers;
-class Playlist;
namespace libdcp {
class MonoPictureAsset;
@@ -64,7 +63,7 @@ bool operator== (QueueItem const & a, QueueItem const & b);
class Writer : public ExceptionStore
{
public:
- Writer (boost::shared_ptr<Film>, boost::shared_ptr<Playlist>);
+ Writer (boost::shared_ptr<Film>);
bool can_fake_write (int) const;
@@ -81,7 +80,6 @@ private:
/** our Film */
boost::shared_ptr<Film> _film;
- boost::shared_ptr<Playlist> _playlist;
/** the first frame index that does not already exist in our MXF */
int _first_nonexistant_frame;