summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-04-06 12:26:12 +0100
committerCarl Hetherington <cth@carlh.net>2013-04-06 12:26:12 +0100
commit1bff0990433ab0ce588acaef7c589fa623bd998b (patch)
tree65cba435e949deb6359bbf75866b52684116df06 /src/lib
parent3429cf48ff2ce056413588be4151be82c8114861 (diff)
Add interface to set up still image lengths.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/content.cc9
-rw-r--r--src/lib/content.h7
-rw-r--r--src/lib/ffmpeg_content.cc15
-rw-r--r--src/lib/ffmpeg_content.h6
-rw-r--r--src/lib/film.cc26
-rw-r--r--src/lib/film.h7
-rw-r--r--src/lib/imagemagick_content.cc15
-rw-r--r--src/lib/imagemagick_content.h8
-rw-r--r--src/lib/player.cc40
-rw-r--r--src/lib/player.h4
-rw-r--r--src/lib/playlist.cc16
-rw-r--r--src/lib/playlist.h7
-rw-r--r--src/lib/sndfile_content.h4
-rw-r--r--src/lib/video_content.cc8
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 (