Upstream version 5.34.92.0
[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       unbalanced_start_(false),
32       pending_open_device_(false),
33       pending_open_device_id_(-1) {
34   // We need to open the device and obtain the label and session ID before
35   // initializing.
36   if (render_view_.get()) {
37     pending_open_device_id_ = GetMediaDeviceManager()->OpenDevice(
38         PP_DEVICETYPE_DEV_VIDEOCAPTURE,
39         device_id,
40         document_url,
41         base::Bind(&PepperPlatformVideoCapture::OnDeviceOpened, this));
42     pending_open_device_ = true;
43   }
44 }
45
46 void PepperPlatformVideoCapture::StartCapture(
47     media::VideoCapture::EventHandler* handler,
48     const media::VideoCaptureParams& params) {
49   DCHECK(handler == handler_);
50
51   if (unbalanced_start_)
52     return;
53
54   if (video_capture_) {
55     unbalanced_start_ = true;
56     AddRef();  // Will be balanced in OnRemoved().
57     video_capture_->StartCapture(handler_proxy_.get(), params);
58   }
59 }
60
61 void PepperPlatformVideoCapture::StopCapture(
62     media::VideoCapture::EventHandler* handler) {
63   DCHECK(handler == handler_);
64   if (!unbalanced_start_)
65     return;
66
67   if (video_capture_) {
68     unbalanced_start_ = false;
69     video_capture_->StopCapture(handler_proxy_.get());
70   }
71 }
72
73 bool PepperPlatformVideoCapture::CaptureStarted() {
74   return handler_proxy_->state().started;
75 }
76
77 int PepperPlatformVideoCapture::CaptureFrameRate() {
78   return handler_proxy_->state().frame_rate;
79 }
80
81 void PepperPlatformVideoCapture::GetDeviceSupportedFormats(
82     const DeviceFormatsCallback& callback) {
83   NOTREACHED();
84 }
85
86 void PepperPlatformVideoCapture::DetachEventHandler() {
87   handler_ = NULL;
88   StopCapture(NULL);
89
90   video_capture_.reset();
91
92   if (render_view_.get()) {
93     if (!label_.empty()) {
94       GetMediaDeviceManager()->CloseDevice(label_);
95       label_.clear();
96     }
97     if (pending_open_device_) {
98       GetMediaDeviceManager()->CancelOpenDevice(pending_open_device_id_);
99       pending_open_device_ = false;
100       pending_open_device_id_ = -1;
101     }
102   }
103 }
104
105 void PepperPlatformVideoCapture::OnStarted(VideoCapture* capture) {
106   if (handler_)
107     handler_->OnStarted(capture);
108 }
109
110 void PepperPlatformVideoCapture::OnStopped(VideoCapture* capture) {
111   if (handler_)
112     handler_->OnStopped(capture);
113 }
114
115 void PepperPlatformVideoCapture::OnPaused(VideoCapture* capture) {
116   if (handler_)
117     handler_->OnPaused(capture);
118 }
119
120 void PepperPlatformVideoCapture::OnError(VideoCapture* capture,
121                                          int error_code) {
122   if (handler_)
123     handler_->OnError(capture, error_code);
124 }
125
126 void PepperPlatformVideoCapture::OnRemoved(VideoCapture* capture) {
127   if (handler_)
128     handler_->OnRemoved(capture);
129
130   Release();  // Balance the AddRef() in StartCapture().
131 }
132
133 void PepperPlatformVideoCapture::OnFrameReady(
134     VideoCapture* capture,
135     const scoped_refptr<media::VideoFrame>& frame) {
136   if (handler_)
137     handler_->OnFrameReady(capture, frame);
138 }
139
140 PepperPlatformVideoCapture::~PepperPlatformVideoCapture() {
141   DCHECK(!video_capture_);
142   DCHECK(label_.empty());
143   DCHECK(!pending_open_device_);
144 }
145
146 void PepperPlatformVideoCapture::Initialize() {
147   VideoCaptureImplManager* manager =
148       RenderThreadImpl::current()->video_capture_impl_manager();
149   video_capture_ = manager->UseDevice(session_id_);
150 }
151
152 void PepperPlatformVideoCapture::OnDeviceOpened(int request_id,
153                                                 bool succeeded,
154                                                 const std::string& label) {
155   pending_open_device_ = false;
156   pending_open_device_id_ = -1;
157
158   succeeded = succeeded && render_view_.get();
159   if (succeeded) {
160     label_ = label;
161     session_id_ = GetMediaDeviceManager()->GetSessionID(
162         PP_DEVICETYPE_DEV_VIDEOCAPTURE, label);
163     Initialize();
164   }
165
166   if (handler_)
167     handler_->OnInitialized(this, succeeded);
168 }
169
170 PepperMediaDeviceManager*
171     PepperPlatformVideoCapture::GetMediaDeviceManager() {
172   return PepperMediaDeviceManager::GetForRenderView(render_view_.get());
173 }
174
175 }  // namespace content