diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-04-01 22:49:31 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-04-01 22:49:31 +0100 |
| commit | db468a15e50c8491d4b8462ad0676be905f49065 (patch) | |
| tree | 4b6d93f0916264f9cf67d11440e5fe491ab58a3a /src/lib | |
| parent | 623845efac0831aa1e2df6b79c4e879a7b901c69 (diff) | |
Various bits.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/ab_transcoder.cc | 24 | ||||
| -rw-r--r-- | src/lib/ab_transcoder.h | 6 | ||||
| -rw-r--r-- | src/lib/analyse_audio_job.cc | 16 | ||||
| -rw-r--r-- | src/lib/audio_decoder.cc | 2 | ||||
| -rw-r--r-- | src/lib/audio_decoder.h | 2 | ||||
| -rw-r--r-- | src/lib/encoder.cc | 31 | ||||
| -rw-r--r-- | src/lib/encoder.h | 4 | ||||
| -rw-r--r-- | src/lib/ffmpeg_decoder.cc | 6 | ||||
| -rw-r--r-- | src/lib/ffmpeg_decoder.h | 4 | ||||
| -rw-r--r-- | src/lib/film.cc | 73 | ||||
| -rw-r--r-- | src/lib/film.h | 15 | ||||
| -rw-r--r-- | src/lib/format.cc | 12 | ||||
| -rw-r--r-- | src/lib/format.h | 16 | ||||
| -rw-r--r-- | src/lib/imagemagick_decoder.cc | 4 | ||||
| -rw-r--r-- | src/lib/imagemagick_decoder.h | 4 | ||||
| -rw-r--r-- | src/lib/playlist.cc | 124 | ||||
| -rw-r--r-- | src/lib/playlist.h | 77 | ||||
| -rw-r--r-- | src/lib/sndfile_decoder.cc | 4 | ||||
| -rw-r--r-- | src/lib/sndfile_decoder.h | 4 | ||||
| -rw-r--r-- | src/lib/transcoder.cc | 22 | ||||
| -rw-r--r-- | src/lib/transcoder.h | 4 | ||||
| -rw-r--r-- | src/lib/video_decoder.cc | 9 | ||||
| -rw-r--r-- | src/lib/video_decoder.h | 2 | ||||
| -rw-r--r-- | src/lib/writer.cc | 7 | ||||
| -rw-r--r-- | src/lib/writer.h | 4 |
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; |
