diff options
Diffstat (limited to 'media/tools/player_x11')
-rw-r--r-- | media/tools/player_x11/gl_video_renderer.cc | 21 | ||||
-rw-r--r-- | media/tools/player_x11/gl_video_renderer.h | 13 | ||||
-rw-r--r-- | media/tools/player_x11/gles_video_renderer.cc | 21 | ||||
-rw-r--r-- | media/tools/player_x11/gles_video_renderer.h | 13 | ||||
-rw-r--r-- | media/tools/player_x11/player_x11.cc | 62 | ||||
-rw-r--r-- | media/tools/player_x11/x11_video_renderer.cc | 21 | ||||
-rw-r--r-- | media/tools/player_x11/x11_video_renderer.h | 13 |
7 files changed, 82 insertions, 82 deletions
diff --git a/media/tools/player_x11/gl_video_renderer.cc b/media/tools/player_x11/gl_video_renderer.cc index 035db82..630fe9e 100644 --- a/media/tools/player_x11/gl_video_renderer.cc +++ b/media/tools/player_x11/gl_video_renderer.cc @@ -18,8 +18,8 @@ GlVideoRenderer* GlVideoRenderer::instance_ = NULL; GlVideoRenderer::GlVideoRenderer(Display* display, Window window) : display_(display), window_(window), - new_frame_(false), - gl_context_(NULL) { + gl_context_(NULL), + glx_thread_message_loop_(NULL) { } GlVideoRenderer::~GlVideoRenderer() { @@ -263,22 +263,13 @@ bool GlVideoRenderer::OnInitialize(media::VideoDecoder* decoder) { } void GlVideoRenderer::OnFrameAvailable() { - AutoLock auto_lock(lock_); - new_frame_ = true; + if (glx_thread_message_loop()) { + glx_thread_message_loop()->PostTask(FROM_HERE, + NewRunnableMethod(this, &GlVideoRenderer::Paint)); + } } void GlVideoRenderer::Paint() { - // Use |new_frame_| to prevent overdraw since Paint() is called more - // often than needed. It is OK to lock only this flag and we don't - // want to lock the whole function because this method takes a long - // time to complete. - { - AutoLock auto_lock(lock_); - if (!new_frame_) - return; - new_frame_ = false; - } - scoped_refptr<media::VideoFrame> video_frame; GetCurrentFrame(&video_frame); diff --git a/media/tools/player_x11/gl_video_renderer.h b/media/tools/player_x11/gl_video_renderer.h index dec35f2..f88129b 100644 --- a/media/tools/player_x11/gl_video_renderer.h +++ b/media/tools/player_x11/gl_video_renderer.h @@ -32,6 +32,14 @@ class GlVideoRenderer : public media::VideoRendererBase { static GlVideoRenderer* instance() { return instance_; } + void set_glx_thread_message_loop(MessageLoop* message_loop) { + glx_thread_message_loop_ = message_loop; + } + + MessageLoop* glx_thread_message_loop() { + return glx_thread_message_loop_; + } + protected: // VideoRendererBase implementation. virtual bool OnInitialize(media::VideoDecoder* decoder); @@ -50,16 +58,13 @@ class GlVideoRenderer : public media::VideoRendererBase { Display* display_; Window window_; - // Protects |new_frame_|. - Lock lock_; - bool new_frame_; - // GL context. GLXContext gl_context_; // 3 textures, one for each plane. GLuint textures_[3]; + MessageLoop* glx_thread_message_loop_; static GlVideoRenderer* instance_; DISALLOW_COPY_AND_ASSIGN(GlVideoRenderer); diff --git a/media/tools/player_x11/gles_video_renderer.cc b/media/tools/player_x11/gles_video_renderer.cc index f6cea9c..fab345a 100644 --- a/media/tools/player_x11/gles_video_renderer.cc +++ b/media/tools/player_x11/gles_video_renderer.cc @@ -23,10 +23,10 @@ GlesVideoRenderer::GlesVideoRenderer(Display* display, Window window) egl_destroy_image_khr_(NULL), display_(display), window_(window), - new_frame_(false), egl_display_(NULL), egl_surface_(NULL), - egl_context_(NULL) { + egl_context_(NULL), + glx_thread_message_loop_(NULL) { } GlesVideoRenderer::~GlesVideoRenderer() { @@ -149,22 +149,13 @@ bool GlesVideoRenderer::OnInitialize(media::VideoDecoder* decoder) { } void GlesVideoRenderer::OnFrameAvailable() { - AutoLock auto_lock(lock_); - new_frame_ = true; + if (glx_thread_message_loop()) { + glx_thread_message_loop()->PostTask(FROM_HERE, + NewRunnableMethod(this, &GlesVideoRenderer::Paint)); + } } void GlesVideoRenderer::Paint() { - // Use |new_frame_| to prevent overdraw since Paint() is called more - // often than needed. It is OK to lock only this flag and we don't - // want to lock the whole function because this method takes a long - // time to complete. - { - AutoLock auto_lock(lock_); - if (!new_frame_) - return; - new_frame_ = false; - } - // Initialize GLES here to avoid context switching. Some drivers doesn't // like switching context between threads. static bool initialized = false; diff --git a/media/tools/player_x11/gles_video_renderer.h b/media/tools/player_x11/gles_video_renderer.h index d93fa2e..2aaa19c 100644 --- a/media/tools/player_x11/gles_video_renderer.h +++ b/media/tools/player_x11/gles_video_renderer.h @@ -35,6 +35,14 @@ class GlesVideoRenderer : public media::VideoRendererBase { static GlesVideoRenderer* instance() { return instance_; } + void set_glx_thread_message_loop(MessageLoop* message_loop) { + glx_thread_message_loop_ = message_loop; + } + + MessageLoop* glx_thread_message_loop() { + return glx_thread_message_loop_; + } + protected: // VideoRendererBase implementation. virtual bool OnInitialize(media::VideoDecoder* decoder); @@ -64,10 +72,6 @@ class GlesVideoRenderer : public media::VideoRendererBase { Display* display_; Window window_; - // Protects |new_frame_|. - Lock lock_; - bool new_frame_; - // EGL context. EGLDisplay egl_display_; EGLSurface egl_surface_; @@ -80,6 +84,7 @@ class GlesVideoRenderer : public media::VideoRendererBase { // 3 textures, one for each plane. GLuint textures_[3]; + MessageLoop* glx_thread_message_loop_; static GlesVideoRenderer* instance_; DISALLOW_COPY_AND_ASSIGN(GlesVideoRenderer); diff --git a/media/tools/player_x11/player_x11.cc b/media/tools/player_x11/player_x11.cc index 73846ed..fb795c5 100644 --- a/media/tools/player_x11/player_x11.cc +++ b/media/tools/player_x11/player_x11.cc @@ -123,6 +123,33 @@ void TerminateHandler(int signal) { g_running = false; } +void PeriodicalUpdate(MessageLoop* message_loop, bool audio_only) { + if (!g_running) { + message_loop->Quit(); + return; + } + + // Consume all the X events + while (XPending(g_display)) { + XEvent e; + XNextEvent(g_display, &e); + if (e.type == Expose) { + if (!audio_only) { + // Tell the renderer to paint. + DCHECK(Renderer::instance()); + Renderer::instance()->Paint(); + } + } else if (e.type == ButtonPress) { + g_running = false; + message_loop->Quit(); + return; + } + } + + message_loop->PostDelayedTask(FROM_HERE, + NewRunnableFunction(PeriodicalUpdate, message_loop, audio_only), 10); +} + int main(int argc, char** argv) { // Read arguments. if (argc == 1) { @@ -164,32 +191,17 @@ int main(int argc, char** argv) { // Check if video is present. audio_only = !pipeline->IsRendered(media::mime_type::kMajorTypeVideo); - while (g_running) { - if (XPending(g_display)) { - XEvent e; - XNextEvent(g_display, &e); - if (e.type == Expose) { - if (!audio_only) { - // Tell the renderer to paint. - DCHECK(Renderer::instance()); - Renderer::instance()->Paint(); - } - } else if (e.type == ButtonPress) { - // Stop the playback. - break; - } - } else { - // If there's no event in the queue, make an expose event. - XEvent event; - event.type = Expose; - XSendEvent(g_display, g_window, true, ExposureMask, &event); - - // TODO(hclam): It is rather arbitrary to sleep for 10ms and wait - // for the next event. We should submit an expose event when - // a frame is available but not firing an expose event every 10ms. - usleep(10000); - } + MessageLoop message_loop; + if (!audio_only) { + // Tell the renderer to paint. + DCHECK(Renderer::instance()); + Renderer::instance()->set_glx_thread_message_loop(&message_loop); } + + message_loop.PostTask(FROM_HERE, + NewRunnableFunction(PeriodicalUpdate, &message_loop, audio_only)); + message_loop.Run(); + pipeline->Stop(NULL); } else{ std::cout << "Pipeline initialization failed..." << std::endl; diff --git a/media/tools/player_x11/x11_video_renderer.cc b/media/tools/player_x11/x11_video_renderer.cc index 50f8b5f..a803dd8 100644 --- a/media/tools/player_x11/x11_video_renderer.cc +++ b/media/tools/player_x11/x11_video_renderer.cc @@ -57,9 +57,9 @@ X11VideoRenderer::X11VideoRenderer(Display* display, Window window) : display_(display), window_(window), image_(NULL), - new_frame_(false), picture_(0), - use_render_(false) { + use_render_(false), + glx_thread_message_loop_(NULL) { } X11VideoRenderer::~X11VideoRenderer() { @@ -132,22 +132,13 @@ bool X11VideoRenderer::OnInitialize(media::VideoDecoder* decoder) { } void X11VideoRenderer::OnFrameAvailable() { - AutoLock auto_lock(lock_); - new_frame_ = true; + if (glx_thread_message_loop()) { + glx_thread_message_loop()->PostTask(FROM_HERE, + NewRunnableMethod(this, &X11VideoRenderer::Paint)); + } } void X11VideoRenderer::Paint() { - // Use |new_frame_| to prevent overdraw since Paint() is called more - // often than needed. It is OK to lock only this flag and we don't - // want to lock the whole function because this method takes a long - // time to complete. - { - AutoLock auto_lock(lock_); - if (!new_frame_) - return; - new_frame_ = false; - } - scoped_refptr<media::VideoFrame> video_frame; GetCurrentFrame(&video_frame); diff --git a/media/tools/player_x11/x11_video_renderer.h b/media/tools/player_x11/x11_video_renderer.h index 2ffb17f..025ed56 100644 --- a/media/tools/player_x11/x11_video_renderer.h +++ b/media/tools/player_x11/x11_video_renderer.h @@ -31,6 +31,14 @@ class X11VideoRenderer : public media::VideoRendererBase { static X11VideoRenderer* instance() { return instance_; } + void set_glx_thread_message_loop(MessageLoop* message_loop) { + glx_thread_message_loop_ = message_loop; + } + + MessageLoop* glx_thread_message_loop() { + return glx_thread_message_loop_; + } + protected: // VideoRendererBase implementation. virtual bool OnInitialize(media::VideoDecoder* decoder); @@ -52,16 +60,13 @@ class X11VideoRenderer : public media::VideoRendererBase { // Image in heap that contains the RGBA data of the video frame. XImage* image_; - // Protects |new_frame_|. - Lock lock_; - bool new_frame_; - // Picture represents the paint target. This is a picture located // in the server. unsigned long picture_; bool use_render_; + MessageLoop* glx_thread_message_loop_; static X11VideoRenderer* instance_; DISALLOW_COPY_AND_ASSIGN(X11VideoRenderer); |