summaryrefslogtreecommitdiffstats
path: root/media
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
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')
-rw-r--r--media/base/factory.h26
-rw-r--r--media/filters/video_renderer_base.cc59
-rw-r--r--media/filters/video_renderer_base.h7
-rw-r--r--media/filters/video_renderer_base_unittest.cc10
-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
14 files changed, 146 insertions, 99 deletions
diff --git a/media/base/factory.h b/media/base/factory.h
index ade8990..49bd868 100644
--- a/media/base/factory.h
+++ b/media/base/factory.h
@@ -187,6 +187,32 @@ class FilterFactoryImpl2 : public FilterFactory {
DISALLOW_COPY_AND_ASSIGN(FilterFactoryImpl2);
};
+template <class Filter, class A, class B, class C>
+class FilterFactoryImpl3 : public FilterFactory {
+ public:
+ FilterFactoryImpl3(A a, B b, C c) : a_(a), b_(b), c_(c) {}
+
+ protected:
+ virtual MediaFilter* Create(FilterType filter_type,
+ const MediaFormat& media_format) {
+ Filter* filter = NULL;
+ if (Filter::filter_type() == filter_type &&
+ Filter::IsMediaFormatSupported(media_format)) {
+ filter = new Filter(a_, b_, c_);
+ }
+ return filter;
+ }
+
+ private:
+ ~FilterFactoryImpl3() {}
+
+ A const a_;
+ B const b_;
+ C const c_;
+
+ DISALLOW_COPY_AND_ASSIGN(FilterFactoryImpl3);
+};
+
//------------------------------------------------------------------------------
// This specialized factory is typically used by test programs that create
diff --git a/media/filters/video_renderer_base.cc b/media/filters/video_renderer_base.cc
index 6eeed60..da80221 100644
--- a/media/filters/video_renderer_base.cc
+++ b/media/filters/video_renderer_base.cc
@@ -111,30 +111,25 @@ void VideoRendererBase::Pause(FilterCallback* callback) {
}
void VideoRendererBase::Stop(FilterCallback* callback) {
- AutoLock auto_lock(lock_);
- state_ = kStopped;
-
- // Signal the subclass we're stopping.
- // TODO(scherkus): do we trust subclasses not to do something silly while
- // we're holding the lock?
- OnStop();
-
- // Clean up our thread if present.
- if (thread_) {
- // Signal the thread since it's possible to get stopped with the video
- // thread waiting for a read to complete.
- frame_available_.Signal();
- {
- AutoUnlock auto_unlock(lock_);
- PlatformThread::Join(thread_);
+ {
+ AutoLock auto_lock(lock_);
+ state_ = kStopped;
+
+ // Clean up our thread if present.
+ if (thread_) {
+ // Signal the thread since it's possible to get stopped with the video
+ // thread waiting for a read to complete.
+ frame_available_.Signal();
+ {
+ AutoUnlock auto_unlock(lock_);
+ PlatformThread::Join(thread_);
+ }
+ thread_ = kNullThreadHandle;
}
- thread_ = kNullThreadHandle;
- }
- if (callback) {
- callback->Run();
- delete callback;
}
+ // Signal the subclass we're stopping.
+ OnStop(callback);
}
void VideoRendererBase::SetPlaybackRate(float playback_rate) {
@@ -154,17 +149,6 @@ void VideoRendererBase::Seek(base::TimeDelta time, FilterCallback* callback) {
for (size_t i = 0; i < kMaxFrames; ++i) {
ScheduleRead_Locked();
}
-
- // TODO(wjia): This would be removed if "Paint" thread allows renderer to
- // allocate EGL images before filters are in playing state.
- if (uses_egl_image()) {
- state_ = kPaused;
- VideoFrame::CreateBlackFrame(width_, height_, &current_frame_);
- DCHECK(current_frame_);
- OnFrameAvailable();
- seek_callback_->Run();
- seek_callback_.reset();
- }
}
void VideoRendererBase::Initialize(VideoDecoder* decoder,
@@ -283,6 +267,9 @@ void VideoRendererBase::ThreadMain() {
if (!frames_.empty() && !frames_.front()->IsEndOfStream()) {
DCHECK_EQ(current_frame_, frames_.front());
frames_.pop_front();
+ // TODO(wjia): Make sure |current_frame_| is not used by renderer any
+ // more. Could use fence or delay recycle by one frame. But both have
+ // problems.
if (uses_egl_image() &&
media::VideoFrame::TYPE_EGL_IMAGE == current_frame_->type()) {
decoder_->FillThisBuffer(current_frame_);
@@ -344,6 +331,11 @@ void VideoRendererBase::ThreadMain() {
void VideoRendererBase::GetCurrentFrame(scoped_refptr<VideoFrame>* frame_out) {
AutoLock auto_lock(lock_);
+
+ if (state_ == kStopped) {
+ VideoFrame::CreateBlackFrame(width_, height_, frame_out);
+ return;
+ }
// We should have initialized and have the current frame.
DCHECK(state_ == kPaused || state_ == kSeeking || state_ == kPlaying ||
state_ == kEnded);
@@ -367,9 +359,6 @@ void VideoRendererBase::OnFillBufferDone(scoped_refptr<VideoFrame> frame) {
// Enqueue the frame.
frames_.push_back(frame);
- if (uses_egl_image() &&
- media::VideoFrame::TYPE_EGL_IMAGE != current_frame_->type())
- current_frame_ = frame;
DCHECK_LE(frames_.size(), kMaxFrames);
frame_available_.Signal();
diff --git a/media/filters/video_renderer_base.h b/media/filters/video_renderer_base.h
index 9f9c865..a0bb0f4 100644
--- a/media/filters/video_renderer_base.h
+++ b/media/filters/video_renderer_base.h
@@ -68,10 +68,11 @@ class VideoRendererBase : public VideoRenderer,
// output surfaces. Implementors should NOT call InitializationComplete().
virtual bool OnInitialize(VideoDecoder* decoder) = 0;
- // Subclass interface. Called before any other stopping actions takes place.
+ // Subclass interface. Called after all other stopping actions take place.
//
- // Implementors should perform any necessary cleanup before returning.
- virtual void OnStop() = 0;
+ // Implementors should perform any necessary cleanup before calling the
+ // callback.
+ virtual void OnStop(FilterCallback* callback) = 0;
// Subclass interface. Called when a new frame is ready for display, which
// can be accessed via GetCurrentFrame().
diff --git a/media/filters/video_renderer_base_unittest.cc b/media/filters/video_renderer_base_unittest.cc
index 02b352a..ae21320 100644
--- a/media/filters/video_renderer_base_unittest.cc
+++ b/media/filters/video_renderer_base_unittest.cc
@@ -4,6 +4,7 @@
#include "base/callback.h"
#include "base/stl_util-inl.h"
+#include "media/base/callback.h"
#include "media/base/data_buffer.h"
#include "media/base/mock_filter_host.h"
#include "media/base/mock_filters.h"
@@ -21,6 +22,9 @@ using ::testing::ReturnRef;
using ::testing::StrictMock;
namespace media {
+ACTION(OnStop) {
+ AutoCallbackRunner auto_runner(arg0);
+}
// Mocked subclass of VideoRendererBase for testing purposes.
class MockVideoRendererBase : public VideoRendererBase {
@@ -30,7 +34,7 @@ class MockVideoRendererBase : public VideoRendererBase {
// VideoRendererBase implementation.
MOCK_METHOD1(OnInitialize, bool(VideoDecoder* decoder));
- MOCK_METHOD0(OnStop, void());
+ MOCK_METHOD1(OnStop, void(FilterCallback* callback));
MOCK_METHOD0(OnFrameAvailable, void());
// Used for verifying check points during tests.
@@ -68,7 +72,9 @@ class VideoRendererBaseTest : public ::testing::Test {
read_queue_.clear();
// Expect a call into the subclass.
- EXPECT_CALL(*renderer_, OnStop());
+ EXPECT_CALL(*renderer_, OnStop(NotNull()))
+ .WillOnce(DoAll(OnStop(), Return()))
+ .RetiresOnSaturation();
EXPECT_CALL(callback_, OnFilterCallback());
EXPECT_CALL(callback_, OnCallbackDestroyed());
renderer_->Stop(callback_.NewCallback());
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: