OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2017 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2017 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #import <OCMock/OCMock.h> | 11 #import <OCMock/OCMock.h> |
12 | 12 |
13 #if TARGET_OS_IPHONE | 13 #if TARGET_OS_IPHONE |
14 #import <UIKit/UIKit.h> | 14 #import <UIKit/UIKit.h> |
15 #endif | 15 #endif |
16 | 16 |
17 #include "webrtc/rtc_base/gunit.h" | 17 #include "webrtc/rtc_base/gunit.h" |
18 | 18 |
19 #import <WebRTC/RTCCameraVideoCapturer.h> | 19 #import <WebRTC/RTCCameraVideoCapturer.h> |
20 #import <WebRTC/RTCDispatcher.h> | 20 #import <WebRTC/RTCDispatcher.h> |
21 #import <WebRTC/RTCVideoFrame.h> | 21 #import <WebRTC/RTCVideoFrame.h> |
| 22 #import "RTCImageHelper.h" |
22 | 23 |
23 #if TARGET_OS_IPHONE | 24 #if TARGET_OS_IPHONE |
24 // Helper method. | 25 // Helper method. |
25 CMSampleBufferRef createTestSampleBufferRef() { | 26 CMSampleBufferRef createTestSampleBufferRef() { |
26 | 27 |
27 // This image is already in the testing bundle. | 28 // This image is already in the testing bundle. |
28 UIImage *image = [UIImage imageNamed:@"Default.png"]; | 29 UIImage *image = [UIImage imageNamed:@"Default.png"]; |
29 CGSize size = image.size; | 30 CGSize size = image.size; |
30 CGImageRef imageRef = [image CGImage]; | 31 CGImageRef imageRef = [image CGImage]; |
31 | 32 |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 [self.delegateMock verify]; | 212 [self.delegateMock verify]; |
212 | 213 |
213 [(id)currentDeviceMock stopMocking]; | 214 [(id)currentDeviceMock stopMocking]; |
214 currentDeviceMock = nil; | 215 currentDeviceMock = nil; |
215 [classMock stopMocking]; | 216 [classMock stopMocking]; |
216 classMock = nil; | 217 classMock = nil; |
217 CFRelease(sampleBuffer); | 218 CFRelease(sampleBuffer); |
218 #endif | 219 #endif |
219 } | 220 } |
220 | 221 |
| 222 - (void)testRotationCamera:(AVCaptureDevicePosition)camera |
| 223 withOrientation:(UIDeviceOrientation)deviceOrientation { |
| 224 #if TARGET_OS_IPHONE |
| 225 // Mock the AVCaptureConnection as we will get the camera position from the co
nnection's |
| 226 // input ports. |
| 227 AVCaptureDeviceInput *inputPortMock = OCMClassMock([AVCaptureDeviceInput class
]); |
| 228 AVCaptureInputPort *captureInputPort = OCMClassMock([AVCaptureInputPort class]
); |
| 229 NSArray *inputPortsArrayMock = @[captureInputPort]; |
| 230 AVCaptureDevice *captureDeviceMock = OCMClassMock([AVCaptureDevice class]); |
| 231 OCMStub(((AVCaptureConnection *)self.captureConnectionMock).inputPorts). |
| 232 andReturn(inputPortsArrayMock); |
| 233 OCMStub(captureInputPort.input).andReturn(inputPortMock); |
| 234 OCMStub(inputPortMock.device).andReturn(captureDeviceMock); |
| 235 OCMStub(captureDeviceMock.position).andReturn(camera); |
| 236 |
| 237 // UpsideDown -> RTCVideoRotation_0. |
| 238 UIDevice *currentDeviceMock = OCMClassMock([UIDevice class]); |
| 239 OCMStub(currentDeviceMock.orientation).andReturn(deviceOrientation); |
| 240 id classMock = OCMClassMock([UIDevice class]); |
| 241 OCMStub([classMock currentDevice]).andReturn(currentDeviceMock); |
| 242 |
| 243 CMSampleBufferRef sampleBuffer = createTestSampleBufferRef(); |
| 244 |
| 245 [[self.delegateMock expect] capturer:self.capturer |
| 246 didCaptureVideoFrame:[OCMArg checkWithBlock:^BOOL(RTCVideoFram
e *expectedFrame) { |
| 247 if (camera == AVCaptureDevicePositionFront) { |
| 248 if (deviceOrientation == UIDeviceOrientationLandscapeLeft) { |
| 249 EXPECT_EQ(expectedFrame.rotation, RTCVideoRotation_180); |
| 250 } else if (deviceOrientation == UIDeviceOrientationLandscapeRight) { |
| 251 EXPECT_EQ(expectedFrame.rotation, RTCVideoRotation_0); |
| 252 } |
| 253 } else if (camera == AVCaptureDevicePositionBack) { |
| 254 if (deviceOrientation == UIDeviceOrientationLandscapeLeft) { |
| 255 EXPECT_EQ(expectedFrame.rotation, RTCVideoRotation_0); |
| 256 } else if (deviceOrientation == UIDeviceOrientationLandscapeRight) { |
| 257 EXPECT_EQ(expectedFrame.rotation, RTCVideoRotation_180); |
| 258 } |
| 259 } |
| 260 return YES; |
| 261 }]]; |
| 262 |
| 263 NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; |
| 264 [center postNotificationName:UIDeviceOrientationDidChangeNotification object:n
il]; |
| 265 |
| 266 // We need to wait for the dispatch to finish. |
| 267 WAIT(0, 1000); |
| 268 |
| 269 [self.capturer captureOutput:self.capturer.captureSession.outputs[0] |
| 270 didOutputSampleBuffer:sampleBuffer |
| 271 fromConnection:self.captureConnectionMock]; |
| 272 |
| 273 [self.delegateMock verify]; |
| 274 |
| 275 [(id)currentDeviceMock stopMocking]; |
| 276 currentDeviceMock = nil; |
| 277 [classMock stopMocking]; |
| 278 classMock = nil; |
| 279 CFRelease(sampleBuffer); |
| 280 #endif |
| 281 } |
| 282 |
| 283 - (void)testRotationFrame { |
| 284 #if TARGET_OS_IPHONE |
| 285 // Mock the AVCaptureConnection as we will get the camera position from the co
nnection's |
| 286 // input ports. |
| 287 AVCaptureDeviceInput *inputPortMock = OCMClassMock([AVCaptureDeviceInput class
]); |
| 288 AVCaptureInputPort *captureInputPort = OCMClassMock([AVCaptureInputPort class]
); |
| 289 NSArray *inputPortsArrayMock = @[captureInputPort]; |
| 290 AVCaptureDevice *captureDeviceMock = OCMClassMock([AVCaptureDevice class]); |
| 291 OCMStub(((AVCaptureConnection *)self.captureConnectionMock).inputPorts). |
| 292 andReturn(inputPortsArrayMock); |
| 293 OCMStub(captureInputPort.input).andReturn(inputPortMock); |
| 294 OCMStub(inputPortMock.device).andReturn(captureDeviceMock); |
| 295 OCMStub(captureDeviceMock.position).andReturn(AVCaptureDevicePositionFront); |
| 296 |
| 297 // UpsideDown -> RTCVideoRotation_0. |
| 298 UIDevice *currentDeviceMock = OCMClassMock([UIDevice class]); |
| 299 OCMStub(currentDeviceMock.orientation).andReturn(UIDeviceOrientationLandscapeL
eft); |
| 300 id classMock = OCMClassMock([UIDevice class]); |
| 301 OCMStub([classMock currentDevice]).andReturn(currentDeviceMock); |
| 302 |
| 303 CMSampleBufferRef sampleBuffer = createTestSampleBufferRef(); |
| 304 |
| 305 [[self.delegateMock expect] capturer:self.capturer |
| 306 didCaptureVideoFrame:[OCMArg checkWithBlock:^BOOL(RTCVideoFram
e *expectedFrame) { |
| 307 // Front camera and landscape left should return 180. But the frame says its
from the back |
| 308 // camera, so rotation should be 0. |
| 309 EXPECT_EQ(expectedFrame.rotation, RTCVideoRotation_0); |
| 310 return YES; |
| 311 }]]; |
| 312 |
| 313 NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; |
| 314 [center postNotificationName:UIDeviceOrientationDidChangeNotification object:n
il]; |
| 315 |
| 316 // We need to wait for the dispatch to finish. |
| 317 WAIT(0, 1000); |
| 318 |
| 319 CFMutableDictionaryRef exif = CFDictionaryCreateMutable(kCFAllocatorDefault, 0
, NULL, NULL); |
| 320 CFDictionarySetValue(exif, CFSTR("LensModel"), CFSTR("iPhone SE back camera 4.
15mm f/2.2")); |
| 321 CMSetAttachment(sampleBuffer, CFSTR("{Exif}"), exif, kCMAttachmentMode_ShouldP
ropagate); |
| 322 |
| 323 [self.capturer captureOutput:self.capturer.captureSession.outputs[0] |
| 324 didOutputSampleBuffer:sampleBuffer |
| 325 fromConnection:self.captureConnectionMock]; |
| 326 |
| 327 [self.delegateMock verify]; |
| 328 |
| 329 [(id)currentDeviceMock stopMocking]; |
| 330 currentDeviceMock = nil; |
| 331 [classMock stopMocking]; |
| 332 classMock = nil; |
| 333 CFRelease(sampleBuffer); |
| 334 #endif |
| 335 } |
| 336 |
| 337 - (void)testImageExif { |
| 338 CMSampleBufferRef sampleBuffer = createTestSampleBufferRef(); |
| 339 CFMutableDictionaryRef exif = CFDictionaryCreateMutable(kCFAllocatorDefault, 0
, NULL, NULL); |
| 340 CFDictionarySetValue(exif, CFSTR("LensModel"), CFSTR("iPhone SE back camera 4.
15mm f/2.2")); |
| 341 CMSetAttachment(sampleBuffer, CFSTR("{Exif}"), exif, kCMAttachmentMode_ShouldP
ropagate); |
| 342 |
| 343 AVCaptureDevicePosition cameraPosition = [RTCImageHelper |
| 344 devicePositionForSampleBuffer:sample
Buffer]; |
| 345 EXPECT_EQ(cameraPosition, AVCaptureDevicePositionBack); |
| 346 } |
| 347 |
221 @end | 348 @end |
222 | 349 |
223 // TODO(kthelgason): Reenable these tests on simulator. | 350 // TODO(kthelgason): Reenable these tests on simulator. |
224 // See bugs.webrtc.org/7813 | 351 // See bugs.webrtc.org/7813 |
225 #if TARGET_IPHONE_SIMULATOR | 352 #if TARGET_IPHONE_SIMULATOR |
226 #define MAYBE_TEST(f, name) TEST(f, DISABLED_##name) | 353 #define MAYBE_TEST(f, name) TEST(f, DISABLED_##name) |
227 #else | 354 #else |
228 #define MAYBE_TEST TEST | 355 #define MAYBE_TEST TEST |
229 #endif | 356 #endif |
230 | 357 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 [test testDelegateCallbackNotCalledWhenInvalidBuffer]; | 389 [test testDelegateCallbackNotCalledWhenInvalidBuffer]; |
263 [test tearDown]; | 390 [test tearDown]; |
264 } | 391 } |
265 | 392 |
266 MAYBE_TEST(RTCCameraVideoCapturerTests, DelegateCallbackWithValidBufferAndOrient
ationUpdate) { | 393 MAYBE_TEST(RTCCameraVideoCapturerTests, DelegateCallbackWithValidBufferAndOrient
ationUpdate) { |
267 RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init]
; | 394 RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init]
; |
268 [test setup]; | 395 [test setup]; |
269 [test testDelegateCallbackWithValidBufferAndOrientationUpdate]; | 396 [test testDelegateCallbackWithValidBufferAndOrientationUpdate]; |
270 [test tearDown]; | 397 [test tearDown]; |
271 } | 398 } |
| 399 |
| 400 MAYBE_TEST(RTCCameraVideoCapturerTests, RotationCameraBackLandscapeLeft) { |
| 401 RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init]
; |
| 402 [test setup]; |
| 403 [test testRotationCamera:AVCaptureDevicePositionBack |
| 404 withOrientation:UIDeviceOrientationLandscapeLeft]; |
| 405 [test tearDown]; |
| 406 } |
| 407 |
| 408 MAYBE_TEST(RTCCameraVideoCapturerTests, RotationCameraFrontLandscapeLeft) { |
| 409 RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init]
; |
| 410 [test setup]; |
| 411 [test testRotationCamera:AVCaptureDevicePositionFront |
| 412 withOrientation:UIDeviceOrientationLandscapeLeft]; |
| 413 [test tearDown]; |
| 414 } |
| 415 |
| 416 MAYBE_TEST(RTCCameraVideoCapturerTests, RotationCameraBackLandscapeRight) { |
| 417 RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init]
; |
| 418 [test setup]; |
| 419 [test testRotationCamera:AVCaptureDevicePositionBack |
| 420 withOrientation:UIDeviceOrientationLandscapeRight]; |
| 421 [test tearDown]; |
| 422 } |
| 423 |
| 424 MAYBE_TEST(RTCCameraVideoCapturerTests, RotationCameraFrontLandscapeRight) { |
| 425 RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init]
; |
| 426 [test setup]; |
| 427 [test testRotationCamera:AVCaptureDevicePositionFront |
| 428 withOrientation:UIDeviceOrientationLandscapeRight]; |
| 429 [test tearDown]; |
| 430 } |
| 431 |
| 432 MAYBE_TEST(RTCCameraVideoCapturerTests, RotationCameraFrame) { |
| 433 RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init]
; |
| 434 [test setup]; |
| 435 [test testRotationFrame]; |
| 436 [test tearDown]; |
| 437 } |
| 438 |
| 439 MAYBE_TEST(RTCCameraVideoCapturerTests, ImageExif) { |
| 440 RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init]
; |
| 441 [test setup]; |
| 442 [test testImageExif]; |
| 443 [test tearDown]; |
| 444 } |
OLD | NEW |