Re-subimission of https://codereview.chromium.org/1041213003/
[chromium-blink-merge.git] / content / renderer / pepper / pepper_platform_video_capture.cc
blob68ef4800402f9291527de8b0a1581ccff5bd7ce8
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"
7 #include "base/bind.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"
16 #include "url/gurl.h"
18 namespace content {
20 PepperPlatformVideoCapture::PepperPlatformVideoCapture(
21 int render_frame_id,
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),
27 session_id_(0),
28 handler_(handler),
29 pending_open_device_(false),
30 pending_open_device_id_(-1),
31 weak_factory_(this) {
32 // We need to open the device and obtain the label and session ID before
33 // initializing.
34 PepperMediaDeviceManager* const device_manager = GetMediaDeviceManager();
35 if (device_manager) {
36 pending_open_device_id_ = device_manager->OpenDevice(
37 PP_DEVICETYPE_DEV_VIDEOCAPTURE,
38 device_id,
39 document_url,
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())
50 return;
51 VideoCaptureImplManager* manager =
52 RenderThreadImpl::current()->video_capture_impl_manager();
53 stop_capture_cb_ =
54 manager->StartCapture(session_id_,
55 params,
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())
67 return;
68 stop_capture_cb_.Run();
69 stop_capture_cb_.Reset();
72 void PepperPlatformVideoCapture::DetachEventHandler() {
73 handler_ = NULL;
74 StopCapture();
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();
81 if (device_manager)
82 device_manager->CloseDevice(label_);
83 label_.clear();
85 if (pending_open_device_) {
86 PepperMediaDeviceManager* const device_manager = GetMediaDeviceManager();
87 if (device_manager)
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,
102 bool succeeded,
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;
109 if (succeeded) {
110 label_ = label;
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_);
118 if (handler_)
119 handler_->OnInitialized(succeeded);
122 void PepperPlatformVideoCapture::OnStateUpdate(VideoCaptureState state) {
123 if (!handler_)
124 return;
125 switch (state) {
126 case VIDEO_CAPTURE_STATE_STARTED:
127 handler_->OnStarted();
128 break;
129 case VIDEO_CAPTURE_STATE_STOPPED:
130 handler_->OnStopped();
131 break;
132 case VIDEO_CAPTURE_STATE_PAUSED:
133 handler_->OnPaused();
134 break;
135 case VIDEO_CAPTURE_STATE_ERROR:
136 handler_->OnError();
137 break;
138 default:
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