OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 #import "media/video/capture/mac/video_capture_device_avfoundation_mac.h" | 5 #import "media/video/capture/mac/video_capture_device_avfoundation_mac.h" |
6 | 6 |
7 #import <CoreVideo/CoreVideo.h> | 7 #import <CoreVideo/CoreVideo.h> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/mac/foundation_util.h" | 10 #include "base/mac/foundation_util.h" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
42 supportedFormats:(media::VideoCaptureFormats*)formats{ | 42 supportedFormats:(media::VideoCaptureFormats*)formats{ |
43 NSArray* devices = [AVCaptureDeviceGlue devices]; | 43 NSArray* devices = [AVCaptureDeviceGlue devices]; |
44 CrAVCaptureDevice* device = nil; | 44 CrAVCaptureDevice* device = nil; |
45 for (device in devices) { | 45 for (device in devices) { |
46 if ([[device uniqueID] UTF8String] == name.id()) | 46 if ([[device uniqueID] UTF8String] == name.id()) |
47 break; | 47 break; |
48 } | 48 } |
49 if (device == nil) | 49 if (device == nil) |
50 return; | 50 return; |
51 for (CrAVCaptureDeviceFormat* format in device.formats) { | 51 for (CrAVCaptureDeviceFormat* format in device.formats) { |
52 // MediaSubType comes is a CMPixelFormatType but can be used as | 52 // MediaSubType is a CMPixelFormatType but can be used as CVPixelFormatType |
53 // CVPixelFormatType as well according to CMFormatDescription.h | 53 // as well according to CMFormatDescription.h |
54 media::VideoPixelFormat pixelFormat = media::PIXEL_FORMAT_UNKNOWN; | 54 media::VideoPixelFormat pixelFormat = media::PIXEL_FORMAT_UNKNOWN; |
55 switch (CoreMediaGlue::CMFormatDescriptionGetMediaSubType( | 55 switch (CoreMediaGlue::CMFormatDescriptionGetMediaSubType( |
56 [format formatDescription])) { | 56 [format formatDescription])) { |
57 case kCVPixelFormatType_422YpCbCr8: // Typical. | 57 case kCVPixelFormatType_422YpCbCr8: // Typical. |
58 pixelFormat = media::PIXEL_FORMAT_UYVY; | 58 pixelFormat = media::PIXEL_FORMAT_UYVY; |
59 break; | 59 break; |
60 case CoreMediaGlue::kCMPixelFormat_422YpCbCr8_yuvs: | 60 case CoreMediaGlue::kCMPixelFormat_422YpCbCr8_yuvs: |
61 pixelFormat = media::PIXEL_FORMAT_YUY2; | 61 pixelFormat = media::PIXEL_FORMAT_YUY2; |
62 break; | 62 break; |
63 case CoreMediaGlue::kCMVideoCodecType_JPEG_OpenDML: | 63 case CoreMediaGlue::kCMVideoCodecType_JPEG_OpenDML: |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
122 [captureSession_ removeInput:captureDeviceInput_]; | 122 [captureSession_ removeInput:captureDeviceInput_]; |
123 // No need to release |captureDeviceInput_|, is owned by the session. | 123 // No need to release |captureDeviceInput_|, is owned by the session. |
124 captureDeviceInput_ = nil; | 124 captureDeviceInput_ = nil; |
125 } | 125 } |
126 return YES; | 126 return YES; |
127 } | 127 } |
128 | 128 |
129 // Look for input device with requested name. | 129 // Look for input device with requested name. |
130 captureDevice_ = [AVCaptureDeviceGlue deviceWithUniqueID:deviceId]; | 130 captureDevice_ = [AVCaptureDeviceGlue deviceWithUniqueID:deviceId]; |
131 if (!captureDevice_) { | 131 if (!captureDevice_) { |
132 DLOG(ERROR) << "Could not open video capture device."; | 132 [self sendErrorString:[NSString |
133 stringWithUTF8String:"Could not open video capture device."]]; | |
133 return NO; | 134 return NO; |
134 } | 135 } |
135 | 136 |
136 // Create the capture input associated with the device. Easy peasy. | 137 // Create the capture input associated with the device. Easy peasy. |
137 NSError* error = nil; | 138 NSError* error = nil; |
138 captureDeviceInput_ = [AVCaptureDeviceInputGlue | 139 captureDeviceInput_ = [AVCaptureDeviceInputGlue |
139 deviceInputWithDevice:captureDevice_ | 140 deviceInputWithDevice:captureDevice_ |
140 error:&error]; | 141 error:&error]; |
141 if (!captureDeviceInput_) { | 142 if (!captureDeviceInput_) { |
142 captureDevice_ = nil; | 143 captureDevice_ = nil; |
143 DLOG(ERROR) << "Could not create video capture input: " | 144 [self sendErrorString:[NSString |
144 << [[error localizedDescription] UTF8String]; | 145 stringWithFormat:@"Could not create video capture input: %@ %@", |
146 [error localizedDescription], | |
147 [error localizedFailureReason]]]; | |
145 return NO; | 148 return NO; |
146 } | 149 } |
147 [captureSession_ addInput:captureDeviceInput_]; | 150 [captureSession_ addInput:captureDeviceInput_]; |
148 | 151 |
149 // Create a new data output for video. The data output is configured to | 152 // Create a new data output for video. The data output is configured to |
150 // discard late frames by default. | 153 // discard late frames by default. |
151 captureVideoDataOutput_.reset( | 154 captureVideoDataOutput_.reset( |
152 [[AVFoundationGlue::AVCaptureVideoDataOutputClass() alloc] init]); | 155 [[AVFoundationGlue::AVCaptureVideoDataOutputClass() alloc] init]); |
153 if (!captureVideoDataOutput_) { | 156 if (!captureVideoDataOutput_) { |
154 [captureSession_ removeInput:captureDeviceInput_]; | 157 [captureSession_ removeInput:captureDeviceInput_]; |
155 DLOG(ERROR) << "Could not create video data output."; | 158 [self sendErrorString:[NSString |
159 stringWithUTF8String:"Could not create video data output."]]; | |
156 return NO; | 160 return NO; |
157 } | 161 } |
158 [captureVideoDataOutput_ | 162 [captureVideoDataOutput_ |
159 setSampleBufferDelegate:self | 163 setSampleBufferDelegate:self |
160 queue:dispatch_get_global_queue( | 164 queue:dispatch_get_global_queue( |
161 DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)]; | 165 DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)]; |
162 [captureSession_ addOutput:captureVideoDataOutput_]; | 166 [captureSession_ addOutput:captureVideoDataOutput_]; |
163 return YES; | 167 return YES; |
164 } | 168 } |
165 | 169 |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
263 if (!frameReceiver_) | 267 if (!frameReceiver_) |
264 return; | 268 return; |
265 frameReceiver_->ReceiveFrame(addressToPass, frameSize, captureFormat, 0, 0); | 269 frameReceiver_->ReceiveFrame(addressToPass, frameSize, captureFormat, 0, 0); |
266 CVPixelBufferUnlockBaseAddress(videoFrame, kLockFlags); | 270 CVPixelBufferUnlockBaseAddress(videoFrame, kLockFlags); |
267 } | 271 } |
268 } | 272 } |
269 | 273 |
270 - (void)onVideoError:(NSNotification*)errorNotification { | 274 - (void)onVideoError:(NSNotification*)errorNotification { |
271 NSError* error = base::mac::ObjCCast<NSError>([[errorNotification userInfo] | 275 NSError* error = base::mac::ObjCCast<NSError>([[errorNotification userInfo] |
272 objectForKey:AVFoundationGlue::AVCaptureSessionErrorKey()]); | 276 objectForKey:AVFoundationGlue::AVCaptureSessionErrorKey()]); |
273 NSString* str_error = | 277 [self sendErrorString:[NSString stringWithFormat:@"%@: %@", |
274 [NSString stringWithFormat:@"%@: %@", | 278 [error localizedDescription], |
Henrik Grunell
2014/05/30 11:48:32
Fix indentation.
mcasas
2014/05/30 12:15:27
Done.
Henrik Grunell
2014/05/30 12:30:48
Nit: I don't know how objective-c is usually inden
| |
275 [error localizedDescription], | 279 [error localizedFailureReason]]]; |
276 [error localizedFailureReason]]; | 280 } |
277 | 281 |
282 - (void)sendErrorString:(NSString*)error { | |
283 DLOG(ERROR) << [error UTF8String]; | |
278 base::AutoLock lock(lock_); | 284 base::AutoLock lock(lock_); |
279 if (frameReceiver_) | 285 if (frameReceiver_) |
280 frameReceiver_->ReceiveError([str_error UTF8String]); | 286 frameReceiver_->ReceiveError([error UTF8String]); |
281 } | 287 } |
282 | 288 |
283 @end | 289 @end |
OLD | NEW |