| 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 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 void VideoCaptureDeviceMac::StopAndDeAllocate() { | 382 void VideoCaptureDeviceMac::StopAndDeAllocate() { |
| 383 DCHECK(task_runner_->BelongsToCurrentThread()); | 383 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 384 DCHECK(state_ == kCapturing || state_ == kError) << state_; | 384 DCHECK(state_ == kCapturing || state_ == kError) << state_; |
| 385 | 385 |
| 386 [capture_device_ setCaptureDevice:nil]; | 386 [capture_device_ setCaptureDevice:nil]; |
| 387 [capture_device_ setFrameReceiver:nil]; | 387 [capture_device_ setFrameReceiver:nil]; |
| 388 client_.reset(); | 388 client_.reset(); |
| 389 state_ = kIdle; | 389 state_ = kIdle; |
| 390 } | 390 } |
| 391 | 391 |
| 392 void VideoCaptureDeviceMac::TakePhoto(TakePhotoCallback callback) { | |
| 393 DCHECK(task_runner_->BelongsToCurrentThread()); | |
| 394 DCHECK(state_ == kCapturing) << state_; | |
| 395 | |
| 396 if (photo_callback_) // Only one picture can be in flight at a time. | |
| 397 return; | |
| 398 | |
| 399 photo_callback_.reset(new TakePhotoCallback(std::move(callback))); | |
| 400 [capture_device_ takePhoto]; | |
| 401 } | |
| 402 | |
| 403 bool VideoCaptureDeviceMac::Init( | 392 bool VideoCaptureDeviceMac::Init( |
| 404 VideoCaptureDevice::Name::CaptureApiType capture_api_type) { | 393 VideoCaptureDevice::Name::CaptureApiType capture_api_type) { |
| 405 DCHECK(task_runner_->BelongsToCurrentThread()); | 394 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 406 DCHECK_EQ(state_, kNotInitialized); | 395 DCHECK_EQ(state_, kNotInitialized); |
| 407 | 396 |
| 408 if (capture_api_type != Name::AVFOUNDATION) | 397 if (capture_api_type != Name::AVFOUNDATION) |
| 409 return false; | 398 return false; |
| 410 | 399 |
| 411 capture_device_.reset( | 400 capture_device_.reset( |
| 412 [[VideoCaptureDeviceAVFoundation alloc] initWithFrameReceiver:this]); | 401 [[VideoCaptureDeviceAVFoundation alloc] initWithFrameReceiver:this]); |
| 413 | 402 |
| 414 if (!capture_device_) | 403 if (!capture_device_) |
| 415 return false; | 404 return false; |
| 416 | 405 |
| 417 state_ = kIdle; | 406 state_ = kIdle; |
| 418 return true; | 407 return true; |
| 419 } | 408 } |
| 420 | 409 |
| 421 void VideoCaptureDeviceMac::ReceiveFrame(const uint8_t* video_frame, | 410 void VideoCaptureDeviceMac::ReceiveFrame(const uint8_t* video_frame, |
| 422 int video_frame_length, | 411 int video_frame_length, |
| 423 const VideoCaptureFormat& frame_format, | 412 const VideoCaptureFormat& frame_format, |
| 424 int aspect_numerator, | 413 int aspect_numerator, |
| 425 int aspect_denominator, | 414 int aspect_denominator, |
| 426 base::TimeDelta timestamp) { | 415 base::TimeDelta timestamp) { |
| 416 // This method is safe to call from a device capture thread, i.e. any thread |
| 417 // controlled by AVFoundation. |
| 427 if (capture_format_.frame_size != frame_format.frame_size) { | 418 if (capture_format_.frame_size != frame_format.frame_size) { |
| 428 ReceiveError(FROM_HERE, | 419 ReceiveError(FROM_HERE, |
| 429 "Captured resolution " + frame_format.frame_size.ToString() + | 420 "Captured resolution " + frame_format.frame_size.ToString() + |
| 430 ", and expected " + capture_format_.frame_size.ToString()); | 421 ", and expected " + capture_format_.frame_size.ToString()); |
| 431 return; | 422 return; |
| 432 } | 423 } |
| 433 | 424 |
| 434 client_->OnIncomingCapturedData(video_frame, video_frame_length, frame_format, | 425 client_->OnIncomingCapturedData(video_frame, video_frame_length, frame_format, |
| 435 0, base::TimeTicks::Now(), timestamp); | 426 0, base::TimeTicks::Now(), timestamp); |
| 436 } | 427 } |
| 437 | 428 |
| 438 void VideoCaptureDeviceMac::OnPhotoTaken(const uint8_t* image_data, | |
| 439 size_t image_length, | |
| 440 const std::string& mime_type) { | |
| 441 DCHECK(photo_callback_); | |
| 442 if (!image_data || !image_length) { | |
| 443 OnPhotoError(); | |
| 444 return; | |
| 445 } | |
| 446 | |
| 447 photo_callback_->Run(mojo::String::From(mime_type), | |
| 448 mojo::Array<uint8_t>(std::vector<uint8_t>( | |
| 449 image_data, image_data + image_length))); | |
| 450 photo_callback_.reset(); | |
| 451 } | |
| 452 | |
| 453 void VideoCaptureDeviceMac::OnPhotoError() { | |
| 454 DLOG(ERROR) << __FUNCTION__ << " error taking picture"; | |
| 455 photo_callback_.reset(); | |
| 456 } | |
| 457 | |
| 458 void VideoCaptureDeviceMac::ReceiveError( | 429 void VideoCaptureDeviceMac::ReceiveError( |
| 459 const tracked_objects::Location& from_here, | 430 const tracked_objects::Location& from_here, |
| 460 const std::string& reason) { | 431 const std::string& reason) { |
| 461 task_runner_->PostTask( | 432 task_runner_->PostTask( |
| 462 FROM_HERE, base::Bind(&VideoCaptureDeviceMac::SetErrorState, | 433 FROM_HERE, base::Bind(&VideoCaptureDeviceMac::SetErrorState, |
| 463 weak_factory_.GetWeakPtr(), from_here, reason)); | 434 weak_factory_.GetWeakPtr(), from_here, reason)); |
| 464 } | 435 } |
| 465 | 436 |
| 466 void VideoCaptureDeviceMac::SetErrorState( | 437 void VideoCaptureDeviceMac::SetErrorState( |
| 467 const tracked_objects::Location& from_here, | 438 const tracked_objects::Location& from_here, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 481 if (![capture_device_ setCaptureHeight:capture_format_.frame_size.height() | 452 if (![capture_device_ setCaptureHeight:capture_format_.frame_size.height() |
| 482 width:capture_format_.frame_size.width() | 453 width:capture_format_.frame_size.width() |
| 483 frameRate:capture_format_.frame_rate]) { | 454 frameRate:capture_format_.frame_rate]) { |
| 484 ReceiveError(FROM_HERE, "Could not configure capture device."); | 455 ReceiveError(FROM_HERE, "Could not configure capture device."); |
| 485 return false; | 456 return false; |
| 486 } | 457 } |
| 487 return true; | 458 return true; |
| 488 } | 459 } |
| 489 | 460 |
| 490 } // namespace media | 461 } // namespace media |
| OLD | NEW |