1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/renderer/pepper/pepper_platform_video_capture.h"
8 #include "base/logging.h"
9 #include "base/message_loop/message_loop_proxy.h"
10 #include "content/renderer/media/video_capture_impl_manager.h"
11 #include "content/renderer/pepper/pepper_media_device_manager.h"
12 #include "content/renderer/pepper/pepper_video_capture_host.h"
13 #include "content/renderer/render_frame_impl.h"
14 #include "content/renderer/render_thread_impl.h"
15 #include "media/base/bind_to_current_loop.h"
20 PepperPlatformVideoCapture::PepperPlatformVideoCapture(
22 const std::string
& device_id
,
23 const GURL
& document_url
,
24 PepperVideoCaptureHost
* handler
)
25 : render_frame_id_(render_frame_id
),
26 device_id_(device_id
),
29 pending_open_device_(false),
30 pending_open_device_id_(-1),
32 // We need to open the device and obtain the label and session ID before
34 PepperMediaDeviceManager
* const device_manager
= GetMediaDeviceManager();
36 pending_open_device_id_
= device_manager
->OpenDevice(
37 PP_DEVICETYPE_DEV_VIDEOCAPTURE
,
40 base::Bind(&PepperPlatformVideoCapture::OnDeviceOpened
,
41 weak_factory_
.GetWeakPtr()));
42 pending_open_device_
= true;
46 void PepperPlatformVideoCapture::StartCapture(
47 const media::VideoCaptureParams
& params
) {
48 DCHECK(thread_checker_
.CalledOnValidThread());
49 if (!stop_capture_cb_
.is_null())
51 VideoCaptureImplManager
* manager
=
52 RenderThreadImpl::current()->video_capture_impl_manager();
54 manager
->StartCapture(session_id_
,
56 media::BindToCurrentLoop(base::Bind(
57 &PepperPlatformVideoCapture::OnStateUpdate
,
58 weak_factory_
.GetWeakPtr())),
59 media::BindToCurrentLoop(base::Bind(
60 &PepperPlatformVideoCapture::OnFrameReady
,
61 weak_factory_
.GetWeakPtr())));
64 void PepperPlatformVideoCapture::StopCapture() {
65 DCHECK(thread_checker_
.CalledOnValidThread());
66 if (stop_capture_cb_
.is_null())
68 stop_capture_cb_
.Run();
69 stop_capture_cb_
.Reset();
72 void PepperPlatformVideoCapture::DetachEventHandler() {
75 if (!release_device_cb_
.is_null()) {
76 release_device_cb_
.Run();
77 release_device_cb_
.Reset();
79 if (!label_
.empty()) {
80 PepperMediaDeviceManager
* const device_manager
= GetMediaDeviceManager();
82 device_manager
->CloseDevice(label_
);
85 if (pending_open_device_
) {
86 PepperMediaDeviceManager
* const device_manager
= GetMediaDeviceManager();
88 device_manager
->CancelOpenDevice(pending_open_device_id_
);
89 pending_open_device_
= false;
90 pending_open_device_id_
= -1;
94 PepperPlatformVideoCapture::~PepperPlatformVideoCapture() {
95 DCHECK(stop_capture_cb_
.is_null());
96 DCHECK(release_device_cb_
.is_null());
97 DCHECK(label_
.empty());
98 DCHECK(!pending_open_device_
);
101 void PepperPlatformVideoCapture::OnDeviceOpened(int request_id
,
103 const std::string
& label
) {
104 pending_open_device_
= false;
105 pending_open_device_id_
= -1;
107 PepperMediaDeviceManager
* const device_manager
= GetMediaDeviceManager();
108 succeeded
= succeeded
&& device_manager
;
111 session_id_
= device_manager
->GetSessionID(
112 PP_DEVICETYPE_DEV_VIDEOCAPTURE
, label
);
113 VideoCaptureImplManager
* manager
=
114 RenderThreadImpl::current()->video_capture_impl_manager();
115 release_device_cb_
= manager
->UseDevice(session_id_
);
119 handler_
->OnInitialized(succeeded
);
122 void PepperPlatformVideoCapture::OnStateUpdate(VideoCaptureState state
) {
126 case VIDEO_CAPTURE_STATE_STARTED
:
127 handler_
->OnStarted();
129 case VIDEO_CAPTURE_STATE_STOPPED
:
130 handler_
->OnStopped();
132 case VIDEO_CAPTURE_STATE_PAUSED
:
133 handler_
->OnPaused();
135 case VIDEO_CAPTURE_STATE_ERROR
:
139 NOTREACHED() << "Unexpected state: " << state
<< ".";
143 void PepperPlatformVideoCapture::OnFrameReady(
144 const scoped_refptr
<media::VideoFrame
>& frame
,
145 const base::TimeTicks
& estimated_capture_time
) {
146 if (handler_
&& !stop_capture_cb_
.is_null())
147 handler_
->OnFrameReady(frame
);
150 PepperMediaDeviceManager
* PepperPlatformVideoCapture::GetMediaDeviceManager() {
151 RenderFrameImpl
* const render_frame
=
152 RenderFrameImpl::FromRoutingID(render_frame_id_
);
153 return render_frame
?
154 PepperMediaDeviceManager::GetForRenderFrame(render_frame
).get() : NULL
;
157 } // namespace content