Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(535)

Side by Side Diff: media/video/capture/mac/video_capture_device_qtkit_mac.mm

Issue 308813002: Mac Video Capture: Connect error logging to WebRTC Log (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 #import "media/video/capture/mac/video_capture_device_qtkit_mac.h" 5 #import "media/video/capture/mac/video_capture_device_qtkit_mac.h"
6 6
7 #import <QTKit/QTKit.h> 7 #import <QTKit/QTKit.h>
8 8
9 #include "base/debug/crash_logging.h" 9 #include "base/debug/crash_logging.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 } 71 }
72 72
73 - (BOOL)setCaptureDevice:(NSString*)deviceId { 73 - (BOOL)setCaptureDevice:(NSString*)deviceId {
74 if (deviceId) { 74 if (deviceId) {
75 // Set the capture device. 75 // Set the capture device.
76 if (captureDeviceInput_) { 76 if (captureDeviceInput_) {
77 DLOG(ERROR) << "Video capture device already set."; 77 DLOG(ERROR) << "Video capture device already set.";
78 return NO; 78 return NO;
79 } 79 }
80 80
81 // TODO(mcasas): Consider using [QTCaptureDevice deviceWithUniqueID] instead
82 // of explicitly forcing reenumeration of devices.
81 NSArray *captureDevices = 83 NSArray *captureDevices =
82 [QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo]; 84 [QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo];
83 NSArray *captureDevicesNames = 85 NSArray *captureDevicesNames =
84 [captureDevices valueForKey:@"uniqueID"]; 86 [captureDevices valueForKey:@"uniqueID"];
85 NSUInteger index = [captureDevicesNames indexOfObject:deviceId]; 87 NSUInteger index = [captureDevicesNames indexOfObject:deviceId];
86 if (index == NSNotFound) { 88 if (index == NSNotFound) {
87 DLOG(ERROR) << "Video capture device not found."; 89 [self sendErrorString:[NSString
90 stringWithUTF8String:"Video capture device not found."]];
88 return NO; 91 return NO;
89 } 92 }
90 QTCaptureDevice *device = [captureDevices objectAtIndex:index]; 93 QTCaptureDevice *device = [captureDevices objectAtIndex:index];
91 if ([[device attributeForKey:QTCaptureDeviceSuspendedAttribute] 94 if ([[device attributeForKey:QTCaptureDeviceSuspendedAttribute]
92 boolValue]) { 95 boolValue]) {
93 DLOG(ERROR) << "Cannot open suspended video capture device."; 96 [self sendErrorString:[NSString
97 stringWithUTF8String:"Cannot open suspended video capture device."]];
94 return NO; 98 return NO;
95 } 99 }
96 NSError *error; 100 NSError *error;
97 if (![device open:&error]) { 101 if (![device open:&error]) {
98 DLOG(ERROR) << "Could not open video capture device." 102 [self sendErrorString:[NSString
99 << [[error localizedDescription] UTF8String]; 103 stringWithFormat:@"Could not open video capture device: %@ %@",
Henrik Grunell 2014/05/30 11:48:32 Clarify by for example "...: %@, reason: %@". Here
mcasas 2014/05/30 12:15:27 Used the original "Big error (%@): %@", this shoul
Henrik Grunell 2014/05/30 12:30:48 SGTM
104 [error localizedDescription],
105 [error localizedFailureReason]]];
100 return NO; 106 return NO;
101 } 107 }
102 captureDeviceInput_ = [[QTCaptureDeviceInput alloc] initWithDevice:device]; 108 captureDeviceInput_ = [[QTCaptureDeviceInput alloc] initWithDevice:device];
103 captureSession_ = [[QTCaptureSession alloc] init]; 109 captureSession_ = [[QTCaptureSession alloc] init];
104 110
105 QTCaptureDecompressedVideoOutput *captureDecompressedOutput = 111 QTCaptureDecompressedVideoOutput *captureDecompressedOutput =
106 [[[QTCaptureDecompressedVideoOutput alloc] init] autorelease]; 112 [[[QTCaptureDecompressedVideoOutput alloc] init] autorelease];
107 [captureDecompressedOutput setDelegate:self]; 113 [captureDecompressedOutput setDelegate:self];
108 if (![captureSession_ addOutput:captureDecompressedOutput error:&error]) { 114 if (![captureSession_ addOutput:captureDecompressedOutput error:&error]) {
109 DLOG(ERROR) << "Could not connect video capture output." 115 [self sendErrorString:[NSString
110 << [[error localizedDescription] UTF8String]; 116 stringWithFormat:@"Could not connect video capture output: %@ %@",
117 [error localizedDescription],
118 [error localizedFailureReason]]];
111 return NO; 119 return NO;
112 } 120 }
113 121
114 // This key can be used to check if video capture code was related to a 122 // This key can be used to check if video capture code was related to a
115 // particular crash. 123 // particular crash.
116 base::debug::SetCrashKeyValue("VideoCaptureDeviceQTKit", "OpenedDevice"); 124 base::debug::SetCrashKeyValue("VideoCaptureDeviceQTKit", "OpenedDevice");
117 125
118 // Set the video pixel format to 2VUY (a.k.a UYVY, packed 4:2:2). 126 // Set the video pixel format to 2VUY (a.k.a UYVY, packed 4:2:2).
119 NSDictionary *captureDictionary = [NSDictionary 127 NSDictionary *captureDictionary = [NSDictionary
120 dictionaryWithObject: 128 dictionaryWithObject:
121 [NSNumber numberWithUnsignedInt:kCVPixelFormatType_422YpCbCr8] 129 [NSNumber numberWithUnsignedInt:kCVPixelFormatType_422YpCbCr8]
122 forKey:(id)kCVPixelBufferPixelFormatTypeKey]; 130 forKey:(id)kCVPixelBufferPixelFormatTypeKey];
123 [captureDecompressedOutput setPixelBufferAttributes:captureDictionary]; 131 [captureDecompressedOutput setPixelBufferAttributes:captureDictionary];
124 132
125 return YES; 133 return YES;
126 } else { 134 } else {
127 // Remove the previously set capture device. 135 // Remove the previously set capture device.
128 if (!captureDeviceInput_) { 136 if (!captureDeviceInput_) {
129 DLOG(ERROR) << "No video capture device set."; 137 [self sendErrorString:[NSString
138 stringWithUTF8String:"No video capture device set, on removal."]];
130 return YES; 139 return YES;
131 } 140 }
132 if ([[captureSession_ inputs] count] > 0) { 141 if ([[captureSession_ inputs] count] > 0) {
133 // The device is still running. 142 // The device is still running.
134 [self stopCapture]; 143 [self stopCapture];
135 } 144 }
136 if ([[captureSession_ outputs] count] > 0) { 145 if ([[captureSession_ outputs] count] > 0) {
137 // Only one output is set for |captureSession_|. 146 // Only one output is set for |captureSession_|.
138 DCHECK_EQ([[captureSession_ outputs] count], 1u); 147 DCHECK_EQ([[captureSession_ outputs] count], 1u);
139 id output = [[captureSession_ outputs] objectAtIndex:0]; 148 id output = [[captureSession_ outputs] objectAtIndex:0];
140 [output setDelegate:nil]; 149 [output setDelegate:nil];
141 150
142 // TODO(shess): QTKit achieves thread safety by posting messages 151 // TODO(shess): QTKit achieves thread safety by posting messages to the
143 // to the main thread. As part of -addOutput:, it posts a 152 // main thread. As part of -addOutput:, it posts a message to the main
144 // message to the main thread which in turn posts a notification 153 // thread which in turn posts a notification which will run in a future
145 // which will run in a future spin after the original method 154 // spin after the original method returns. -removeOutput: can post a
146 // returns. -removeOutput: can post a main-thread message in 155 // main-thread message in between while holding a lock which the
147 // between while holding a lock which the notification handler 156 // notification handler will need. Posting either -addOutput: or
148 // will need. Posting either -addOutput: or -removeOutput: to 157 // -removeOutput: to the main thread should fix it, remove is likely
149 // the main thread should fix it, remove is likely safer. 158 // safer. http://crbug.com/152757
150 // http://crbug.com/152757
151 [captureSession_ performSelectorOnMainThread:@selector(removeOutput:) 159 [captureSession_ performSelectorOnMainThread:@selector(removeOutput:)
152 withObject:output 160 withObject:output
153 waitUntilDone:YES]; 161 waitUntilDone:YES];
154 } 162 }
155 [captureSession_ release]; 163 [captureSession_ release];
156 captureSession_ = nil; 164 captureSession_ = nil;
157 [captureDeviceInput_ release]; 165 [captureDeviceInput_ release];
158 captureDeviceInput_ = nil; 166 captureDeviceInput_ = nil;
159 return YES; 167 return YES;
160 } 168 }
161 } 169 }
162 170
163 - (BOOL)setCaptureHeight:(int)height width:(int)width frameRate:(int)frameRate { 171 - (BOOL)setCaptureHeight:(int)height width:(int)width frameRate:(int)frameRate {
164 if (!captureDeviceInput_) { 172 if (!captureDeviceInput_) {
165 DLOG(ERROR) << "No video capture device set."; 173 [self sendErrorString:[NSString
174 stringWithUTF8String:"No video capture device set."]];
166 return NO; 175 return NO;
167 } 176 }
168 if ([[captureSession_ outputs] count] != 1) { 177 if ([[captureSession_ outputs] count] != 1) {
169 DLOG(ERROR) << "Video capture capabilities already set."; 178 [self sendErrorString:[NSString
179 stringWithUTF8String:"Video capture capabilities already set."]];
170 return NO; 180 return NO;
171 } 181 }
172 if (frameRate <= 0) { 182 if (frameRate <= 0) {
173 DLOG(ERROR) << "Wrong frame rate."; 183 [self sendErrorString:[NSString stringWithUTF8String: "Wrong frame rate."]];
174 return NO; 184 return NO;
175 } 185 }
176 186
177 frameRate_ = frameRate; 187 frameRate_ = frameRate;
178 188
179 QTCaptureDecompressedVideoOutput *output = 189 QTCaptureDecompressedVideoOutput *output =
180 [[captureSession_ outputs] objectAtIndex:0]; 190 [[captureSession_ outputs] objectAtIndex:0];
181 191
182 // Set up desired output properties. The old capture dictionary is used to 192 // Set up desired output properties. The old capture dictionary is used to
183 // retrieve the initial pixel format, which must be maintained. 193 // retrieve the initial pixel format, which must be maintained.
184 NSDictionary* videoSettingsDictionary = @{ 194 NSDictionary* videoSettingsDictionary = @{
185 (id)kCVPixelBufferWidthKey : @(width), 195 (id)kCVPixelBufferWidthKey : @(width),
186 (id)kCVPixelBufferHeightKey : @(height), 196 (id)kCVPixelBufferHeightKey : @(height),
187 (id)kCVPixelBufferPixelFormatTypeKey : [[output pixelBufferAttributes] 197 (id)kCVPixelBufferPixelFormatTypeKey : [[output pixelBufferAttributes]
188 valueForKey:(id)kCVPixelBufferPixelFormatTypeKey] 198 valueForKey:(id)kCVPixelBufferPixelFormatTypeKey]
189 }; 199 };
190 [output setPixelBufferAttributes:videoSettingsDictionary]; 200 [output setPixelBufferAttributes:videoSettingsDictionary];
191 201
192 [output setMinimumVideoFrameInterval:(NSTimeInterval)1/(float)frameRate]; 202 [output setMinimumVideoFrameInterval:(NSTimeInterval)1/(float)frameRate];
193 return YES; 203 return YES;
194 } 204 }
195 205
196 - (BOOL)startCapture { 206 - (BOOL)startCapture {
197 if ([[captureSession_ outputs] count] == 0) { 207 if ([[captureSession_ outputs] count] == 0) {
198 // Capture properties not set. 208 // Capture properties not set.
199 DLOG(ERROR) << "Video capture device not initialized."; 209 [self sendErrorString:[NSString
210 stringWithUTF8String:"Video capture device not initialized."]];
200 return NO; 211 return NO;
201 } 212 }
202 if ([[captureSession_ inputs] count] == 0) { 213 if ([[captureSession_ inputs] count] == 0) {
203 NSError *error; 214 NSError *error;
204 if (![captureSession_ addInput:captureDeviceInput_ error:&error]) { 215 if (![captureSession_ addInput:captureDeviceInput_ error:&error]) {
205 DLOG(ERROR) << "Could not connect video capture device." 216 [self sendErrorString:[NSString
206 << [[error localizedDescription] UTF8String]; 217 stringWithFormat:@"Could not connect video capture device: %@ %@",
218 [error localizedDescription],
219 [error localizedFailureReason]]];
220
207 return NO; 221 return NO;
208 } 222 }
209 NSNotificationCenter * notificationCenter = 223 NSNotificationCenter * notificationCenter =
210 [NSNotificationCenter defaultCenter]; 224 [NSNotificationCenter defaultCenter];
211 [notificationCenter addObserver:self 225 [notificationCenter addObserver:self
212 selector:@selector(handleNotification:) 226 selector:@selector(handleNotification:)
213 name:QTCaptureSessionRuntimeErrorNotification 227 name:QTCaptureSessionRuntimeErrorNotification
214 object:captureSession_]; 228 object:captureSession_];
215 [captureSession_ startRunning]; 229 [captureSession_ startRunning];
216 } 230 }
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 aspectNumerator, aspectDenominator); 316 aspectNumerator, aspectDenominator);
303 317
304 CVPixelBufferUnlockBaseAddress(videoFrame, kLockFlags); 318 CVPixelBufferUnlockBaseAddress(videoFrame, kLockFlags);
305 } 319 }
306 [lock_ unlock]; 320 [lock_ unlock];
307 } 321 }
308 322
309 - (void)handleNotification:(NSNotification*)errorNotification { 323 - (void)handleNotification:(NSNotification*)errorNotification {
310 NSError * error = (NSError*)[[errorNotification userInfo] 324 NSError * error = (NSError*)[[errorNotification userInfo]
311 objectForKey:QTCaptureSessionErrorKey]; 325 objectForKey:QTCaptureSessionErrorKey];
312 NSString* str_error = 326 [self sendErrorString:[NSString stringWithFormat:@"%@: %@",
313 [NSString stringWithFormat:@"%@: %@", 327 [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: Same here.
314 [error localizedDescription], 328 [error localizedFailureReason]]];
315 [error localizedFailureReason]]; 329 }
316 330
317 frameReceiver_->ReceiveError([str_error UTF8String]); 331 - (void)sendErrorString:(NSString*)error {
332 [lock_ lock];
333 if (frameReceiver_)
334 frameReceiver_->ReceiveError([error UTF8String]);
335 [lock_ unlock];
318 } 336 }
319 337
320 @end 338 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698