+
+void
+GLVideoView::start ()
+{
+ VideoView::start ();
+
+ boost::mutex::scoped_lock lm (_playing_mutex);
+ _playing = true;
+ _playing_condition.notify_all ();
+}
+
+void
+GLVideoView::stop ()
+{
+ boost::mutex::scoped_lock lm (_playing_mutex);
+ _playing = false;
+}
+
+void
+GLVideoView::thread ()
+try
+{
+ {
+ boost::mutex::scoped_lock lm (_canvas_mutex);
+ _context = new wxGLContext (_canvas); //local
+ _canvas->SetCurrent (*_context);
+ }
+
+ while (true) {
+ boost::mutex::scoped_lock lm (_playing_mutex);
+ while (!_playing && !_one_shot) {
+ _playing_condition.wait (lm);
+ }
+ _one_shot = false;
+ lm.unlock ();
+
+ Position<int> inter_position;
+ dcp::Size inter_size;
+ if (length() != dcpomatic::DCPTime()) {
+ dcpomatic::DCPTime const next = position() + one_video_frame();
+
+ if (next >= length()) {
+ _viewer->finished ();
+ continue;
+ }
+
+ get_next_frame (false);
+ shared_ptr<PlayerVideo> pv = player_video().first;
+ if (pv) {
+ set_image (pv->image(bind(&PlayerVideo::force, _1, AV_PIX_FMT_RGB24), false, true));
+ inter_position = pv->inter_position();
+ inter_size = pv->inter_size();
+ }
+ }
+ draw (inter_position, inter_size);
+
+ while (true) {
+ optional<int> n = time_until_next_frame();
+ if (!n || *n > 5) {
+ break;
+ }
+ get_next_frame (true);
+ add_dropped ();
+ }
+
+ boost::this_thread::interruption_point ();
+ dcpomatic_sleep_milliseconds (time_until_next_frame().get_value_or(0));
+ }
+
+ /* XXX: leaks _context, but that seems preferable to deleting it here
+ * without also deleting the wxGLCanvas.
+ */
+}
+catch (boost::thread_interrupted& e)
+{
+ store_current ();
+}
+
+bool
+GLVideoView::display_next_frame (bool non_blocking)
+{
+ bool const r = get_next_frame (non_blocking);
+ request_one_shot ();
+ return r;
+}
+
+void
+GLVideoView::request_one_shot ()
+{
+ boost::mutex::scoped_lock lm (_playing_mutex);
+ _one_shot = true;
+ _playing_condition.notify_all ();
+}
+
+void
+GLVideoView::create ()
+{
+ if (!_thread.joinable()) {
+ _thread = boost::thread (boost::bind(&GLVideoView::thread, this));
+ }
+}