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 |