From 956da4b106e14c49b179176acf6484c479c21094 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 2 Apr 2013 21:20:35 +0100 Subject: [PATCH] Various fixes. --- src/lib/audio_content.cc | 6 ++++++ src/lib/audio_content.h | 1 + src/lib/content.cc | 7 +++++++ src/lib/content.h | 2 ++ src/lib/ffmpeg_content.cc | 19 +++++++++++++++++ src/lib/ffmpeg_content.h | 2 ++ src/lib/film.cc | 19 +++++++++++++++-- src/lib/film.h | 3 ++- src/lib/imagemagick_content.cc | 8 ++++++++ src/lib/imagemagick_content.h | 1 + src/lib/imagemagick_decoder.cc | 8 +++++--- src/lib/playlist.cc | 6 +++++- src/lib/sndfile_content.cc | 6 ++++++ src/lib/sndfile_content.h | 1 + src/lib/video_content.cc | 9 +++++++++ src/lib/video_content.h | 1 + src/lib/video_decoder.cc | 6 ++++++ src/lib/video_decoder.h | 1 + src/wx/film_viewer.cc | 37 +++++++++++++++++++++++++--------- src/wx/film_viewer.h | 2 ++ 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 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); + 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 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); + Content (Content const &); virtual void examine (boost::shared_ptr, boost::shared_ptr, bool); virtual std::string summary () const = 0; virtual void as_xml (xmlpp::Node *) const; + virtual boost::shared_ptr 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 node) } } +FFmpegContent::FFmpegContent (FFmpegContent const & o) + : Content (o) + , VideoContent (o) + , AudioContent (o) + , boost::enable_shared_from_this (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 (id)); } + +shared_ptr +FFmpegContent::clone () const +{ + return shared_ptr (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); + FFmpegContent (FFmpegContent const &); void examine (boost::shared_ptr, boost::shared_ptr, bool); std::string summary () const; void as_xml (xmlpp::Node *) const; + boost::shared_ptr 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 c) { shared_ptr 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 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 c) if (i != _content.end ()) { _content.erase (i); } + + for (list::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; @@ -328,6 +328,7 @@ private: bool _use_dci_name; bool _trust_content_headers; ContentList _content; + std::list _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, shared_ptr job, bool qu } take_from_video_decoder (decoder); + + Changed (VideoContentProperty::VIDEO_LENGTH); +} + +shared_ptr +ImageMagickContent::clone () const +{ + return shared_ptr (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, boost::shared_ptr, bool); std::string summary () const; void as_xml (xmlpp::Node *) const; + boost::shared_ptr 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 fc = dynamic_pointer_cast (*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 +SndfileContent::clone () const +{ + return shared_ptr (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); std::string summary () const; + boost::shared_ptr 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 node) _video_frame_rate = node->number_child ("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); + 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, 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, double); void emit_subtitle (boost::shared_ptr); + 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 (); @@ -122,6 +118,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 f) { @@ -136,6 +154,7 @@ FilmViewer::set_film (shared_ptr 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; boost::shared_ptr _player; -- 2.30.2