| 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> |
| 11 #include <stdint.h> | 11 #include <stdint.h> |
| 12 | 12 |
| 13 #include <limits> | 13 #include <limits> |
| 14 #include <utility> | 14 #include <utility> |
| 15 | 15 |
| 16 #include "base/bind.h" | 16 #include "base/bind.h" |
| 17 #include "base/location.h" | 17 #include "base/location.h" |
| 18 #include "base/logging.h" | 18 #include "base/logging.h" |
| 19 #include "base/mac/scoped_ioobject.h" | 19 #include "base/mac/scoped_ioobject.h" |
| 20 #include "base/mac/scoped_ioplugininterface.h" | 20 #include "base/mac/scoped_ioplugininterface.h" |
| 21 #include "base/macros.h" | 21 #include "base/macros.h" |
| 22 #include "base/single_thread_task_runner.h" | 22 #include "base/single_thread_task_runner.h" |
| 23 #include "base/strings/string_number_conversions.h" | 23 #include "base/strings/string_number_conversions.h" |
| 24 #include "base/thread_task_runner_handle.h" | 24 #include "base/thread_task_runner_handle.h" |
| 25 #include "base/time/time.h" | 25 #include "base/time/time.h" |
| 26 #import "media/base/mac/avfoundation_glue.h" | 26 #import "media/base/mac/avfoundation_glue.h" |
| 27 #include "media/base/timestamp_constants.h" | 27 #include "media/base/timestamp_constants.h" |
| 28 #import "media/capture/video/mac/platform_video_capturing_mac.h" | 28 #import "media/capture/video/mac/platform_video_capturing_mac.h" |
| 29 #import "media/capture/video/mac/video_capture_device_avfoundation_mac.h" | 29 #import "media/capture/video/mac/video_capture_device_avfoundation_mac.h" |
| 30 #import "media/capture/video/mac/video_capture_device_qtkit_mac.h" | |
| 31 #include "ui/gfx/geometry/size.h" | 30 #include "ui/gfx/geometry/size.h" |
| 32 | 31 |
| 33 @implementation DeviceNameAndTransportType | 32 @implementation DeviceNameAndTransportType |
| 34 | 33 |
| 35 - (id)initWithName:(NSString*)deviceName transportType:(int32_t)transportType { | 34 - (id)initWithName:(NSString*)deviceName transportType:(int32_t)transportType { |
| 36 if (self = [super init]) { | 35 if (self = [super init]) { |
| 37 deviceName_.reset([deviceName copy]); | 36 deviceName_.reset([deviceName copy]); |
| 38 transportType_ = transportType; | 37 transportType_ = transportType; |
| 39 } | 38 } |
| 40 return self; | 39 return self; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 52 | 51 |
| 53 namespace media { | 52 namespace media { |
| 54 | 53 |
| 55 // Mac specific limits for minimum and maximum frame rate. | 54 // Mac specific limits for minimum and maximum frame rate. |
| 56 const float kMinFrameRate = 1.0f; | 55 const float kMinFrameRate = 1.0f; |
| 57 const float kMaxFrameRate = 30.0f; | 56 const float kMaxFrameRate = 30.0f; |
| 58 | 57 |
| 59 // In device identifiers, the USB VID and PID are stored in 4 bytes each. | 58 // In device identifiers, the USB VID and PID are stored in 4 bytes each. |
| 60 const size_t kVidPidSize = 4; | 59 const size_t kVidPidSize = 4; |
| 61 | 60 |
| 62 const struct Resolution { | |
| 63 const int width; | |
| 64 const int height; | |
| 65 } kQVGA = {320, 240}, kVGA = {640, 480}, kHD = {1280, 720}; | |
| 66 | |
| 67 const struct Resolution* const kWellSupportedResolutions[] = { | |
| 68 &kQVGA, | |
| 69 &kVGA, | |
| 70 &kHD, | |
| 71 }; | |
| 72 | |
| 73 // Rescaling the image to fix the pixel aspect ratio runs the risk of making | |
| 74 // the aspect ratio worse, if QTKit selects a new source mode with a different | |
| 75 // shape. This constant ensures that we don't take this risk if the current | |
| 76 // aspect ratio is tolerable. | |
| 77 const float kMaxPixelAspectRatio = 1.15; | |
| 78 | |
| 79 // The following constants are extracted from the specification "Universal | 61 // The following constants are extracted from the specification "Universal |
| 80 // Serial Bus Device Class Definition for Video Devices", Rev. 1.1 June 1, 2005. | 62 // Serial Bus Device Class Definition for Video Devices", Rev. 1.1 June 1, 2005. |
| 81 // http://www.usb.org/developers/devclass_docs/USB_Video_Class_1_1.zip | 63 // http://www.usb.org/developers/devclass_docs/USB_Video_Class_1_1.zip |
| 82 // CS_INTERFACE: Sec. A.4 "Video Class-Specific Descriptor Types". | 64 // CS_INTERFACE: Sec. A.4 "Video Class-Specific Descriptor Types". |
| 83 const int kVcCsInterface = 0x24; | 65 const int kVcCsInterface = 0x24; |
| 84 // VC_PROCESSING_UNIT: Sec. A.5 "Video Class-Specific VC Interface Descriptor | 66 // VC_PROCESSING_UNIT: Sec. A.5 "Video Class-Specific VC Interface Descriptor |
| 85 // Subtypes". | 67 // Subtypes". |
| 86 const int kVcProcessingUnit = 0x5; | 68 const int kVcProcessingUnit = 0x5; |
| 87 // SET_CUR: Sec. A.8 "Video Class-Specific Request Codes". | 69 // SET_CUR: Sec. A.8 "Video Class-Specific Request Codes". |
| 88 const int kVcRequestCodeSetCur = 0x1; | 70 const int kVcRequestCodeSetCur = 0x1; |
| 89 // PU_POWER_LINE_FREQUENCY_CONTROL: Sec. A.9.5 "Processing Unit Control | 71 // PU_POWER_LINE_FREQUENCY_CONTROL: Sec. A.9.5 "Processing Unit Control |
| 90 // Selectors". | 72 // Selectors". |
| 91 const int kPuPowerLineFrequencyControl = 0x5; | 73 const int kPuPowerLineFrequencyControl = 0x5; |
| 92 // Sec. 4.2.2.3.5 Power Line Frequency Control. | 74 // Sec. 4.2.2.3.5 Power Line Frequency Control. |
| 93 const int k50Hz = 1; | 75 const int k50Hz = 1; |
| 94 const int k60Hz = 2; | 76 const int k60Hz = 2; |
| 95 const int kPuPowerLineFrequencyControlCommandSize = 1; | 77 const int kPuPowerLineFrequencyControlCommandSize = 1; |
| 96 | 78 |
| 97 // Addition to the IOUSB family of structures, with subtype and unit ID. | 79 // Addition to the IOUSB family of structures, with subtype and unit ID. |
| 98 typedef struct IOUSBInterfaceDescriptor { | 80 typedef struct IOUSBInterfaceDescriptor { |
| 99 IOUSBDescriptorHeader header; | 81 IOUSBDescriptorHeader header; |
| 100 UInt8 bDescriptorSubType; | 82 UInt8 bDescriptorSubType; |
| 101 UInt8 bUnitID; | 83 UInt8 bUnitID; |
| 102 } IOUSBInterfaceDescriptor; | 84 } IOUSBInterfaceDescriptor; |
| 103 | 85 |
| 104 static void GetBestMatchSupportedResolution(gfx::Size* resolution) { | |
| 105 int min_diff = std::numeric_limits<int32_t>::max(); | |
| 106 const int desired_area = resolution->GetArea(); | |
| 107 for (size_t i = 0; i < arraysize(kWellSupportedResolutions); ++i) { | |
| 108 const int area = kWellSupportedResolutions[i]->width * | |
| 109 kWellSupportedResolutions[i]->height; | |
| 110 const int diff = std::abs(desired_area - area); | |
| 111 if (diff < min_diff) { | |
| 112 min_diff = diff; | |
| 113 resolution->SetSize(kWellSupportedResolutions[i]->width, | |
| 114 kWellSupportedResolutions[i]->height); | |
| 115 } | |
| 116 } | |
| 117 } | |
| 118 | |
| 119 // Tries to create a user-side device interface for a given USB device. Returns | 86 // Tries to create a user-side device interface for a given USB device. Returns |
| 120 // true if interface was found and passes it back in |device_interface|. The | 87 // true if interface was found and passes it back in |device_interface|. The |
| 121 // caller should release |device_interface|. | 88 // caller should release |device_interface|. |
| 122 static bool FindDeviceInterfaceInUsbDevice( | 89 static bool FindDeviceInterfaceInUsbDevice( |
| 123 const int vendor_id, | 90 const int vendor_id, |
| 124 const int product_id, | 91 const int product_id, |
| 125 const io_service_t usb_device, | 92 const io_service_t usb_device, |
| 126 IOUSBDeviceInterface*** device_interface) { | 93 IOUSBDeviceInterface*** device_interface) { |
| 127 // Create a plugin, i.e. a user-side controller to manipulate USB device. | 94 // Create a plugin, i.e. a user-side controller to manipulate USB device. |
| 128 IOCFPlugInInterface** plugin; | 95 IOCFPlugInInterface** plugin; |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 const size_t vid_location = unique_id_.size() - 2 * kVidPidSize; | 307 const size_t vid_location = unique_id_.size() - 2 * kVidPidSize; |
| 341 std::string id_vendor = unique_id_.substr(vid_location, kVidPidSize); | 308 std::string id_vendor = unique_id_.substr(vid_location, kVidPidSize); |
| 342 const size_t pid_location = unique_id_.size() - kVidPidSize; | 309 const size_t pid_location = unique_id_.size() - kVidPidSize; |
| 343 std::string id_product = unique_id_.substr(pid_location, kVidPidSize); | 310 std::string id_product = unique_id_.substr(pid_location, kVidPidSize); |
| 344 | 311 |
| 345 return id_vendor + ":" + id_product; | 312 return id_vendor + ":" + id_product; |
| 346 } | 313 } |
| 347 | 314 |
| 348 VideoCaptureDeviceMac::VideoCaptureDeviceMac(const Name& device_name) | 315 VideoCaptureDeviceMac::VideoCaptureDeviceMac(const Name& device_name) |
| 349 : device_name_(device_name), | 316 : device_name_(device_name), |
| 350 tried_to_square_pixels_(false), | |
| 351 task_runner_(base::ThreadTaskRunnerHandle::Get()), | 317 task_runner_(base::ThreadTaskRunnerHandle::Get()), |
| 352 state_(kNotInitialized), | 318 state_(kNotInitialized), |
| 353 capture_device_(nil), | 319 capture_device_(nil), |
| 354 first_timestamp_(media::kNoTimestamp()), | 320 first_timestamp_(media::kNoTimestamp()), |
| 355 weak_factory_(this) { | 321 weak_factory_(this) { |
| 356 // Avoid reconfiguring AVFoundation or blacklisted devices. | |
| 357 final_resolution_selected_ = AVFoundationGlue::IsAVFoundationSupported() || | |
| 358 device_name.is_blacklisted(); | |
| 359 } | 322 } |
| 360 | 323 |
| 361 VideoCaptureDeviceMac::~VideoCaptureDeviceMac() { | 324 VideoCaptureDeviceMac::~VideoCaptureDeviceMac() { |
| 362 DCHECK(task_runner_->BelongsToCurrentThread()); | 325 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 363 [capture_device_ release]; | 326 [capture_device_ release]; |
| 364 } | 327 } |
| 365 | 328 |
| 366 void VideoCaptureDeviceMac::AllocateAndStart( | 329 void VideoCaptureDeviceMac::AllocateAndStart( |
| 367 const VideoCaptureParams& params, | 330 const VideoCaptureParams& params, |
| 368 scoped_ptr<VideoCaptureDevice::Client> client) { | 331 scoped_ptr<VideoCaptureDevice::Client> client) { |
| 369 DCHECK(task_runner_->BelongsToCurrentThread()); | 332 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 370 if (state_ != kIdle) { | 333 if (state_ != kIdle) { |
| 371 return; | 334 return; |
| 372 } | 335 } |
| 373 | 336 |
| 374 // QTKit API can scale captured frame to any size requested, which would lead | |
| 375 // to undesired aspect ratio changes. Try to open the camera with a known | |
| 376 // supported format and let the client crop/pad the captured frames. | |
| 377 gfx::Size resolution = params.requested_format.frame_size; | |
| 378 if (!AVFoundationGlue::IsAVFoundationSupported()) | |
| 379 GetBestMatchSupportedResolution(&resolution); | |
| 380 | |
| 381 client_ = std::move(client); | 337 client_ = std::move(client); |
| 382 if (device_name_.capture_api_type() == Name::AVFOUNDATION) | 338 if (device_name_.capture_api_type() == Name::AVFOUNDATION) |
| 383 LogMessage("Using AVFoundation for device: " + device_name_.name()); | 339 LogMessage("Using AVFoundation for device: " + device_name_.name()); |
| 384 else | 340 |
| 385 LogMessage("Using QTKit for device: " + device_name_.name()); | |
| 386 NSString* deviceId = | 341 NSString* deviceId = |
| 387 [NSString stringWithUTF8String:device_name_.id().c_str()]; | 342 [NSString stringWithUTF8String:device_name_.id().c_str()]; |
| 388 | 343 |
| 389 [capture_device_ setFrameReceiver:this]; | 344 [capture_device_ setFrameReceiver:this]; |
| 390 | 345 |
| 391 if (![capture_device_ setCaptureDevice:deviceId]) { | 346 if (![capture_device_ setCaptureDevice:deviceId]) { |
| 392 SetErrorState(FROM_HERE, "Could not open capture device."); | 347 SetErrorState(FROM_HERE, "Could not open capture device."); |
| 393 return; | 348 return; |
| 394 } | 349 } |
| 395 | 350 |
| 396 capture_format_.frame_size = resolution; | 351 capture_format_.frame_size = params.requested_format.frame_size; |
| 397 capture_format_.frame_rate = | 352 capture_format_.frame_rate = |
| 398 std::max(kMinFrameRate, | 353 std::max(kMinFrameRate, |
| 399 std::min(params.requested_format.frame_rate, kMaxFrameRate)); | 354 std::min(params.requested_format.frame_rate, kMaxFrameRate)); |
| 400 // Leave the pixel format selection to AVFoundation/QTKit. The pixel format | 355 // Leave the pixel format selection to AVFoundation. The pixel format |
| 401 // will be passed to |ReceiveFrame|. | 356 // will be passed to |ReceiveFrame|. |
| 402 capture_format_.pixel_format = PIXEL_FORMAT_UNKNOWN; | 357 capture_format_.pixel_format = PIXEL_FORMAT_UNKNOWN; |
| 403 | 358 |
| 404 // QTKit: Set the capture resolution only if this is VGA or smaller, otherwise | |
| 405 // leave it unconfigured and start capturing: QTKit will produce frames at the | |
| 406 // native resolution, allowing us to identify cameras whose native resolution | |
| 407 // is too low for HD. This additional information comes at a cost in startup | |
| 408 // latency, because the webcam will need to be reopened if its default | |
| 409 // resolution is not HD or VGA. | |
| 410 // AVfoundation is configured for all resolutions. | |
| 411 if (AVFoundationGlue::IsAVFoundationSupported() || | |
| 412 resolution.width() <= kVGA.width || resolution.height() <= kVGA.height) { | |
| 413 if (!UpdateCaptureResolution()) | 359 if (!UpdateCaptureResolution()) |
| 414 return; | 360 return; |
| 415 } | |
| 416 | 361 |
| 417 // Try setting the power line frequency removal (anti-flicker). The built-in | 362 // Try setting the power line frequency removal (anti-flicker). The built-in |
| 418 // cameras are normally suspended so the configuration must happen right | 363 // cameras are normally suspended so the configuration must happen right |
| 419 // before starting capture and during configuration. | 364 // before starting capture and during configuration. |
| 420 const std::string& device_model = device_name_.GetModel(); | 365 const std::string& device_model = device_name_.GetModel(); |
| 421 if (device_model.length() > 2 * kVidPidSize) { | 366 if (device_model.length() > 2 * kVidPidSize) { |
| 422 std::string vendor_id = device_model.substr(0, kVidPidSize); | 367 std::string vendor_id = device_model.substr(0, kVidPidSize); |
| 423 std::string model_id = device_model.substr(kVidPidSize + 1); | 368 std::string model_id = device_model.substr(kVidPidSize + 1); |
| 424 int vendor_id_as_int, model_id_as_int; | 369 int vendor_id_as_int, model_id_as_int; |
| 425 if (base::HexStringToInt(base::StringPiece(vendor_id), &vendor_id_as_int) && | 370 if (base::HexStringToInt(base::StringPiece(vendor_id), &vendor_id_as_int) && |
| (...skipping 12 matching lines...) Expand all Loading... |
| 438 } | 383 } |
| 439 | 384 |
| 440 void VideoCaptureDeviceMac::StopAndDeAllocate() { | 385 void VideoCaptureDeviceMac::StopAndDeAllocate() { |
| 441 DCHECK(task_runner_->BelongsToCurrentThread()); | 386 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 442 DCHECK(state_ == kCapturing || state_ == kError) << state_; | 387 DCHECK(state_ == kCapturing || state_ == kError) << state_; |
| 443 | 388 |
| 444 [capture_device_ setCaptureDevice:nil]; | 389 [capture_device_ setCaptureDevice:nil]; |
| 445 [capture_device_ setFrameReceiver:nil]; | 390 [capture_device_ setFrameReceiver:nil]; |
| 446 client_.reset(); | 391 client_.reset(); |
| 447 state_ = kIdle; | 392 state_ = kIdle; |
| 448 tried_to_square_pixels_ = false; | |
| 449 } | 393 } |
| 450 | 394 |
| 451 bool VideoCaptureDeviceMac::Init( | 395 bool VideoCaptureDeviceMac::Init( |
| 452 VideoCaptureDevice::Name::CaptureApiType capture_api_type) { | 396 VideoCaptureDevice::Name::CaptureApiType capture_api_type) { |
| 453 DCHECK(task_runner_->BelongsToCurrentThread()); | 397 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 454 DCHECK_EQ(state_, kNotInitialized); | 398 DCHECK_EQ(state_, kNotInitialized); |
| 455 | 399 |
| 456 if (capture_api_type == Name::AVFOUNDATION) { | 400 if (capture_api_type == Name::AVFOUNDATION) { |
| 457 capture_device_ = | 401 capture_device_ = |
| 458 [[VideoCaptureDeviceAVFoundation alloc] initWithFrameReceiver:this]; | 402 [[VideoCaptureDeviceAVFoundation alloc] initWithFrameReceiver:this]; |
| 459 } else { | |
| 460 capture_device_ = | |
| 461 [[VideoCaptureDeviceQTKit alloc] initWithFrameReceiver:this]; | |
| 462 } | 403 } |
| 463 | 404 |
| 464 if (!capture_device_) | 405 if (!capture_device_) |
| 465 return false; | 406 return false; |
| 466 | 407 |
| 467 state_ = kIdle; | 408 state_ = kIdle; |
| 468 return true; | 409 return true; |
| 469 } | 410 } |
| 470 | 411 |
| 471 void VideoCaptureDeviceMac::ReceiveFrame(const uint8_t* video_frame, | 412 void VideoCaptureDeviceMac::ReceiveFrame(const uint8_t* video_frame, |
| 472 int video_frame_length, | 413 int video_frame_length, |
| 473 const VideoCaptureFormat& frame_format, | 414 const VideoCaptureFormat& frame_format, |
| 474 int aspect_numerator, | 415 int aspect_numerator, |
| 475 int aspect_denominator, | 416 int aspect_denominator, |
| 476 base::TimeDelta timestamp) { | 417 base::TimeDelta timestamp) { |
| 477 // This method is safe to call from a device capture thread, i.e. any thread | 418 // This method is safe to call from a device capture thread, i.e. any thread |
| 478 // controlled by QTKit/AVFoundation. | 419 // controlled by AVFoundation. |
| 479 if (!final_resolution_selected_) { | 420 if (capture_format_.frame_size != frame_format.frame_size) { |
| 480 DCHECK(!AVFoundationGlue::IsAVFoundationSupported()); | |
| 481 if (capture_format_.frame_size.width() > kVGA.width || | |
| 482 capture_format_.frame_size.height() > kVGA.height) { | |
| 483 // We are requesting HD. Make sure that the picture is good, otherwise | |
| 484 // drop down to VGA. | |
| 485 bool change_to_vga = false; | |
| 486 if (frame_format.frame_size.width() < | |
| 487 capture_format_.frame_size.width() || | |
| 488 frame_format.frame_size.height() < | |
| 489 capture_format_.frame_size.height()) { | |
| 490 // These are the default capture settings, not yet configured to match | |
| 491 // |capture_format_|. | |
| 492 DCHECK(frame_format.frame_rate == 0); | |
| 493 DVLOG(1) << "Switching to VGA because the default resolution is " | |
| 494 << frame_format.frame_size.ToString(); | |
| 495 change_to_vga = true; | |
| 496 } | |
| 497 | |
| 498 if (capture_format_.frame_size == frame_format.frame_size && | |
| 499 aspect_numerator != aspect_denominator) { | |
| 500 DVLOG(1) << "Switching to VGA because HD has nonsquare pixel " | |
| 501 << "aspect ratio " << aspect_numerator << ":" | |
| 502 << aspect_denominator; | |
| 503 change_to_vga = true; | |
| 504 } | |
| 505 | |
| 506 if (change_to_vga) | |
| 507 capture_format_.frame_size.SetSize(kVGA.width, kVGA.height); | |
| 508 } | |
| 509 | |
| 510 if (capture_format_.frame_size == frame_format.frame_size && | |
| 511 !tried_to_square_pixels_ && | |
| 512 (aspect_numerator > kMaxPixelAspectRatio * aspect_denominator || | |
| 513 aspect_denominator > kMaxPixelAspectRatio * aspect_numerator)) { | |
| 514 // The requested size results in non-square PAR. Shrink the frame to 1:1 | |
| 515 // PAR (assuming QTKit selects the same input mode, which is not | |
| 516 // guaranteed). | |
| 517 int new_width = capture_format_.frame_size.width(); | |
| 518 int new_height = capture_format_.frame_size.height(); | |
| 519 if (aspect_numerator < aspect_denominator) | |
| 520 new_width = (new_width * aspect_numerator) / aspect_denominator; | |
| 521 else | |
| 522 new_height = (new_height * aspect_denominator) / aspect_numerator; | |
| 523 capture_format_.frame_size.SetSize(new_width, new_height); | |
| 524 tried_to_square_pixels_ = true; | |
| 525 } | |
| 526 | |
| 527 if (capture_format_.frame_size == frame_format.frame_size) { | |
| 528 final_resolution_selected_ = true; | |
| 529 } else { | |
| 530 UpdateCaptureResolution(); | |
| 531 // Let the resolution update sink through QTKit and wait for next frame. | |
| 532 return; | |
| 533 } | |
| 534 } | |
| 535 | |
| 536 // QTKit capture source can change resolution if someone else reconfigures the | |
| 537 // camera, and that is fine: http://crbug.com/353620. In AVFoundation, this | |
| 538 // should not happen, it should resize internally. | |
| 539 if (!AVFoundationGlue::IsAVFoundationSupported()) { | |
| 540 capture_format_.frame_size = frame_format.frame_size; | |
| 541 } else if (capture_format_.frame_size != frame_format.frame_size) { | |
| 542 ReceiveError(FROM_HERE, | 421 ReceiveError(FROM_HERE, |
| 543 "Captured resolution " + frame_format.frame_size.ToString() + | 422 "Captured resolution " + frame_format.frame_size.ToString() + |
| 544 ", and expected " + capture_format_.frame_size.ToString()); | 423 ", and expected " + capture_format_.frame_size.ToString()); |
| 545 return; | 424 return; |
| 546 } | 425 } |
| 547 | 426 |
| 548 base::TimeTicks aligned_timestamp; | 427 base::TimeTicks aligned_timestamp; |
| 549 if (timestamp == media::kNoTimestamp()) { | 428 if (timestamp == media::kNoTimestamp()) { |
| 550 aligned_timestamp = base::TimeTicks::Now(); | 429 aligned_timestamp = base::TimeTicks::Now(); |
| 551 } else { | 430 } else { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 585 if (![capture_device_ setCaptureHeight:capture_format_.frame_size.height() | 464 if (![capture_device_ setCaptureHeight:capture_format_.frame_size.height() |
| 586 width:capture_format_.frame_size.width() | 465 width:capture_format_.frame_size.width() |
| 587 frameRate:capture_format_.frame_rate]) { | 466 frameRate:capture_format_.frame_rate]) { |
| 588 ReceiveError(FROM_HERE, "Could not configure capture device."); | 467 ReceiveError(FROM_HERE, "Could not configure capture device."); |
| 589 return false; | 468 return false; |
| 590 } | 469 } |
| 591 return true; | 470 return true; |
| 592 } | 471 } |
| 593 | 472 |
| 594 } // namespace media | 473 } // namespace media |
| OLD | NEW |