Index: content/renderer/media/media_stream_video_capturer_source.cc |
diff --git a/content/renderer/media/media_stream_video_capturer_source.cc b/content/renderer/media/media_stream_video_capturer_source.cc |
index 0eb31044e8dbb952b1aa09453634c0ce70828733..b6bc73a2ddaa20f4dfe3f280fbf99970fa72aac2 100644 |
--- a/content/renderer/media/media_stream_video_capturer_source.cc |
+++ b/content/renderer/media/media_stream_video_capturer_source.cc |
@@ -5,11 +5,9 @@ |
#include "content/renderer/media/media_stream_video_capturer_source.h" |
#include "base/bind.h" |
-#include "base/callback_helpers.h" |
#include "base/location.h" |
#include "content/renderer/media/video_capture_impl_manager.h" |
#include "content/renderer/render_thread_impl.h" |
-#include "media/base/bind_to_current_loop.h" |
#include "media/base/video_frame.h" |
namespace { |
@@ -40,27 +38,24 @@ |
device_info.device.type == MEDIA_DESKTOP_VIDEO_CAPTURE), |
got_first_frame_(false) { |
DVLOG(3) << "VideoCapturerDelegate::ctor"; |
- |
- // NULL in unit test. |
+ // RenderThreadImpl::current() may be NULL in testing. |
if (RenderThreadImpl::current()) { |
- VideoCaptureImplManager* manager = |
- RenderThreadImpl::current()->video_capture_impl_manager(); |
- if (manager) |
- release_device_cb_ = manager->UseDevice(session_id_); |
- } |
+ capture_engine_ = RenderThreadImpl::current()->video_capture_impl_manager() |
+ ->UseDevice(device_info.session_id); |
+ DCHECK(capture_engine_); |
+ } |
+ message_loop_proxy_ = base::MessageLoopProxy::current(); |
} |
VideoCapturerDelegate::~VideoCapturerDelegate() { |
DVLOG(3) << "VideoCapturerDelegate::dtor"; |
DCHECK(new_frame_callback_.is_null()); |
- if (!release_device_cb_.is_null()) |
- release_device_cb_.Run(); |
} |
void VideoCapturerDelegate::GetCurrentSupportedFormats( |
int max_requested_width, |
int max_requested_height, |
- const VideoCaptureDeviceFormatsCB& callback) { |
+ const SupportedFormatsCallback& callback) { |
DVLOG(3) << "GetCurrentSupportedFormats(" |
<< " { max_requested_height = " << max_requested_height << "})" |
<< " { max_requested_width = " << max_requested_width << "})"; |
@@ -80,64 +75,85 @@ |
return; |
} |
- // NULL in unit test. |
- if (!RenderThreadImpl::current()) |
- return; |
- VideoCaptureImplManager* manager = |
- RenderThreadImpl::current()->video_capture_impl_manager(); |
- if (!manager) |
- return; |
DCHECK(source_formats_callback_.is_null()); |
source_formats_callback_ = callback; |
- manager->GetDeviceFormatsInUse( |
- session_id_, |
- media::BindToCurrentLoop( |
- base::Bind( |
- &VideoCapturerDelegate::OnDeviceFormatsInUseReceived, this))); |
-} |
- |
-void VideoCapturerDelegate::StartCapture( |
+ capture_engine_->GetDeviceFormatsInUse(base::Bind( |
+ &VideoCapturerDelegate::OnDeviceFormatsInUseReceived, this)); |
+} |
+ |
+void VideoCapturerDelegate::StartDeliver( |
const media::VideoCaptureParams& params, |
- const VideoCaptureDeliverFrameCB& new_frame_callback, |
+ const NewFrameCallback& new_frame_callback, |
const StartedCallback& started_callback) { |
DCHECK(params.requested_format.IsValid()); |
- DCHECK(thread_checker_.CalledOnValidThread()); |
+ DCHECK(message_loop_proxy_->BelongsToCurrentThread()); |
new_frame_callback_ = new_frame_callback; |
started_callback_ = started_callback; |
got_first_frame_ = false; |
- // NULL in unit test. |
- if (!RenderThreadImpl::current()) |
- return; |
- VideoCaptureImplManager* manager = |
- RenderThreadImpl::current()->video_capture_impl_manager(); |
- if (!manager) |
- return; |
- stop_capture_cb_ = |
- manager->StartCapture( |
- session_id_, |
- params, |
- media::BindToCurrentLoop(base::Bind( |
- &VideoCapturerDelegate::OnStateUpdateOnRenderThread, this)), |
- media::BindToCurrentLoop(base::Bind( |
- &VideoCapturerDelegate::OnFrameReadyOnRenderThread, this))); |
-} |
- |
-void VideoCapturerDelegate::StopCapture() { |
+ // Increase the reference count to ensure the object is not deleted until |
+ // it is unregistered in VideoCapturerDelegate::OnRemoved. |
+ AddRef(); |
+ capture_engine_->StartCapture(this, params); |
+} |
+ |
+void VideoCapturerDelegate::StopDeliver() { |
// Immediately make sure we don't provide more frames. |
- DVLOG(3) << "VideoCapturerDelegate::StopCapture()"; |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- if (!stop_capture_cb_.is_null()) { |
- base::ResetAndReturn(&stop_capture_cb_).Run(); |
- } |
+ DVLOG(3) << "VideoCapturerDelegate::StopDeliver()"; |
+ DCHECK(message_loop_proxy_->BelongsToCurrentThread()); |
+ capture_engine_->StopCapture(this); |
new_frame_callback_.Reset(); |
started_callback_.Reset(); |
source_formats_callback_.Reset(); |
} |
+void VideoCapturerDelegate::OnStarted(media::VideoCapture* capture) { |
+ DVLOG(3) << "VideoCapturerDelegate::OnStarted"; |
+ DCHECK(!message_loop_proxy_->BelongsToCurrentThread()); |
+} |
+ |
+void VideoCapturerDelegate::OnStopped(media::VideoCapture* capture) { |
+ DCHECK(!message_loop_proxy_->BelongsToCurrentThread()); |
+} |
+ |
+void VideoCapturerDelegate::OnPaused(media::VideoCapture* capture) { |
+ DCHECK(!message_loop_proxy_->BelongsToCurrentThread()); |
+} |
+ |
+void VideoCapturerDelegate::OnError(media::VideoCapture* capture, |
+ int error_code) { |
+ DVLOG(3) << "VideoCapturerDelegate::OnError"; |
+ DCHECK(!message_loop_proxy_->BelongsToCurrentThread()); |
+ message_loop_proxy_->PostTask( |
+ FROM_HERE, |
+ base::Bind(&VideoCapturerDelegate::OnErrorOnRenderThread, this, capture)); |
+} |
+ |
+void VideoCapturerDelegate::OnRemoved(media::VideoCapture* capture) { |
+ DVLOG(3) << " MediaStreamVideoCapturerSource::OnRemoved"; |
+ DCHECK(!message_loop_proxy_->BelongsToCurrentThread()); |
+ |
+ // Balance the AddRef in StartDeliver. |
+ // This means we are no longer registered as an event handler and can safely |
+ // be deleted. |
+ Release(); |
+} |
+ |
+void VideoCapturerDelegate::OnFrameReady( |
+ media::VideoCapture* capture, |
+ const scoped_refptr<media::VideoFrame>& frame) { |
+ DCHECK(!message_loop_proxy_->BelongsToCurrentThread()); |
+ message_loop_proxy_->PostTask( |
+ FROM_HERE, |
+ base::Bind(&VideoCapturerDelegate::OnFrameReadyOnRenderThread, |
+ this, |
+ capture, |
+ frame)); |
+} |
+ |
void VideoCapturerDelegate::OnFrameReadyOnRenderThread( |
- const scoped_refptr<media::VideoFrame>& frame, |
- const media::VideoCaptureFormat& format) { |
+ media::VideoCapture* capture, |
+ const scoped_refptr<media::VideoFrame>& frame) { |
if (!got_first_frame_) { |
got_first_frame_ = true; |
if (!started_callback_.is_null()) |
@@ -145,54 +161,41 @@ |
} |
if (!new_frame_callback_.is_null()) { |
- new_frame_callback_.Run(frame, format); |
- } |
-} |
- |
-void VideoCapturerDelegate::OnStateUpdateOnRenderThread( |
- VideoCaptureState state) { |
- if (state == VIDEO_CAPTURE_STATE_ERROR && !started_callback_.is_null()) { |
+ new_frame_callback_.Run(frame); |
+ } |
+} |
+ |
+void VideoCapturerDelegate::OnErrorOnRenderThread( |
+ media::VideoCapture* capture) { |
+ if (!started_callback_.is_null()) |
started_callback_.Run(false); |
- } |
} |
void VideoCapturerDelegate::OnDeviceFormatsInUseReceived( |
const media::VideoCaptureFormats& formats_in_use) { |
DVLOG(3) << "OnDeviceFormatsInUseReceived: " << formats_in_use.size(); |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- // StopCapture() might have destroyed |source_formats_callback_| before |
+ DCHECK(message_loop_proxy_ == base::MessageLoopProxy::current()); |
+ // StopDeliver() might have destroyed |source_formats_callback_| before |
// arriving here. |
if (source_formats_callback_.is_null()) |
return; |
- // If there are no formats in use, try to retrieve the whole list of |
- // supported form. |
if (!formats_in_use.empty()) { |
source_formats_callback_.Run(formats_in_use); |
source_formats_callback_.Reset(); |
- return; |
- } |
- |
- // NULL in unit test. |
- if (!RenderThreadImpl::current()) |
- return; |
- VideoCaptureImplManager* manager = |
- RenderThreadImpl::current()->video_capture_impl_manager(); |
- if (!manager) |
- return; |
- manager->GetDeviceSupportedFormats( |
- session_id_, |
- media::BindToCurrentLoop( |
- base::Bind( |
- &VideoCapturerDelegate::OnDeviceSupportedFormatsEnumerated, |
- this))); |
+ } else { |
+ // If there are no formats in use, try to retrieve the whole list of |
+ // supported formats. |
+ capture_engine_->GetDeviceSupportedFormats(base::Bind( |
+ &VideoCapturerDelegate::OnDeviceSupportedFormatsEnumerated, this)); |
+ } |
} |
void VideoCapturerDelegate::OnDeviceSupportedFormatsEnumerated( |
const media::VideoCaptureFormats& formats) { |
DVLOG(3) << "OnDeviceSupportedFormatsEnumerated: " << formats.size() |
<< " received"; |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- // StopCapture() might have destroyed |source_formats_callback_| before |
+ DCHECK(message_loop_proxy_ == base::MessageLoopProxy::current()); |
+ // StopDeliver() might have destroyed |source_formats_callback_| before |
// arriving here. |
if (source_formats_callback_.is_null()) |
return; |
@@ -243,7 +246,7 @@ |
device_info().device.type == MEDIA_DESKTOP_VIDEO_CAPTURE) { |
new_params.allow_resolution_change = true; |
} |
- delegate_->StartCapture( |
+ delegate_->StartDeliver( |
new_params, |
base::Bind(&MediaStreamVideoCapturerSource::DeliverVideoFrame, |
base::Unretained(this)), |
@@ -252,7 +255,7 @@ |
} |
void MediaStreamVideoCapturerSource::StopSourceImpl() { |
- delegate_->StopCapture(); |
+ delegate_->StopDeliver(); |
} |
} // namespace content |