Make viewer cope with multiple video frames being emitted on a single pass.
authorCarl Hetherington <cth@carlh.net>
Sat, 13 Jul 2013 12:02:29 +0000 (13:02 +0100)
committerCarl Hetherington <cth@carlh.net>
Sat, 13 Jul 2013 12:02:29 +0000 (13:02 +0100)
src/wx/film_viewer.cc
src/wx/film_viewer.h

index d27386d3d685ca79fac6bed542b38efd4cf744b4..819949f1e84786e84e32badccfadf48126d1ce40 100644 (file)
@@ -47,6 +47,7 @@ using std::min;
 using std::max;
 using std::cout;
 using std::list;
+using std::make_pair;
 using boost::shared_ptr;
 using boost::dynamic_pointer_cast;
 using boost::weak_ptr;
@@ -119,6 +120,7 @@ FilmViewer::set_film (shared_ptr<Film> f)
        _film = f;
 
        _frame.reset ();
+       _queue.clear ();
 
        if (!_film) {
                return;
@@ -126,7 +128,7 @@ FilmViewer::set_film (shared_ptr<Film> f)
 
        _player = f->player ();
        _player->disable_audio ();
-       _player->Video.connect (boost::bind (&FilmViewer::process_video, this, _1, _2, _3));
+       _player->Video.connect (boost::bind (&FilmViewer::process_video, this, _1, _3));
        _player->Changed.connect (boost::bind (&FilmViewer::player_changed, this));
 
        calculate_sizes ();
@@ -264,10 +266,15 @@ FilmViewer::check_play_state ()
 }
 
 void
-FilmViewer::process_video (shared_ptr<const Image> image, bool, Time t)
+FilmViewer::process_video (shared_ptr<const Image> image, Time t)
 {
+       if (_got_frame) {
+               /* This is an additional frame emitted by a single pass.  Store it. */
+               _queue.push_front (make_pair (image, t));
+               return;
+       }
+       
        _frame = image;
-
        _got_frame = true;
 
        double const fps = _film->dcp_video_frame_rate ();
@@ -296,13 +303,19 @@ FilmViewer::fetch_next_frame ()
                return;
        }
 
-       try {
-               _got_frame = false;
-               while (!_got_frame && !_player->pass ()) {}
-       } catch (DecodeError& e) {
-               _play_button->SetValue (false);
-               check_play_state ();
-               error_dialog (this, wxString::Format (_("Could not decode video for view (%s)"), std_to_wx(e.what()).data()));
+       _got_frame = false;
+       
+       if (!_queue.empty ()) {
+               process_video (_queue.back().first, _queue.back().second);
+               _queue.pop_back ();
+       } else {
+               try {
+                       while (!_got_frame && !_player->pass ()) {}
+               } catch (DecodeError& e) {
+                       _play_button->SetValue (false);
+                       check_play_state ();
+                       error_dialog (this, wxString::Format (_("Could not decode video for view (%s)"), std_to_wx(e.what()).data()));
+               }
        }
 
        _panel->Refresh ();
index 7587911e874c9d1a371879b7fbedd3147fc1ef3b..28fc4971d287eefbdc4a496814f750954e91abd6 100644 (file)
@@ -58,7 +58,7 @@ private:
        void slider_moved (wxScrollEvent &);
        void play_clicked (wxCommandEvent &);
        void timer (wxTimerEvent &);
-       void process_video (boost::shared_ptr<const Image>, bool, Time);
+       void process_video (boost::shared_ptr<const Image>, Time);
        void calculate_sizes ();
        void check_play_state ();
        void fetch_current_frame_again ();
@@ -88,4 +88,6 @@ private:
        libdcp::Size _out_size;
        /** Size of the panel that we have available */
        libdcp::Size _panel_size;
+
+       std::list<std::pair<boost::shared_ptr<const Image>, Time> > _queue;
 };