diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-04-06 12:26:12 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-04-06 12:26:12 +0100 |
| commit | 1bff0990433ab0ce588acaef7c589fa623bd998b (patch) | |
| tree | 65cba435e949deb6359bbf75866b52684116df06 /src/lib | |
| parent | 3429cf48ff2ce056413588be4151be82c8114861 (diff) | |
Add interface to set up still image lengths.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/content.cc | 9 | ||||
| -rw-r--r-- | src/lib/content.h | 7 | ||||
| -rw-r--r-- | src/lib/ffmpeg_content.cc | 15 | ||||
| -rw-r--r-- | src/lib/ffmpeg_content.h | 6 | ||||
| -rw-r--r-- | src/lib/film.cc | 26 | ||||
| -rw-r--r-- | src/lib/film.h | 7 | ||||
| -rw-r--r-- | src/lib/imagemagick_content.cc | 15 | ||||
| -rw-r--r-- | src/lib/imagemagick_content.h | 8 | ||||
| -rw-r--r-- | src/lib/player.cc | 40 | ||||
| -rw-r--r-- | src/lib/player.h | 4 | ||||
| -rw-r--r-- | src/lib/playlist.cc | 16 | ||||
| -rw-r--r-- | src/lib/playlist.h | 7 | ||||
| -rw-r--r-- | src/lib/sndfile_content.h | 4 | ||||
| -rw-r--r-- | src/lib/video_content.cc | 8 |
14 files changed, 128 insertions, 44 deletions
diff --git a/src/lib/content.cc b/src/lib/content.cc index 786b5fb09..9c3bcd39d 100644 --- a/src/lib/content.cc +++ b/src/lib/content.cc @@ -39,7 +39,8 @@ Content::Content (shared_ptr<const cxml::Node> node) } Content::Content (Content const & o) - : _file (o._file) + : boost::enable_shared_from_this<Content> (o) + , _file (o._file) , _digest (o._digest) { @@ -60,3 +61,9 @@ Content::examine (shared_ptr<Film>, shared_ptr<Job>, bool) boost::mutex::scoped_lock lm (_mutex); _digest = d; } + +void +Content::signal_changed (int p) +{ + Changed (shared_from_this (), p); +} diff --git a/src/lib/content.h b/src/lib/content.h index 11c7438a6..fc2672c95 100644 --- a/src/lib/content.h +++ b/src/lib/content.h @@ -23,6 +23,7 @@ #include <boost/filesystem.hpp> #include <boost/signals2.hpp> #include <boost/thread/mutex.hpp> +#include <boost/enable_shared_from_this.hpp> #include <libxml++/libxml++.h> namespace cxml { @@ -32,7 +33,7 @@ namespace cxml { class Job; class Film; -class Content +class Content : public boost::enable_shared_from_this<Content> { public: Content (boost::filesystem::path); @@ -50,9 +51,11 @@ public: return _file; } - boost::signals2::signal<void (int)> Changed; + boost::signals2::signal<void (boost::weak_ptr<Content>, int)> Changed; protected: + void signal_changed (int); + mutable boost::mutex _mutex; private: diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index 7834cb76e..cc95105e5 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -73,7 +73,6 @@ FFmpegContent::FFmpegContent (FFmpegContent const & o) : Content (o) , VideoContent (o) , AudioContent (o) - , boost::enable_shared_from_this<FFmpegContent> (o) , _subtitle_streams (o._subtitle_streams) , _subtitle_stream (o._subtitle_stream) , _audio_streams (o._audio_streams) @@ -148,11 +147,11 @@ FFmpegContent::examine (shared_ptr<Film> film, shared_ptr<Job> job, bool quick) take_from_video_decoder (decoder); - Changed (VideoContentProperty::VIDEO_LENGTH); - Changed (FFmpegContentProperty::SUBTITLE_STREAMS); - Changed (FFmpegContentProperty::SUBTITLE_STREAM); - Changed (FFmpegContentProperty::AUDIO_STREAMS); - Changed (FFmpegContentProperty::AUDIO_STREAM); + signal_changed (VideoContentProperty::VIDEO_LENGTH); + signal_changed (FFmpegContentProperty::SUBTITLE_STREAMS); + signal_changed (FFmpegContentProperty::SUBTITLE_STREAM); + signal_changed (FFmpegContentProperty::AUDIO_STREAMS); + signal_changed (FFmpegContentProperty::AUDIO_STREAM); } string @@ -184,7 +183,7 @@ FFmpegContent::set_subtitle_stream (FFmpegSubtitleStream s) _subtitle_stream = s; } - Changed (FFmpegContentProperty::SUBTITLE_STREAM); + signal_changed (FFmpegContentProperty::SUBTITLE_STREAM); } void @@ -195,7 +194,7 @@ FFmpegContent::set_audio_stream (FFmpegAudioStream s) _audio_stream = s; } - Changed (FFmpegContentProperty::AUDIO_STREAM); + signal_changed (FFmpegContentProperty::AUDIO_STREAM); } ContentAudioFrame diff --git a/src/lib/ffmpeg_content.h b/src/lib/ffmpeg_content.h index 3d69a2f99..cc603e680 100644 --- a/src/lib/ffmpeg_content.h +++ b/src/lib/ffmpeg_content.h @@ -77,12 +77,16 @@ public: static int const AUDIO_STREAM; }; -class FFmpegContent : public VideoContent, public AudioContent, public boost::enable_shared_from_this<FFmpegContent> +class FFmpegContent : public VideoContent, public AudioContent { public: FFmpegContent (boost::filesystem::path); FFmpegContent (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>, bool); std::string summary () const; diff --git a/src/lib/film.cc b/src/lib/film.cc index 976f65313..69d2a28e2 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -110,6 +110,8 @@ Film::Film (string d, bool must_exist) , _dirty (false) { set_dci_date_today (); + + _playlist->ContentChanged.connect (bind (&Film::content_changed, this, _1, _2)); /* Make state.directory a complete path without ..s (where possible) (Code swiped from Adam Bowen on stackoverflow) @@ -179,6 +181,8 @@ Film::Film (Film const & o) _content.push_back ((*i)->clone ()); } + _playlist->ContentChanged.connect (bind (&Film::content_changed, this, _1, _2)); + _playlist->setup (_content); } @@ -485,14 +489,17 @@ Film::read_metadata () for (list<shared_ptr<cxml::Node> >::iterator i = c.begin(); i != c.end(); ++i) { string const type = (*i)->string_child ("Type"); + boost::shared_ptr<Content> c; if (type == "FFmpeg") { - _content.push_back (shared_ptr<Content> (new FFmpegContent (*i))); + c.reset (new FFmpegContent (*i)); } else if (type == "ImageMagick") { - _content.push_back (shared_ptr<Content> (new ImageMagickContent (*i))); + c.reset (new ImageMagickContent (*i)); } else if (type == "Sndfile") { - _content.push_back (shared_ptr<Content> (new SndfileContent (*i))); + c.reset (new SndfileContent (*i)); } + + _content.push_back (c); } _dirty = false; @@ -1037,7 +1044,6 @@ Film::add_content (shared_ptr<Content> c) { boost::mutex::scoped_lock lm (_state_mutex); _content.push_back (c); - _content_connections.push_back (c->Changed.connect (bind (&Film::content_changed, this, _1))); } signal_changed (CONTENT); @@ -1054,14 +1060,6 @@ Film::remove_content (shared_ptr<Content> c) if (i != _content.end ()) { _content.erase (i); } - - for (list<boost::signals2::connection>::iterator i = _content_connections.begin(); i != _content_connections.end(); ++i) { - i->disconnect (); - } - - for (ContentList::iterator i = _content.begin(); i != _content.end(); ++i) { - _content_connections.push_back (c->Changed.connect (bind (&Film::content_changed, this, _1))); - } } signal_changed (CONTENT); @@ -1238,13 +1236,13 @@ Film::set_ffmpeg_audio_stream (FFmpegAudioStream s) } void -Film::content_changed (int p) +Film::content_changed (boost::weak_ptr<Content> c, int p) { if (p == VideoContentProperty::VIDEO_FRAME_RATE) { set_dcp_frame_rate (best_dcp_frame_rate (video_frame_rate ())); } if (ui_signaller) { - ui_signaller->emit (boost::bind (boost::ref (ContentChanged), p)); + ui_signaller->emit (boost::bind (boost::ref (ContentChanged), c, p)); } } diff --git a/src/lib/film.h b/src/lib/film.h index 091ac4f97..9c5f561e6 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -119,7 +119,7 @@ public: void set_ffmpeg_subtitle_stream (FFmpegSubtitleStream); void set_ffmpeg_audio_stream (FFmpegAudioStream); - + /** Identifiers for the parts of our state; used for signalling changes. */ @@ -299,7 +299,7 @@ public: mutable boost::signals2::signal<void (Property)> Changed; /** Emitted when some property of our content has changed */ - mutable boost::signals2::signal<void (int)> ContentChanged; + mutable boost::signals2::signal<void (boost::weak_ptr<Content>, int)> ContentChanged; boost::signals2::signal<void ()> AudioAnalysisSucceeded; @@ -312,7 +312,7 @@ private: void analyse_audio_finished (); std::string video_state_identifier () const; void read_metadata (); - void content_changed (int); + void content_changed (boost::weak_ptr<Content>, int); boost::shared_ptr<FFmpegContent> ffmpeg () const; /** Log to write to */ @@ -334,7 +334,6 @@ private: bool _use_dci_name; bool _trust_content_headers; ContentList _content; - std::list<boost::signals2::connection> _content_connections; /** The type of content that this Film represents (feature, trailer etc.) */ DCPContentType const * _dcp_content_type; /** The format to present this Film in (flat, scope, etc.) */ diff --git a/src/lib/imagemagick_content.cc b/src/lib/imagemagick_content.cc index f7c76a34d..912c180a8 100644 --- a/src/lib/imagemagick_content.cc +++ b/src/lib/imagemagick_content.cc @@ -72,13 +72,13 @@ ImageMagickContent::examine (shared_ptr<Film> film, shared_ptr<Job> job, bool qu { boost::mutex::scoped_lock lm (_mutex); - /* XXX */ + /* Initial length */ _video_length = 10 * 24; } take_from_video_decoder (decoder); - Changed (VideoContentProperty::VIDEO_LENGTH); + signal_changed (VideoContentProperty::VIDEO_LENGTH); } shared_ptr<Content> @@ -86,3 +86,14 @@ ImageMagickContent::clone () const { return shared_ptr<Content> (new ImageMagickContent (*this)); } + +void +ImageMagickContent::set_video_length (ContentVideoFrame len) +{ + { + boost::mutex::scoped_lock lm (_mutex); + _video_length = len; + } + + signal_changed (VideoContentProperty::VIDEO_LENGTH); +} diff --git a/src/lib/imagemagick_content.h b/src/lib/imagemagick_content.h index 2ca58f255..b1e7f9495 100644 --- a/src/lib/imagemagick_content.h +++ b/src/lib/imagemagick_content.h @@ -24,16 +24,22 @@ namespace cxml { class Node; } -class ImageMagickContent : public VideoContent, public boost::enable_shared_from_this<ImageMagickContent> +class ImageMagickContent : public VideoContent { public: ImageMagickContent (boost::filesystem::path); ImageMagickContent (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>, bool); std::string summary () const; void as_xml (xmlpp::Node *) const; boost::shared_ptr<Content> clone () const; + void set_video_length (ContentVideoFrame); + static bool valid_file (boost::filesystem::path); }; diff --git a/src/lib/player.cc b/src/lib/player.cc index 6e2e7ed14..60917ba09 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -27,6 +27,8 @@ using std::list; using boost::shared_ptr; +using boost::weak_ptr; +using boost::dynamic_pointer_cast; Player::Player (shared_ptr<const Film> f, shared_ptr<const Playlist> p) : _film (f) @@ -34,11 +36,12 @@ Player::Player (shared_ptr<const Film> f, shared_ptr<const Playlist> p) , _video (true) , _audio (true) , _subtitles (true) - , _have_setup_decoders (false) + , _have_valid_decoders (false) , _ffmpeg_decoder_done (false) , _video_sync (true) { - + _playlist->Changed.connect (bind (&Player::playlist_changed, this)); + _playlist->ContentChanged.connect (bind (&Player::content_changed, this, _1, _2)); } void @@ -62,9 +65,9 @@ Player::disable_subtitles () bool Player::pass () { - if (!_have_setup_decoders) { + if (!_have_valid_decoders) { setup_decoders (); - _have_setup_decoders = true; + _have_valid_decoders = true; } bool done = true; @@ -138,9 +141,9 @@ Player::process_audio (shared_ptr<AudioBuffers> b) bool Player::seek (double t) { - if (!_have_setup_decoders) { + if (!_have_valid_decoders) { setup_decoders (); - _have_setup_decoders = true; + _have_valid_decoders = true; } bool r = false; @@ -183,9 +186,9 @@ Player::seek (double t) bool Player::seek_to_last () { - if (!_have_setup_decoders) { + if (!_have_valid_decoders) { setup_decoders (); - _have_setup_decoders = true; + _have_valid_decoders = true; } bool r = false; @@ -278,3 +281,24 @@ Player::last_video_time () const return 0; } + +void +Player::content_changed (weak_ptr<Content> w, int p) +{ + shared_ptr<Content> c = w.lock (); + if (!c) { + return; + } + + if (p == VideoContentProperty::VIDEO_LENGTH) { + if (dynamic_pointer_cast<FFmpegContent> (c)) { + _have_valid_decoders = false; + } + } +} + +void +Player::playlist_changed () +{ + _have_valid_decoders = false; +} diff --git a/src/lib/player.h b/src/lib/player.h index bc728d8f2..79203692e 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -56,6 +56,8 @@ 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 (); + void playlist_changed (); + void content_changed (boost::weak_ptr<Content>, int); boost::shared_ptr<const Film> _film; boost::shared_ptr<const Playlist> _playlist; @@ -64,7 +66,7 @@ private: bool _audio; bool _subtitles; - bool _have_setup_decoders; + bool _have_valid_decoders; boost::shared_ptr<FFmpegDecoder> _ffmpeg_decoder; bool _ffmpeg_decoder_done; std::list<boost::shared_ptr<ImageMagickDecoder> > _imagemagick_decoders; diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index 0a4803f6e..e0220ef6f 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -31,6 +31,7 @@ using std::list; using std::cout; using std::vector; using boost::shared_ptr; +using boost::weak_ptr; using boost::dynamic_pointer_cast; Playlist::Playlist () @@ -50,6 +51,12 @@ Playlist::setup (ContentList content) _imagemagick.clear (); _sndfile.clear (); + for (list<boost::signals2::connection>::iterator i = _content_connections.begin(); i != _content_connections.end(); ++i) { + i->disconnect (); + } + + _content_connections.clear (); + for (ContentList::const_iterator i = content.begin(); i != content.end(); ++i) { shared_ptr<FFmpegContent> fc = dynamic_pointer_cast<FFmpegContent> (*i); if (fc) { @@ -74,7 +81,11 @@ Playlist::setup (ContentList content) _sndfile.push_back (sc); _audio_from = AUDIO_SNDFILE; } + + _content_connections.push_back ((*i)->Changed.connect (bind (&Playlist::content_changed, this, _1, _2))); } + + Changed (); } ContentAudioFrame @@ -208,3 +219,8 @@ Playlist::has_audio () const return _audio_from != AUDIO_NONE; } +void +Playlist::content_changed (weak_ptr<Content> c, int p) +{ + ContentChanged (c, p); +} diff --git a/src/lib/playlist.h b/src/lib/playlist.h index 29a52d433..1a24a0227 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -84,12 +84,19 @@ public: std::list<boost::shared_ptr<const SndfileContent> > sndfile () const { return _sndfile; } + + mutable boost::signals2::signal<void ()> Changed; + mutable boost::signals2::signal<void (boost::weak_ptr<Content>, int)> ContentChanged; private: + void content_changed (boost::weak_ptr<Content>, int); + 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; + + std::list<boost::signals2::connection> _content_connections; }; diff --git a/src/lib/sndfile_content.h b/src/lib/sndfile_content.h index 90845ba08..b696b57a5 100644 --- a/src/lib/sndfile_content.h +++ b/src/lib/sndfile_content.h @@ -28,6 +28,10 @@ class SndfileContent : public AudioContent public: SndfileContent (boost::filesystem::path); SndfileContent (boost::shared_ptr<const cxml::Node>); + + boost::shared_ptr<SndfileContent> shared_from_this () { + return boost::dynamic_pointer_cast<SndfileContent> (Content::shared_from_this ()); + } std::string summary () const; std::string information () const; diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc index 14897c570..8176c5c41 100644 --- a/src/lib/video_content.cc +++ b/src/lib/video_content.cc @@ -81,14 +81,18 @@ VideoContent::take_from_video_decoder (shared_ptr<VideoDecoder> d) _video_frame_rate = vfr; } - Changed (VideoContentProperty::VIDEO_SIZE); - Changed (VideoContentProperty::VIDEO_FRAME_RATE); + signal_changed (VideoContentProperty::VIDEO_SIZE); + signal_changed (VideoContentProperty::VIDEO_FRAME_RATE); } string VideoContent::information () const { + if (video_size().width == 0 || video_size().height == 0) { + return ""; + } + stringstream s; s << String::compose ( |
