Various fixes.
authorCarl Hetherington <cth@carlh.net>
Tue, 2 Apr 2013 20:20:35 +0000 (21:20 +0100)
committerCarl Hetherington <cth@carlh.net>
Tue, 2 Apr 2013 20:20:35 +0000 (21:20 +0100)
20 files changed:
src/lib/audio_content.cc
src/lib/audio_content.h
src/lib/content.cc
src/lib/content.h
src/lib/ffmpeg_content.cc
src/lib/ffmpeg_content.h
src/lib/film.cc
src/lib/film.h
src/lib/imagemagick_content.cc
src/lib/imagemagick_content.h
src/lib/imagemagick_decoder.cc
src/lib/playlist.cc
src/lib/sndfile_content.cc
src/lib/sndfile_content.h
src/lib/video_content.cc
src/lib/video_content.h
src/lib/video_decoder.cc
src/lib/video_decoder.h
src/wx/film_viewer.cc
src/wx/film_viewer.h

index 74b8ea2cebd1099d45dd0c4359df45f22071b3f0..b5419a058992e527355f7b84b9b6e9f27e764eb7 100644 (file)
@@ -14,3 +14,9 @@ AudioContent::AudioContent (shared_ptr<const cxml::Node> node)
 {
 
 }
+
+AudioContent::AudioContent (AudioContent const & o)
+       : Content (o)
+{
+
+}
index f3dd81efb9d9e72c06c3a2b27629dee4aefa2c02..24391b01c68251dc10784f8237b18f267d2dd15d 100644 (file)
@@ -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;
index 977f2e2a78f73d1d7b47a00010010357242ef356..0c21822cba066c5e037923d18b5bd71c059f0c0a 100644 (file)
@@ -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
 {
index 87ef4658125282e8a900d391ccbc6e7708463a6f..3f348ca91c15d824f3b9a72efae101425cc71907 100644 (file)
@@ -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);
index 50a69ae7b29c51e24561938b526fc3b528ddb3d2..5bff1cecc0768eecdb0f44d5c9c022b0828b16fd 100644 (file)
@@ -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));
+}
index c56dc0a61ecfdfb7cfe89cd854f97d1e637c2fc7..598ebf4849d7d3eb6ff26af2a5950efd70b036be 100644 (file)
@@ -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;
index d82dce2972780a6505194a50d278e89e3f24231f..20a7ee49bcbf07ac8ec75e89c145d9615cdd254f 100644 (file)
@@ -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));
+       }
+}
index e1084e1ca048c221e45b687c052d605bdd787c13..f0a85fbf3bb7da2d9e6ba69e32904c0ed981c85d 100644 (file)
@@ -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.) */
index f9572b518fccf8a369b984423e855ed2e7e943a3..5ad94db45f0e5609983d1b99d8e98f0c1500e500 100644 (file)
@@ -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));
 }
index 5820bd807ef5560c3b244e4fe7357a99a52790c5..2ca58f25532866d460f6c96058673cebd24a688e 100644 (file)
@@ -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);
 };
index 508863e3e003d43350524ee46ec2b966cc1fe82a..dff177548fd6004bfbf538bc8d7973a20d6e5a8d 100644 (file)
@@ -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 ());
index 609d4096cb739ca00c31bd7c5d745a55857a7e86..3822420da1a3f4c7de9c46c09004ff8104f82487 100644 (file)
@@ -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;
index 4794e4d3193e7f267e76b8f98917f3ed7d00dbb3..657e7d519c3b5ac5779b580e6ff40728d5248628 100644 (file)
@@ -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));
+}
index b9a500c883f544b878aaa4518d47f78e3d424560..81a964ec8a1d909875139aab465b828b72bdb467 100644 (file)
@@ -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;
index e697a281d8d30f2fc97744730a3314264f7d0b3e..f48813f601a84086a83373b519054a584d51bc96 100644 (file)
@@ -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
 {
index 7c9db890aa175ed6b85655b38fe7c199f8cfbe85..25cb289384fad94d3ad3374ef30e50ae687f9272 100644 (file)
@@ -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;
 
index 32b06085f21b741e060111cb0bd913fcfcf51d93..47385cc614c8c1387e756b254edbb85f6c78b333 100644 (file)
@@ -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.
index a2fd5b6510a1fb297c555cf49ce749772e998d21..74343e856a6761c2d029e677f1af0815ed3865ba 100644 (file)
@@ -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:
index e45f79a87734f6775bab2f2427510296744f3622..9cf47950857d9d6ed6b30d5f439be395cceb21fe 100644 (file)
@@ -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<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 ();
        }
index f557d69b8f03f9f3e45e8e15274b7280bf7b316b..e28703fdd89ea9e3cbd9981ac39ead1edbbb103f 100644 (file)
@@ -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;