OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/renderer/pepper/pepper_platform_video_capture.h" | 5 #include "content/renderer/pepper/pepper_platform_video_capture.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/message_loop/message_loop_proxy.h" | 9 #include "base/message_loop/message_loop_proxy.h" |
10 #include "content/renderer/media/video_capture_impl_manager.h" | 10 #include "content/renderer/media/video_capture_impl_manager.h" |
11 #include "content/renderer/pepper/pepper_media_device_manager.h" | 11 #include "content/renderer/pepper/pepper_media_device_manager.h" |
12 #include "content/renderer/pepper/pepper_video_capture_host.h" | 12 #include "content/renderer/pepper/pepper_video_capture_host.h" |
13 #include "content/renderer/render_thread_impl.h" | 13 #include "content/renderer/render_thread_impl.h" |
14 #include "content/renderer/render_view_impl.h" | 14 #include "content/renderer/render_view_impl.h" |
15 #include "media/base/bind_to_current_loop.h" | 15 #include "media/video/capture/video_capture_proxy.h" |
16 #include "url/gurl.h" | 16 #include "url/gurl.h" |
17 | 17 |
18 namespace content { | 18 namespace content { |
19 | 19 |
20 PepperPlatformVideoCapture::PepperPlatformVideoCapture( | 20 PepperPlatformVideoCapture::PepperPlatformVideoCapture( |
21 const base::WeakPtr<RenderViewImpl>& render_view, | 21 const base::WeakPtr<RenderViewImpl>& render_view, |
22 const std::string& device_id, | 22 const std::string& device_id, |
23 const GURL& document_url, | 23 const GURL& document_url, |
24 PepperVideoCaptureHost* handler) | 24 PepperVideoCaptureHost* handler) |
25 : render_view_(render_view), | 25 : render_view_(render_view), |
26 device_id_(device_id), | 26 device_id_(device_id), |
27 session_id_(0), | 27 session_id_(0), |
| 28 handler_proxy_(new media::VideoCaptureHandlerProxy( |
| 29 this, |
| 30 base::MessageLoopProxy::current())), |
28 handler_(handler), | 31 handler_(handler), |
| 32 unbalanced_start_(false), |
29 pending_open_device_(false), | 33 pending_open_device_(false), |
30 pending_open_device_id_(-1), | 34 pending_open_device_id_(-1) { |
31 weak_factory_(this) { | |
32 // We need to open the device and obtain the label and session ID before | 35 // We need to open the device and obtain the label and session ID before |
33 // initializing. | 36 // initializing. |
34 if (render_view_.get()) { | 37 if (render_view_.get()) { |
35 pending_open_device_id_ = GetMediaDeviceManager()->OpenDevice( | 38 pending_open_device_id_ = GetMediaDeviceManager()->OpenDevice( |
36 PP_DEVICETYPE_DEV_VIDEOCAPTURE, | 39 PP_DEVICETYPE_DEV_VIDEOCAPTURE, |
37 device_id, | 40 device_id, |
38 document_url, | 41 document_url, |
39 base::Bind(&PepperPlatformVideoCapture::OnDeviceOpened, | 42 base::Bind(&PepperPlatformVideoCapture::OnDeviceOpened, this)); |
40 weak_factory_.GetWeakPtr())); | |
41 pending_open_device_ = true; | 43 pending_open_device_ = true; |
42 } | 44 } |
43 } | 45 } |
44 | 46 |
45 void PepperPlatformVideoCapture::StartCapture( | 47 void PepperPlatformVideoCapture::StartCapture( |
| 48 media::VideoCapture::EventHandler* handler, |
46 const media::VideoCaptureParams& params) { | 49 const media::VideoCaptureParams& params) { |
47 DCHECK(thread_checker_.CalledOnValidThread()); | 50 DCHECK(handler == handler_); |
48 if (!stop_capture_cb_.is_null()) | 51 |
| 52 if (unbalanced_start_) |
49 return; | 53 return; |
50 VideoCaptureImplManager* manager = | 54 |
51 RenderThreadImpl::current()->video_capture_impl_manager(); | 55 if (video_capture_) { |
52 stop_capture_cb_ = | 56 unbalanced_start_ = true; |
53 manager->StartCapture(session_id_, | 57 AddRef(); // Will be balanced in OnRemoved(). |
54 params, | 58 video_capture_->StartCapture(handler_proxy_.get(), params); |
55 media::BindToCurrentLoop(base::Bind( | 59 } |
56 &PepperPlatformVideoCapture::OnStateUpdate, | |
57 weak_factory_.GetWeakPtr())), | |
58 media::BindToCurrentLoop(base::Bind( | |
59 &PepperPlatformVideoCapture::OnFrameReady, | |
60 weak_factory_.GetWeakPtr()))); | |
61 } | 60 } |
62 | 61 |
63 void PepperPlatformVideoCapture::StopCapture() { | 62 void PepperPlatformVideoCapture::StopCapture( |
64 DCHECK(thread_checker_.CalledOnValidThread()); | 63 media::VideoCapture::EventHandler* handler) { |
65 if (stop_capture_cb_.is_null()) | 64 DCHECK(handler == handler_); |
| 65 if (!unbalanced_start_) |
66 return; | 66 return; |
67 stop_capture_cb_.Run(); | 67 |
68 stop_capture_cb_.Reset(); | 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::GetDeviceSupportedFormats( |
| 83 const DeviceFormatsCallback& callback) { |
| 84 NOTREACHED(); |
| 85 } |
| 86 |
| 87 void PepperPlatformVideoCapture::GetDeviceFormatsInUse( |
| 88 const DeviceFormatsInUseCallback& callback) { |
| 89 NOTREACHED(); |
69 } | 90 } |
70 | 91 |
71 void PepperPlatformVideoCapture::DetachEventHandler() { | 92 void PepperPlatformVideoCapture::DetachEventHandler() { |
72 handler_ = NULL; | 93 handler_ = NULL; |
73 StopCapture(); | 94 StopCapture(NULL); |
74 if (!release_device_cb_.is_null()) { | 95 |
75 release_device_cb_.Run(); | 96 video_capture_.reset(); |
76 release_device_cb_.Reset(); | 97 |
77 } | |
78 if (render_view_.get()) { | 98 if (render_view_.get()) { |
79 if (!label_.empty()) { | 99 if (!label_.empty()) { |
80 GetMediaDeviceManager()->CloseDevice(label_); | 100 GetMediaDeviceManager()->CloseDevice(label_); |
81 label_.clear(); | 101 label_.clear(); |
82 } | 102 } |
83 if (pending_open_device_) { | 103 if (pending_open_device_) { |
84 GetMediaDeviceManager()->CancelOpenDevice(pending_open_device_id_); | 104 GetMediaDeviceManager()->CancelOpenDevice(pending_open_device_id_); |
85 pending_open_device_ = false; | 105 pending_open_device_ = false; |
86 pending_open_device_id_ = -1; | 106 pending_open_device_id_ = -1; |
87 } | 107 } |
88 } | 108 } |
89 } | 109 } |
90 | 110 |
| 111 void PepperPlatformVideoCapture::OnStarted(VideoCapture* capture) { |
| 112 if (handler_) |
| 113 handler_->OnStarted(capture); |
| 114 } |
| 115 |
| 116 void PepperPlatformVideoCapture::OnStopped(VideoCapture* capture) { |
| 117 if (handler_) |
| 118 handler_->OnStopped(capture); |
| 119 } |
| 120 |
| 121 void PepperPlatformVideoCapture::OnPaused(VideoCapture* capture) { |
| 122 if (handler_) |
| 123 handler_->OnPaused(capture); |
| 124 } |
| 125 |
| 126 void PepperPlatformVideoCapture::OnError(VideoCapture* capture, |
| 127 int error_code) { |
| 128 if (handler_) |
| 129 handler_->OnError(capture, error_code); |
| 130 } |
| 131 |
| 132 void PepperPlatformVideoCapture::OnRemoved(VideoCapture* capture) { |
| 133 if (handler_) |
| 134 handler_->OnRemoved(capture); |
| 135 |
| 136 Release(); // Balance the AddRef() in StartCapture(). |
| 137 } |
| 138 |
| 139 void PepperPlatformVideoCapture::OnFrameReady( |
| 140 VideoCapture* capture, |
| 141 const scoped_refptr<media::VideoFrame>& frame) { |
| 142 if (handler_) |
| 143 handler_->OnFrameReady(capture, frame); |
| 144 } |
| 145 |
91 PepperPlatformVideoCapture::~PepperPlatformVideoCapture() { | 146 PepperPlatformVideoCapture::~PepperPlatformVideoCapture() { |
92 DCHECK(stop_capture_cb_.is_null()); | 147 DCHECK(!video_capture_); |
93 DCHECK(release_device_cb_.is_null()); | |
94 DCHECK(label_.empty()); | 148 DCHECK(label_.empty()); |
95 DCHECK(!pending_open_device_); | 149 DCHECK(!pending_open_device_); |
96 } | 150 } |
97 | 151 |
| 152 void PepperPlatformVideoCapture::Initialize() { |
| 153 VideoCaptureImplManager* manager = |
| 154 RenderThreadImpl::current()->video_capture_impl_manager(); |
| 155 video_capture_ = manager->UseDevice(session_id_); |
| 156 } |
| 157 |
98 void PepperPlatformVideoCapture::OnDeviceOpened(int request_id, | 158 void PepperPlatformVideoCapture::OnDeviceOpened(int request_id, |
99 bool succeeded, | 159 bool succeeded, |
100 const std::string& label) { | 160 const std::string& label) { |
101 pending_open_device_ = false; | 161 pending_open_device_ = false; |
102 pending_open_device_id_ = -1; | 162 pending_open_device_id_ = -1; |
103 | 163 |
104 succeeded = succeeded && render_view_.get(); | 164 succeeded = succeeded && render_view_.get(); |
105 if (succeeded) { | 165 if (succeeded) { |
106 label_ = label; | 166 label_ = label; |
107 session_id_ = GetMediaDeviceManager()->GetSessionID( | 167 session_id_ = GetMediaDeviceManager()->GetSessionID( |
108 PP_DEVICETYPE_DEV_VIDEOCAPTURE, label); | 168 PP_DEVICETYPE_DEV_VIDEOCAPTURE, label); |
109 VideoCaptureImplManager* manager = | 169 Initialize(); |
110 RenderThreadImpl::current()->video_capture_impl_manager(); | |
111 release_device_cb_ = manager->UseDevice(session_id_); | |
112 } | 170 } |
113 | 171 |
114 if (handler_) | 172 if (handler_) |
115 handler_->OnInitialized(succeeded); | 173 handler_->OnInitialized(this, 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 } | 174 } |
145 | 175 |
146 PepperMediaDeviceManager* PepperPlatformVideoCapture::GetMediaDeviceManager() { | 176 PepperMediaDeviceManager* PepperPlatformVideoCapture::GetMediaDeviceManager() { |
147 return PepperMediaDeviceManager::GetForRenderView(render_view_.get()); | 177 return PepperMediaDeviceManager::GetForRenderView(render_view_.get()); |
148 } | 178 } |
149 | 179 |
150 } // namespace content | 180 } // namespace content |
OLD | NEW |