diff options
author | wjia@google.com <wjia@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-24 19:15:07 +0000 |
---|---|---|
committer | wjia@google.com <wjia@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-24 19:15:07 +0000 |
commit | 5e83826af14858fca1ebac8281afa75107281e7b (patch) | |
tree | 467fbad219ff625270ebe0455dabe4459f1c7e36 /media/tools | |
parent | cc2de439d0fd34aac593b1fabc40f0626c5848e1 (diff) | |
download | chromium_src-5e83826af14858fca1ebac8281afa75107281e7b.zip chromium_src-5e83826af14858fca1ebac8281afa75107281e7b.tar.gz chromium_src-5e83826af14858fca1ebac8281afa75107281e7b.tar.bz2 |
1. remove initial rendering lag time for egl image decoding path
2. put all GLES operations in one thread
BUG=none
TEST=dev platform and desktop
Review URL: http://codereview.chromium.org/2836019
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@50749 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/tools')
-rw-r--r-- | media/tools/player_wtl/player_wtl.cc | 2 | ||||
-rw-r--r-- | media/tools/player_wtl/wtl_renderer.cc | 6 | ||||
-rw-r--r-- | media/tools/player_wtl/wtl_renderer.h | 2 | ||||
-rw-r--r-- | media/tools/player_x11/gl_video_renderer.cc | 11 | ||||
-rw-r--r-- | media/tools/player_x11/gl_video_renderer.h | 17 | ||||
-rw-r--r-- | media/tools/player_x11/gles_video_renderer.cc | 30 | ||||
-rw-r--r-- | media/tools/player_x11/gles_video_renderer.h | 19 | ||||
-rw-r--r-- | media/tools/player_x11/player_x11.cc | 28 | ||||
-rw-r--r-- | media/tools/player_x11/x11_video_renderer.cc | 11 | ||||
-rw-r--r-- | media/tools/player_x11/x11_video_renderer.h | 17 |
10 files changed, 84 insertions, 59 deletions
diff --git a/media/tools/player_wtl/player_wtl.cc b/media/tools/player_wtl/player_wtl.cc index 73abc95..5df87a7 100644 --- a/media/tools/player_wtl/player_wtl.cc +++ b/media/tools/player_wtl/player_wtl.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/media/tools/player_wtl/wtl_renderer.cc b/media/tools/player_wtl/wtl_renderer.cc index 28a6f3e..73c97db 100644 --- a/media/tools/player_wtl/wtl_renderer.cc +++ b/media/tools/player_wtl/wtl_renderer.cc @@ -19,7 +19,11 @@ bool WtlVideoRenderer::IsMediaFormatSupported( return ParseMediaFormat(media_format, NULL, NULL, NULL, NULL); } -void WtlVideoRenderer::OnStop() { +void WtlVideoRenderer::OnStop(media::FilterCallback* callback) { + if (callback) { + callback->Run(); + delete callback; + } } bool WtlVideoRenderer::OnInitialize(media::VideoDecoder* decoder) { diff --git a/media/tools/player_wtl/wtl_renderer.h b/media/tools/player_wtl/wtl_renderer.h index 86aa61f..70fbe0e 100644 --- a/media/tools/player_wtl/wtl_renderer.h +++ b/media/tools/player_wtl/wtl_renderer.h @@ -20,7 +20,7 @@ class WtlVideoRenderer : public media::VideoRendererBase { protected: // VideoRendererBase implementation. virtual bool OnInitialize(media::VideoDecoder* decoder); - virtual void OnStop(); + virtual void OnStop(media::FilterCallback* callback); virtual void OnFrameAvailable(); private: diff --git a/media/tools/player_x11/gl_video_renderer.cc b/media/tools/player_x11/gl_video_renderer.cc index a828fbe..e2f4681 100644 --- a/media/tools/player_x11/gl_video_renderer.cc +++ b/media/tools/player_x11/gl_video_renderer.cc @@ -13,11 +13,12 @@ GlVideoRenderer* GlVideoRenderer::instance_ = NULL; -GlVideoRenderer::GlVideoRenderer(Display* display, Window window) +GlVideoRenderer::GlVideoRenderer(Display* display, Window window, + MessageLoop* message_loop) : display_(display), window_(window), gl_context_(NULL), - glx_thread_message_loop_(NULL) { + glx_thread_message_loop_(message_loop) { } GlVideoRenderer::~GlVideoRenderer() { @@ -29,9 +30,13 @@ bool GlVideoRenderer::IsMediaFormatSupported( return ParseMediaFormat(media_format, NULL, NULL, NULL, NULL); } -void GlVideoRenderer::OnStop() { +void GlVideoRenderer::OnStop(media::FilterCallback* callback) { glXMakeCurrent(display_, 0, NULL); glXDestroyContext(display_, gl_context_); + if (callback) { + callback->Run(); + delete callback; + } } static GLXContext InitGLContext(Display* display, Window window) { diff --git a/media/tools/player_x11/gl_video_renderer.h b/media/tools/player_x11/gl_video_renderer.h index 24599bf..71f8d77 100644 --- a/media/tools/player_x11/gl_video_renderer.h +++ b/media/tools/player_x11/gl_video_renderer.h @@ -9,17 +9,20 @@ #include "base/lock.h" #include "base/scoped_ptr.h" #include "media/base/factory.h" +#include "media/base/filters.h" #include "media/filters/video_renderer_base.h" class GlVideoRenderer : public media::VideoRendererBase { public: static media::FilterFactory* CreateFactory(Display* display, - Window window) { - return new media::FilterFactoryImpl2< - GlVideoRenderer, Display*, Window>(display, window); + Window window, + MessageLoop* message_loop) { + return new media::FilterFactoryImpl3< + GlVideoRenderer, Display*, Window, MessageLoop*>(display, window, + message_loop); } - GlVideoRenderer(Display* display, Window window); + GlVideoRenderer(Display* display, Window window, MessageLoop* message_loop); // This method is called to paint the current video frame to the assigned // window. @@ -30,10 +33,6 @@ 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_; } @@ -41,7 +40,7 @@ class GlVideoRenderer : public media::VideoRendererBase { protected: // VideoRendererBase implementation. virtual bool OnInitialize(media::VideoDecoder* decoder); - virtual void OnStop(); + virtual void OnStop(media::FilterCallback* callback); virtual void OnFrameAvailable(); private: diff --git a/media/tools/player_x11/gles_video_renderer.cc b/media/tools/player_x11/gles_video_renderer.cc index 4bca69c..0b36e74 100644 --- a/media/tools/player_x11/gles_video_renderer.cc +++ b/media/tools/player_x11/gles_video_renderer.cc @@ -11,14 +11,15 @@ #include <X11/extensions/Xcomposite.h> #include "media/base/buffers.h" -#include "media/base/pipeline.h" #include "media/base/filter_host.h" +#include "media/base/pipeline.h" #include "media/base/video_frame.h" #include "media/base/yuv_convert.h" GlesVideoRenderer* GlesVideoRenderer::instance_ = NULL; -GlesVideoRenderer::GlesVideoRenderer(Display* display, Window window) +GlesVideoRenderer::GlesVideoRenderer(Display* display, Window window, + MessageLoop* message_loop) : egl_create_image_khr_(NULL), egl_destroy_image_khr_(NULL), display_(display), @@ -26,7 +27,7 @@ GlesVideoRenderer::GlesVideoRenderer(Display* display, Window window) egl_display_(NULL), egl_surface_(NULL), egl_context_(NULL), - glx_thread_message_loop_(NULL) { + glx_thread_message_loop_(message_loop) { } GlesVideoRenderer::~GlesVideoRenderer() { @@ -38,11 +39,17 @@ bool GlesVideoRenderer::IsMediaFormatSupported( return ParseMediaFormat(media_format, NULL, NULL, NULL, NULL); } -void GlesVideoRenderer::OnStop() { - // TODO(hclam): Context switching seems to be broek so the following - // calls may fail. Need to fix them. - eglMakeCurrent(egl_display_, EGL_NO_SURFACE, - EGL_NO_SURFACE, EGL_NO_CONTEXT); +void GlesVideoRenderer::OnStop(media::FilterCallback* callback) { + if (glx_thread_message_loop()) { + glx_thread_message_loop()->PostTask(FROM_HERE, + NewRunnableMethod(this, &GlesVideoRenderer::DeInitializeGlesTask, + callback)); + } +} + +void GlesVideoRenderer::DeInitializeGlesTask(media::FilterCallback* callback) { + DCHECK_EQ(glx_thread_message_loop(), MessageLoop::current()); + for (size_t i = 0; i < egl_frames_.size(); ++i) { scoped_refptr<media::VideoFrame> frame = egl_frames_[i].first; if (frame->private_buffer()) @@ -51,8 +58,15 @@ void GlesVideoRenderer::OnStop() { glDeleteTextures(1, &egl_frames_[i].second); } egl_frames_.clear(); + eglMakeCurrent(egl_display_, EGL_NO_SURFACE, + EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(egl_display_, egl_context_); eglDestroySurface(egl_display_, egl_surface_); + + if (callback) { + callback->Run(); + delete callback; + } } // Matrix used for the YUV to RGB conversion. diff --git a/media/tools/player_x11/gles_video_renderer.h b/media/tools/player_x11/gles_video_renderer.h index 195f33e..27780b6 100644 --- a/media/tools/player_x11/gles_video_renderer.h +++ b/media/tools/player_x11/gles_video_renderer.h @@ -13,18 +13,21 @@ #include "base/lock.h" #include "base/scoped_ptr.h" #include "media/base/factory.h" +#include "media/base/filters.h" #include "media/base/video_frame.h" #include "media/filters/video_renderer_base.h" class GlesVideoRenderer : public media::VideoRendererBase { public: static media::FilterFactory* CreateFactory(Display* display, - Window window) { - return new media::FilterFactoryImpl2< - GlesVideoRenderer, Display*, Window>(display, window); + Window window, + MessageLoop* message_loop) { + return new media::FilterFactoryImpl3< + GlesVideoRenderer, Display*, Window, MessageLoop*>(display, window, + message_loop); } - GlesVideoRenderer(Display* display, Window window); + GlesVideoRenderer(Display* display, Window window, MessageLoop* message_loop); // This method is called to paint the current video frame to the assigned // window. @@ -35,10 +38,6 @@ 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_; } @@ -46,7 +45,7 @@ class GlesVideoRenderer : public media::VideoRendererBase { protected: // VideoRendererBase implementation. virtual bool OnInitialize(media::VideoDecoder* decoder); - virtual void OnStop(); + virtual void OnStop(media::FilterCallback* callback); virtual void OnFrameAvailable(); private: @@ -62,6 +61,8 @@ class GlesVideoRenderer : public media::VideoRendererBase { void CreateTextureAndProgramEgl(); void CreateTextureAndProgramYuv2Rgb(); + void DeInitializeGlesTask(media::FilterCallback* callback); + PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr_; PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image_khr_; diff --git a/media/tools/player_x11/player_x11.cc b/media/tools/player_x11/player_x11.cc index 3833b4e..8811b98 100644 --- a/media/tools/player_x11/player_x11.cc +++ b/media/tools/player_x11/player_x11.cc @@ -68,7 +68,8 @@ bool InitX11() { bool InitPipeline(MessageLoop* message_loop, const char* filename, bool enable_audio, - scoped_refptr<media::PipelineImpl>* pipeline) { + scoped_refptr<media::PipelineImpl>* pipeline, + MessageLoop* paint_message_loop) { // Initialize OpenMAX. if (CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableOpenMax) && @@ -94,7 +95,8 @@ bool InitPipeline(MessageLoop* message_loop, factories->AddFactory(media::OmxVideoDecoder::CreateFactory()); } factories->AddFactory(media::FFmpegVideoDecoder::CreateFactory()); - factories->AddFactory(Renderer::CreateFactory(g_display, g_window)); + factories->AddFactory(Renderer::CreateFactory(g_display, g_window, + paint_message_loop)); if (enable_audio) { factories->AddFactory(media::AudioRendererImpl::CreateFilterFactory()); @@ -129,6 +131,7 @@ void TerminateHandler(int signal) { void PeriodicalUpdate( media::PipelineImpl* pipeline, MessageLoop* message_loop, + base::WaitableEvent* stop_event, bool audio_only) { if (!g_running) { message_loop->Quit(); @@ -172,7 +175,9 @@ void PeriodicalUpdate( g_running = false; // QuitNow is more responsive than Quit since renderer_base is till // posting paint messages. - message_loop->QuitNow(); + pipeline->Stop(NewCallback(stop_event, + &base::WaitableEvent::Signal)); + message_loop->Quit(); return; } else if (key == XK_space) { if (pipeline->GetPlaybackRate() < 0.01f) // paused @@ -189,7 +194,7 @@ void PeriodicalUpdate( message_loop->PostDelayedTask(FROM_HERE, NewRunnableFunction(PeriodicalUpdate, pipeline, - message_loop, audio_only), 10); + message_loop, stop_event, audio_only), 10); } int main(int argc, char** argv) { @@ -227,31 +232,24 @@ int main(int argc, char** argv) { scoped_ptr<base::Thread> thread; scoped_refptr<media::PipelineImpl> pipeline; MessageLoop message_loop; + base::WaitableEvent stop_event(false, false); thread.reset(new base::Thread("PipelineThread")); thread->Start(); if (InitPipeline(thread->message_loop(), filename.c_str(), - enable_audio, &pipeline)) { + enable_audio, &pipeline, &message_loop)) { // Main loop of the application. g_running = true; // Check if video is present. audio_only = !pipeline->IsRendered(media::mime_type::kMajorTypeVideo); - 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, pipeline.get(), - &message_loop, audio_only)); + &message_loop, &stop_event, audio_only)); message_loop.Run(); // Need to wait for pipeline to be fully stopped before stopping the thread. - base::WaitableEvent event(false, false); - pipeline->Stop(NewCallback(&event, &base::WaitableEvent::Signal)); - event.Wait(); + stop_event.Wait(); } 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 a1a9f15..881a719 100644 --- a/media/tools/player_x11/x11_video_renderer.cc +++ b/media/tools/player_x11/x11_video_renderer.cc @@ -53,13 +53,14 @@ static XRenderPictFormat* GetRenderARGB32Format(Display* dpy) { return pictformat; } -X11VideoRenderer::X11VideoRenderer(Display* display, Window window) +X11VideoRenderer::X11VideoRenderer(Display* display, Window window, + MessageLoop* message_loop) : display_(display), window_(window), image_(NULL), picture_(0), use_render_(false), - glx_thread_message_loop_(NULL) { + glx_thread_message_loop_(message_loop) { } X11VideoRenderer::~X11VideoRenderer() { @@ -71,11 +72,15 @@ bool X11VideoRenderer::IsMediaFormatSupported( return ParseMediaFormat(media_format, NULL, NULL, NULL, NULL); } -void X11VideoRenderer::OnStop() { +void X11VideoRenderer::OnStop(media::FilterCallback* callback) { if (image_) { XDestroyImage(image_); } XRenderFreePicture(display_, picture_); + if (callback) { + callback->Run(); + delete callback; + } } bool X11VideoRenderer::OnInitialize(media::VideoDecoder* decoder) { diff --git a/media/tools/player_x11/x11_video_renderer.h b/media/tools/player_x11/x11_video_renderer.h index 5b7a954..2bd9dc4 100644 --- a/media/tools/player_x11/x11_video_renderer.h +++ b/media/tools/player_x11/x11_video_renderer.h @@ -10,17 +10,20 @@ #include "base/lock.h" #include "base/scoped_ptr.h" #include "media/base/factory.h" +#include "media/base/filters.h" #include "media/filters/video_renderer_base.h" class X11VideoRenderer : public media::VideoRendererBase { public: static media::FilterFactory* CreateFactory(Display* display, - Window window) { - return new media::FilterFactoryImpl2< - X11VideoRenderer, Display*, Window>(display, window); + Window window, + MessageLoop* message_loop) { + return new media::FilterFactoryImpl3< + X11VideoRenderer, Display*, Window, MessageLoop*>(display, window, + message_loop); } - X11VideoRenderer(Display* display, Window window); + X11VideoRenderer(Display* display, Window window, MessageLoop* message_loop); // This method is called to paint the current video frame to the assigned // window. @@ -31,10 +34,6 @@ 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_; } @@ -42,7 +41,7 @@ class X11VideoRenderer : public media::VideoRendererBase { protected: // VideoRendererBase implementation. virtual bool OnInitialize(media::VideoDecoder* decoder); - virtual void OnStop(); + virtual void OnStop(media::FilterCallback* callback); virtual void OnFrameAvailable(); private: |