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;
_panel->SetDoubleBuffered (true);
#endif
-#if wxMAJOR_VERSION == 2 && wxMINOR_VERSION >= 9
_panel->SetBackgroundStyle (wxBG_STYLE_PAINT);
-#endif
_v_sizer = new wxBoxSizer (wxVERTICAL);
SetSizer (_v_sizer);
_film = f;
_frame.reset ();
+ _queue.clear ();
if (!_film) {
return;
}
- _player = f->player ();
+ _player = f->make_player ();
_player->disable_audio ();
- _player->Video.connect (boost::bind (&FilmViewer::process_video, this, _1, _2, _3));
- _player->Changed.connect (boost::bind (&FilmViewer::player_changed, this));
+ _player->Video.connect (boost::bind (&FilmViewer::process_video, this, _1, _3));
+ _player->Changed.connect (boost::bind (&FilmViewer::player_changed, this, _1));
calculate_sizes ();
+ fetch_current_frame_again ();
}
void
return;
}
- Time const t = _film->video_frames_to_time (1);
-
- _player->seek (_player->video_position() - t * 1.5, true);
+ /* Player::video_position is the time after the last frame that we received.
+ We want to see it again, so seek back one frame.
+ */
+
+ Time p = _player->video_position() - _film->video_frames_to_time (1);
+ if (p < 0) {
+ p = 0;
+ }
+
+ _player->seek (p, true);
fetch_next_frame ();
}
return;
}
- shared_ptr<SimpleImage> packed_frame (new SimpleImage (_frame, false));
+ shared_ptr<Image> packed_frame (new Image (_frame, false));
wxImage frame (_out_size.width, _out_size.height, packed_frame->data()[0], true);
wxBitmap frame_bitmap (frame);
}
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 ();
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 ();
return;
}
- Time const t = _film->video_frames_to_time (1);
+ /* Player::video_position is the time after the last frame that we received.
+ We want to see the one before it, so we need to go back 2.
+ */
- _player->seek (_player->video_position() - t * 2.5, true);
+ _player->seek (_player->video_position() - _film->video_frames_to_time(2), true);
fetch_next_frame ();
}
}
void
-FilmViewer::player_changed ()
+FilmViewer::player_changed (bool frequent)
{
+ if (frequent) {
+ return;
+ }
+
calculate_sizes ();
fetch_current_frame_again ();
}