summaryrefslogtreecommitdiffstats
path: root/media/tools
diff options
context:
space:
mode:
authorwjia@google.com <wjia@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-24 19:15:07 +0000
committerwjia@google.com <wjia@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-24 19:15:07 +0000
commit5e83826af14858fca1ebac8281afa75107281e7b (patch)
tree467fbad219ff625270ebe0455dabe4459f1c7e36 /media/tools
parentcc2de439d0fd34aac593b1fabc40f0626c5848e1 (diff)
downloadchromium_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.cc2
-rw-r--r--media/tools/player_wtl/wtl_renderer.cc6
-rw-r--r--media/tools/player_wtl/wtl_renderer.h2
-rw-r--r--media/tools/player_x11/gl_video_renderer.cc11
-rw-r--r--media/tools/player_x11/gl_video_renderer.h17
-rw-r--r--media/tools/player_x11/gles_video_renderer.cc30
-rw-r--r--media/tools/player_x11/gles_video_renderer.h19
-rw-r--r--media/tools/player_x11/player_x11.cc28
-rw-r--r--media/tools/player_x11/x11_video_renderer.cc11
-rw-r--r--media/tools/player_x11/x11_video_renderer.h17
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: