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 |
392 bool VideoCaptureDeviceMac::Init( | 403 bool VideoCaptureDeviceMac::Init( |
393 VideoCaptureDevice::Name::CaptureApiType capture_api_type) { | 404 VideoCaptureDevice::Name::CaptureApiType capture_api_type) { |
394 DCHECK(task_runner_->BelongsToCurrentThread()); | 405 DCHECK(task_runner_->BelongsToCurrentThread()); |
395 DCHECK_EQ(state_, kNotInitialized); | 406 DCHECK_EQ(state_, kNotInitialized); |
396 | 407 |
397 if (capture_api_type != Name::AVFOUNDATION) | 408 if (capture_api_type != Name::AVFOUNDATION) |
398 return false; | 409 return false; |
399 | 410 |
400 capture_device_.reset( | 411 capture_device_.reset( |
401 [[VideoCaptureDeviceAVFoundation alloc] initWithFrameReceiver:this]); | 412 [[VideoCaptureDeviceAVFoundation alloc] initWithFrameReceiver:this]); |
402 | 413 |
403 if (!capture_device_) | 414 if (!capture_device_) |
404 return false; | 415 return false; |
405 | 416 |
406 state_ = kIdle; | 417 state_ = kIdle; |
407 return true; | 418 return true; |
408 } | 419 } |
409 | 420 |
410 void VideoCaptureDeviceMac::ReceiveFrame(const uint8_t* video_frame, | 421 void VideoCaptureDeviceMac::ReceiveFrame(const uint8_t* video_frame, |
411 int video_frame_length, | 422 int video_frame_length, |
412 const VideoCaptureFormat& frame_format, | 423 const VideoCaptureFormat& frame_format, |
413 int aspect_numerator, | 424 int aspect_numerator, |
414 int aspect_denominator, | 425 int aspect_denominator, |
415 base::TimeDelta timestamp) { | 426 base::TimeDelta timestamp) { |
416 // This method is safe to call from a device capture thread, i.e. any thread | |
417 // controlled by AVFoundation. | |
418 if (capture_format_.frame_size != frame_format.frame_size) { | 427 if (capture_format_.frame_size != frame_format.frame_size) { |
419 ReceiveError(FROM_HERE, | 428 ReceiveError(FROM_HERE, |
420 "Captured resolution " + frame_format.frame_size.ToString() + | 429 "Captured resolution " + frame_format.frame_size.ToString() + |
421 ", and expected " + capture_format_.frame_size.ToString()); | 430 ", and expected " + capture_format_.frame_size.ToString()); |
422 return; | 431 return; |
423 } | 432 } |
424 | 433 |
425 client_->OnIncomingCapturedData(video_frame, video_frame_length, frame_format, | 434 client_->OnIncomingCapturedData(video_frame, video_frame_length, frame_format, |
426 0, base::TimeTicks::Now(), timestamp); | 435 0, base::TimeTicks::Now(), timestamp); |
427 } | 436 } |
428 | 437 |
| 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 |
429 void VideoCaptureDeviceMac::ReceiveError( | 458 void VideoCaptureDeviceMac::ReceiveError( |
430 const tracked_objects::Location& from_here, | 459 const tracked_objects::Location& from_here, |
431 const std::string& reason) { | 460 const std::string& reason) { |
432 task_runner_->PostTask( | 461 task_runner_->PostTask( |
433 FROM_HERE, base::Bind(&VideoCaptureDeviceMac::SetErrorState, | 462 FROM_HERE, base::Bind(&VideoCaptureDeviceMac::SetErrorState, |
434 weak_factory_.GetWeakPtr(), from_here, reason)); | 463 weak_factory_.GetWeakPtr(), from_here, reason)); |
435 } | 464 } |
436 | 465 |
437 void VideoCaptureDeviceMac::SetErrorState( | 466 void VideoCaptureDeviceMac::SetErrorState( |
438 const tracked_objects::Location& from_here, | 467 const tracked_objects::Location& from_here, |
(...skipping 13 matching lines...) Expand all Loading... |
452 if (![capture_device_ setCaptureHeight:capture_format_.frame_size.height() | 481 if (![capture_device_ setCaptureHeight:capture_format_.frame_size.height() |
453 width:capture_format_.frame_size.width() | 482 width:capture_format_.frame_size.width() |
454 frameRate:capture_format_.frame_rate]) { | 483 frameRate:capture_format_.frame_rate]) { |
455 ReceiveError(FROM_HERE, "Could not configure capture device."); | 484 ReceiveError(FROM_HERE, "Could not configure capture device."); |
456 return false; | 485 return false; |
457 } | 486 } |
458 return true; | 487 return true; |
459 } | 488 } |
460 | 489 |
461 } // namespace media | 490 } // namespace media |
OLD | NEW |