X-Git-Url: https://main.carlh.net/gitweb/?p=dcpomatic.git;a=blobdiff_plain;f=src%2Fwx%2Fgl_video_view.cc;h=836b3eb351584b790e9c6f077c4e090b3d73277a;hp=df45a143f42206fde7d1633aa656703bf2a56052;hb=83c9e9c858072ab919916269790dcc65565fdd25;hpb=edfb627f1226814ac804473b54d781ffd6db2700 diff --git a/src/wx/gl_video_view.cc b/src/wx/gl_video_view.cc index df45a143f..836b3eb35 100644 --- a/src/wx/gl_video_view.cc +++ b/src/wx/gl_video_view.cc @@ -20,11 +20,13 @@ #include "gl_video_view.h" #include "film_viewer.h" +#include "wx_util.h" #include "lib/image.h" #include "lib/dcpomatic_assert.h" #include "lib/exceptions.h" #include "lib/cross.h" #include "lib/player_video.h" +#include "lib/butler.h" #include #include @@ -55,10 +57,17 @@ GLVideoView::GLVideoView (FilmViewer* viewer, wxWindow *parent) : VideoView (viewer) , _vsync_enabled (false) , _thread (0) + , _playing (false) + , _one_shot (false) { _canvas = new wxGLCanvas (parent, wxID_ANY, 0, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE); _canvas->Bind (wxEVT_PAINT, boost::bind(&GLVideoView::paint, this)); _canvas->Bind (wxEVT_SIZE, boost::bind(boost::ref(Sized))); + _canvas->Bind (wxEVT_CREATE, boost::bind(&GLVideoView::create, this)); + + _canvas->Bind (wxEVT_TIMER, boost::bind(&GLVideoView::check_for_butler_errors, this)); + _timer.reset (new wxTimer(_canvas)); + _timer->Start (2000); #if defined(DCPOMATIC_LINUX) && defined(DCPOMATIC_HAVE_GLX_SWAP_INTERVAL_EXT) if (_canvas->IsExtensionSupported("GLX_EXT_swap_control")) { @@ -95,15 +104,23 @@ GLVideoView::GLVideoView (FilmViewer* viewer, wxWindow *parent) GLVideoView::~GLVideoView () { - if (_thread) { - _thread->interrupt (); - _thread->join (); - } + _thread->interrupt (); + _thread->join (); delete _thread; glDeleteTextures (1, &_id); } +void +GLVideoView::check_for_butler_errors () +{ + try { + _viewer->butler()->rethrow (); + } catch (DecodeError& e) { + error_dialog (get(), e.what()); + } +} + static void check_gl_error (char const * last) { @@ -116,14 +133,7 @@ check_gl_error (char const * last) void GLVideoView::paint () { - /* XXX_b: can't do this yet */ -#if 0 - _viewer->state_timer().set("paint-panel"); - _canvas->SetCurrent (*_context); - wxPaintDC dc (_canvas); - draw (); - _viewer->state_timer().unset(); -#endif + request_one_shot (); } void @@ -169,9 +179,11 @@ GLVideoView::draw () glTranslatef (0, 0, 0); + dcp::Size const out_size = _viewer->out_size (); + if (_size) { + /* Render our image (texture) */ glBegin (GL_QUADS); - glTexCoord2f (0, 1); glVertex2f (0, _size->height); glTexCoord2f (1, 1); @@ -180,11 +192,19 @@ GLVideoView::draw () glVertex2f (_size->width, 0); glTexCoord2f (0, 0); glVertex2f (0, 0); - + glEnd (); + } else { + /* No image, so just fill with black */ + glBegin (GL_QUADS); + glColor3ub (0, 0, 0); + glVertex2f (0, 0); + glVertex2f (out_size.width, 0); + glVertex2f (out_size.width, out_size.height); + glVertex2f (0, out_size.height); + glVertex2f (0, 0); glEnd (); } - dcp::Size const out_size = _viewer->out_size (); wxSize const canvas_size = _canvas->GetSize (); if (!_viewer->pad_black() && out_size.width < canvas_size.GetWidth()) { @@ -263,18 +283,16 @@ GLVideoView::set_image (shared_ptr image) void GLVideoView::start () { - _thread = new boost::thread (boost::bind(&GLVideoView::thread, this)); + boost::mutex::scoped_lock lm (_playing_mutex); + _playing = true; + _playing_condition.notify_all (); } void GLVideoView::stop () { - if (_thread) { - _thread->interrupt (); - _thread->join (); - } - delete _thread; - _thread = 0; + boost::mutex::scoped_lock lm (_playing_mutex); + _playing = false; } void @@ -285,21 +303,25 @@ try _context = new wxGLContext (_canvas); _canvas->SetCurrent (*_context); - std::cout << "Here we go " << video_frame_rate() << " " << to_string(length()) << "\n"; - while (true) { - dcpomatic::DCPTime const next = position() + one_video_frame(); - - if (next >= length()) { - _viewer->stop (); - _viewer->emit_finished (); - continue; + boost::mutex::scoped_lock lm (_playing_mutex); + while (!_playing && !_one_shot) { + _playing_condition.wait (lm); } + _one_shot = false; + lm.unlock (); + + if (length() != dcpomatic::DCPTime()) { + dcpomatic::DCPTime const next = position() + one_video_frame(); + + if (next >= length()) { + _viewer->stop (); + _viewer->emit_finished (); + continue; + } - get_next_frame (false); - { - boost::mutex::scoped_lock lm (_mutex); - set_image (_player_video.first->image(bind(&PlayerVideo::force, _1, AV_PIX_FMT_RGB24), false, true)); + get_next_frame (false); + set_image (player_video().first->image(bind(&PlayerVideo::force, _1, AV_PIX_FMT_RGB24), false, true)); } draw (); @@ -323,6 +345,23 @@ catch (boost::thread_interrupted& e) bool GLVideoView::display_next_frame (bool non_blocking) { - return get_next_frame (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) { + _thread = new boost::thread (boost::bind(&GLVideoView::thread, this)); + } +}