summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorjiesun@google.com <jiesun@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-09 16:00:32 +0000
committerjiesun@google.com <jiesun@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-09 16:00:32 +0000
commitdb9074beb04cd9129f7a1f58bd77c7596ba0f4d2 (patch)
tree392ef77f36075e6d95b7a690119d346e98bed349 /media
parenta65bce4eea95ed4c31c75c726475410e2b245103 (diff)
downloadchromium_src-db9074beb04cd9129f7a1f58bd77c7596ba0f4d2.zip
chromium_src-db9074beb04cd9129f7a1f58bd77c7596ba0f4d2.tar.gz
chromium_src-db9074beb04cd9129f7a1f58bd77c7596ba0f4d2.tar.bz2
change X/GL thread to message loop for injecting task
1. there are need to allocate buffer in this thread, requested by other threads. therefore it is natural to use message loop instead of infinite loop. 2. in the future, gpu command buffer consumer is running on it own thread and own the eglContext. we need to post buffer allocation there, therefore this change make player_x11 more resemble the real workflow in chrome. TEST= glVideoRender on host machine. glesVideoRender/x11VideoRender on arm netbook. BUGS=None Review URL: http://codereview.chromium.org/2724005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@49255 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/tools/player_x11/gl_video_renderer.cc21
-rw-r--r--media/tools/player_x11/gl_video_renderer.h13
-rw-r--r--media/tools/player_x11/gles_video_renderer.cc21
-rw-r--r--media/tools/player_x11/gles_video_renderer.h13
-rw-r--r--media/tools/player_x11/player_x11.cc62
-rw-r--r--media/tools/player_x11/x11_video_renderer.cc21
-rw-r--r--media/tools/player_x11/x11_video_renderer.h13
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);