Upstream version 7.36.149.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/base/bind_to_current_loop.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_(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   if (render_view_.get()) {
35     pending_open_device_id_ = GetMediaDeviceManager()->OpenDevice(
36         PP_DEVICETYPE_DEV_VIDEOCAPTURE,
37         device_id,
38         document_url,
39         base::Bind(&PepperPlatformVideoCapture::OnDeviceOpened,
40                    weak_factory_.GetWeakPtr()));
41     pending_open_device_ = true;
42   }
43 }
44
45 void PepperPlatformVideoCapture::StartCapture(
46     const media::VideoCaptureParams& params) {
47   DCHECK(thread_checker_.CalledOnValidThread());
48   if (!stop_capture_cb_.is_null())
49     return;
50   VideoCaptureImplManager* manager =
51       RenderThreadImpl::current()->video_capture_impl_manager();
52   stop_capture_cb_ =
53       manager->StartCapture(session_id_,
54                             params,
55                             media::BindToCurrentLoop(base::Bind(
56                                 &PepperPlatformVideoCapture::OnStateUpdate,
57                                 weak_factory_.GetWeakPtr())),
58                             media::BindToCurrentLoop(base::Bind(
59                                 &PepperPlatformVideoCapture::OnFrameReady,
60                                 weak_factory_.GetWeakPtr())));
61 }
62
63 void PepperPlatformVideoCapture::StopCapture() {
64   DCHECK(thread_checker_.CalledOnValidThread());
65   if (stop_capture_cb_.is_null())
66     return;
67   stop_capture_cb_.Run();
68   stop_capture_cb_.Reset();
69 }
70
71 void PepperPlatformVideoCapture::DetachEventHandler() {
72   handler_ = NULL;
73   StopCapture();
74   if (!release_device_cb_.is_null()) {
75     release_device_cb_.Run();
76     release_device_cb_.Reset();
77   }
78   if (render_view_.get()) {
79     if (!label_.empty()) {
80       GetMediaDeviceManager()->CloseDevice(label_);
81       label_.clear();
82     }
83     if (pending_open_device_) {
84       GetMediaDeviceManager()->CancelOpenDevice(pending_open_device_id_);
85       pending_open_device_ = false;
86       pending_open_device_id_ = -1;
87     }
88   }
89 }
90
91 PepperPlatformVideoCapture::~PepperPlatformVideoCapture() {
92   DCHECK(stop_capture_cb_.is_null());
93   DCHECK(release_device_cb_.is_null());
94   DCHECK(label_.empty());
95   DCHECK(!pending_open_device_);
96 }
97
98 void PepperPlatformVideoCapture::OnDeviceOpened(int request_id,
99                                                 bool succeeded,
100                                                 const std::string& label) {
101   pending_open_device_ = false;
102   pending_open_device_id_ = -1;
103
104   succeeded = succeeded && render_view_.get();
105   if (succeeded) {
106     label_ = label;
107     session_id_ = GetMediaDeviceManager()->GetSessionID(
108         PP_DEVICETYPE_DEV_VIDEOCAPTURE, label);
109     VideoCaptureImplManager* manager =
110         RenderThreadImpl::current()->video_capture_impl_manager();
111     release_device_cb_ = manager->UseDevice(session_id_);
112   }
113
114   if (handler_)
115     handler_->OnInitialized(succeeded);
116 }
117
118 void PepperPlatformVideoCapture::OnStateUpdate(VideoCaptureState state) {
119   if (!handler_)
120     return;
121   switch (state) {
122     case VIDEO_CAPTURE_STATE_STARTED:
123       handler_->OnStarted();
124       break;
125     case VIDEO_CAPTURE_STATE_STOPPED:
126       handler_->OnStopped();
127       break;
128     case VIDEO_CAPTURE_STATE_PAUSED:
129       handler_->OnPaused();
130       break;
131     case VIDEO_CAPTURE_STATE_ERROR:
132       handler_->OnError();
133       break;
134     default:
135       NOTREACHED() << "Unexpected state: " << state << ".";
136   }
137 }
138
139 void PepperPlatformVideoCapture::OnFrameReady(
140     const scoped_refptr<media::VideoFrame>& frame,
141     const media::VideoCaptureFormat& format) {
142   if (handler_ && !stop_capture_cb_.is_null())
143     handler_->OnFrameReady(frame, format);
144 }
145
146 PepperMediaDeviceManager* PepperPlatformVideoCapture::GetMediaDeviceManager() {
147   return PepperMediaDeviceManager::GetForRenderView(render_view_.get());
148 }
149
150 }  // namespace content