diff options
author | piman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-02 19:59:15 +0000 |
---|---|---|
committer | piman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-02 19:59:15 +0000 |
commit | 15397c469e1d2ab4113415cd95d802f5e0fbf38a (patch) | |
tree | 0e1201e981a8217a4282ac05a4316f4131f54162 /media | |
parent | 86c6a0b5a5c08aa5ed1244e4a4fc2796393ad5a5 (diff) | |
download | chromium_src-15397c469e1d2ab4113415cd95d802f5e0fbf38a.zip chromium_src-15397c469e1d2ab4113415cd95d802f5e0fbf38a.tar.gz chromium_src-15397c469e1d2ab4113415cd95d802f5e0fbf38a.tar.bz2 |
Add a proxy for thread-hopping VideoCapture::EventHandler.
BUG=None
TEST=Video Capture PPAPI example (in later CL)
Review URL: http://codereview.chromium.org/7537037
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@95140 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r-- | media/media.gyp | 2 | ||||
-rw-r--r-- | media/video/capture/video_capture_proxy.cc | 137 | ||||
-rw-r--r-- | media/video/capture/video_capture_proxy.h | 94 |
3 files changed, 233 insertions, 0 deletions
diff --git a/media/media.gyp b/media/media.gyp index d024f57..efcb8a6 100644 --- a/media/media.gyp +++ b/media/media.gyp @@ -186,6 +186,8 @@ 'video/capture/linux/video_capture_device_linux.h', 'video/capture/video_capture.h', 'video/capture/video_capture_device.h', + 'video/capture/video_capture_proxy.cc', + 'video/capture/video_capture_proxy.h', 'video/capture/win/filter_base_win.cc', 'video/capture/win/filter_base_win.h', 'video/capture/win/pin_base_win.cc', diff --git a/media/video/capture/video_capture_proxy.cc b/media/video/capture/video_capture_proxy.cc new file mode 100644 index 0000000..efd2bef --- /dev/null +++ b/media/video/capture/video_capture_proxy.cc @@ -0,0 +1,137 @@ +// Copyright (c) 2011 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. + +#include "media/video/capture/video_capture_proxy.h" + +#include "base/message_loop_proxy.h" + +namespace { + +// Called on VC thread: extracts the state out of the VideoCapture, and +// serialize it into a VideoCaptureState. +media::VideoCaptureHandlerProxy::VideoCaptureState GetState( + media::VideoCapture* capture) { + media::VideoCaptureHandlerProxy::VideoCaptureState state; + state.started = capture->CaptureStarted(); + state.width = capture->CaptureWidth(); + state.height = capture->CaptureHeight(); + state.frame_rate = capture->CaptureFrameRate(); + return state; +} + +} // anonymous namespace + +namespace media { + +VideoCaptureHandlerProxy::VideoCaptureHandlerProxy( + VideoCapture::EventHandler* proxied, + scoped_refptr<base::MessageLoopProxy> main_message_loop) + : proxied_(proxied), + main_message_loop_(main_message_loop) { +} + +VideoCaptureHandlerProxy::~VideoCaptureHandlerProxy() { +} + +void VideoCaptureHandlerProxy::OnStarted(VideoCapture* capture) { + main_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( + this, + &VideoCaptureHandlerProxy::OnStartedOnMainThread, + capture, + GetState(capture))); +} + +void VideoCaptureHandlerProxy::OnStopped(VideoCapture* capture) { + main_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( + this, + &VideoCaptureHandlerProxy::OnStoppedOnMainThread, + capture, + GetState(capture))); +} + +void VideoCaptureHandlerProxy::OnPaused(VideoCapture* capture) { + main_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( + this, + &VideoCaptureHandlerProxy::OnPausedOnMainThread, + capture, + GetState(capture))); +} + +void VideoCaptureHandlerProxy::OnError(VideoCapture* capture, int error_code) { + main_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( + this, + &VideoCaptureHandlerProxy::OnErrorOnMainThread, + capture, + GetState(capture), + error_code)); +} + +void VideoCaptureHandlerProxy::OnBufferReady( + VideoCapture* capture, + scoped_refptr<VideoCapture::VideoFrameBuffer> buffer) { + main_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( + this, + &VideoCaptureHandlerProxy::OnBufferReadyOnMainThread, + capture, + GetState(capture), + buffer)); +} + +void VideoCaptureHandlerProxy::OnDeviceInfoReceived( + VideoCapture* capture, + const VideoCaptureParams& device_info) { + main_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( + this, + &VideoCaptureHandlerProxy::OnDeviceInfoReceivedOnMainThread, + capture, + GetState(capture), + device_info)); +} + +void VideoCaptureHandlerProxy::OnStartedOnMainThread( + VideoCapture* capture, + const VideoCaptureState& state) { + state_ = state; + proxied_->OnStarted(capture); +} + +void VideoCaptureHandlerProxy::OnStoppedOnMainThread( + VideoCapture* capture, + const VideoCaptureState& state) { + state_ = state; + proxied_->OnStopped(capture); +} + +void VideoCaptureHandlerProxy::OnPausedOnMainThread( + VideoCapture* capture, + const VideoCaptureState& state) { + state_ = state; + proxied_->OnPaused(capture); +} + +void VideoCaptureHandlerProxy::OnErrorOnMainThread( + VideoCapture* capture, + const VideoCaptureState& state, + int error_code) { + state_ = state; + proxied_->OnError(capture, error_code); +} + +void VideoCaptureHandlerProxy::OnBufferReadyOnMainThread( + VideoCapture* capture, + const VideoCaptureState& state, + scoped_refptr<VideoCapture::VideoFrameBuffer> buffer) { + state_ = state; + proxied_->OnBufferReady(capture, buffer); +} + +void VideoCaptureHandlerProxy::OnDeviceInfoReceivedOnMainThread( + VideoCapture* capture, + const VideoCaptureState& state, + const VideoCaptureParams& device_info) { + state_ = state; + proxied_->OnDeviceInfoReceived(capture, device_info); +} + +} // namespace media diff --git a/media/video/capture/video_capture_proxy.h b/media/video/capture/video_capture_proxy.h new file mode 100644 index 0000000..3e51fd4 --- /dev/null +++ b/media/video/capture/video_capture_proxy.h @@ -0,0 +1,94 @@ +// Copyright (c) 2011 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. + +#ifndef MEDIA_VIDEO_CAPTURE_VIDEO_CAPTURE_PROXY_H_ +#define MEDIA_VIDEO_CAPTURE_VIDEO_CAPTURE_PROXY_H_ + +#include "base/compiler_specific.h" +#include "base/memory/ref_counted.h" +#include "base/task.h" +#include "media/video/capture/video_capture.h" + +namespace base { +class MessageLoopProxy; +} + +namespace media { + +// This is a helper class to proxy a VideoCapture::EventHandler. In the renderer +// process, the VideoCaptureImpl calls its handler on a "Video Capture" thread, +// this class allows seamless proxying to another thread ("main thread"), which +// would be the thread where the instance of this class is created. The +// "proxied" handler is then called on that thread. +// Since the VideoCapture is living on the "Video Capture" thread, querying its +// state from the "main thread" is fundamentally racy. Instead this class keeps +// track of the state every time it is called by the VideoCapture (on the VC +// thread), and forwards that information to the main thread. +class VideoCaptureHandlerProxy : public VideoCapture::EventHandler { + public: + struct VideoCaptureState { + VideoCaptureState() : started(false), width(0), height(0), frame_rate(0) {} + bool started; + int width; + int height; + int frame_rate; + }; + + // Called on main thread. + VideoCaptureHandlerProxy( + VideoCapture::EventHandler* proxied, + scoped_refptr<base::MessageLoopProxy> main_message_loop); + virtual ~VideoCaptureHandlerProxy(); + + // Retrieves the state of the VideoCapture. Must be called on main thread. + const VideoCaptureState& state() const { return state_; } + VideoCapture::EventHandler* proxied() const { return proxied_; } + + // VideoCapture::EventHandler implementation, called on VC thread. + virtual void OnStarted(VideoCapture* capture) OVERRIDE; + virtual void OnStopped(VideoCapture* capture) OVERRIDE; + virtual void OnPaused(VideoCapture* capture) OVERRIDE; + virtual void OnError(VideoCapture* capture, int error_code) OVERRIDE; + virtual void OnBufferReady( + VideoCapture* capture, + scoped_refptr<VideoCapture::VideoFrameBuffer> buffer) OVERRIDE; + virtual void OnDeviceInfoReceived( + VideoCapture* capture, + const VideoCaptureParams& device_info) OVERRIDE; + + private: + // Called on main thread. + void OnStartedOnMainThread( + VideoCapture* capture, + const VideoCaptureState& state); + void OnStoppedOnMainThread( + VideoCapture* capture, + const VideoCaptureState& state); + void OnPausedOnMainThread( + VideoCapture* capture, + const VideoCaptureState& state); + void OnErrorOnMainThread( + VideoCapture* capture, + const VideoCaptureState& state, + int error_code); + void OnBufferReadyOnMainThread( + VideoCapture* capture, + const VideoCaptureState& state, + scoped_refptr<VideoCapture::VideoFrameBuffer> buffer); + void OnDeviceInfoReceivedOnMainThread( + VideoCapture* capture, + const VideoCaptureState& state, + const VideoCaptureParams& device_info); + + // Only accessed from main thread. + VideoCapture::EventHandler* proxied_; + VideoCaptureState state_; + + scoped_refptr<base::MessageLoopProxy> main_message_loop_; +}; + +} // namespace media +DISABLE_RUNNABLE_METHOD_REFCOUNT(media::VideoCaptureHandlerProxy); + +#endif // MEDIA_VIDEO_CAPTURE_VIDEO_CAPTURE_PROXY_H_ |