diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-05-23 17:18:49 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-05-23 17:18:49 +0100 |
| commit | 64a2f1bb6a7b972607fa363631ef7a47444e8217 (patch) | |
| tree | 020c028a93f113e372e70f485857ce04dea5db3d /src/lib | |
| parent | 8c6fe8e1e8c8f6d5932606f2a5b6e1b87681ae38 (diff) | |
Various bits and pieces.
Diffstat (limited to 'src/lib')
31 files changed, 277 insertions, 160 deletions
diff --git a/src/lib/audio_content.cc b/src/lib/audio_content.cc index a3942f64b..607e71c50 100644 --- a/src/lib/audio_content.cc +++ b/src/lib/audio_content.cc @@ -32,24 +32,24 @@ int const AudioContentProperty::AUDIO_FRAME_RATE = 202; int const AudioContentProperty::AUDIO_GAIN = 203; int const AudioContentProperty::AUDIO_DELAY = 204; -AudioContent::AudioContent (Time s) - : Content (s) +AudioContent::AudioContent (shared_ptr<const Film> f, Time s) + : Content (f, s) , _audio_gain (0) , _audio_delay (0) { } -AudioContent::AudioContent (boost::filesystem::path f) - : Content (f) +AudioContent::AudioContent (shared_ptr<const Film> f, boost::filesystem::path p) + : Content (f, p) , _audio_gain (0) , _audio_delay (0) { } -AudioContent::AudioContent (shared_ptr<const cxml::Node> node) - : Content (node) +AudioContent::AudioContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node) + : Content (f, node) { _audio_gain = node->number_child<float> ("AudioGain"); _audio_delay = node->number_child<int> ("AudioDelay"); diff --git a/src/lib/audio_content.h b/src/lib/audio_content.h index e767fd326..0c5287eaf 100644 --- a/src/lib/audio_content.h +++ b/src/lib/audio_content.h @@ -42,9 +42,9 @@ public: class AudioContent : public virtual Content { public: - AudioContent (Time); - AudioContent (boost::filesystem::path); - AudioContent (boost::shared_ptr<const cxml::Node>); + AudioContent (boost::shared_ptr<const Film>, Time); + AudioContent (boost::shared_ptr<const Film>, boost::filesystem::path); + AudioContent (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>); AudioContent (AudioContent const &); void as_xml (xmlpp::Node *) const; @@ -52,7 +52,7 @@ public: virtual int audio_channels () const = 0; virtual ContentAudioFrame audio_length () const = 0; virtual int content_audio_frame_rate () const = 0; - virtual int output_audio_frame_rate (boost::shared_ptr<const Film>) const = 0; + virtual int output_audio_frame_rate () const = 0; virtual AudioMapping audio_mapping () const = 0; void set_audio_gain (float); diff --git a/src/lib/audio_decoder.cc b/src/lib/audio_decoder.cc index ddda816a5..6712e0624 100644 --- a/src/lib/audio_decoder.cc +++ b/src/lib/audio_decoder.cc @@ -32,15 +32,18 @@ AudioDecoder::AudioDecoder (shared_ptr<const Film> f, shared_ptr<const AudioCont : Decoder (f) , _next_audio (0) , _audio_content (c) - , _output_audio_frame_rate (_audio_content->output_audio_frame_rate (f)) { - if (_audio_content->content_audio_frame_rate() != _output_audio_frame_rate) { + if (_audio_content->content_audio_frame_rate() != _audio_content->output_audio_frame_rate()) { shared_ptr<const Film> film = _film.lock (); assert (film); stringstream s; - s << String::compose ("Will resample audio from %1 to %2", _audio_content->content_audio_frame_rate(), _output_audio_frame_rate); + s << String::compose ( + "Will resample audio from %1 to %2", + _audio_content->content_audio_frame_rate(), _audio_content->output_audio_frame_rate() + ); + film->log()->log (s.str ()); /* We will be using planar float data when we call the @@ -55,7 +58,7 @@ AudioDecoder::AudioDecoder (shared_ptr<const Film> f, shared_ptr<const AudioCont 0, av_get_default_channel_layout (MAX_AUDIO_CHANNELS), AV_SAMPLE_FMT_FLTP, - _output_audio_frame_rate, + _audio_content->output_audio_frame_rate(), av_get_default_channel_layout (MAX_AUDIO_CHANNELS), AV_SAMPLE_FMT_FLTP, _audio_content->content_audio_frame_rate(), @@ -115,7 +118,9 @@ AudioDecoder::audio (shared_ptr<const AudioBuffers> data, Time time) if (_swr_context) { /* Compute the resampled frames count and add 32 for luck */ - int const max_resampled_frames = ceil ((int64_t) data->frames() * _output_audio_frame_rate / _audio_content->content_audio_frame_rate()) + 32; + int const max_resampled_frames = ceil ( + (int64_t) data->frames() * _audio_content->output_audio_frame_rate() / _audio_content->content_audio_frame_rate() + ) + 32; shared_ptr<AudioBuffers> resampled (new AudioBuffers (MAX_AUDIO_CHANNELS, max_resampled_frames)); diff --git a/src/lib/audio_decoder.h b/src/lib/audio_decoder.h index 0f7cb6dbd..fb9f23f03 100644 --- a/src/lib/audio_decoder.h +++ b/src/lib/audio_decoder.h @@ -46,11 +46,10 @@ protected: void audio (boost::shared_ptr<const AudioBuffers>, Time); Time _next_audio; - -private: boost::shared_ptr<const AudioContent> _audio_content; + +private: SwrContext* _swr_context; - int _output_audio_frame_rate; }; #endif diff --git a/src/lib/black_decoder.cc b/src/lib/black_decoder.cc index 482cd2ce1..e8e1a3df2 100644 --- a/src/lib/black_decoder.cc +++ b/src/lib/black_decoder.cc @@ -18,9 +18,14 @@ */ #include "black_decoder.h" +#include "image.h" +#include "null_content.h" -BlackDecoder::BlackDecoder (shared_ptr<Film> f, shared_ptr<NullContent> c) - : VideoDecoder (f, c) +using boost::shared_ptr; + +BlackDecoder::BlackDecoder (shared_ptr<const Film> f, shared_ptr<NullContent> c) + : Decoder (f) + , VideoDecoder (f, c) { } @@ -29,7 +34,7 @@ void BlackDecoder::pass () { if (!_image) { - _image.reset (new SimpleImage (AV_PIX_FMT_RGB24, video_size ())); + _image.reset (new SimpleImage (AV_PIX_FMT_RGB24, video_size(), true)); _image->make_black (); video (_image, false, _next_video); } else { @@ -59,3 +64,9 @@ BlackDecoder::next () const { return _next_video; } + +void +BlackDecoder::seek (Time t) +{ + _next_video = t; +} diff --git a/src/lib/black_decoder.h b/src/lib/black_decoder.h index bb3e7711d..b4beb0fdd 100644 --- a/src/lib/black_decoder.h +++ b/src/lib/black_decoder.h @@ -19,6 +19,8 @@ #include "video_decoder.h" +class NullContent; + class BlackDecoder : public VideoDecoder { public: diff --git a/src/lib/content.cc b/src/lib/content.cc index 43d0ef958..395359fa7 100644 --- a/src/lib/content.cc +++ b/src/lib/content.cc @@ -29,20 +29,23 @@ using std::string; using boost::shared_ptr; using boost::lexical_cast; -Content::Content (Time s) - : _start (s) +Content::Content (shared_ptr<const Film> f, Time s) + : _film (f) + , _start (s) { } -Content::Content (boost::filesystem::path f) - : _file (f) +Content::Content (shared_ptr<const Film> f, boost::filesystem::path p) + : _film (f) + , _file (p) , _start (0) { } -Content::Content (shared_ptr<const cxml::Node> node) +Content::Content (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node) + : _film (f) { _file = node->string_child ("File"); _digest = node->string_child ("Digest"); @@ -51,6 +54,7 @@ Content::Content (shared_ptr<const cxml::Node> node) Content::Content (Content const & o) : boost::enable_shared_from_this<Content> (o) + , _film (o._film) , _file (o._file) , _digest (o._digest) , _start (o._start) @@ -68,7 +72,7 @@ Content::as_xml (xmlpp::Node* node) const } void -Content::examine (shared_ptr<Film>, shared_ptr<Job>) +Content::examine (shared_ptr<Job>) { string const d = md5_digest (_file); boost::mutex::scoped_lock lm (_mutex); diff --git a/src/lib/content.h b/src/lib/content.h index db1e56bc4..bcfbef7e3 100644 --- a/src/lib/content.h +++ b/src/lib/content.h @@ -39,17 +39,17 @@ class Film; class Content : public boost::enable_shared_from_this<Content> { public: - Content (Time); - Content (boost::filesystem::path); - Content (boost::shared_ptr<const cxml::Node>); + Content (boost::shared_ptr<const Film>, Time); + Content (boost::shared_ptr<const Film>, boost::filesystem::path); + Content (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>); Content (Content const &); - virtual void examine (boost::shared_ptr<Film>, boost::shared_ptr<Job>); + virtual void examine (boost::shared_ptr<Job>); virtual std::string summary () const = 0; virtual std::string information () const = 0; virtual void as_xml (xmlpp::Node *) const; virtual boost::shared_ptr<Content> clone () const = 0; - virtual Time length (boost::shared_ptr<const Film>) const = 0; + virtual Time length () const = 0; boost::filesystem::path file () const { boost::mutex::scoped_lock lm (_mutex); @@ -66,15 +66,16 @@ public: return _start; } - Time end (boost::shared_ptr<const Film> f) const { - return start() + length(f); + Time end () const { + return start() + length(); } boost::signals2::signal<void (boost::weak_ptr<Content>, int)> Changed; protected: void signal_changed (int); - + + boost::weak_ptr<const Film> _film; mutable boost::mutex _mutex; private: diff --git a/src/lib/examine_content_job.cc b/src/lib/examine_content_job.cc index 21ab4a71d..6d5f4faf9 100644 --- a/src/lib/examine_content_job.cc +++ b/src/lib/examine_content_job.cc @@ -47,7 +47,7 @@ ExamineContentJob::name () const void ExamineContentJob::run () { - _content->examine (_film, shared_from_this ()); + _content->examine (shared_from_this ()); set_progress (1); set_state (FINISHED_OK); } diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index 2a4283353..ad7af07d8 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -42,18 +42,18 @@ int const FFmpegContentProperty::SUBTITLE_STREAM = 101; int const FFmpegContentProperty::AUDIO_STREAMS = 102; int const FFmpegContentProperty::AUDIO_STREAM = 103; -FFmpegContent::FFmpegContent (boost::filesystem::path f) - : Content (f) - , VideoContent (f) - , AudioContent (f) +FFmpegContent::FFmpegContent (shared_ptr<const Film> f, boost::filesystem::path p) + : Content (f, p) + , VideoContent (f, p) + , AudioContent (f, p) { } -FFmpegContent::FFmpegContent (shared_ptr<const cxml::Node> node) - : Content (node) - , VideoContent (node) - , AudioContent (node) +FFmpegContent::FFmpegContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node) + : Content (f, node) + , VideoContent (f, node) + , AudioContent (f, node) { list<shared_ptr<cxml::Node> > c = node->node_children ("SubtitleStream"); for (list<shared_ptr<cxml::Node> >::const_iterator i = c.begin(); i != c.end(); ++i) { @@ -112,11 +112,14 @@ FFmpegContent::as_xml (xmlpp::Node* node) const } void -FFmpegContent::examine (shared_ptr<Film> film, shared_ptr<Job> job) +FFmpegContent::examine (shared_ptr<Job> job) { job->set_progress_unknown (); - Content::examine (film, job); + Content::examine (job); + + shared_ptr<const Film> film = _film.lock (); + assert (film); shared_ptr<FFmpegDecoder> decoder (new FFmpegDecoder (film, shared_from_this (), true, false, false)); @@ -233,8 +236,11 @@ FFmpegContent::content_audio_frame_rate () const } int -FFmpegContent::output_audio_frame_rate (shared_ptr<const Film> film) const +FFmpegContent::output_audio_frame_rate () const { + shared_ptr<const Film> film = _film.lock (); + assert (film); + /* Resample to a DCI-approved sample rate */ double t = dcp_audio_frame_rate (content_audio_frame_rate ()); @@ -308,8 +314,11 @@ FFmpegContent::clone () const } Time -FFmpegContent::length (shared_ptr<const Film> film) const +FFmpegContent::length () const { + shared_ptr<const Film> film = _film.lock (); + assert (film); + FrameRateConversion frc (video_frame_rate (), film->dcp_video_frame_rate ()); return video_length() * frc.factor() * TIME_HZ / film->dcp_video_frame_rate (); } diff --git a/src/lib/ffmpeg_content.h b/src/lib/ffmpeg_content.h index 9d842515e..d5b986996 100644 --- a/src/lib/ffmpeg_content.h +++ b/src/lib/ffmpeg_content.h @@ -80,26 +80,26 @@ public: class FFmpegContent : public VideoContent, public AudioContent { public: - FFmpegContent (boost::filesystem::path); - FFmpegContent (boost::shared_ptr<const cxml::Node>); + FFmpegContent (boost::shared_ptr<const Film>, boost::filesystem::path); + FFmpegContent (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>); FFmpegContent (FFmpegContent const &); boost::shared_ptr<FFmpegContent> shared_from_this () { return boost::dynamic_pointer_cast<FFmpegContent> (Content::shared_from_this ()); } - void examine (boost::shared_ptr<Film>, boost::shared_ptr<Job>); + void examine (boost::shared_ptr<Job>); std::string summary () const; std::string information () const; void as_xml (xmlpp::Node *) const; boost::shared_ptr<Content> clone () const; - Time length (boost::shared_ptr<const Film>) const; + Time length () const; /* AudioContent */ int audio_channels () const; ContentAudioFrame audio_length () const; int content_audio_frame_rate () const; - int output_audio_frame_rate (boost::shared_ptr<const Film>) const; + int output_audio_frame_rate () const; AudioMapping audio_mapping () const; std::vector<boost::shared_ptr<FFmpegSubtitleStream> > subtitle_streams () const { diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index f7bb97944..b45ba8585 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -473,6 +473,7 @@ void FFmpegDecoder::do_seek (Time t, bool backwards, bool accurate) { int64_t const vt = t / (av_q2d (_format_context->streams[_video_stream]->time_base) * TIME_HZ); + cout << "seek-> " << t << "\n"; av_seek_frame (_format_context, _video_stream, vt, backwards ? AVSEEK_FLAG_BACKWARD : 0); avcodec_flush_buffers (_video_codec_context); diff --git a/src/lib/film.cc b/src/lib/film.cc index b561c2d15..9103024ab 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -83,15 +83,12 @@ using libdcp::Size; int const Film::state_version = 4; -/** Construct a Film object in a given directory, reading any metadata - * file that exists in that directory. An exception will be thrown if - * must_exist is true and the specified directory does not exist. +/** Construct a Film object in a given directory. * * @param d Film directory. - * @param must_exist true to throw an exception if does not exist. */ -Film::Film (string d, bool must_exist) +Film::Film (string d) : _playlist (new Playlist) , _use_dci_name (true) , _dcp_content_type (Config::instance()->default_dcp_content_type ()) @@ -131,21 +128,6 @@ Film::Film (string d, bool must_exist) } set_directory (result.string ()); - - if (!boost::filesystem::exists (directory())) { - if (must_exist) { - throw OpenFileError (directory()); - } else { - boost::filesystem::create_directory (directory()); - } - } - - if (must_exist) { - read_metadata (); - } else { - write_metadata (); - } - _log.reset (new FileLog (file ("log"))); } @@ -388,6 +370,10 @@ Film::encoded_frames () const void Film::write_metadata () const { + if (!boost::filesystem::exists (directory())) { + boost::filesystem::create_directory (directory()); + } + boost::mutex::scoped_lock lm (_state_mutex); LocaleGuard lg; @@ -477,7 +463,7 @@ Film::read_metadata () _dcp_video_frame_rate = f.number_child<int> ("DCPVideoFrameRate"); _dci_date = boost::gregorian::from_undelimited_string (f.string_child ("DCIDate")); - _playlist->set_from_xml (f.node_child ("Playlist")); + _playlist->set_from_xml (shared_from_this(), f.node_child ("Playlist")); _dirty = false; } @@ -865,7 +851,7 @@ Film::remove_content (shared_ptr<Content> c) Time Film::length () const { - return _playlist->length (shared_from_this ()); + return _playlist->length (); } bool diff --git a/src/lib/film.h b/src/lib/film.h index 71a3b1c34..b8d4ee40e 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -56,7 +56,7 @@ class Player; class Film : public boost::enable_shared_from_this<Film> { public: - Film (std::string d, bool must_exist = true); + Film (std::string d); Film (Film const &); std::string info_dir () const; @@ -86,6 +86,7 @@ public: std::string file (std::string f) const; std::string dir (std::string d) const; + void read_metadata (); void write_metadata () const; std::string dci_name (bool if_created_now) const; @@ -259,7 +260,6 @@ private: void signal_changed (Property); void analyse_audio_finished (); std::string video_state_identifier () const; - void read_metadata (); void playlist_changed (); void playlist_content_changed (boost::weak_ptr<Content>, int); std::string filename_safe_name () const; diff --git a/src/lib/imagemagick_content.cc b/src/lib/imagemagick_content.cc index f9daf204e..ac04fb15b 100644 --- a/src/lib/imagemagick_content.cc +++ b/src/lib/imagemagick_content.cc @@ -29,16 +29,16 @@ using std::string; using std::stringstream; using boost::shared_ptr; -ImageMagickContent::ImageMagickContent (boost::filesystem::path f) - : Content (f) - , VideoContent (f) +ImageMagickContent::ImageMagickContent (shared_ptr<const Film> f, boost::filesystem::path p) + : Content (f, p) + , VideoContent (f, p) { } -ImageMagickContent::ImageMagickContent (shared_ptr<const cxml::Node> node) - : Content (node) - , VideoContent (node) +ImageMagickContent::ImageMagickContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node) + : Content (f, node) + , VideoContent (f, node) { } @@ -66,9 +66,13 @@ ImageMagickContent::as_xml (xmlpp::Node* node) const } void -ImageMagickContent::examine (shared_ptr<Film> film, shared_ptr<Job> job) +ImageMagickContent::examine (shared_ptr<Job> job) { - Content::examine (film, job); + Content::examine (job); + + shared_ptr<const Film> film = _film.lock (); + assert (film); + shared_ptr<ImageMagickDecoder> decoder (new ImageMagickDecoder (film, shared_from_this())); { @@ -100,8 +104,11 @@ ImageMagickContent::set_video_length (ContentVideoFrame len) } Time -ImageMagickContent::length (shared_ptr<const Film> film) const +ImageMagickContent::length () const { + shared_ptr<const Film> film = _film.lock (); + assert (film); + FrameRateConversion frc (24, film->dcp_video_frame_rate ()); return video_length() * frc.factor() * TIME_HZ / film->dcp_video_frame_rate (); } diff --git a/src/lib/imagemagick_content.h b/src/lib/imagemagick_content.h index b7f2cd2c3..e3e827892 100644 --- a/src/lib/imagemagick_content.h +++ b/src/lib/imagemagick_content.h @@ -27,18 +27,18 @@ namespace cxml { class ImageMagickContent : public VideoContent { public: - ImageMagickContent (boost::filesystem::path); - ImageMagickContent (boost::shared_ptr<const cxml::Node>); + ImageMagickContent (boost::shared_ptr<const Film>, boost::filesystem::path); + ImageMagickContent (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>); boost::shared_ptr<ImageMagickContent> shared_from_this () { return boost::dynamic_pointer_cast<ImageMagickContent> (Content::shared_from_this ()); }; - void examine (boost::shared_ptr<Film>, boost::shared_ptr<Job>); + void examine (boost::shared_ptr<Job>); std::string summary () const; void as_xml (xmlpp::Node *) const; boost::shared_ptr<Content> clone () const; - Time length (boost::shared_ptr<const Film>) const; + Time length () const; void set_video_length (ContentVideoFrame); diff --git a/src/lib/null_content.cc b/src/lib/null_content.cc index 0e275a393..0084972c2 100644 --- a/src/lib/null_content.cc +++ b/src/lib/null_content.cc @@ -17,12 +17,32 @@ */ -NullContent::NullContent (Time s, Time len, shared_ptr<const Film> f) - : Content (s) - , VideoContent (s, f->time_to_video_frames (len)) - , AudioContent (s) +#include "null_content.h" +#include "film.h" + +using boost::shared_ptr; + +NullContent::NullContent (shared_ptr<const Film> f, Time s, Time len) + : Content (f, s) + , VideoContent (f, s, f->time_to_video_frames (len)) + , AudioContent (f, s) , _audio_length (f->time_to_audio_frames (len)) - , _content_audio_frame_rate (f->dcp_audio_frame_rate ()) + , _length (len) +{ + +} + +int +NullContent::content_audio_frame_rate () const { + return output_audio_frame_rate (); +} + +int +NullContent::output_audio_frame_rate () const +{ + shared_ptr<const Film> film = _film.lock (); + assert (film); + return film->dcp_audio_frame_rate (); } diff --git a/src/lib/null_content.h b/src/lib/null_content.h index e68008782..d4a3b7371 100644 --- a/src/lib/null_content.h +++ b/src/lib/null_content.h @@ -19,12 +19,13 @@ #include <string> #include <boost/shared_ptr.hpp> -#include "content.h" +#include "video_content.h" +#include "audio_content.h" class NullContent : public VideoContent, public AudioContent { public: - NullContent (Time, Time, boost::shared_ptr<const Film>); + NullContent (boost::shared_ptr<const Film>, Time, Time); std::string summary () const { return ""; @@ -48,23 +49,19 @@ public: return _audio_length; } - int content_audio_frame_rate () const { - return _content_audio_frame_rate; - } + int content_audio_frame_rate () const; - int output_audio_frame_rate (boost::shared_ptr<const Film> f) const { - return f->dcp_audio_frame_rate (); - } + int output_audio_frame_rate () const; AudioMapping audio_mapping () const { return AudioMapping (); } - Time length (boost::shared_ptr<const Film>) const { + Time length () const { return _length; } private: ContentAudioFrame _audio_length; - ContentAudioFrame _content_audio_frame_rate; + Time _length; }; diff --git a/src/lib/player.cc b/src/lib/player.cc index b0a408c10..c87e27ba3 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -62,8 +62,6 @@ Player::Player (shared_ptr<const Film> f, shared_ptr<const Playlist> p) , _have_valid_pieces (false) , _position (0) , _audio_buffers (MAX_AUDIO_CHANNELS, 0) - , _last_video (0) - , _last_was_black (false) , _next_audio (0) { _playlist->Changed.connect (bind (&Player::playlist_changed, this)); @@ -104,7 +102,7 @@ Player::pass () shared_ptr<Piece> earliest; for (list<shared_ptr<Piece> >::iterator i = _pieces.begin(); i != _pieces.end(); ++i) { - if ((*i)->content->end(_film) < _position) { + if ((*i)->content->end() < _position) { continue; } @@ -124,7 +122,7 @@ Player::pass () /* Move position to earliest active next emission */ for (list<shared_ptr<Piece> >::iterator i = _pieces.begin(); i != _pieces.end(); ++i) { - if ((*i)->content->end(_film) < _position) { + if ((*i)->content->end() < _position) { continue; } @@ -200,6 +198,16 @@ Player::seek (Time t) return; } + for (list<shared_ptr<Piece> >::iterator i = _pieces.begin(); i != _pieces.end(); ++i) { + if ((*i)->content->end() < t) { + continue; + } + + (*i)->decoder->seek (t); + } + + _position = t; + /* XXX: don't seek audio because we don't need to... */ } @@ -290,18 +298,18 @@ Player::setup_pieces () if (dynamic_pointer_cast<VideoContent> ((*i)->content)) { Time const diff = video_pos - (*i)->content->start(); if (diff > 0) { - shared_ptr<NullContent> nc (new NullContent (video_pos, diff)); + shared_ptr<NullContent> nc (new NullContent (_film, video_pos, diff)); _pieces.push_back (shared_ptr<Piece> (new Piece (nc, shared_ptr<Decoder> (new BlackDecoder (_film, nc))))); } - video_pos = (*i)->content->start() + (*i)->content->length(_film); + video_pos = (*i)->content->end(); } else { Time const diff = audio_pos - (*i)->content->start(); if (diff > 0) { - shared_ptr<NullContent> nc (new NullContent (audio_pos, diff)); + shared_ptr<NullContent> nc (new NullContent (_film, audio_pos, diff)); _pieces.push_back (shared_ptr<Piece> (new Piece (nc, shared_ptr<Decoder> (new SilenceDecoder (_film, nc))))); } - audio_pos = (*i)->content->start() + (*i)->content->length(_film); + audio_pos = (*i)->content->end(); } } diff --git a/src/lib/player.h b/src/lib/player.h index c8f6eecb8..a5fe844f0 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -56,8 +56,8 @@ public: void seek_back (); void seek_forward (); - Time last_video () const { - return _last_video; + Time position () const { + return _position; } private: @@ -81,13 +81,7 @@ private: /** Time of the earliest thing not yet to have been emitted */ Time _position; - Time _last_black; - Time _last_silence; - - /* XXX: position and last_video? Need both? */ AudioBuffers _audio_buffers; - Time _last_video; - bool _last_was_black; Time _next_audio; }; diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index 36d6c6b52..7ab320558 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -122,7 +122,7 @@ Playlist::video_digest () const /** @param node <Playlist> node */ void -Playlist::set_from_xml (shared_ptr<const cxml::Node> node) +Playlist::set_from_xml (shared_ptr<const Film> film, shared_ptr<const cxml::Node> node) { list<shared_ptr<cxml::Node> > c = node->node_children ("Content"); for (list<shared_ptr<cxml::Node> >::iterator i = c.begin(); i != c.end(); ++i) { @@ -131,11 +131,11 @@ Playlist::set_from_xml (shared_ptr<const cxml::Node> node) boost::shared_ptr<Content> content; if (type == "FFmpeg") { - content.reset (new FFmpegContent (*i)); + content.reset (new FFmpegContent (film, *i)); } else if (type == "ImageMagick") { - content.reset (new ImageMagickContent (*i)); + content.reset (new ImageMagickContent (film, *i)); } else if (type == "Sndfile") { - content.reset (new SndfileContent (*i)); + content.reset (new SndfileContent (film, *i)); } _content.push_back (content); @@ -261,11 +261,11 @@ Playlist::best_dcp_frame_rate () const } Time -Playlist::length (shared_ptr<const Film> film) const +Playlist::length () const { Time len = 0; for (ContentList::const_iterator i = _content.begin(); i != _content.end(); ++i) { - len = max (len, (*i)->end (film)); + len = max (len, (*i)->end ()); } return len; diff --git a/src/lib/playlist.h b/src/lib/playlist.h index e8cac0247..aff6017fa 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -61,7 +61,7 @@ public: ~Playlist (); void as_xml (xmlpp::Node *); - void set_from_xml (boost::shared_ptr<const cxml::Node>); + void set_from_xml (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>); void add (boost::shared_ptr<Content>); void remove (boost::shared_ptr<Content>); @@ -83,7 +83,7 @@ public: void set_loop (int l); - Time length (boost::shared_ptr<const Film>) const; + Time length () const; int best_dcp_frame_rate () const; mutable boost::signals2::signal<void ()> Changed; diff --git a/src/lib/silence_decoder.cc b/src/lib/silence_decoder.cc new file mode 100644 index 000000000..9eee5bb10 --- /dev/null +++ b/src/lib/silence_decoder.cc @@ -0,0 +1,56 @@ +/* + Copyright (C) 2013 Carl Hetherington <cth@carlh.net> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "silence_decoder.h" +#include "null_content.h" +#include "audio_buffers.h" + +using std::min; +using boost::shared_ptr; + +SilenceDecoder::SilenceDecoder (shared_ptr<const Film> f, shared_ptr<NullContent> c) + : Decoder (f) + , AudioDecoder (f, c) +{ + +} + +void +SilenceDecoder::pass () +{ + shared_ptr<const Film> film = _film.lock (); + assert (film); + + Time const this_time = min (_audio_content->length() - _next_audio, TIME_HZ / 2); + shared_ptr<AudioBuffers> data (new AudioBuffers (MAX_AUDIO_CHANNELS, film->time_to_audio_frames (this_time))); + data->make_silent (); + audio (data, _next_audio); +} + +void +SilenceDecoder::seek (Time t) +{ + _next_audio = t; +} + +Time +SilenceDecoder::next () const +{ + return _next_audio; +} diff --git a/src/lib/silence_decoder.h b/src/lib/silence_decoder.h index eec3c8ed9..e2a004d61 100644 --- a/src/lib/silence_decoder.h +++ b/src/lib/silence_decoder.h @@ -17,6 +17,12 @@ */ +#include <boost/shared_ptr.hpp> +#include "audio_decoder.h" + +class Film; +class NullContent; + class SilenceDecoder : public AudioDecoder { public: diff --git a/src/lib/sndfile_content.cc b/src/lib/sndfile_content.cc index 758ae942d..0f895c95e 100644 --- a/src/lib/sndfile_content.cc +++ b/src/lib/sndfile_content.cc @@ -33,9 +33,9 @@ using std::cout; using boost::shared_ptr; using boost::lexical_cast; -SndfileContent::SndfileContent (boost::filesystem::path f) - : Content (f) - , AudioContent (f) +SndfileContent::SndfileContent (shared_ptr<const Film> f, boost::filesystem::path p) + : Content (f, p) + , AudioContent (f, p) , _audio_channels (0) , _audio_length (0) , _audio_frame_rate (0) @@ -43,9 +43,9 @@ SndfileContent::SndfileContent (boost::filesystem::path f) } -SndfileContent::SndfileContent (shared_ptr<const cxml::Node> node) - : Content (node) - , AudioContent (node) +SndfileContent::SndfileContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node) + : Content (f, node) + , AudioContent (f, node) { _audio_channels = node->number_child<int> ("AudioChannels"); _audio_length = node->number_child<ContentAudioFrame> ("AudioLength"); @@ -93,10 +93,13 @@ SndfileContent::clone () const } void -SndfileContent::examine (shared_ptr<Film> film, shared_ptr<Job> job) +SndfileContent::examine (shared_ptr<Job> job) { job->set_progress_unknown (); - Content::examine (film, job); + Content::examine (job); + + shared_ptr<const Film> film = _film.lock (); + assert (film); SndfileDecoder dec (film, shared_from_this()); @@ -122,15 +125,20 @@ SndfileContent::as_xml (xmlpp::Node* node) const node->add_child("AudioFrameRate")->add_child_text (lexical_cast<string> (_audio_frame_rate)); } -int -SndfileContent::output_audio_frame_rate (shared_ptr<const Film>) const +Time +SndfileContent::length () const { - /* Resample to a DCI-approved sample rate */ - return dcp_audio_frame_rate (content_audio_frame_rate ()); + shared_ptr<const Film> film = _film.lock (); + assert (film); + + return film->audio_frames_to_time (audio_length ()); } -Time -SndfileContent::length (shared_ptr<const Film> film) const +int +SndfileContent::output_audio_frame_rate () const { - return film->audio_frames_to_time (audio_length ()); + shared_ptr<const Film> film = _film.lock (); + assert (film); + + return film->dcp_audio_frame_rate (); } diff --git a/src/lib/sndfile_content.h b/src/lib/sndfile_content.h index bb7fa5f50..17423b8ed 100644 --- a/src/lib/sndfile_content.h +++ b/src/lib/sndfile_content.h @@ -31,19 +31,19 @@ namespace cxml { class SndfileContent : public AudioContent { public: - SndfileContent (boost::filesystem::path); - SndfileContent (boost::shared_ptr<const cxml::Node>); + SndfileContent (boost::shared_ptr<const Film>, boost::filesystem::path); + SndfileContent (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>); boost::shared_ptr<SndfileContent> shared_from_this () { return boost::dynamic_pointer_cast<SndfileContent> (Content::shared_from_this ()); } - void examine (boost::shared_ptr<Film>, boost::shared_ptr<Job>); + void examine (boost::shared_ptr<Job>); std::string summary () const; std::string information () const; void as_xml (xmlpp::Node *) const; boost::shared_ptr<Content> clone () const; - Time length (boost::shared_ptr<const Film>) const; + Time length () const; /* AudioContent */ int audio_channels () const { @@ -61,7 +61,7 @@ public: return _audio_frame_rate; } - int output_audio_frame_rate (boost::shared_ptr<const Film>) const; + int output_audio_frame_rate () const; AudioMapping audio_mapping () const { boost::mutex::scoped_lock lm (_mutex); diff --git a/src/lib/types.h b/src/lib/types.h index 4b8b8072d..8f2fe2c71 100644 --- a/src/lib/types.h +++ b/src/lib/types.h @@ -31,7 +31,7 @@ typedef int64_t ContentAudioFrame; typedef int ContentVideoFrame; typedef int64_t Time; #define TIME_MAX INT64_MAX -#define TIME_HZ 96000 +#define TIME_HZ ((Time) 96000) typedef int64_t OutputAudioFrame; typedef int OutputVideoFrame; diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc index e07773048..2e413678f 100644 --- a/src/lib/video_content.cc +++ b/src/lib/video_content.cc @@ -34,22 +34,22 @@ using std::setprecision; using boost::shared_ptr; using boost::lexical_cast; -VideoContent::VideoContent (Time s, ContentVideoFrame len) - : Content (s) +VideoContent::VideoContent (shared_ptr<const Film> f, Time s, ContentVideoFrame len) + : Content (f, s) , _video_length (len) { } -VideoContent::VideoContent (boost::filesystem::path f) - : Content (f) +VideoContent::VideoContent (shared_ptr<const Film> f, boost::filesystem::path p) + : Content (f, p) , _video_length (0) { } -VideoContent::VideoContent (shared_ptr<const cxml::Node> node) - : Content (node) +VideoContent::VideoContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node) + : Content (f, node) { _video_length = node->number_child<ContentVideoFrame> ("VideoLength"); _video_size.width = node->number_child<int> ("VideoWidth"); diff --git a/src/lib/video_content.h b/src/lib/video_content.h index 8b0461e3f..7dde927af 100644 --- a/src/lib/video_content.h +++ b/src/lib/video_content.h @@ -37,9 +37,9 @@ public: class VideoContent : public virtual Content { public: - VideoContent (Time); - VideoContent (boost::filesystem::path); - VideoContent (boost::shared_ptr<const cxml::Node>); + VideoContent (boost::shared_ptr<const Film>, Time, ContentVideoFrame); + VideoContent (boost::shared_ptr<const Film>, boost::filesystem::path); + VideoContent (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>); VideoContent (VideoContent const &); void as_xml (xmlpp::Node *) const; diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h index 0f1432907..b31766b50 100644 --- a/src/lib/video_decoder.h +++ b/src/lib/video_decoder.h @@ -46,9 +46,9 @@ protected: void subtitle (boost::shared_ptr<TimedSubtitle>); Time _next_video; + boost::shared_ptr<const VideoContent> _video_content; private: - boost::shared_ptr<const VideoContent> _video_content; boost::shared_ptr<TimedSubtitle> _timed_subtitle; FrameRateConversion _frame_rate_conversion; bool _odd; diff --git a/src/lib/wscript b/src/lib/wscript index 1da245484..e7349a9c4 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -11,6 +11,7 @@ sources = """ audio_decoder.cc audio_mapping.cc audio_source.cc + black_decoder.cc config.cc combiner.cc container.cc @@ -38,11 +39,13 @@ sources = """ job_manager.cc log.cc lut.cc + null_content.cc player.cc playlist.cc scp_dcp_job.cc scaler.cc server.cc + silence_decoder.cc sndfile_content.cc sndfile_decoder.cc sound_processor.cc |
