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/browser/renderer_host/media/video_capture_manager.h" | 5 #include "content/browser/renderer_host/media/video_capture_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <set> | 8 #include <set> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/bind_helpers.h" | 12 #include "base/bind_helpers.h" |
13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
14 #include "base/location.h" | 14 #include "base/location.h" |
15 #include "base/logging.h" | 15 #include "base/logging.h" |
16 #include "base/memory/ptr_util.h" | 16 #include "base/memory/ptr_util.h" |
17 #include "base/metrics/histogram_macros.h" | 17 #include "base/metrics/histogram_macros.h" |
18 #include "base/single_thread_task_runner.h" | 18 #include "base/single_thread_task_runner.h" |
19 #include "base/stl_util.h" | 19 #include "base/stl_util.h" |
20 #include "base/strings/stringprintf.h" | 20 #include "base/strings/stringprintf.h" |
21 #include "base/task_runner_util.h" | 21 #include "base/task_runner_util.h" |
22 #include "base/threading/sequenced_worker_pool.h" | 22 #include "base/threading/sequenced_worker_pool.h" |
23 #include "base/threading/thread_task_runner_handle.h" | 23 #include "base/threading/thread_task_runner_handle.h" |
24 #include "build/build_config.h" | 24 #include "build/build_config.h" |
25 #include "content/browser/media/capture/desktop_capture_device_uma_types.h" | 25 #include "content/browser/media/capture/desktop_capture_device_uma_types.h" |
26 #include "content/browser/media/capture/web_contents_video_capture_device.h" | 26 #include "content/browser/media/capture/web_contents_video_capture_device.h" |
27 #include "content/browser/media/media_internals.h" | 27 #include "content/browser/media/media_internals.h" |
28 #include "content/browser/renderer_host/media/video_capture_controller.h" | 28 #include "content/browser/renderer_host/media/video_capture_controller.h" |
29 #include "content/browser/renderer_host/media/video_capture_controller_event_han
dler.h" | 29 #include "content/browser/renderer_host/media/video_capture_controller_event_han
dler.h" |
| 30 #include "content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h" |
| 31 #include "content/browser/renderer_host/media/video_frame_receiver_on_io_thread.
h" |
30 #include "content/public/browser/browser_thread.h" | 32 #include "content/public/browser/browser_thread.h" |
31 #include "content/public/browser/desktop_media_id.h" | 33 #include "content/public/browser/desktop_media_id.h" |
32 #include "content/public/common/media_stream_request.h" | 34 #include "content/public/common/media_stream_request.h" |
33 #include "media/base/bind_to_current_loop.h" | 35 #include "media/base/bind_to_current_loop.h" |
34 #include "media/base/media_switches.h" | 36 #include "media/base/media_switches.h" |
| 37 #include "media/capture/video/video_capture_buffer_pool_impl.h" |
| 38 #include "media/capture/video/video_capture_buffer_tracker_factory_impl.h" |
35 #include "media/capture/video/video_capture_device.h" | 39 #include "media/capture/video/video_capture_device.h" |
| 40 #include "media/capture/video/video_capture_device_client.h" |
36 #include "media/capture/video/video_capture_device_factory.h" | 41 #include "media/capture/video/video_capture_device_factory.h" |
37 | 42 |
38 #if defined(ENABLE_SCREEN_CAPTURE) && !defined(OS_ANDROID) | 43 #if defined(ENABLE_SCREEN_CAPTURE) && !defined(OS_ANDROID) |
39 #include "content/browser/media/capture/desktop_capture_device.h" | 44 #include "content/browser/media/capture/desktop_capture_device.h" |
40 #if defined(USE_AURA) | 45 #if defined(USE_AURA) |
41 #include "content/browser/media/capture/desktop_capture_device_aura.h" | 46 #include "content/browser/media/capture/desktop_capture_device_aura.h" |
42 #endif | 47 #endif |
43 #endif | 48 #endif |
44 | 49 |
45 #if defined(ENABLE_SCREEN_CAPTURE) && defined(OS_ANDROID) | 50 #if defined(ENABLE_SCREEN_CAPTURE) && defined(OS_ANDROID) |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 formats->erase(last, formats->end()); | 112 formats->erase(last, formats->end()); |
108 // Mark all formats as I420, since this is what the renderer side will get | 113 // Mark all formats as I420, since this is what the renderer side will get |
109 // anyhow: the actual pixel format is decided at the device level. | 114 // anyhow: the actual pixel format is decided at the device level. |
110 // Don't do this for Y16 format as it is handled separatelly. | 115 // Don't do this for Y16 format as it is handled separatelly. |
111 for (auto& format : *formats) { | 116 for (auto& format : *formats) { |
112 if (format.pixel_format != media::PIXEL_FORMAT_Y16) | 117 if (format.pixel_format != media::PIXEL_FORMAT_Y16) |
113 format.pixel_format = media::PIXEL_FORMAT_I420; | 118 format.pixel_format = media::PIXEL_FORMAT_I420; |
114 } | 119 } |
115 } | 120 } |
116 | 121 |
117 // The maximum number of buffers in the capture pipeline. See | 122 // The maximum number of video frame buffers in-flight at any one time. This |
118 // VideoCaptureController ctor comments for more details. | 123 // value should be based on the logical capacity of the capture pipeline, and |
| 124 // not on hardware performance. For example, tab capture requires more buffers |
| 125 // than webcam capture because the pipeline is longer (it includes read-backs |
| 126 // pending in the GPU pipeline). |
119 const int kMaxNumberOfBuffers = 3; | 127 const int kMaxNumberOfBuffers = 3; |
120 // TODO(miu): The value for tab capture should be determined programmatically. | 128 // TODO(miu): The value for tab capture should be determined programmatically. |
121 // http://crbug.com/460318 | 129 // http://crbug.com/460318 |
122 const int kMaxNumberOfBuffersForTabCapture = 10; | 130 const int kMaxNumberOfBuffersForTabCapture = 10; |
123 | 131 |
124 // Used for logging capture events. | 132 // Used for logging capture events. |
125 // Elements in this enum should not be deleted or rearranged; the only | 133 // Elements in this enum should not be deleted or rearranged; the only |
126 // permitted operation is to add new elements before NUM_VIDEO_CAPTURE_EVENT. | 134 // permitted operation is to add new elements before NUM_VIDEO_CAPTURE_EVENT. |
127 enum VideoCaptureEvent { | 135 enum VideoCaptureEvent { |
128 VIDEO_CAPTURE_START_CAPTURE = 0, | 136 VIDEO_CAPTURE_START_CAPTURE = 0, |
129 VIDEO_CAPTURE_STOP_CAPTURE_OK = 1, | 137 VIDEO_CAPTURE_STOP_CAPTURE_OK = 1, |
130 VIDEO_CAPTURE_STOP_CAPTURE_DUE_TO_ERROR = 2, | 138 VIDEO_CAPTURE_STOP_CAPTURE_DUE_TO_ERROR = 2, |
131 VIDEO_CAPTURE_STOP_CAPTURE_OK_NO_FRAMES_PRODUCED_BY_DEVICE = 3, | 139 VIDEO_CAPTURE_STOP_CAPTURE_OK_NO_FRAMES_PRODUCED_BY_DEVICE = 3, |
132 VIDEO_CAPTURE_STOP_CAPTURE_OK_NO_FRAMES_PRODUCED_BY_DESKTOP_OR_TAB = 4, | 140 VIDEO_CAPTURE_STOP_CAPTURE_OK_NO_FRAMES_PRODUCED_BY_DESKTOP_OR_TAB = 4, |
133 NUM_VIDEO_CAPTURE_EVENT | 141 NUM_VIDEO_CAPTURE_EVENT |
134 }; | 142 }; |
135 | 143 |
136 void LogVideoCaptureEvent(VideoCaptureEvent event) { | 144 void LogVideoCaptureEvent(VideoCaptureEvent event) { |
137 UMA_HISTOGRAM_ENUMERATION("Media.VideoCaptureManager.Event", | 145 UMA_HISTOGRAM_ENUMERATION("Media.VideoCaptureManager.Event", |
138 event, | 146 event, |
139 NUM_VIDEO_CAPTURE_EVENT); | 147 NUM_VIDEO_CAPTURE_EVENT); |
140 } | 148 } |
141 | 149 |
142 // Counter used for identifying a DeviceRequest to start a capture device. | 150 // Counter used for identifying a DeviceRequest to start a capture device. |
143 static int g_device_start_id = 0; | 151 static int g_device_start_id = 0; |
144 | 152 |
145 const media::VideoCaptureSessionId kFakeSessionId = -1; | 153 const media::VideoCaptureSessionId kFakeSessionId = -1; |
146 | 154 |
| 155 std::unique_ptr<media::VideoCaptureJpegDecoder> CreateGpuJpegDecoder( |
| 156 const media::VideoCaptureJpegDecoder::DecodeDoneCB& decode_done_cb) { |
| 157 return base::MakeUnique<content::VideoCaptureGpuJpegDecoder>(decode_done_cb); |
| 158 } |
| 159 |
147 } // namespace | 160 } // namespace |
148 | 161 |
149 namespace content { | 162 namespace content { |
150 | 163 |
151 // Instances of this struct go through 3 different phases during their lifetime. | 164 // Instances of this struct go through several different phases during their |
| 165 // lifetime. |
152 // Phase 1: When first created (in GetOrCreateDeviceEntry()), this consists of | 166 // Phase 1: When first created (in GetOrCreateDeviceEntry()), this consists of |
153 // only a controller. Clients can already connect to the controller, but there | 167 // only the |video_capture_controller|. Clients can already connect to the |
154 // is no device present. | 168 // controller, but there is no |buffer_pool| or |video_capture_device| present. |
155 // Phase 2: When a request to "start" the entry comes in (via | 169 // Phase 2: When a request to "start" the entry comes in (via |
156 // HandleQueuedStartRequest()), a VideoCaptureDevice::Client is created | 170 // HandleQueuedStartRequest()), |buffer_pool| is created and creation of |
157 // via video_capture_controller()->NewDeviceClient() and is used to schedule the | 171 // |video_capture_device| is scheduled to run asynchronously on the Device |
158 // creation and start of a VideoCaptureDevice on the Device Thread. | 172 // Thread. |
159 // Phase 3: As soon as the creation of the VideoCaptureDevice is complete, this | 173 // Phase 3: As soon as the creation of the VideoCaptureDevice is complete, this |
160 // newly created VideoCaptureDevice instance is connected to the | 174 // newly created VideoCaptureDevice instance is connected to the |
161 // VideoCaptureController via SetConsumerFeedbackObserver(). | 175 // VideoCaptureController via SetConsumerFeedbackObserver(). Furthermore, the |
162 class VideoCaptureManager::DeviceEntry { | 176 // |buffer_pool| is connected to the |video_capture_controller| as a |
| 177 // FrameBufferPool via SetFrameBufferPool(). |
| 178 // Phase 4: This phase can only be reached on Android. When the application goes |
| 179 // to the background, the |video_capture_device| is asynchronously stopped and |
| 180 // released on the Device Thread. The existing |buffer_pool| is kept alive, and |
| 181 // all clients of |video_capture_controller| stay connected. When the |
| 182 // application is resumed, we transition to Phase 2, except that the existing |
| 183 // |buffer_pool| get reused instead of creating a new one. |
| 184 struct VideoCaptureManager::DeviceEntry { |
163 public: | 185 public: |
164 DeviceEntry(MediaStreamType stream_type, | 186 DeviceEntry(MediaStreamType stream_type, |
165 const std::string& id, | 187 const std::string& id, |
166 std::unique_ptr<VideoCaptureController> controller, | |
167 const media::VideoCaptureParams& params); | 188 const media::VideoCaptureParams& params); |
168 ~DeviceEntry(); | 189 ~DeviceEntry(); |
| 190 std::unique_ptr<media::VideoCaptureDevice::Client> CreateDeviceClient(); |
| 191 std::unique_ptr<media::FrameBufferPool> CreateFrameBufferPool(); |
169 | 192 |
170 const int serial_id; | 193 const int serial_id; |
171 const MediaStreamType stream_type; | 194 const MediaStreamType stream_type; |
172 const std::string id; | 195 const std::string id; |
173 const media::VideoCaptureParams parameters; | 196 const media::VideoCaptureParams parameters; |
174 | 197 VideoCaptureController video_capture_controller; |
175 VideoCaptureController* video_capture_controller() const; | 198 scoped_refptr<media::VideoCaptureBufferPool> buffer_pool; |
176 media::VideoCaptureDevice* video_capture_device() const; | 199 std::unique_ptr<media::VideoCaptureDevice> video_capture_device; |
177 | |
178 void SetVideoCaptureDevice(std::unique_ptr<VideoCaptureDevice> device); | |
179 std::unique_ptr<VideoCaptureDevice> ReleaseVideoCaptureDevice(); | |
180 | |
181 private: | |
182 const std::unique_ptr<VideoCaptureController> video_capture_controller_; | |
183 | |
184 std::unique_ptr<VideoCaptureDevice> video_capture_device_; | |
185 | |
186 base::ThreadChecker thread_checker_; | |
187 }; | 200 }; |
188 | 201 |
189 // Bundles a media::VideoCaptureDeviceDescriptor with corresponding supported | 202 // Bundles a media::VideoCaptureDeviceDescriptor with corresponding supported |
190 // video formats. | 203 // video formats. |
191 struct VideoCaptureManager::DeviceInfo { | 204 struct VideoCaptureManager::DeviceInfo { |
192 DeviceInfo(); | 205 DeviceInfo(); |
193 DeviceInfo(media::VideoCaptureDeviceDescriptor descriptor); | 206 DeviceInfo(media::VideoCaptureDeviceDescriptor descriptor); |
194 DeviceInfo(const DeviceInfo& other); | 207 DeviceInfo(const DeviceInfo& other); |
195 ~DeviceInfo(); | 208 ~DeviceInfo(); |
196 DeviceInfo& operator=(const DeviceInfo& other); | 209 DeviceInfo& operator=(const DeviceInfo& other); |
197 | 210 |
198 media::VideoCaptureDeviceDescriptor descriptor; | 211 media::VideoCaptureDeviceDescriptor descriptor; |
199 media::VideoCaptureFormats supported_formats; | 212 media::VideoCaptureFormats supported_formats; |
200 }; | 213 }; |
201 | 214 |
| 215 class BufferPoolFrameBufferPool : public media::FrameBufferPool { |
| 216 public: |
| 217 explicit BufferPoolFrameBufferPool( |
| 218 scoped_refptr<media::VideoCaptureBufferPool> buffer_pool) |
| 219 : buffer_pool_(std::move(buffer_pool)) {} |
| 220 |
| 221 void SetBufferHold(int buffer_id) override { |
| 222 buffer_pool_->HoldForConsumers(buffer_id, 1); |
| 223 } |
| 224 |
| 225 void ReleaseBufferHold(int buffer_id) override { |
| 226 buffer_pool_->RelinquishConsumerHold(buffer_id, 1); |
| 227 } |
| 228 |
| 229 mojo::ScopedSharedBufferHandle GetHandleForTransit(int buffer_id) override { |
| 230 return buffer_pool_->GetHandleForTransit(buffer_id); |
| 231 } |
| 232 |
| 233 private: |
| 234 scoped_refptr<media::VideoCaptureBufferPool> buffer_pool_; |
| 235 }; |
| 236 |
202 // Class used for queuing request for starting a device. | 237 // Class used for queuing request for starting a device. |
203 class VideoCaptureManager::CaptureDeviceStartRequest { | 238 class VideoCaptureManager::CaptureDeviceStartRequest { |
204 public: | 239 public: |
205 CaptureDeviceStartRequest(int serial_id, | 240 CaptureDeviceStartRequest(int serial_id, |
206 media::VideoCaptureSessionId session_id, | 241 media::VideoCaptureSessionId session_id, |
207 const media::VideoCaptureParams& params); | 242 const media::VideoCaptureParams& params); |
208 int serial_id() const { return serial_id_; } | 243 int serial_id() const { return serial_id_; } |
209 media::VideoCaptureSessionId session_id() const { return session_id_; } | 244 media::VideoCaptureSessionId session_id() const { return session_id_; } |
210 media::VideoCaptureParams params() const { return params_; } | 245 media::VideoCaptureParams params() const { return params_; } |
211 | 246 |
212 // Set to true if the device should be stopped before it has successfully | 247 // Set to true if the device should be stopped before it has successfully |
213 // been started. | 248 // been started. |
214 bool abort_start() const { return abort_start_; } | 249 bool abort_start() const { return abort_start_; } |
215 void set_abort_start() { abort_start_ = true; } | 250 void set_abort_start() { abort_start_ = true; } |
216 | 251 |
217 private: | 252 private: |
218 const int serial_id_; | 253 const int serial_id_; |
219 const media::VideoCaptureSessionId session_id_; | 254 const media::VideoCaptureSessionId session_id_; |
220 const media::VideoCaptureParams params_; | 255 const media::VideoCaptureParams params_; |
221 // Set to true if the device should be stopped before it has successfully | 256 // Set to true if the device should be stopped before it has successfully |
222 // been started. | 257 // been started. |
223 bool abort_start_; | 258 bool abort_start_; |
224 }; | 259 }; |
225 | 260 |
226 VideoCaptureManager::DeviceEntry::DeviceEntry( | 261 VideoCaptureManager::DeviceEntry::DeviceEntry( |
227 MediaStreamType stream_type, | 262 MediaStreamType stream_type, |
228 const std::string& id, | 263 const std::string& id, |
229 std::unique_ptr<VideoCaptureController> controller, | |
230 const media::VideoCaptureParams& params) | 264 const media::VideoCaptureParams& params) |
231 : serial_id(g_device_start_id++), | 265 : serial_id(g_device_start_id++), |
232 stream_type(stream_type), | 266 stream_type(stream_type), |
233 id(id), | 267 id(id), |
234 parameters(params), | 268 parameters(params) {} |
235 video_capture_controller_(std::move(controller)) {} | |
236 | 269 |
237 VideoCaptureManager::DeviceEntry::~DeviceEntry() { | 270 VideoCaptureManager::DeviceEntry::~DeviceEntry() { |
238 DCHECK(thread_checker_.CalledOnValidThread()); | 271 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
239 // DCHECK that this DeviceEntry does not still own a | 272 // DCHECK that this DeviceEntry does not still own a |
240 // media::VideoCaptureDevice. media::VideoCaptureDevice must be deleted on | 273 // media::VideoCaptureDevice. media::VideoCaptureDevice must be deleted on |
241 // the device thread. | 274 // the device thread. |
242 DCHECK(video_capture_device_ == nullptr); | 275 DCHECK(video_capture_device == nullptr); |
243 } | 276 } |
244 | 277 |
245 void VideoCaptureManager::DeviceEntry::SetVideoCaptureDevice( | 278 std::unique_ptr<media::VideoCaptureDevice::Client> |
246 std::unique_ptr<VideoCaptureDevice> device) { | 279 VideoCaptureManager::DeviceEntry::CreateDeviceClient() { |
247 DCHECK(thread_checker_.CalledOnValidThread()); | 280 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
248 video_capture_device_.swap(device); | 281 |
| 282 const int max_buffers = stream_type == MEDIA_TAB_VIDEO_CAPTURE |
| 283 ? kMaxNumberOfBuffersForTabCapture |
| 284 : kMaxNumberOfBuffers; |
| 285 if (!buffer_pool) { |
| 286 buffer_pool = new media::VideoCaptureBufferPoolImpl( |
| 287 base::MakeUnique<media::VideoCaptureBufferTrackerFactoryImpl>(), |
| 288 max_buffers); |
| 289 } |
| 290 |
| 291 return base::MakeUnique<media::VideoCaptureDeviceClient>( |
| 292 base::MakeUnique<VideoFrameReceiverOnIOThread>( |
| 293 video_capture_controller.GetWeakPtrForIOThread()), |
| 294 buffer_pool, |
| 295 base::Bind( |
| 296 &CreateGpuJpegDecoder, |
| 297 base::Bind(&media::VideoFrameReceiver::OnIncomingCapturedVideoFrame, |
| 298 video_capture_controller.GetWeakPtrForIOThread()))); |
249 } | 299 } |
250 | 300 |
251 std::unique_ptr<media::VideoCaptureDevice> | 301 std::unique_ptr<media::FrameBufferPool> |
252 VideoCaptureManager::DeviceEntry::ReleaseVideoCaptureDevice() { | 302 VideoCaptureManager::DeviceEntry::CreateFrameBufferPool() { |
253 DCHECK(thread_checker_.CalledOnValidThread()); | 303 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
254 return std::move(video_capture_device_); | 304 DCHECK(buffer_pool); |
255 } | 305 return base::MakeUnique<BufferPoolFrameBufferPool>(buffer_pool); |
256 | |
257 VideoCaptureController* | |
258 VideoCaptureManager::DeviceEntry::video_capture_controller() const { | |
259 DCHECK(thread_checker_.CalledOnValidThread()); | |
260 return video_capture_controller_.get(); | |
261 } | |
262 | |
263 media::VideoCaptureDevice* | |
264 VideoCaptureManager::DeviceEntry::video_capture_device() const { | |
265 DCHECK(thread_checker_.CalledOnValidThread()); | |
266 return video_capture_device_.get(); | |
267 } | 306 } |
268 | 307 |
269 VideoCaptureManager::DeviceInfo::DeviceInfo() = default; | 308 VideoCaptureManager::DeviceInfo::DeviceInfo() = default; |
270 | 309 |
271 VideoCaptureManager::DeviceInfo::DeviceInfo( | 310 VideoCaptureManager::DeviceInfo::DeviceInfo( |
272 media::VideoCaptureDeviceDescriptor descriptor) | 311 media::VideoCaptureDeviceDescriptor descriptor) |
273 : descriptor(descriptor) {} | 312 : descriptor(descriptor) {} |
274 | 313 |
275 VideoCaptureManager::DeviceInfo::DeviceInfo( | 314 VideoCaptureManager::DeviceInfo::DeviceInfo( |
276 const VideoCaptureManager::DeviceInfo& other) = default; | 315 const VideoCaptureManager::DeviceInfo& other) = default; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 if (session_it == sessions_.end()) { | 417 if (session_it == sessions_.end()) { |
379 NOTREACHED(); | 418 NOTREACHED(); |
380 return; | 419 return; |
381 } | 420 } |
382 | 421 |
383 DeviceEntry* const existing_device = | 422 DeviceEntry* const existing_device = |
384 GetDeviceEntryByTypeAndId(session_it->second.type, session_it->second.id); | 423 GetDeviceEntryByTypeAndId(session_it->second.type, session_it->second.id); |
385 if (existing_device) { | 424 if (existing_device) { |
386 // Remove any client that is still using the session. This is safe to call | 425 // Remove any client that is still using the session. This is safe to call |
387 // even if there are no clients using the session. | 426 // even if there are no clients using the session. |
388 existing_device->video_capture_controller() | 427 existing_device->video_capture_controller.StopSession(capture_session_id); |
389 ->StopSession(capture_session_id); | |
390 | 428 |
391 // StopSession() may have removed the last client, so we might need to | 429 // StopSession() may have removed the last client, so we might need to |
392 // close the device. | 430 // close the device. |
393 DestroyDeviceEntryIfNoClients(existing_device); | 431 DestroyDeviceEntryIfNoClients(existing_device); |
394 } | 432 } |
395 | 433 |
396 // Notify listeners asynchronously, and forget the session. | 434 // Notify listeners asynchronously, and forget the session. |
397 base::ThreadTaskRunnerHandle::Get()->PostTask( | 435 base::ThreadTaskRunnerHandle::Get()->PostTask( |
398 FROM_HERE, base::Bind(&VideoCaptureManager::OnClosed, this, | 436 FROM_HERE, base::Bind(&VideoCaptureManager::OnClosed, this, |
399 session_it->second.type, capture_session_id)); | 437 session_it->second.type, capture_session_id)); |
(...skipping 27 matching lines...) Expand all Loading... |
427 if (request->serial_id() == entry->serial_id) { | 465 if (request->serial_id() == entry->serial_id) { |
428 request->set_abort_start(); | 466 request->set_abort_start(); |
429 DVLOG(3) << "DoStopDevice, aborting start request for device " | 467 DVLOG(3) << "DoStopDevice, aborting start request for device " |
430 << entry->id << " serial_id = " << entry->serial_id; | 468 << entry->id << " serial_id = " << entry->serial_id; |
431 return; | 469 return; |
432 } | 470 } |
433 } | 471 } |
434 | 472 |
435 DVLOG(3) << "DoStopDevice. Send stop request for device = " << entry->id | 473 DVLOG(3) << "DoStopDevice. Send stop request for device = " << entry->id |
436 << " serial_id = " << entry->serial_id << "."; | 474 << " serial_id = " << entry->serial_id << "."; |
437 entry->video_capture_controller()->OnLog( | 475 entry->video_capture_controller.OnLog( |
438 base::StringPrintf("Stopping device: id: %s", entry->id.c_str())); | 476 base::StringPrintf("Stopping device: id: %s", entry->id.c_str())); |
439 entry->video_capture_controller()->SetConsumerFeedbackObserver(nullptr); | 477 entry->video_capture_controller.SetConsumerFeedbackObserver(nullptr); |
| 478 entry->video_capture_controller.SetFrameBufferPool(nullptr); |
440 | 479 |
441 // |entry->video_capture_device| can be null if creating the device has | 480 // |entry->video_capture_device| can be null if creating the device has |
442 // failed. | 481 // failed. |
443 if (entry->video_capture_device()) { | 482 if (entry->video_capture_device) { |
444 device_task_runner_->PostTask( | 483 device_task_runner_->PostTask( |
445 FROM_HERE, | 484 FROM_HERE, |
446 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, | 485 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, |
447 base::Passed(entry->ReleaseVideoCaptureDevice()))); | 486 base::Passed(&entry->video_capture_device))); |
448 } | 487 } |
449 } | 488 } |
450 | 489 |
451 void VideoCaptureManager::HandleQueuedStartRequest() { | 490 void VideoCaptureManager::HandleQueuedStartRequest() { |
452 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 491 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
453 // Remove all start requests that have been aborted. | 492 // Remove all start requests that have been aborted. |
454 while (device_start_queue_.begin() != device_start_queue_.end() && | 493 while (device_start_queue_.begin() != device_start_queue_.end() && |
455 device_start_queue_.begin()->abort_start()) { | 494 device_start_queue_.begin()->abort_start()) { |
456 device_start_queue_.pop_front(); | 495 device_start_queue_.pop_front(); |
457 } | 496 } |
458 DeviceStartQueue::iterator request = device_start_queue_.begin(); | 497 DeviceStartQueue::iterator request = device_start_queue_.begin(); |
459 if (request == device_start_queue_.end()) | 498 if (request == device_start_queue_.end()) |
460 return; | 499 return; |
461 | 500 |
462 const int serial_id = request->serial_id(); | 501 const int serial_id = request->serial_id(); |
463 DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id); | 502 DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id); |
464 DCHECK(entry); | 503 DCHECK(entry); |
465 | 504 |
466 DVLOG(3) << "HandleQueuedStartRequest, Post start to device thread, device = " | 505 DVLOG(3) << "HandleQueuedStartRequest, Post start to device thread, device = " |
467 << entry->id << " start id = " << entry->serial_id; | 506 << entry->id << " start id = " << entry->serial_id; |
468 | 507 |
| 508 std::unique_ptr<media::VideoCaptureDevice::Client> device_client = |
| 509 entry->CreateDeviceClient(); |
| 510 std::unique_ptr<media::FrameBufferPool> frame_buffer_pool = |
| 511 entry->CreateFrameBufferPool(); |
| 512 |
469 base::Callback<std::unique_ptr<VideoCaptureDevice>(void)> | 513 base::Callback<std::unique_ptr<VideoCaptureDevice>(void)> |
470 start_capture_function; | 514 start_capture_function; |
471 | 515 |
472 switch (entry->stream_type) { | 516 switch (entry->stream_type) { |
473 case MEDIA_DEVICE_VIDEO_CAPTURE: { | 517 case MEDIA_DEVICE_VIDEO_CAPTURE: { |
474 // We look up the device id from the renderer in our local enumeration | 518 // We look up the device id from the renderer in our local enumeration |
475 // since the renderer does not have all the information that might be | 519 // since the renderer does not have all the information that might be |
476 // held in the browser-side VideoCaptureDevice::Name structure. | 520 // held in the browser-side VideoCaptureDevice::Name structure. |
477 const DeviceInfo* found = GetDeviceInfoById(entry->id); | 521 const DeviceInfo* found = GetDeviceInfoById(entry->id); |
478 if (found) { | 522 if (found) { |
479 entry->video_capture_controller()->OnLog( | 523 entry->video_capture_controller.OnLog( |
480 base::StringPrintf("Starting device: id: %s, name: %s, api: %s", | 524 base::StringPrintf("Starting device: id: %s, name: %s, api: %s", |
481 found->descriptor.device_id.c_str(), | 525 found->descriptor.device_id.c_str(), |
482 found->descriptor.GetNameAndModel().c_str(), | 526 found->descriptor.GetNameAndModel().c_str(), |
483 found->descriptor.GetCaptureApiTypeString())); | 527 found->descriptor.GetCaptureApiTypeString())); |
484 | 528 |
485 start_capture_function = base::Bind( | 529 start_capture_function = |
486 &VideoCaptureManager::DoStartDeviceCaptureOnDeviceThread, this, | 530 base::Bind(&VideoCaptureManager::DoStartDeviceCaptureOnDeviceThread, |
487 found->descriptor, request->params(), | 531 this, found->descriptor, request->params(), |
488 base::Passed(entry->video_capture_controller()->NewDeviceClient())); | 532 base::Passed(std::move(device_client))); |
489 } else { | 533 } else { |
490 // Errors from DoStartDeviceCaptureOnDeviceThread go via | 534 // Errors from DoStartDeviceCaptureOnDeviceThread go via |
491 // VideoCaptureDeviceClient::OnError, which needs some thread | 535 // VideoCaptureDeviceClient::OnError, which needs some thread |
492 // dancing to get errors processed on the IO thread. But since | 536 // dancing to get errors processed on the IO thread. But since |
493 // we're on that thread, we call VideoCaptureController | 537 // we're on that thread, we call VideoCaptureController |
494 // methods directly. | 538 // methods directly. |
495 const std::string log_message = base::StringPrintf( | 539 const std::string log_message = base::StringPrintf( |
496 "Error on %s:%d: device %s unknown. Maybe recently disconnected?", | 540 "Error on %s:%d: device %s unknown. Maybe recently disconnected?", |
497 __FILE__, __LINE__, entry->id.c_str()); | 541 __FILE__, __LINE__, entry->id.c_str()); |
498 DLOG(ERROR) << log_message; | 542 DLOG(ERROR) << log_message; |
499 entry->video_capture_controller()->OnLog(log_message); | 543 entry->video_capture_controller.OnLog(log_message); |
500 entry->video_capture_controller()->OnError(); | 544 entry->video_capture_controller.OnError(); |
501 // Drop the failed start request. | 545 // Drop the failed start request. |
502 device_start_queue_.pop_front(); | 546 device_start_queue_.pop_front(); |
503 | 547 |
504 return; | 548 return; |
505 } | 549 } |
506 break; | 550 break; |
507 } | 551 } |
508 case MEDIA_TAB_VIDEO_CAPTURE: | 552 case MEDIA_TAB_VIDEO_CAPTURE: |
509 start_capture_function = base::Bind( | 553 start_capture_function = base::Bind( |
510 &VideoCaptureManager::DoStartTabCaptureOnDeviceThread, this, | 554 &VideoCaptureManager::DoStartTabCaptureOnDeviceThread, this, |
511 entry->id, request->params(), | 555 entry->id, request->params(), base::Passed(std::move(device_client))); |
512 base::Passed(entry->video_capture_controller()->NewDeviceClient())); | |
513 break; | 556 break; |
514 | 557 |
515 case MEDIA_DESKTOP_VIDEO_CAPTURE: | 558 case MEDIA_DESKTOP_VIDEO_CAPTURE: |
516 start_capture_function = base::Bind( | 559 start_capture_function = base::Bind( |
517 &VideoCaptureManager::DoStartDesktopCaptureOnDeviceThread, this, | 560 &VideoCaptureManager::DoStartDesktopCaptureOnDeviceThread, this, |
518 entry->id, request->params(), | 561 entry->id, request->params(), base::Passed(std::move(device_client))); |
519 base::Passed(entry->video_capture_controller()->NewDeviceClient())); | |
520 break; | 562 break; |
521 | 563 |
522 default: { | 564 default: { |
523 NOTIMPLEMENTED(); | 565 NOTIMPLEMENTED(); |
524 return; | 566 return; |
525 } | 567 } |
526 } | 568 } |
527 base::PostTaskAndReplyWithResult( | 569 base::PostTaskAndReplyWithResult( |
528 device_task_runner_.get(), FROM_HERE, start_capture_function, | 570 device_task_runner_.get(), FROM_HERE, start_capture_function, |
529 base::Bind(&VideoCaptureManager::OnDeviceStarted, this, | 571 base::Bind(&VideoCaptureManager::OnDeviceStarted, this, |
530 request->serial_id())); | 572 request->serial_id(), base::Passed(&frame_buffer_pool))); |
531 } | 573 } |
532 | 574 |
533 void VideoCaptureManager::OnDeviceStarted( | 575 void VideoCaptureManager::OnDeviceStarted( |
534 int serial_id, | 576 int serial_id, |
| 577 std::unique_ptr<media::FrameBufferPool> frame_buffer_pool, |
535 std::unique_ptr<VideoCaptureDevice> device) { | 578 std::unique_ptr<VideoCaptureDevice> device) { |
536 DVLOG(3) << __func__; | 579 DVLOG(3) << __func__; |
537 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 580 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
538 DCHECK_EQ(serial_id, device_start_queue_.begin()->serial_id()); | 581 DCHECK_EQ(serial_id, device_start_queue_.begin()->serial_id()); |
539 // |device| can be null if creation failed in | 582 // |device| can be null if creation failed in |
540 // DoStartDeviceCaptureOnDeviceThread. | 583 // DoStartDeviceCaptureOnDeviceThread. |
541 if (device_start_queue_.front().abort_start()) { | 584 if (device_start_queue_.front().abort_start()) { |
542 // The device is no longer wanted. Stop the device again. | 585 // The device is no longer wanted. Stop the device again. |
543 DVLOG(3) << "OnDeviceStarted but start request have been aborted."; | 586 DVLOG(3) << "OnDeviceStarted but start request have been aborted."; |
544 media::VideoCaptureDevice* device_ptr = device.get(); | 587 media::VideoCaptureDevice* device_ptr = device.get(); |
545 base::Closure closure = | 588 base::Closure closure = |
546 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, | 589 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, |
547 base::Passed(&device)); | 590 base::Passed(&device)); |
548 if (device_ptr && !device_task_runner_->PostTask(FROM_HERE, closure)) { | 591 if (device_ptr && !device_task_runner_->PostTask(FROM_HERE, closure)) { |
549 // PostTask failed. The device must be stopped anyway. | 592 // PostTask failed. The device must be stopped anyway. |
550 device_ptr->StopAndDeAllocate(); | 593 device_ptr->StopAndDeAllocate(); |
551 } | 594 } |
552 } else { | 595 } else { |
553 DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id); | 596 DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id); |
554 DCHECK(entry); | 597 DCHECK(entry); |
555 DCHECK(!entry->video_capture_device()); | 598 DCHECK(!entry->video_capture_device); |
556 // Passing raw pointer |device.get()| to the controller is safe, | 599 if (device) { |
557 // because we transfer ownership of it to |entry|. We are calling | 600 entry->video_capture_controller.SetFrameBufferPool( |
558 // SetConsumerFeedbackObserver(nullptr) before releasing | 601 std::move(frame_buffer_pool)); |
559 // |entry->video_capture_device_| on the |device_task_runner_|. | 602 // Passing raw pointer |device.get()| to the controller is safe, |
560 entry->video_capture_controller()->SetConsumerFeedbackObserver( | 603 // because we transfer ownership of it to |entry|. We are calling |
561 base::MakeUnique<VideoFrameConsumerFeedbackObserverOnTaskRunner>( | 604 // SetConsumerFeedbackObserver(nullptr) before releasing |
562 device.get(), device_task_runner_)); | 605 // |entry->video_capture_device_| on the |device_task_runner_|. |
563 entry->SetVideoCaptureDevice(std::move(device)); | 606 entry->video_capture_controller.SetConsumerFeedbackObserver( |
| 607 base::MakeUnique<VideoFrameConsumerFeedbackObserverOnTaskRunner>( |
| 608 device.get(), device_task_runner_)); |
| 609 } |
| 610 entry->video_capture_device = std::move(device); |
564 | 611 |
565 if (entry->stream_type == MEDIA_DESKTOP_VIDEO_CAPTURE) { | 612 if (entry->stream_type == MEDIA_DESKTOP_VIDEO_CAPTURE) { |
566 const media::VideoCaptureSessionId session_id = | 613 const media::VideoCaptureSessionId session_id = |
567 device_start_queue_.front().session_id(); | 614 device_start_queue_.front().session_id(); |
568 DCHECK(session_id != kFakeSessionId); | 615 DCHECK(session_id != kFakeSessionId); |
569 MaybePostDesktopCaptureWindowId(session_id); | 616 MaybePostDesktopCaptureWindowId(session_id); |
570 } | 617 } |
571 | 618 |
572 auto it = photo_request_queue_.begin(); | 619 auto it = photo_request_queue_.begin(); |
573 while (it != photo_request_queue_.end()) { | 620 while (it != photo_request_queue_.end()) { |
574 auto request = it++; | 621 auto request = it++; |
575 DeviceEntry* maybe_entry = GetDeviceEntryBySessionId(request->first); | 622 DeviceEntry* maybe_entry = GetDeviceEntryBySessionId(request->first); |
576 if (maybe_entry && maybe_entry->video_capture_device()) { | 623 if (maybe_entry && maybe_entry->video_capture_device) { |
577 request->second.Run(maybe_entry->video_capture_device()); | 624 request->second.Run(maybe_entry->video_capture_device.get()); |
578 photo_request_queue_.erase(request); | 625 photo_request_queue_.erase(request); |
579 } | 626 } |
580 } | 627 } |
581 } | 628 } |
582 | 629 |
583 device_start_queue_.pop_front(); | 630 device_start_queue_.pop_front(); |
584 HandleQueuedStartRequest(); | 631 HandleQueuedStartRequest(); |
585 } | 632 } |
586 | 633 |
587 std::unique_ptr<media::VideoCaptureDevice> | 634 std::unique_ptr<media::VideoCaptureDevice> |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
680 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 727 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
681 DVLOG(1) << __func__ << ", session_id = " << session_id << ", request: " | 728 DVLOG(1) << __func__ << ", session_id = " << session_id << ", request: " |
682 << media::VideoCaptureFormat::ToString(params.requested_format); | 729 << media::VideoCaptureFormat::ToString(params.requested_format); |
683 | 730 |
684 DeviceEntry* entry = GetOrCreateDeviceEntry(session_id, params); | 731 DeviceEntry* entry = GetOrCreateDeviceEntry(session_id, params); |
685 if (!entry) { | 732 if (!entry) { |
686 done_cb.Run(base::WeakPtr<VideoCaptureController>()); | 733 done_cb.Run(base::WeakPtr<VideoCaptureController>()); |
687 return; | 734 return; |
688 } | 735 } |
689 | 736 |
690 DCHECK(entry->video_capture_controller()); | |
691 | |
692 LogVideoCaptureEvent(VIDEO_CAPTURE_START_CAPTURE); | 737 LogVideoCaptureEvent(VIDEO_CAPTURE_START_CAPTURE); |
693 | 738 |
694 // First client starts the device. | 739 // First client starts the device. |
695 if (!entry->video_capture_controller()->HasActiveClient() && | 740 if (!entry->video_capture_controller.HasActiveClient() && |
696 !entry->video_capture_controller()->HasPausedClient()) { | 741 !entry->video_capture_controller.HasPausedClient()) { |
697 DVLOG(1) << "VideoCaptureManager starting device (type = " | 742 DVLOG(1) << "VideoCaptureManager starting device (type = " |
698 << entry->stream_type << ", id = " << entry->id << ")"; | 743 << entry->stream_type << ", id = " << entry->id << ")"; |
699 QueueStartDevice(session_id, entry, params); | 744 QueueStartDevice(session_id, entry, params); |
700 } | 745 } |
701 // Run the callback first, as AddClient() may trigger OnFrameInfo(). | 746 // Run the callback first, as AddClient() may trigger OnFrameInfo(). |
702 done_cb.Run(entry->video_capture_controller()->GetWeakPtrForIOThread()); | 747 done_cb.Run(entry->video_capture_controller.GetWeakPtrForIOThread()); |
703 entry->video_capture_controller()->AddClient( | 748 entry->video_capture_controller.AddClient(client_id, client_handler, |
704 client_id, client_handler, session_id, params); | 749 session_id, params); |
705 } | 750 } |
706 | 751 |
707 void VideoCaptureManager::StopCaptureForClient( | 752 void VideoCaptureManager::StopCaptureForClient( |
708 VideoCaptureController* controller, | 753 VideoCaptureController* controller, |
709 VideoCaptureControllerID client_id, | 754 VideoCaptureControllerID client_id, |
710 VideoCaptureControllerEventHandler* client_handler, | 755 VideoCaptureControllerEventHandler* client_handler, |
711 bool aborted_due_to_error) { | 756 bool aborted_due_to_error) { |
712 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 757 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
713 DCHECK(controller); | 758 DCHECK(controller); |
714 DCHECK(client_handler); | 759 DCHECK(client_handler); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
759 DCHECK(controller); | 804 DCHECK(controller); |
760 DCHECK(client_handler); | 805 DCHECK(client_handler); |
761 DeviceEntry* entry = GetDeviceEntryByController(controller); | 806 DeviceEntry* entry = GetDeviceEntryByController(controller); |
762 if (!entry) | 807 if (!entry) |
763 NOTREACHED() << "Got Null entry while pausing capture"; | 808 NOTREACHED() << "Got Null entry while pausing capture"; |
764 | 809 |
765 const bool had_active_client = controller->HasActiveClient(); | 810 const bool had_active_client = controller->HasActiveClient(); |
766 controller->PauseClient(client_id, client_handler); | 811 controller->PauseClient(client_id, client_handler); |
767 if (!had_active_client || controller->HasActiveClient()) | 812 if (!had_active_client || controller->HasActiveClient()) |
768 return; | 813 return; |
769 if (media::VideoCaptureDevice* device = entry->video_capture_device()) { | 814 if (media::VideoCaptureDevice* device = entry->video_capture_device.get()) { |
770 device_task_runner_->PostTask( | 815 device_task_runner_->PostTask( |
771 FROM_HERE, | 816 FROM_HERE, |
772 base::Bind(&VideoCaptureDevice::MaybeSuspend, | 817 base::Bind(&VideoCaptureDevice::MaybeSuspend, |
773 // Unretained is safe to use here because |device| would be | 818 // Unretained is safe to use here because |device| would be |
774 // null if it was scheduled for shutdown and destruction, and | 819 // null if it was scheduled for shutdown and destruction, and |
775 // because this task is guaranteed to run before the task | 820 // because this task is guaranteed to run before the task |
776 // that destroys the |device|. | 821 // that destroys the |device|. |
777 base::Unretained(device))); | 822 base::Unretained(device))); |
778 } | 823 } |
779 } | 824 } |
780 | 825 |
781 void VideoCaptureManager::ResumeCaptureForClient( | 826 void VideoCaptureManager::ResumeCaptureForClient( |
782 media::VideoCaptureSessionId session_id, | 827 media::VideoCaptureSessionId session_id, |
783 const media::VideoCaptureParams& params, | 828 const media::VideoCaptureParams& params, |
784 VideoCaptureController* controller, | 829 VideoCaptureController* controller, |
785 VideoCaptureControllerID client_id, | 830 VideoCaptureControllerID client_id, |
786 VideoCaptureControllerEventHandler* client_handler) { | 831 VideoCaptureControllerEventHandler* client_handler) { |
787 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 832 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
788 DCHECK(controller); | 833 DCHECK(controller); |
789 DCHECK(client_handler); | 834 DCHECK(client_handler); |
790 | 835 |
791 DeviceEntry* entry = GetDeviceEntryByController(controller); | 836 DeviceEntry* entry = GetDeviceEntryByController(controller); |
792 if (!entry) | 837 if (!entry) |
793 NOTREACHED() << "Got Null entry while resuming capture"; | 838 NOTREACHED() << "Got Null entry while resuming capture"; |
794 | 839 |
795 const bool had_active_client = controller->HasActiveClient(); | 840 const bool had_active_client = controller->HasActiveClient(); |
796 controller->ResumeClient(client_id, client_handler); | 841 controller->ResumeClient(client_id, client_handler); |
797 if (had_active_client || !controller->HasActiveClient()) | 842 if (had_active_client || !controller->HasActiveClient()) |
798 return; | 843 return; |
799 if (media::VideoCaptureDevice* device = entry->video_capture_device()) { | 844 if (media::VideoCaptureDevice* device = entry->video_capture_device.get()) { |
800 device_task_runner_->PostTask( | 845 device_task_runner_->PostTask( |
801 FROM_HERE, | 846 FROM_HERE, |
802 base::Bind(&VideoCaptureDevice::Resume, | 847 base::Bind(&VideoCaptureDevice::Resume, |
803 // Unretained is safe to use here because |device| would be | 848 // Unretained is safe to use here because |device| would be |
804 // null if it was scheduled for shutdown and destruction, and | 849 // null if it was scheduled for shutdown and destruction, and |
805 // because this task is guaranteed to run before the task | 850 // because this task is guaranteed to run before the task |
806 // that destroys the |device|. | 851 // that destroys the |device|. |
807 base::Unretained(device))); | 852 base::Unretained(device))); |
808 } | 853 } |
809 } | 854 } |
810 | 855 |
811 void VideoCaptureManager::RequestRefreshFrameForClient( | 856 void VideoCaptureManager::RequestRefreshFrameForClient( |
812 VideoCaptureController* controller) { | 857 VideoCaptureController* controller) { |
813 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 858 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
814 | 859 |
815 if (DeviceEntry* entry = GetDeviceEntryByController(controller)) { | 860 if (DeviceEntry* entry = GetDeviceEntryByController(controller)) { |
816 if (media::VideoCaptureDevice* device = entry->video_capture_device()) { | 861 if (media::VideoCaptureDevice* device = entry->video_capture_device.get()) { |
817 device_task_runner_->PostTask( | 862 device_task_runner_->PostTask( |
818 FROM_HERE, | 863 FROM_HERE, |
819 base::Bind(&VideoCaptureDevice::RequestRefreshFrame, | 864 base::Bind(&VideoCaptureDevice::RequestRefreshFrame, |
820 // Unretained is safe to use here because |device| would be | 865 // Unretained is safe to use here because |device| would be |
821 // null if it was scheduled for shutdown and destruction, | 866 // null if it was scheduled for shutdown and destruction, |
822 // and because this task is guaranteed to run before the | 867 // and because this task is guaranteed to run before the |
823 // task that destroys the |device|. | 868 // task that destroys the |device|. |
824 base::Unretained(device))); | 869 base::Unretained(device))); |
825 } | 870 } |
826 } | 871 } |
(...skipping 27 matching lines...) Expand all Loading... |
854 if (it == sessions_.end()) | 899 if (it == sessions_.end()) |
855 return false; | 900 return false; |
856 DVLOG(1) << "GetDeviceFormatsInUse for device: " << it->second.name; | 901 DVLOG(1) << "GetDeviceFormatsInUse for device: " << it->second.name; |
857 | 902 |
858 // Return the currently in-use format(s) of the device, if it's started. | 903 // Return the currently in-use format(s) of the device, if it's started. |
859 DeviceEntry* device_in_use = | 904 DeviceEntry* device_in_use = |
860 GetDeviceEntryByTypeAndId(it->second.type, it->second.id); | 905 GetDeviceEntryByTypeAndId(it->second.type, it->second.id); |
861 if (device_in_use) { | 906 if (device_in_use) { |
862 // Currently only one format-in-use is supported at the VCC level. | 907 // Currently only one format-in-use is supported at the VCC level. |
863 formats_in_use->push_back( | 908 formats_in_use->push_back( |
864 device_in_use->video_capture_controller()->GetVideoCaptureFormat()); | 909 device_in_use->video_capture_controller.GetVideoCaptureFormat()); |
865 } | 910 } |
866 return true; | 911 return true; |
867 } | 912 } |
868 | 913 |
869 void VideoCaptureManager::SetDesktopCaptureWindowId( | 914 void VideoCaptureManager::SetDesktopCaptureWindowId( |
870 media::VideoCaptureSessionId session_id, | 915 media::VideoCaptureSessionId session_id, |
871 gfx::NativeViewId window_id) { | 916 gfx::NativeViewId window_id) { |
872 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 917 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
873 VLOG(2) << "SetDesktopCaptureWindowId called for session " << session_id; | 918 VLOG(2) << "SetDesktopCaptureWindowId called for session " << session_id; |
874 | 919 |
875 notification_window_ids_[session_id] = window_id; | 920 notification_window_ids_[session_id] = window_id; |
876 MaybePostDesktopCaptureWindowId(session_id); | 921 MaybePostDesktopCaptureWindowId(session_id); |
877 } | 922 } |
878 | 923 |
879 void VideoCaptureManager::MaybePostDesktopCaptureWindowId( | 924 void VideoCaptureManager::MaybePostDesktopCaptureWindowId( |
880 media::VideoCaptureSessionId session_id) { | 925 media::VideoCaptureSessionId session_id) { |
881 SessionMap::iterator session_it = sessions_.find(session_id); | 926 SessionMap::iterator session_it = sessions_.find(session_id); |
882 if (session_it == sessions_.end()) | 927 if (session_it == sessions_.end()) |
883 return; | 928 return; |
884 | 929 |
885 DeviceEntry* const existing_device = | 930 DeviceEntry* const existing_device = |
886 GetDeviceEntryByTypeAndId(session_it->second.type, session_it->second.id); | 931 GetDeviceEntryByTypeAndId(session_it->second.type, session_it->second.id); |
887 if (!existing_device) { | 932 if (!existing_device) { |
888 DVLOG(2) << "Failed to find an existing screen capture device."; | 933 DVLOG(2) << "Failed to find an existing screen capture device."; |
889 return; | 934 return; |
890 } | 935 } |
891 | 936 |
892 if (!existing_device->video_capture_device()) { | 937 if (!existing_device->video_capture_device) { |
893 DVLOG(2) << "Screen capture device not yet started."; | 938 DVLOG(2) << "Screen capture device not yet started."; |
894 return; | 939 return; |
895 } | 940 } |
896 | 941 |
897 DCHECK_EQ(MEDIA_DESKTOP_VIDEO_CAPTURE, existing_device->stream_type); | 942 DCHECK_EQ(MEDIA_DESKTOP_VIDEO_CAPTURE, existing_device->stream_type); |
898 DesktopMediaID id = DesktopMediaID::Parse(existing_device->id); | 943 DesktopMediaID id = DesktopMediaID::Parse(existing_device->id); |
899 if (id.is_null()) | 944 if (id.is_null()) |
900 return; | 945 return; |
901 | 946 |
902 auto window_id_it = notification_window_ids_.find(session_id); | 947 auto window_id_it = notification_window_ids_.find(session_id); |
903 if (window_id_it == notification_window_ids_.end()) { | 948 if (window_id_it == notification_window_ids_.end()) { |
904 DVLOG(2) << "Notification window id not set for screen capture."; | 949 DVLOG(2) << "Notification window id not set for screen capture."; |
905 return; | 950 return; |
906 } | 951 } |
907 | 952 |
908 // Post |existing_device->video_capture_device| to the VideoCaptureDevice to | 953 // Post |existing_device->video_capture_device| to the VideoCaptureDevice to |
909 // the device_task_runner_. This is safe since the device is destroyed on the | 954 // the device_task_runner_. This is safe since the device is destroyed on the |
910 // device_task_runner_. | 955 // device_task_runner_. |
911 device_task_runner_->PostTask( | 956 device_task_runner_->PostTask( |
912 FROM_HERE, | 957 FROM_HERE, |
913 base::Bind(&VideoCaptureManager::SetDesktopCaptureWindowIdOnDeviceThread, | 958 base::Bind(&VideoCaptureManager::SetDesktopCaptureWindowIdOnDeviceThread, |
914 this, | 959 this, existing_device->video_capture_device.get(), |
915 existing_device->video_capture_device(), | |
916 window_id_it->second)); | 960 window_id_it->second)); |
917 | 961 |
918 notification_window_ids_.erase(window_id_it); | 962 notification_window_ids_.erase(window_id_it); |
919 } | 963 } |
920 | 964 |
921 void VideoCaptureManager::GetPhotoCapabilities( | 965 void VideoCaptureManager::GetPhotoCapabilities( |
922 int session_id, | 966 int session_id, |
923 VideoCaptureDevice::GetPhotoCapabilitiesCallback callback) { | 967 VideoCaptureDevice::GetPhotoCapabilitiesCallback callback) { |
924 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 968 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
925 | 969 |
926 const DeviceEntry* entry = GetDeviceEntryBySessionId(session_id); | 970 const DeviceEntry* entry = GetDeviceEntryBySessionId(session_id); |
927 if (!entry) | 971 if (!entry) |
928 return; | 972 return; |
929 VideoCaptureDevice* device = entry->video_capture_device(); | 973 VideoCaptureDevice* device = entry->video_capture_device.get(); |
930 if (device) { | 974 if (device) { |
931 VideoCaptureManager::DoGetPhotoCapabilities(std::move(callback), device); | 975 VideoCaptureManager::DoGetPhotoCapabilities(std::move(callback), device); |
932 return; | 976 return; |
933 } | 977 } |
934 // |entry| is known but |device| is nullptr, queue up a request for later. | 978 // |entry| is known but |device| is nullptr, queue up a request for later. |
935 photo_request_queue_.emplace_back( | 979 photo_request_queue_.emplace_back( |
936 session_id, base::Bind(&VideoCaptureManager::DoGetPhotoCapabilities, this, | 980 session_id, base::Bind(&VideoCaptureManager::DoGetPhotoCapabilities, this, |
937 base::Passed(&callback))); | 981 base::Passed(&callback))); |
938 } | 982 } |
939 | 983 |
940 void VideoCaptureManager::SetPhotoOptions( | 984 void VideoCaptureManager::SetPhotoOptions( |
941 int session_id, | 985 int session_id, |
942 media::mojom::PhotoSettingsPtr settings, | 986 media::mojom::PhotoSettingsPtr settings, |
943 VideoCaptureDevice::SetPhotoOptionsCallback callback) { | 987 VideoCaptureDevice::SetPhotoOptionsCallback callback) { |
944 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 988 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
945 | 989 |
946 const DeviceEntry* entry = GetDeviceEntryBySessionId(session_id); | 990 const DeviceEntry* entry = GetDeviceEntryBySessionId(session_id); |
947 if (!entry) | 991 if (!entry) |
948 return; | 992 return; |
949 VideoCaptureDevice* device = entry->video_capture_device(); | 993 VideoCaptureDevice* device = entry->video_capture_device.get(); |
950 if (device) { | 994 if (device) { |
951 VideoCaptureManager::DoSetPhotoOptions(std::move(callback), | 995 VideoCaptureManager::DoSetPhotoOptions(std::move(callback), |
952 std::move(settings), device); | 996 std::move(settings), device); |
953 return; | 997 return; |
954 } | 998 } |
955 // |entry| is known but |device| is nullptr, queue up a request for later. | 999 // |entry| is known but |device| is nullptr, queue up a request for later. |
956 photo_request_queue_.emplace_back( | 1000 photo_request_queue_.emplace_back( |
957 session_id, base::Bind(&VideoCaptureManager::DoSetPhotoOptions, this, | 1001 session_id, base::Bind(&VideoCaptureManager::DoSetPhotoOptions, this, |
958 base::Passed(&callback), base::Passed(&settings))); | 1002 base::Passed(&callback), base::Passed(&settings))); |
959 } | 1003 } |
960 | 1004 |
961 void VideoCaptureManager::TakePhoto( | 1005 void VideoCaptureManager::TakePhoto( |
962 int session_id, | 1006 int session_id, |
963 VideoCaptureDevice::TakePhotoCallback callback) { | 1007 VideoCaptureDevice::TakePhotoCallback callback) { |
964 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1008 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
965 | 1009 |
966 const DeviceEntry* entry = GetDeviceEntryBySessionId(session_id); | 1010 const DeviceEntry* entry = GetDeviceEntryBySessionId(session_id); |
967 if (!entry) | 1011 if (!entry) |
968 return; | 1012 return; |
969 VideoCaptureDevice* device = entry->video_capture_device(); | 1013 VideoCaptureDevice* device = entry->video_capture_device.get(); |
970 if (device) { | 1014 if (device) { |
971 VideoCaptureManager::DoTakePhoto(std::move(callback), device); | 1015 VideoCaptureManager::DoTakePhoto(std::move(callback), device); |
972 return; | 1016 return; |
973 } | 1017 } |
974 // |entry| is known but |device| is nullptr, queue up a request for later. | 1018 // |entry| is known but |device| is nullptr, queue up a request for later. |
975 photo_request_queue_.emplace_back( | 1019 photo_request_queue_.emplace_back( |
976 session_id, base::Bind(&VideoCaptureManager::DoTakePhoto, this, | 1020 session_id, base::Bind(&VideoCaptureManager::DoTakePhoto, this, |
977 base::Passed(&callback))); | 1021 base::Passed(&callback))); |
978 } | 1022 } |
979 | 1023 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1067 ConsolidateCaptureFormats(&device_info.supported_formats); | 1111 ConsolidateCaptureFormats(&device_info.supported_formats); |
1068 new_devices_info_cache.push_back(device_info); | 1112 new_devices_info_cache.push_back(device_info); |
1069 } | 1113 } |
1070 | 1114 |
1071 on_devices_enumerated_callback.Run(new_devices_info_cache); | 1115 on_devices_enumerated_callback.Run(new_devices_info_cache); |
1072 } | 1116 } |
1073 | 1117 |
1074 void VideoCaptureManager::DestroyDeviceEntryIfNoClients(DeviceEntry* entry) { | 1118 void VideoCaptureManager::DestroyDeviceEntryIfNoClients(DeviceEntry* entry) { |
1075 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1119 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
1076 // Removal of the last client stops the device. | 1120 // Removal of the last client stops the device. |
1077 if (!entry->video_capture_controller()->HasActiveClient() && | 1121 if (!entry->video_capture_controller.HasActiveClient() && |
1078 !entry->video_capture_controller()->HasPausedClient()) { | 1122 !entry->video_capture_controller.HasPausedClient()) { |
1079 DVLOG(1) << "VideoCaptureManager stopping device (type = " | 1123 DVLOG(1) << "VideoCaptureManager stopping device (type = " |
1080 << entry->stream_type << ", id = " << entry->id << ")"; | 1124 << entry->stream_type << ", id = " << entry->id << ")"; |
1081 | 1125 |
1082 // The DeviceEntry is removed from |devices_| immediately. The controller is | 1126 // The DeviceEntry is removed from |devices_| immediately. The controller is |
1083 // deleted immediately, and the device is freed asynchronously. After this | 1127 // deleted immediately, and the device is freed asynchronously. After this |
1084 // point, subsequent requests to open this same device ID will create a new | 1128 // point, subsequent requests to open this same device ID will create a new |
1085 // DeviceEntry, VideoCaptureController, and VideoCaptureDevice. | 1129 // DeviceEntry, VideoCaptureController, and VideoCaptureDevice. |
1086 DoStopDevice(entry); | 1130 DoStopDevice(entry); |
1087 // TODO(mcasas): use a helper function https://crbug.com/624854. | 1131 // TODO(mcasas): use a helper function https://crbug.com/624854. |
1088 DeviceEntries::iterator device_it = | 1132 DeviceEntries::iterator device_it = |
(...skipping 29 matching lines...) Expand all Loading... |
1118 return nullptr; | 1162 return nullptr; |
1119 } | 1163 } |
1120 | 1164 |
1121 VideoCaptureManager::DeviceEntry* | 1165 VideoCaptureManager::DeviceEntry* |
1122 VideoCaptureManager::GetDeviceEntryByController( | 1166 VideoCaptureManager::GetDeviceEntryByController( |
1123 const VideoCaptureController* controller) const { | 1167 const VideoCaptureController* controller) const { |
1124 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1168 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
1125 | 1169 |
1126 // Look up |controller| in |devices_|. | 1170 // Look up |controller| in |devices_|. |
1127 for (const std::unique_ptr<DeviceEntry>& device : devices_) { | 1171 for (const std::unique_ptr<DeviceEntry>& device : devices_) { |
1128 if (device->video_capture_controller() == controller) | 1172 if (&device->video_capture_controller == controller) |
1129 return device.get(); | 1173 return device.get(); |
1130 } | 1174 } |
1131 return nullptr; | 1175 return nullptr; |
1132 } | 1176 } |
1133 | 1177 |
1134 VideoCaptureManager::DeviceEntry* VideoCaptureManager::GetDeviceEntryBySerialId( | 1178 VideoCaptureManager::DeviceEntry* VideoCaptureManager::GetDeviceEntryBySerialId( |
1135 int serial_id) const { | 1179 int serial_id) const { |
1136 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1180 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
1137 | 1181 |
1138 for (const std::unique_ptr<DeviceEntry>& device : devices_) { | 1182 for (const std::unique_ptr<DeviceEntry>& device : devices_) { |
(...skipping 24 matching lines...) Expand all Loading... |
1163 | 1207 |
1164 // Check if another session has already opened this device. If so, just | 1208 // Check if another session has already opened this device. If so, just |
1165 // use that opened device. | 1209 // use that opened device. |
1166 DeviceEntry* const existing_device = | 1210 DeviceEntry* const existing_device = |
1167 GetDeviceEntryByTypeAndId(device_info.type, device_info.id); | 1211 GetDeviceEntryByTypeAndId(device_info.type, device_info.id); |
1168 if (existing_device) { | 1212 if (existing_device) { |
1169 DCHECK_EQ(device_info.type, existing_device->stream_type); | 1213 DCHECK_EQ(device_info.type, existing_device->stream_type); |
1170 return existing_device; | 1214 return existing_device; |
1171 } | 1215 } |
1172 | 1216 |
1173 const int max_buffers = device_info.type == MEDIA_TAB_VIDEO_CAPTURE ? | 1217 devices_.emplace_back( |
1174 kMaxNumberOfBuffersForTabCapture : kMaxNumberOfBuffers; | 1218 new DeviceEntry(device_info.type, device_info.id, params)); |
1175 std::unique_ptr<VideoCaptureController> video_capture_controller( | 1219 return devices_.back().get(); |
1176 new VideoCaptureController(max_buffers)); | |
1177 DeviceEntry* new_device = | |
1178 new DeviceEntry(device_info.type, device_info.id, | |
1179 std::move(video_capture_controller), params); | |
1180 devices_.emplace_back(new_device); | |
1181 return new_device; | |
1182 } | 1220 } |
1183 | 1221 |
1184 void VideoCaptureManager::SetDesktopCaptureWindowIdOnDeviceThread( | 1222 void VideoCaptureManager::SetDesktopCaptureWindowIdOnDeviceThread( |
1185 media::VideoCaptureDevice* device, | 1223 media::VideoCaptureDevice* device, |
1186 gfx::NativeViewId window_id) { | 1224 gfx::NativeViewId window_id) { |
1187 DCHECK(IsOnDeviceThread()); | 1225 DCHECK(IsOnDeviceThread()); |
1188 #if defined(ENABLE_SCREEN_CAPTURE) && !defined(OS_ANDROID) | 1226 #if defined(ENABLE_SCREEN_CAPTURE) && !defined(OS_ANDROID) |
1189 DesktopCaptureDevice* desktop_device = | 1227 DesktopCaptureDevice* desktop_device = |
1190 static_cast<DesktopCaptureDevice*>(device); | 1228 static_cast<DesktopCaptureDevice*>(device); |
1191 desktop_device->SetNotificationWindowId(window_id); | 1229 desktop_device->SetNotificationWindowId(window_id); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1257 } | 1295 } |
1258 } | 1296 } |
1259 | 1297 |
1260 void VideoCaptureManager::ResumeDevices() { | 1298 void VideoCaptureManager::ResumeDevices() { |
1261 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1299 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
1262 | 1300 |
1263 for (auto& entry : devices_) { | 1301 for (auto& entry : devices_) { |
1264 // Do not resume Content Video Capture devices, e.g. Tab or Screen capture. | 1302 // Do not resume Content Video Capture devices, e.g. Tab or Screen capture. |
1265 // Do not try to restart already running devices. | 1303 // Do not try to restart already running devices. |
1266 if (entry->stream_type != MEDIA_DEVICE_VIDEO_CAPTURE || | 1304 if (entry->stream_type != MEDIA_DEVICE_VIDEO_CAPTURE || |
1267 entry->video_capture_device()) | 1305 entry->video_capture_device) |
1268 continue; | 1306 continue; |
1269 | 1307 |
1270 // Check if the device is already in the start queue. | 1308 // Check if the device is already in the start queue. |
1271 bool device_in_queue = false; | 1309 bool device_in_queue = false; |
1272 for (auto& request : device_start_queue_) { | 1310 for (auto& request : device_start_queue_) { |
1273 if (request.serial_id() == entry->serial_id) { | 1311 if (request.serial_id() == entry->serial_id) { |
1274 device_in_queue = true; | 1312 device_in_queue = true; |
1275 break; | 1313 break; |
1276 } | 1314 } |
1277 } | 1315 } |
1278 | 1316 |
1279 if (!device_in_queue) { | 1317 if (!device_in_queue) { |
1280 // Session ID is only valid for Screen capture. So we can fake it to | 1318 // Session ID is only valid for Screen capture. So we can fake it to |
1281 // resume video capture devices here. | 1319 // resume video capture devices here. |
1282 QueueStartDevice(kFakeSessionId, entry.get(), entry->parameters); | 1320 QueueStartDevice(kFakeSessionId, entry.get(), entry->parameters); |
1283 } | 1321 } |
1284 } | 1322 } |
1285 } | 1323 } |
1286 #endif // defined(OS_ANDROID) | 1324 #endif // defined(OS_ANDROID) |
1287 | 1325 |
1288 } // namespace content | 1326 } // namespace content |
OLD | NEW |