Upstream version 9.38.198.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_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"
17
18 namespace content {
19
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;
43   }
44 }
45
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())));
62 }
63
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();
70 }
71
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();
78   }
79   if (!label_.empty()) {
80     PepperMediaDeviceManager* const device_manager = GetMediaDeviceManager();
81     if (device_manager)
82       device_manager->CloseDevice(label_);
83     label_.clear();
84   }
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;
91   }
92 }
93
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_);
99 }
100
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;
106
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_);
116   }
117
118   if (handler_)
119     handler_->OnInitialized(succeeded);
120 }
121
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 << ".";
140   }
141 }
142
143 void PepperPlatformVideoCapture::OnFrameReady(
144     const scoped_refptr<media::VideoFrame>& frame,
145     const media::VideoCaptureFormat& format,
146     const base::TimeTicks& estimated_capture_time) {
147   if (handler_ && !stop_capture_cb_.is_null())
148     handler_->OnFrameReady(frame, format);
149 }
150
151 PepperMediaDeviceManager* PepperPlatformVideoCapture::GetMediaDeviceManager() {
152   RenderFrameImpl* const render_frame =
153       RenderFrameImpl::FromRoutingID(render_frame_id_);
154   return render_frame ?
155       PepperMediaDeviceManager::GetForRenderFrame(render_frame) : NULL;
156 }
157
158 }  // namespace content