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 "media/capture/video/mac/video_capture_device_mac.h" | 5 #include "media/capture/video/mac/video_capture_device_mac.h" |
6 | 6 |
7 #include <IOKit/IOCFPlugIn.h> | 7 #include <IOKit/IOCFPlugIn.h> |
8 #include <IOKit/usb/IOUSBLib.h> | 8 #include <IOKit/usb/IOUSBLib.h> |
9 #include <IOKit/usb/USBSpec.h> | 9 #include <IOKit/usb/USBSpec.h> |
10 #include <stddef.h> | 10 #include <stddef.h> |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
285 &video_control_interface)) { | 285 &video_control_interface)) { |
286 return; | 286 return; |
287 } | 287 } |
288 base::mac::ScopedIOPluginInterface<IOCFPlugInInterface> | 288 base::mac::ScopedIOPluginInterface<IOCFPlugInInterface> |
289 plugin_interface_ref(video_control_interface); | 289 plugin_interface_ref(video_control_interface); |
290 | 290 |
291 SetAntiFlickerInVideoControlInterface(video_control_interface, frequency); | 291 SetAntiFlickerInVideoControlInterface(video_control_interface, frequency); |
292 } | 292 } |
293 } | 293 } |
294 | 294 |
295 const std::string VideoCaptureDevice::Name::GetModel() const { | 295 VideoCaptureDeviceMac::VideoCaptureDeviceMac( |
296 // Skip the AVFoundation's not USB nor built-in devices. | 296 const VideoCaptureDeviceDescriptor& device_descriptor) |
297 if (capture_api_type() == AVFOUNDATION && transport_type() != USB_OR_BUILT_IN) | 297 : device_descriptor_(device_descriptor), |
298 return ""; | |
299 if (capture_api_type() == DECKLINK) | |
300 return ""; | |
301 // Both PID and VID are 4 characters. | |
302 if (unique_id_.size() < 2 * kVidPidSize) | |
303 return ""; | |
304 | |
305 // The last characters of device id is a concatenation of VID and then PID. | |
306 const size_t vid_location = unique_id_.size() - 2 * kVidPidSize; | |
307 std::string id_vendor = unique_id_.substr(vid_location, kVidPidSize); | |
308 const size_t pid_location = unique_id_.size() - kVidPidSize; | |
309 std::string id_product = unique_id_.substr(pid_location, kVidPidSize); | |
310 | |
311 return id_vendor + ":" + id_product; | |
312 } | |
313 | |
314 VideoCaptureDeviceMac::VideoCaptureDeviceMac(const Name& device_name) | |
315 : device_name_(device_name), | |
316 task_runner_(base::ThreadTaskRunnerHandle::Get()), | 298 task_runner_(base::ThreadTaskRunnerHandle::Get()), |
317 state_(kNotInitialized), | 299 state_(kNotInitialized), |
318 capture_device_(nil), | 300 capture_device_(nil), |
319 weak_factory_(this) { | 301 weak_factory_(this) {} |
320 } | |
321 | 302 |
322 VideoCaptureDeviceMac::~VideoCaptureDeviceMac() { | 303 VideoCaptureDeviceMac::~VideoCaptureDeviceMac() { |
323 DCHECK(task_runner_->BelongsToCurrentThread()); | 304 DCHECK(task_runner_->BelongsToCurrentThread()); |
324 } | 305 } |
325 | 306 |
326 void VideoCaptureDeviceMac::AllocateAndStart( | 307 void VideoCaptureDeviceMac::AllocateAndStart( |
327 const VideoCaptureParams& params, | 308 const VideoCaptureParams& params, |
328 std::unique_ptr<VideoCaptureDevice::Client> client) { | 309 std::unique_ptr<VideoCaptureDevice::Client> client) { |
329 DCHECK(task_runner_->BelongsToCurrentThread()); | 310 DCHECK(task_runner_->BelongsToCurrentThread()); |
330 if (state_ != kIdle) { | 311 if (state_ != kIdle) { |
331 return; | 312 return; |
332 } | 313 } |
333 | 314 |
334 client_ = std::move(client); | 315 client_ = std::move(client); |
335 if (device_name_.capture_api_type() == Name::AVFOUNDATION) | 316 if (device_descriptor_.capture_api == VideoCaptureApi::MACOSX_AVFOUNDATION) |
336 LogMessage("Using AVFoundation for device: " + device_name_.name()); | 317 LogMessage("Using AVFoundation for device: " + |
318 device_descriptor_.friendly_name); | |
337 | 319 |
338 NSString* deviceId = | 320 NSString* deviceId = |
339 [NSString stringWithUTF8String:device_name_.id().c_str()]; | 321 [NSString stringWithUTF8String:device_descriptor_.device_id.c_str()]; |
340 | 322 |
341 [capture_device_ setFrameReceiver:this]; | 323 [capture_device_ setFrameReceiver:this]; |
342 | 324 |
343 if (![capture_device_ setCaptureDevice:deviceId]) { | 325 if (![capture_device_ setCaptureDevice:deviceId]) { |
344 SetErrorState(FROM_HERE, "Could not open capture device."); | 326 SetErrorState(FROM_HERE, "Could not open capture device."); |
345 return; | 327 return; |
346 } | 328 } |
347 | 329 |
348 capture_format_.frame_size = params.requested_format.frame_size; | 330 capture_format_.frame_size = params.requested_format.frame_size; |
349 capture_format_.frame_rate = | 331 capture_format_.frame_rate = |
350 std::max(kMinFrameRate, | 332 std::max(kMinFrameRate, |
351 std::min(params.requested_format.frame_rate, kMaxFrameRate)); | 333 std::min(params.requested_format.frame_rate, kMaxFrameRate)); |
352 // Leave the pixel format selection to AVFoundation. The pixel format | 334 // Leave the pixel format selection to AVFoundation. The pixel format |
353 // will be passed to |ReceiveFrame|. | 335 // will be passed to |ReceiveFrame|. |
354 capture_format_.pixel_format = PIXEL_FORMAT_UNKNOWN; | 336 capture_format_.pixel_format = PIXEL_FORMAT_UNKNOWN; |
355 | 337 |
356 if (!UpdateCaptureResolution()) | 338 if (!UpdateCaptureResolution()) |
357 return; | 339 return; |
358 | 340 |
359 // Try setting the power line frequency removal (anti-flicker). The built-in | 341 // Try setting the power line frequency removal (anti-flicker). The built-in |
360 // cameras are normally suspended so the configuration must happen right | 342 // cameras are normally suspended so the configuration must happen right |
361 // before starting capture and during configuration. | 343 // before starting capture and during configuration. |
362 const std::string& device_model = device_name_.GetModel(); | 344 std::string device_model = GetDeviceModelId( |
emircan
2016/07/28 21:23:02
const std::string& device_model?
chfremer
2016/07/29 18:09:51
I will add const, but const reference is not possi
| |
345 device_descriptor_.device_id, device_descriptor_.capture_api, | |
346 device_descriptor_.transport_type); | |
363 if (device_model.length() > 2 * kVidPidSize) { | 347 if (device_model.length() > 2 * kVidPidSize) { |
364 std::string vendor_id = device_model.substr(0, kVidPidSize); | 348 std::string vendor_id = device_model.substr(0, kVidPidSize); |
365 std::string model_id = device_model.substr(kVidPidSize + 1); | 349 std::string model_id = device_model.substr(kVidPidSize + 1); |
366 int vendor_id_as_int, model_id_as_int; | 350 int vendor_id_as_int, model_id_as_int; |
367 if (base::HexStringToInt(base::StringPiece(vendor_id), &vendor_id_as_int) && | 351 if (base::HexStringToInt(base::StringPiece(vendor_id), &vendor_id_as_int) && |
368 base::HexStringToInt(base::StringPiece(model_id), &model_id_as_int)) { | 352 base::HexStringToInt(base::StringPiece(model_id), &model_id_as_int)) { |
369 SetAntiFlickerInUsbDevice(vendor_id_as_int, model_id_as_int, | 353 SetAntiFlickerInUsbDevice(vendor_id_as_int, model_id_as_int, |
370 GetPowerLineFrequency(params)); | 354 GetPowerLineFrequency(params)); |
371 } | 355 } |
372 } | 356 } |
(...skipping 20 matching lines...) Expand all Loading... | |
393 DCHECK(task_runner_->BelongsToCurrentThread()); | 377 DCHECK(task_runner_->BelongsToCurrentThread()); |
394 DCHECK(state_ == kCapturing) << state_; | 378 DCHECK(state_ == kCapturing) << state_; |
395 | 379 |
396 if (photo_callback_) // Only one picture can be in flight at a time. | 380 if (photo_callback_) // Only one picture can be in flight at a time. |
397 return; | 381 return; |
398 | 382 |
399 photo_callback_.reset(new TakePhotoCallback(std::move(callback))); | 383 photo_callback_.reset(new TakePhotoCallback(std::move(callback))); |
400 [capture_device_ takePhoto]; | 384 [capture_device_ takePhoto]; |
401 } | 385 } |
402 | 386 |
403 bool VideoCaptureDeviceMac::Init( | 387 bool VideoCaptureDeviceMac::Init(VideoCaptureApi capture_api_type) { |
404 VideoCaptureDevice::Name::CaptureApiType capture_api_type) { | |
405 DCHECK(task_runner_->BelongsToCurrentThread()); | 388 DCHECK(task_runner_->BelongsToCurrentThread()); |
406 DCHECK_EQ(state_, kNotInitialized); | 389 DCHECK_EQ(state_, kNotInitialized); |
407 | 390 |
408 if (capture_api_type != Name::AVFOUNDATION) | 391 if (capture_api_type != VideoCaptureApi::MACOSX_AVFOUNDATION) |
409 return false; | 392 return false; |
410 | 393 |
411 capture_device_.reset( | 394 capture_device_.reset( |
412 [[VideoCaptureDeviceAVFoundation alloc] initWithFrameReceiver:this]); | 395 [[VideoCaptureDeviceAVFoundation alloc] initWithFrameReceiver:this]); |
413 | 396 |
414 if (!capture_device_) | 397 if (!capture_device_) |
415 return false; | 398 return false; |
416 | 399 |
417 state_ = kIdle; | 400 state_ = kIdle; |
418 return true; | 401 return true; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
457 } | 440 } |
458 | 441 |
459 void VideoCaptureDeviceMac::ReceiveError( | 442 void VideoCaptureDeviceMac::ReceiveError( |
460 const tracked_objects::Location& from_here, | 443 const tracked_objects::Location& from_here, |
461 const std::string& reason) { | 444 const std::string& reason) { |
462 task_runner_->PostTask( | 445 task_runner_->PostTask( |
463 FROM_HERE, base::Bind(&VideoCaptureDeviceMac::SetErrorState, | 446 FROM_HERE, base::Bind(&VideoCaptureDeviceMac::SetErrorState, |
464 weak_factory_.GetWeakPtr(), from_here, reason)); | 447 weak_factory_.GetWeakPtr(), from_here, reason)); |
465 } | 448 } |
466 | 449 |
450 void VideoCaptureDeviceMac::LogMessage(const std::string& message) { | |
451 DCHECK(task_runner_->BelongsToCurrentThread()); | |
452 if (client_) | |
453 client_->OnLog(message); | |
454 } | |
455 | |
456 // static | |
457 std::string VideoCaptureDeviceMac::GetDeviceModelId( | |
458 const std::string& device_id, | |
459 VideoCaptureApi capture_api, | |
460 VideoCaptureTransportType transport_type) { | |
461 // Skip the AVFoundation's not USB nor built-in devices. | |
462 if (capture_api == VideoCaptureApi::MACOSX_AVFOUNDATION && | |
463 transport_type != VideoCaptureTransportType::MACOSX_USB_OR_BUILT_IN) | |
464 return ""; | |
465 if (capture_api == VideoCaptureApi::MACOSX_DECKLINK) | |
466 return ""; | |
467 // Both PID and VID are 4 characters. | |
468 if (device_id.size() < 2 * kVidPidSize) | |
469 return ""; | |
470 | |
471 // The last characters of device id is a concatenation of VID and then PID. | |
472 const size_t vid_location = device_id.size() - 2 * kVidPidSize; | |
473 std::string id_vendor = device_id.substr(vid_location, kVidPidSize); | |
474 const size_t pid_location = device_id.size() - kVidPidSize; | |
475 std::string id_product = device_id.substr(pid_location, kVidPidSize); | |
476 | |
477 return id_vendor + ":" + id_product; | |
478 } | |
479 | |
467 void VideoCaptureDeviceMac::SetErrorState( | 480 void VideoCaptureDeviceMac::SetErrorState( |
468 const tracked_objects::Location& from_here, | 481 const tracked_objects::Location& from_here, |
469 const std::string& reason) { | 482 const std::string& reason) { |
470 DCHECK(task_runner_->BelongsToCurrentThread()); | 483 DCHECK(task_runner_->BelongsToCurrentThread()); |
471 state_ = kError; | 484 state_ = kError; |
472 client_->OnError(from_here, reason); | 485 client_->OnError(from_here, reason); |
473 } | 486 } |
474 | 487 |
475 void VideoCaptureDeviceMac::LogMessage(const std::string& message) { | |
476 DCHECK(task_runner_->BelongsToCurrentThread()); | |
477 if (client_) | |
478 client_->OnLog(message); | |
479 } | |
480 | |
481 bool VideoCaptureDeviceMac::UpdateCaptureResolution() { | 488 bool VideoCaptureDeviceMac::UpdateCaptureResolution() { |
482 if (![capture_device_ setCaptureHeight:capture_format_.frame_size.height() | 489 if (![capture_device_ setCaptureHeight:capture_format_.frame_size.height() |
483 width:capture_format_.frame_size.width() | 490 width:capture_format_.frame_size.width() |
484 frameRate:capture_format_.frame_rate]) { | 491 frameRate:capture_format_.frame_rate]) { |
485 ReceiveError(FROM_HERE, "Could not configure capture device."); | 492 ReceiveError(FROM_HERE, "Could not configure capture device."); |
486 return false; | 493 return false; |
487 } | 494 } |
488 return true; | 495 return true; |
489 } | 496 } |
490 | 497 |
491 } // namespace media | 498 } // namespace media |
OLD | NEW |