summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-04-02 21:20:35 +0100
committerCarl Hetherington <cth@carlh.net>2013-04-02 21:20:35 +0100
commit956da4b106e14c49b179176acf6484c479c21094 (patch)
tree0fee47183fd58dcf90ef059171c2e73d9916bb89 /src
parent20cd8bdecb9667f7d838dbb7210f3e1a4765c662 (diff)
Various fixes.
Diffstat (limited to 'src')
-rw-r--r--src/lib/audio_content.cc6
-rw-r--r--src/lib/audio_content.h1
-rw-r--r--src/lib/content.cc7
-rw-r--r--src/lib/content.h2
-rw-r--r--src/lib/ffmpeg_content.cc19
-rw-r--r--src/lib/ffmpeg_content.h2
-rw-r--r--src/lib/film.cc19
-rw-r--r--src/lib/film.h3
-rw-r--r--src/lib/imagemagick_content.cc8
-rw-r--r--src/lib/imagemagick_content.h1
-rw-r--r--src/lib/imagemagick_decoder.cc8
-rw-r--r--src/lib/playlist.cc6
-rw-r--r--src/lib/sndfile_content.cc6
-rw-r--r--src/lib/sndfile_content.h1
-rw-r--r--src/lib/video_content.cc9
-rw-r--r--src/lib/video_content.h1
-rw-r--r--src/lib/video_decoder.cc6
-rw-r--r--src/lib/video_decoder.h1
-rw-r--r--src/wx/film_viewer.cc37
-rw-r--r--src/wx/film_viewer.h2
20 files changed, 128 insertions, 17 deletions
diff --git a/src/lib/audio_content.cc b/src/lib/audio_content.cc
index 74b8ea2ce..b5419a058 100644
--- a/src/lib/audio_content.cc
+++ b/src/lib/audio_content.cc
@@ -14,3 +14,9 @@ AudioContent::AudioContent (shared_ptr<const cxml::Node> node)
{
}
+
+AudioContent::AudioContent (AudioContent const & o)
+ : Content (o)
+{
+
+}
diff --git a/src/lib/audio_content.h b/src/lib/audio_content.h
index f3dd81efb..24391b01c 100644
--- a/src/lib/audio_content.h
+++ b/src/lib/audio_content.h
@@ -13,6 +13,7 @@ class AudioContent : public virtual Content
public:
AudioContent (boost::filesystem::path);
AudioContent (boost::shared_ptr<const cxml::Node>);
+ AudioContent (AudioContent const &);
virtual int audio_channels () const = 0;
virtual ContentAudioFrame audio_length () const = 0;
diff --git a/src/lib/content.cc b/src/lib/content.cc
index 977f2e2a7..0c21822cb 100644
--- a/src/lib/content.cc
+++ b/src/lib/content.cc
@@ -19,6 +19,13 @@ Content::Content (shared_ptr<const cxml::Node> node)
_digest = node->string_child ("Digest");
}
+Content::Content (Content const & o)
+ : _file (o._file)
+ , _digest (o._digest)
+{
+
+}
+
void
Content::as_xml (xmlpp::Node* node) const
{
diff --git a/src/lib/content.h b/src/lib/content.h
index 87ef46581..3f348ca91 100644
--- a/src/lib/content.h
+++ b/src/lib/content.h
@@ -37,10 +37,12 @@ class Content
public:
Content (boost::filesystem::path);
Content (boost::shared_ptr<const cxml::Node>);
+ Content (Content const &);
virtual void examine (boost::shared_ptr<Film>, boost::shared_ptr<Job>, bool);
virtual std::string summary () const = 0;
virtual void as_xml (xmlpp::Node *) const;
+ virtual boost::shared_ptr<Content> clone () const = 0;
boost::filesystem::path file () const {
boost::mutex::scoped_lock lm (_mutex);
diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc
index 50a69ae7b..5bff1cecc 100644
--- a/src/lib/ffmpeg_content.cc
+++ b/src/lib/ffmpeg_content.cc
@@ -68,6 +68,19 @@ FFmpegContent::FFmpegContent (shared_ptr<const cxml::Node> node)
}
}
+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)
+ , _audio_stream (o._audio_stream)
+{
+
+}
+
void
FFmpegContent::as_xml (xmlpp::Node* node) const
{
@@ -256,3 +269,9 @@ FFmpegSubtitleStream::as_xml (xmlpp::Node* root) const
root->add_child("Name")->add_child_text (name);
root->add_child("Id")->add_child_text (lexical_cast<string> (id));
}
+
+shared_ptr<Content>
+FFmpegContent::clone () const
+{
+ return shared_ptr<Content> (new FFmpegContent (*this));
+}
diff --git a/src/lib/ffmpeg_content.h b/src/lib/ffmpeg_content.h
index c56dc0a61..598ebf484 100644
--- a/src/lib/ffmpeg_content.h
+++ b/src/lib/ffmpeg_content.h
@@ -82,10 +82,12 @@ class FFmpegContent : public VideoContent, public AudioContent, public boost::en
public:
FFmpegContent (boost::filesystem::path);
FFmpegContent (boost::shared_ptr<const cxml::Node>);
+ FFmpegContent (FFmpegContent const &);
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;
/* AudioContent */
int audio_channels () const;
diff --git a/src/lib/film.cc b/src/lib/film.cc
index d82dce297..20a7ee49b 100644
--- a/src/lib/film.cc
+++ b/src/lib/film.cc
@@ -177,7 +177,7 @@ Film::Film (Film const & o)
, _dci_date (o._dci_date)
, _dirty (o._dirty)
{
- for (ContentList::iterator i = o._content.begin(); i != o._content.end(); ++i) {
+ for (ContentList::const_iterator i = o._content.begin(); i != o._content.end(); ++i) {
_content.push_back ((*i)->clone ());
}
@@ -328,7 +328,6 @@ void
Film::examine_content (shared_ptr<Content> c)
{
shared_ptr<Job> j (new ExamineContentJob (shared_from_this(), c, trust_content_headers ()));
- j->Finished.connect (bind (&Film::examine_content_finished, this));
JobManager::instance()->add (j);
}
@@ -1029,6 +1028,7 @@ 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)));
_playlist->setup (_content);
}
@@ -1046,6 +1046,14 @@ 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);
@@ -1141,3 +1149,10 @@ Film::video_length () const
return _playlist->video_length ();
}
+void
+Film::content_changed (int p)
+{
+ if (ui_signaller) {
+ ui_signaller->emit (boost::bind (boost::ref (ContentChanged), p));
+ }
+}
diff --git a/src/lib/film.h b/src/lib/film.h
index e1084e1ca..f0a85fbf3 100644
--- a/src/lib/film.h
+++ b/src/lib/film.h
@@ -134,7 +134,6 @@ public:
AB,
AUDIO_GAIN,
AUDIO_DELAY,
- STILL_DURATION,
SUBTITLE_STREAM,
WITH_SUBTITLES,
SUBTITLE_OFFSET,
@@ -308,6 +307,7 @@ private:
void analyse_audio_finished ();
std::string video_state_identifier () const;
void read_metadata ();
+ void content_changed (int);
/** Log to write to */
boost::shared_ptr<Log> _log;
@@ -328,6 +328,7 @@ 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 f9572b518..5ad94db45 100644
--- a/src/lib/imagemagick_content.cc
+++ b/src/lib/imagemagick_content.cc
@@ -76,4 +76,12 @@ ImageMagickContent::examine (shared_ptr<Film> film, shared_ptr<Job> job, bool qu
}
take_from_video_decoder (decoder);
+
+ Changed (VideoContentProperty::VIDEO_LENGTH);
+}
+
+shared_ptr<Content>
+ImageMagickContent::clone () const
+{
+ return shared_ptr<Content> (new ImageMagickContent (*this));
}
diff --git a/src/lib/imagemagick_content.h b/src/lib/imagemagick_content.h
index 5820bd807..2ca58f255 100644
--- a/src/lib/imagemagick_content.h
+++ b/src/lib/imagemagick_content.h
@@ -33,6 +33,7 @@ public:
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;
static bool valid_file (boost::filesystem::path);
};
diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc
index 508863e3e..dff177548 100644
--- a/src/lib/imagemagick_decoder.cc
+++ b/src/lib/imagemagick_decoder.cc
@@ -61,12 +61,14 @@ ImageMagickDecoder::video_length () const
bool
ImageMagickDecoder::pass ()
{
- if (_position > 0 && _position < _imagemagick_content->video_length ()) {
+ if (_position < 0 || _position >= _imagemagick_content->video_length ()) {
+ return true;
+ }
+
+ if (have_last_video ()) {
repeat_last_video ();
_position++;
return false;
- } else if (_position >= _imagemagick_content->video_length ()) {
- return true;
}
Magick::Image* magick_image = new Magick::Image (_imagemagick_content->file().string ());
diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc
index 609d4096c..3822420da 100644
--- a/src/lib/playlist.cc
+++ b/src/lib/playlist.cc
@@ -43,6 +43,10 @@ Playlist::setup (ContentList content)
{
_video_from = VIDEO_NONE;
_audio_from = AUDIO_NONE;
+
+ _ffmpeg.reset ();
+ _imagemagick.clear ();
+ _sndfile.clear ();
for (ContentList::const_iterator i = content.begin(); i != content.end(); ++i) {
shared_ptr<FFmpegContent> fc = dynamic_pointer_cast<FFmpegContent> (*i);
@@ -307,7 +311,7 @@ Player::seek (double t)
_imagemagick_decoder = _imagemagick_decoders.begin ();
while (_imagemagick_decoder != _imagemagick_decoders.end ()) {
double const this_length = (*_imagemagick_decoder)->video_length() / _film->video_frame_rate ();
- if (this_length < t) {
+ if (t < this_length) {
break;
}
t -= this_length;
diff --git a/src/lib/sndfile_content.cc b/src/lib/sndfile_content.cc
index 4794e4d31..657e7d519 100644
--- a/src/lib/sndfile_content.cc
+++ b/src/lib/sndfile_content.cc
@@ -64,3 +64,9 @@ SndfileContent::valid_file (boost::filesystem::path f)
transform (ext.begin(), ext.end(), ext.begin(), ::tolower);
return (ext == ".wav" || ext == ".aif" || ext == ".aiff");
}
+
+shared_ptr<Content>
+SndfileContent::clone () const
+{
+ return shared_ptr<Content> (new SndfileContent (*this));
+}
diff --git a/src/lib/sndfile_content.h b/src/lib/sndfile_content.h
index b9a500c88..81a964ec8 100644
--- a/src/lib/sndfile_content.h
+++ b/src/lib/sndfile_content.h
@@ -11,6 +11,7 @@ public:
SndfileContent (boost::shared_ptr<const cxml::Node>);
std::string summary () const;
+ boost::shared_ptr<Content> clone () const;
/* AudioContent */
int audio_channels () const;
diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc
index e697a281d..f48813f60 100644
--- a/src/lib/video_content.cc
+++ b/src/lib/video_content.cc
@@ -26,6 +26,15 @@ VideoContent::VideoContent (shared_ptr<const cxml::Node> node)
_video_frame_rate = node->number_child<float> ("VideoFrameRate");
}
+VideoContent::VideoContent (VideoContent const & o)
+ : Content (o)
+ , _video_length (o._video_length)
+ , _video_size (o._video_size)
+ , _video_frame_rate (o._video_frame_rate)
+{
+
+}
+
void
VideoContent::as_xml (xmlpp::Node* node) const
{
diff --git a/src/lib/video_content.h b/src/lib/video_content.h
index 7c9db890a..25cb28938 100644
--- a/src/lib/video_content.h
+++ b/src/lib/video_content.h
@@ -19,6 +19,7 @@ class VideoContent : public virtual Content
public:
VideoContent (boost::filesystem::path);
VideoContent (boost::shared_ptr<const cxml::Node>);
+ VideoContent (VideoContent const &);
void as_xml (xmlpp::Node *) const;
diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc
index 32b06085f..47385cc61 100644
--- a/src/lib/video_decoder.cc
+++ b/src/lib/video_decoder.cc
@@ -54,6 +54,12 @@ VideoDecoder::emit_video (shared_ptr<Image> image, double t)
_last_source_time = t;
}
+bool
+VideoDecoder::have_last_video () const
+{
+ return _last_image;
+}
+
/** Called by subclasses to repeat the last video frame that we
* passed to emit_video(). If emit_video hasn't yet been called,
* we will generate a black frame.
diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h
index a2fd5b651..74343e856 100644
--- a/src/lib/video_decoder.h
+++ b/src/lib/video_decoder.h
@@ -58,6 +58,7 @@ protected:
void emit_video (boost::shared_ptr<Image>, double);
void emit_subtitle (boost::shared_ptr<TimedSubtitle>);
+ bool have_last_video () const;
void repeat_last_video ();
private:
diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc
index e45f79a87..9cf479508 100644
--- a/src/wx/film_viewer.cc
+++ b/src/wx/film_viewer.cc
@@ -35,6 +35,7 @@
#include "lib/examine_content_job.h"
#include "lib/filter.h"
#include "lib/playlist.h"
+#include "lib/video_content.h"
#include "film_viewer.h"
#include "wx_util.h"
#include "video_decoder.h"
@@ -97,12 +98,7 @@ FilmViewer::film_changed (Film::Property p)
break;
case Film::CONTENT:
{
- _player = _film->player ();
- _player->disable_audio ();
- _player->disable_subtitles ();
- _player->disable_video_sync ();
-
- _player->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3));
+ setup_player ();
calculate_sizes ();
get_frame ();
_panel->Refresh ();
@@ -123,6 +119,28 @@ FilmViewer::film_changed (Film::Property p)
}
void
+FilmViewer::setup_player ()
+{
+ _player = _film->player ();
+ _player->disable_audio ();
+ _player->disable_subtitles ();
+ _player->disable_video_sync ();
+ _player->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3));
+}
+
+void
+FilmViewer::film_content_changed (int p)
+{
+ if (p == VideoContentProperty::VIDEO_LENGTH || p == VideoContentProperty::VIDEO_SIZE) {
+ setup_player ();
+ calculate_sizes ();
+ get_frame ();
+ _panel->Refresh ();
+ _v_sizer->Layout ();
+ }
+}
+
+void
FilmViewer::set_film (shared_ptr<Film> f)
{
if (_film == f) {
@@ -136,6 +154,7 @@ FilmViewer::set_film (shared_ptr<Film> f)
}
_film->Changed.connect (boost::bind (&FilmViewer::film_changed, this, _1));
+ _film->ContentChanged.connect (boost::bind (&FilmViewer::film_content_changed, this, _1));
film_changed (Film::CONTENT);
film_changed (Film::FORMAT);
@@ -276,14 +295,13 @@ FilmViewer::raw_to_display ()
_clear_required = true;
}
-#if 0
if (_raw_sub) {
/* Our output is already cropped by the decoder, so we need to account for that
when working out the scale that we are applying.
*/
- Size const cropped_size = _film->cropped_size (_film->size ());
+ Size const cropped_size = _film->cropped_size (_film->video_size ());
Rect tx = subtitle_transformed_area (
float (_film_size.width) / cropped_size.width,
@@ -297,7 +315,6 @@ FilmViewer::raw_to_display ()
} else {
_display_sub.reset ();
}
-#endif
}
void
@@ -353,7 +370,7 @@ FilmViewer::check_play_state ()
}
if (_play_button->GetValue()) {
-// _timer.Start (1000 / _film->source_frame_rate());
+ _timer.Start (1000 / _film->video_frame_rate());
} else {
_timer.Stop ();
}
diff --git a/src/wx/film_viewer.h b/src/wx/film_viewer.h
index f557d69b8..e28703fdd 100644
--- a/src/wx/film_viewer.h
+++ b/src/wx/film_viewer.h
@@ -42,6 +42,7 @@ public:
private:
void film_changed (Film::Property);
+ void film_content_changed (int);
void paint_panel (wxPaintEvent &);
void panel_sized (wxSizeEvent &);
void slider_moved (wxScrollEvent &);
@@ -55,6 +56,7 @@ private:
void raw_to_display ();
void get_frame ();
void active_jobs_changed (bool);
+ void setup_player ();
boost::shared_ptr<Film> _film;
boost::shared_ptr<Player> _player;