- add sources.
[platform/framework/web/crosswalk.git] / src / content / renderer / pepper / pepper_platform_video_capture.cc
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.
4
5 #include "content/renderer/pepper/pepper_platform_video_capture.h"
6
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_thread_impl.h"
14 #include "content/renderer/render_view_impl.h"
15 #include "media/video/capture/video_capture_proxy.h"
16 #include "url/gurl.h"
17
18 namespace content {
19
20 PepperPlatformVideoCapture::PepperPlatformVideoCapture(
21     const base::WeakPtr<RenderViewImpl>& render_view,
22     const std::string& device_id,
23     const GURL& document_url,
24     PepperVideoCaptureHost* handler)
25     : render_view_(render_view),
26       device_id_(device_id),
27       session_id_(0),
28       handler_proxy_(new media::VideoCaptureHandlerProxy(
29           this, base::MessageLoopProxy::current())),
30       handler_(handler),
31       video_capture_(NULL),
32       unbalanced_start_(false),
33       pending_open_device_(false),
34       pending_open_device_id_(-1) {
35   // We need to open the device and obtain the label and session ID before
36   // initializing.
37   if (render_view_.get()) {
38     pending_open_device_id_ = GetMediaDeviceManager()->OpenDevice(
39         PP_DEVICETYPE_DEV_VIDEOCAPTURE,
40         device_id,
41         document_url,
42         base::Bind(&PepperPlatformVideoCapture::OnDeviceOpened, this));
43     pending_open_device_ = true;
44   }
45 }
46
47 void PepperPlatformVideoCapture::StartCapture(
48     media::VideoCapture::EventHandler* handler,
49     const media::VideoCaptureParams& params) {
50   DCHECK(handler == handler_);
51
52   if (unbalanced_start_)
53     return;
54
55   if (video_capture_) {
56     unbalanced_start_ = true;
57     AddRef();  // Will be balanced in OnRemoved().
58     video_capture_->StartCapture(handler_proxy_.get(), params);
59   }
60 }
61
62 void PepperPlatformVideoCapture::StopCapture(
63     media::VideoCapture::EventHandler* handler) {
64   DCHECK(handler == handler_);
65   if (!unbalanced_start_)
66     return;
67
68   if (video_capture_) {
69     unbalanced_start_ = false;
70     video_capture_->StopCapture(handler_proxy_.get());
71   }
72 }
73
74 bool PepperPlatformVideoCapture::CaptureStarted() {
75   return handler_proxy_->state().started;
76 }
77
78 int PepperPlatformVideoCapture::CaptureFrameRate() {
79   return handler_proxy_->state().frame_rate;
80 }
81
82 void PepperPlatformVideoCapture::DetachEventHandler() {
83   handler_ = NULL;
84   StopCapture(NULL);
85
86   if (video_capture_) {
87     VideoCaptureImplManager* manager =
88         RenderThreadImpl::current()->video_capture_impl_manager();
89     manager->RemoveDevice(session_id_, handler_proxy_.get());
90     video_capture_ = NULL;
91   }
92
93   if (render_view_.get()) {
94     if (!label_.empty()) {
95       GetMediaDeviceManager()->CloseDevice(label_);
96       label_.clear();
97     }
98     if (pending_open_device_) {
99       GetMediaDeviceManager()->CancelOpenDevice(pending_open_device_id_);
100       pending_open_device_ = false;
101       pending_open_device_id_ = -1;
102     }
103   }
104 }
105
106 void PepperPlatformVideoCapture::OnStarted(VideoCapture* capture) {
107   if (handler_)
108     handler_->OnStarted(capture);
109 }
110
111 void PepperPlatformVideoCapture::OnStopped(VideoCapture* capture) {
112   if (handler_)
113     handler_->OnStopped(capture);
114 }
115
116 void PepperPlatformVideoCapture::OnPaused(VideoCapture* capture) {
117   if (handler_)
118     handler_->OnPaused(capture);
119 }
120
121 void PepperPlatformVideoCapture::OnError(VideoCapture* capture,
122                                          int error_code) {
123   if (handler_)
124     handler_->OnError(capture, error_code);
125 }
126
127 void PepperPlatformVideoCapture::OnRemoved(VideoCapture* capture) {
128   if (handler_)
129     handler_->OnRemoved(capture);
130
131   Release();  // Balance the AddRef() in StartCapture().
132 }
133
134 void PepperPlatformVideoCapture::OnFrameReady(
135     VideoCapture* capture,
136     const scoped_refptr<media::VideoFrame>& frame) {
137   if (handler_)
138     handler_->OnFrameReady(capture, frame);
139 }
140
141 PepperPlatformVideoCapture::~PepperPlatformVideoCapture() {
142   DCHECK(!video_capture_);
143   DCHECK(label_.empty());
144   DCHECK(!pending_open_device_);
145 }
146
147 void PepperPlatformVideoCapture::Initialize() {
148   VideoCaptureImplManager* manager =
149       RenderThreadImpl::current()->video_capture_impl_manager();
150   video_capture_ = manager->AddDevice(session_id_, handler_proxy_.get());
151 }
152
153 void PepperPlatformVideoCapture::OnDeviceOpened(int request_id,
154                                                 bool succeeded,
155                                                 const std::string& label) {
156   pending_open_device_ = false;
157   pending_open_device_id_ = -1;
158
159   succeeded = succeeded && render_view_.get();
160   if (succeeded) {
161     label_ = label;
162     session_id_ = GetMediaDeviceManager()->GetSessionID(
163         PP_DEVICETYPE_DEV_VIDEOCAPTURE, label);
164     Initialize();
165   }
166
167   if (handler_)
168     handler_->OnInitialized(this, succeeded);
169 }
170
171 PepperMediaDeviceManager*
172     PepperPlatformVideoCapture::GetMediaDeviceManager() {
173   return PepperMediaDeviceManager::GetForRenderView(render_view_.get());
174 }
175
176 }  // namespace content