1*d9f75844SAndroid Build Coastguard Worker/* 2*d9f75844SAndroid Build Coastguard Worker * Copyright 2017 The WebRTC project authors. All Rights Reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker 11*d9f75844SAndroid Build Coastguard Worker#import <XCTest/XCTest.h> 12*d9f75844SAndroid Build Coastguard Worker 13*d9f75844SAndroid Build Coastguard Worker#import <Foundation/Foundation.h> 14*d9f75844SAndroid Build Coastguard Worker#import <MetalKit/MetalKit.h> 15*d9f75844SAndroid Build Coastguard Worker#import <OCMock/OCMock.h> 16*d9f75844SAndroid Build Coastguard Worker 17*d9f75844SAndroid Build Coastguard Worker#import "components/renderer/metal/RTCMTLVideoView.h" 18*d9f75844SAndroid Build Coastguard Worker 19*d9f75844SAndroid Build Coastguard Worker#import "api/video_frame_buffer/RTCNativeI420Buffer.h" 20*d9f75844SAndroid Build Coastguard Worker#import "base/RTCVideoFrameBuffer.h" 21*d9f75844SAndroid Build Coastguard Worker#import "components/renderer/metal/RTCMTLNV12Renderer.h" 22*d9f75844SAndroid Build Coastguard Worker#import "components/video_frame_buffer/RTCCVPixelBuffer.h" 23*d9f75844SAndroid Build Coastguard Worker 24*d9f75844SAndroid Build Coastguard Workerstatic size_t kBufferWidth = 200; 25*d9f75844SAndroid Build Coastguard Workerstatic size_t kBufferHeight = 200; 26*d9f75844SAndroid Build Coastguard Worker 27*d9f75844SAndroid Build Coastguard Worker// Extension of RTC_OBJC_TYPE(RTCMTLVideoView) for testing purposes. 28*d9f75844SAndroid Build Coastguard Worker@interface RTC_OBJC_TYPE (RTCMTLVideoView) 29*d9f75844SAndroid Build Coastguard Worker(Testing) 30*d9f75844SAndroid Build Coastguard Worker 31*d9f75844SAndroid Build Coastguard Worker @property(nonatomic, readonly) MTKView *metalView; 32*d9f75844SAndroid Build Coastguard Worker 33*d9f75844SAndroid Build Coastguard Worker+ (BOOL)isMetalAvailable; 34*d9f75844SAndroid Build Coastguard Worker+ (UIView *)createMetalView:(CGRect)frame; 35*d9f75844SAndroid Build Coastguard Worker+ (id<RTCMTLRenderer>)createNV12Renderer; 36*d9f75844SAndroid Build Coastguard Worker+ (id<RTCMTLRenderer>)createI420Renderer; 37*d9f75844SAndroid Build Coastguard Worker- (void)drawInMTKView:(id)view; 38*d9f75844SAndroid Build Coastguard Worker@end 39*d9f75844SAndroid Build Coastguard Worker 40*d9f75844SAndroid Build Coastguard Worker@interface RTCMTLVideoViewTests : XCTestCase 41*d9f75844SAndroid Build Coastguard Worker@property(nonatomic, strong) id classMock; 42*d9f75844SAndroid Build Coastguard Worker@property(nonatomic, strong) id rendererNV12Mock; 43*d9f75844SAndroid Build Coastguard Worker@property(nonatomic, strong) id rendererI420Mock; 44*d9f75844SAndroid Build Coastguard Worker@property(nonatomic, strong) id frameMock; 45*d9f75844SAndroid Build Coastguard Worker@end 46*d9f75844SAndroid Build Coastguard Worker 47*d9f75844SAndroid Build Coastguard Worker@implementation RTCMTLVideoViewTests 48*d9f75844SAndroid Build Coastguard Worker 49*d9f75844SAndroid Build Coastguard Worker@synthesize classMock = _classMock; 50*d9f75844SAndroid Build Coastguard Worker@synthesize rendererNV12Mock = _rendererNV12Mock; 51*d9f75844SAndroid Build Coastguard Worker@synthesize rendererI420Mock = _rendererI420Mock; 52*d9f75844SAndroid Build Coastguard Worker@synthesize frameMock = _frameMock; 53*d9f75844SAndroid Build Coastguard Worker 54*d9f75844SAndroid Build Coastguard Worker- (void)setUp { 55*d9f75844SAndroid Build Coastguard Worker self.classMock = OCMClassMock([RTC_OBJC_TYPE(RTCMTLVideoView) class]); 56*d9f75844SAndroid Build Coastguard Worker [self startMockingNilView]; 57*d9f75844SAndroid Build Coastguard Worker} 58*d9f75844SAndroid Build Coastguard Worker 59*d9f75844SAndroid Build Coastguard Worker- (void)tearDown { 60*d9f75844SAndroid Build Coastguard Worker [self.classMock stopMocking]; 61*d9f75844SAndroid Build Coastguard Worker [self.rendererI420Mock stopMocking]; 62*d9f75844SAndroid Build Coastguard Worker [self.rendererNV12Mock stopMocking]; 63*d9f75844SAndroid Build Coastguard Worker [self.frameMock stopMocking]; 64*d9f75844SAndroid Build Coastguard Worker self.classMock = nil; 65*d9f75844SAndroid Build Coastguard Worker self.rendererI420Mock = nil; 66*d9f75844SAndroid Build Coastguard Worker self.rendererNV12Mock = nil; 67*d9f75844SAndroid Build Coastguard Worker self.frameMock = nil; 68*d9f75844SAndroid Build Coastguard Worker} 69*d9f75844SAndroid Build Coastguard Worker 70*d9f75844SAndroid Build Coastguard Worker- (id)frameMockWithCVPixelBuffer:(BOOL)hasCVPixelBuffer { 71*d9f75844SAndroid Build Coastguard Worker id frameMock = OCMClassMock([RTC_OBJC_TYPE(RTCVideoFrame) class]); 72*d9f75844SAndroid Build Coastguard Worker if (hasCVPixelBuffer) { 73*d9f75844SAndroid Build Coastguard Worker CVPixelBufferRef pixelBufferRef; 74*d9f75844SAndroid Build Coastguard Worker CVPixelBufferCreate(kCFAllocatorDefault, 75*d9f75844SAndroid Build Coastguard Worker kBufferWidth, 76*d9f75844SAndroid Build Coastguard Worker kBufferHeight, 77*d9f75844SAndroid Build Coastguard Worker kCVPixelFormatType_420YpCbCr8Planar, 78*d9f75844SAndroid Build Coastguard Worker nil, 79*d9f75844SAndroid Build Coastguard Worker &pixelBufferRef); 80*d9f75844SAndroid Build Coastguard Worker OCMStub([frameMock buffer]) 81*d9f75844SAndroid Build Coastguard Worker .andReturn([[RTC_OBJC_TYPE(RTCCVPixelBuffer) alloc] initWithPixelBuffer:pixelBufferRef]); 82*d9f75844SAndroid Build Coastguard Worker } else { 83*d9f75844SAndroid Build Coastguard Worker OCMStub([frameMock buffer]) 84*d9f75844SAndroid Build Coastguard Worker .andReturn([[RTC_OBJC_TYPE(RTCI420Buffer) alloc] initWithWidth:kBufferWidth 85*d9f75844SAndroid Build Coastguard Worker height:kBufferHeight]); 86*d9f75844SAndroid Build Coastguard Worker } 87*d9f75844SAndroid Build Coastguard Worker OCMStub([((RTC_OBJC_TYPE(RTCVideoFrame) *)frameMock) width]).andReturn(kBufferWidth); 88*d9f75844SAndroid Build Coastguard Worker OCMStub([((RTC_OBJC_TYPE(RTCVideoFrame) *)frameMock) height]).andReturn(kBufferHeight); 89*d9f75844SAndroid Build Coastguard Worker OCMStub([frameMock timeStampNs]).andReturn(arc4random_uniform(INT_MAX)); 90*d9f75844SAndroid Build Coastguard Worker return frameMock; 91*d9f75844SAndroid Build Coastguard Worker} 92*d9f75844SAndroid Build Coastguard Worker 93*d9f75844SAndroid Build Coastguard Worker- (id)rendererMockWithSuccessfulSetup:(BOOL)success { 94*d9f75844SAndroid Build Coastguard Worker id rendererMock = OCMClassMock([RTCMTLRenderer class]); 95*d9f75844SAndroid Build Coastguard Worker OCMStub([rendererMock addRenderingDestination:[OCMArg any]]).andReturn(success); 96*d9f75844SAndroid Build Coastguard Worker return rendererMock; 97*d9f75844SAndroid Build Coastguard Worker} 98*d9f75844SAndroid Build Coastguard Worker 99*d9f75844SAndroid Build Coastguard Worker- (void)startMockingNilView { 100*d9f75844SAndroid Build Coastguard Worker // Use OCMock 2 syntax here until OCMock is upgraded to 3.4 101*d9f75844SAndroid Build Coastguard Worker [[[self.classMock stub] andReturn:nil] createMetalView:CGRectZero]; 102*d9f75844SAndroid Build Coastguard Worker} 103*d9f75844SAndroid Build Coastguard Worker 104*d9f75844SAndroid Build Coastguard Worker#pragma mark - Test cases 105*d9f75844SAndroid Build Coastguard Worker 106*d9f75844SAndroid Build Coastguard Worker- (void)testInitAssertsIfMetalUnavailabe { 107*d9f75844SAndroid Build Coastguard Worker // given 108*d9f75844SAndroid Build Coastguard Worker OCMStub([self.classMock isMetalAvailable]).andReturn(NO); 109*d9f75844SAndroid Build Coastguard Worker 110*d9f75844SAndroid Build Coastguard Worker // when 111*d9f75844SAndroid Build Coastguard Worker BOOL asserts = NO; 112*d9f75844SAndroid Build Coastguard Worker @try { 113*d9f75844SAndroid Build Coastguard Worker RTC_OBJC_TYPE(RTCMTLVideoView) *realView = 114*d9f75844SAndroid Build Coastguard Worker [[RTC_OBJC_TYPE(RTCMTLVideoView) alloc] initWithFrame:CGRectZero]; 115*d9f75844SAndroid Build Coastguard Worker (void)realView; 116*d9f75844SAndroid Build Coastguard Worker } @catch (NSException *ex) { 117*d9f75844SAndroid Build Coastguard Worker asserts = YES; 118*d9f75844SAndroid Build Coastguard Worker } 119*d9f75844SAndroid Build Coastguard Worker 120*d9f75844SAndroid Build Coastguard Worker XCTAssertTrue(asserts); 121*d9f75844SAndroid Build Coastguard Worker} 122*d9f75844SAndroid Build Coastguard Worker 123*d9f75844SAndroid Build Coastguard Worker- (void)testRTCVideoRenderNilFrameCallback { 124*d9f75844SAndroid Build Coastguard Worker // given 125*d9f75844SAndroid Build Coastguard Worker OCMStub([self.classMock isMetalAvailable]).andReturn(YES); 126*d9f75844SAndroid Build Coastguard Worker 127*d9f75844SAndroid Build Coastguard Worker RTC_OBJC_TYPE(RTCMTLVideoView) *realView = 128*d9f75844SAndroid Build Coastguard Worker [[RTC_OBJC_TYPE(RTCMTLVideoView) alloc] initWithFrame:CGRectMake(0, 0, 640, 480)]; 129*d9f75844SAndroid Build Coastguard Worker self.frameMock = OCMClassMock([RTC_OBJC_TYPE(RTCVideoFrame) class]); 130*d9f75844SAndroid Build Coastguard Worker 131*d9f75844SAndroid Build Coastguard Worker [[self.frameMock reject] buffer]; 132*d9f75844SAndroid Build Coastguard Worker [[self.classMock reject] createNV12Renderer]; 133*d9f75844SAndroid Build Coastguard Worker [[self.classMock reject] createI420Renderer]; 134*d9f75844SAndroid Build Coastguard Worker 135*d9f75844SAndroid Build Coastguard Worker // when 136*d9f75844SAndroid Build Coastguard Worker [realView renderFrame:nil]; 137*d9f75844SAndroid Build Coastguard Worker [realView drawInMTKView:realView.metalView]; 138*d9f75844SAndroid Build Coastguard Worker 139*d9f75844SAndroid Build Coastguard Worker // then 140*d9f75844SAndroid Build Coastguard Worker [self.frameMock verify]; 141*d9f75844SAndroid Build Coastguard Worker [self.classMock verify]; 142*d9f75844SAndroid Build Coastguard Worker} 143*d9f75844SAndroid Build Coastguard Worker 144*d9f75844SAndroid Build Coastguard Worker- (void)testRTCVideoRenderFrameCallbackI420 { 145*d9f75844SAndroid Build Coastguard Worker // given 146*d9f75844SAndroid Build Coastguard Worker OCMStub([self.classMock isMetalAvailable]).andReturn(YES); 147*d9f75844SAndroid Build Coastguard Worker self.rendererI420Mock = [self rendererMockWithSuccessfulSetup:YES]; 148*d9f75844SAndroid Build Coastguard Worker self.frameMock = [self frameMockWithCVPixelBuffer:NO]; 149*d9f75844SAndroid Build Coastguard Worker 150*d9f75844SAndroid Build Coastguard Worker OCMExpect([self.rendererI420Mock drawFrame:self.frameMock]); 151*d9f75844SAndroid Build Coastguard Worker OCMExpect([self.classMock createI420Renderer]).andReturn(self.rendererI420Mock); 152*d9f75844SAndroid Build Coastguard Worker [[self.classMock reject] createNV12Renderer]; 153*d9f75844SAndroid Build Coastguard Worker 154*d9f75844SAndroid Build Coastguard Worker RTC_OBJC_TYPE(RTCMTLVideoView) *realView = 155*d9f75844SAndroid Build Coastguard Worker [[RTC_OBJC_TYPE(RTCMTLVideoView) alloc] initWithFrame:CGRectMake(0, 0, 640, 480)]; 156*d9f75844SAndroid Build Coastguard Worker 157*d9f75844SAndroid Build Coastguard Worker // when 158*d9f75844SAndroid Build Coastguard Worker [realView renderFrame:self.frameMock]; 159*d9f75844SAndroid Build Coastguard Worker [realView drawInMTKView:realView.metalView]; 160*d9f75844SAndroid Build Coastguard Worker 161*d9f75844SAndroid Build Coastguard Worker // then 162*d9f75844SAndroid Build Coastguard Worker [self.rendererI420Mock verify]; 163*d9f75844SAndroid Build Coastguard Worker [self.classMock verify]; 164*d9f75844SAndroid Build Coastguard Worker} 165*d9f75844SAndroid Build Coastguard Worker 166*d9f75844SAndroid Build Coastguard Worker- (void)testRTCVideoRenderFrameCallbackNV12 { 167*d9f75844SAndroid Build Coastguard Worker // given 168*d9f75844SAndroid Build Coastguard Worker OCMStub([self.classMock isMetalAvailable]).andReturn(YES); 169*d9f75844SAndroid Build Coastguard Worker self.rendererNV12Mock = [self rendererMockWithSuccessfulSetup:YES]; 170*d9f75844SAndroid Build Coastguard Worker self.frameMock = [self frameMockWithCVPixelBuffer:YES]; 171*d9f75844SAndroid Build Coastguard Worker 172*d9f75844SAndroid Build Coastguard Worker OCMExpect([self.rendererNV12Mock drawFrame:self.frameMock]); 173*d9f75844SAndroid Build Coastguard Worker OCMExpect([self.classMock createNV12Renderer]).andReturn(self.rendererNV12Mock); 174*d9f75844SAndroid Build Coastguard Worker [[self.classMock reject] createI420Renderer]; 175*d9f75844SAndroid Build Coastguard Worker 176*d9f75844SAndroid Build Coastguard Worker RTC_OBJC_TYPE(RTCMTLVideoView) *realView = 177*d9f75844SAndroid Build Coastguard Worker [[RTC_OBJC_TYPE(RTCMTLVideoView) alloc] initWithFrame:CGRectMake(0, 0, 640, 480)]; 178*d9f75844SAndroid Build Coastguard Worker 179*d9f75844SAndroid Build Coastguard Worker // when 180*d9f75844SAndroid Build Coastguard Worker [realView renderFrame:self.frameMock]; 181*d9f75844SAndroid Build Coastguard Worker [realView drawInMTKView:realView.metalView]; 182*d9f75844SAndroid Build Coastguard Worker 183*d9f75844SAndroid Build Coastguard Worker // then 184*d9f75844SAndroid Build Coastguard Worker [self.rendererNV12Mock verify]; 185*d9f75844SAndroid Build Coastguard Worker [self.classMock verify]; 186*d9f75844SAndroid Build Coastguard Worker} 187*d9f75844SAndroid Build Coastguard Worker 188*d9f75844SAndroid Build Coastguard Worker- (void)testRTCVideoRenderWorksAfterReconstruction { 189*d9f75844SAndroid Build Coastguard Worker OCMStub([self.classMock isMetalAvailable]).andReturn(YES); 190*d9f75844SAndroid Build Coastguard Worker self.rendererNV12Mock = [self rendererMockWithSuccessfulSetup:YES]; 191*d9f75844SAndroid Build Coastguard Worker self.frameMock = [self frameMockWithCVPixelBuffer:YES]; 192*d9f75844SAndroid Build Coastguard Worker 193*d9f75844SAndroid Build Coastguard Worker OCMExpect([self.rendererNV12Mock drawFrame:self.frameMock]); 194*d9f75844SAndroid Build Coastguard Worker OCMExpect([self.classMock createNV12Renderer]).andReturn(self.rendererNV12Mock); 195*d9f75844SAndroid Build Coastguard Worker [[self.classMock reject] createI420Renderer]; 196*d9f75844SAndroid Build Coastguard Worker 197*d9f75844SAndroid Build Coastguard Worker RTC_OBJC_TYPE(RTCMTLVideoView) *realView = 198*d9f75844SAndroid Build Coastguard Worker [[RTC_OBJC_TYPE(RTCMTLVideoView) alloc] initWithFrame:CGRectMake(0, 0, 640, 480)]; 199*d9f75844SAndroid Build Coastguard Worker 200*d9f75844SAndroid Build Coastguard Worker [realView renderFrame:self.frameMock]; 201*d9f75844SAndroid Build Coastguard Worker [realView drawInMTKView:realView.metalView]; 202*d9f75844SAndroid Build Coastguard Worker [self.rendererNV12Mock verify]; 203*d9f75844SAndroid Build Coastguard Worker [self.classMock verify]; 204*d9f75844SAndroid Build Coastguard Worker 205*d9f75844SAndroid Build Coastguard Worker // Recreate view. 206*d9f75844SAndroid Build Coastguard Worker realView = [[RTC_OBJC_TYPE(RTCMTLVideoView) alloc] initWithFrame:CGRectMake(0, 0, 640, 480)]; 207*d9f75844SAndroid Build Coastguard Worker OCMExpect([self.rendererNV12Mock drawFrame:self.frameMock]); 208*d9f75844SAndroid Build Coastguard Worker // View hould reinit renderer. 209*d9f75844SAndroid Build Coastguard Worker OCMExpect([self.classMock createNV12Renderer]).andReturn(self.rendererNV12Mock); 210*d9f75844SAndroid Build Coastguard Worker 211*d9f75844SAndroid Build Coastguard Worker [realView renderFrame:self.frameMock]; 212*d9f75844SAndroid Build Coastguard Worker [realView drawInMTKView:realView.metalView]; 213*d9f75844SAndroid Build Coastguard Worker [self.rendererNV12Mock verify]; 214*d9f75844SAndroid Build Coastguard Worker [self.classMock verify]; 215*d9f75844SAndroid Build Coastguard Worker} 216*d9f75844SAndroid Build Coastguard Worker 217*d9f75844SAndroid Build Coastguard Worker- (void)testDontRedrawOldFrame { 218*d9f75844SAndroid Build Coastguard Worker OCMStub([self.classMock isMetalAvailable]).andReturn(YES); 219*d9f75844SAndroid Build Coastguard Worker self.rendererNV12Mock = [self rendererMockWithSuccessfulSetup:YES]; 220*d9f75844SAndroid Build Coastguard Worker self.frameMock = [self frameMockWithCVPixelBuffer:YES]; 221*d9f75844SAndroid Build Coastguard Worker 222*d9f75844SAndroid Build Coastguard Worker OCMExpect([self.rendererNV12Mock drawFrame:self.frameMock]); 223*d9f75844SAndroid Build Coastguard Worker OCMExpect([self.classMock createNV12Renderer]).andReturn(self.rendererNV12Mock); 224*d9f75844SAndroid Build Coastguard Worker [[self.classMock reject] createI420Renderer]; 225*d9f75844SAndroid Build Coastguard Worker 226*d9f75844SAndroid Build Coastguard Worker RTC_OBJC_TYPE(RTCMTLVideoView) *realView = 227*d9f75844SAndroid Build Coastguard Worker [[RTC_OBJC_TYPE(RTCMTLVideoView) alloc] initWithFrame:CGRectMake(0, 0, 640, 480)]; 228*d9f75844SAndroid Build Coastguard Worker [realView renderFrame:self.frameMock]; 229*d9f75844SAndroid Build Coastguard Worker [realView drawInMTKView:realView.metalView]; 230*d9f75844SAndroid Build Coastguard Worker 231*d9f75844SAndroid Build Coastguard Worker [self.rendererNV12Mock verify]; 232*d9f75844SAndroid Build Coastguard Worker [self.classMock verify]; 233*d9f75844SAndroid Build Coastguard Worker 234*d9f75844SAndroid Build Coastguard Worker [[self.rendererNV12Mock reject] drawFrame:[OCMArg any]]; 235*d9f75844SAndroid Build Coastguard Worker 236*d9f75844SAndroid Build Coastguard Worker [realView renderFrame:self.frameMock]; 237*d9f75844SAndroid Build Coastguard Worker [realView drawInMTKView:realView.metalView]; 238*d9f75844SAndroid Build Coastguard Worker 239*d9f75844SAndroid Build Coastguard Worker [self.rendererNV12Mock verify]; 240*d9f75844SAndroid Build Coastguard Worker} 241*d9f75844SAndroid Build Coastguard Worker 242*d9f75844SAndroid Build Coastguard Worker- (void)testDoDrawNewFrame { 243*d9f75844SAndroid Build Coastguard Worker OCMStub([self.classMock isMetalAvailable]).andReturn(YES); 244*d9f75844SAndroid Build Coastguard Worker self.rendererNV12Mock = [self rendererMockWithSuccessfulSetup:YES]; 245*d9f75844SAndroid Build Coastguard Worker self.frameMock = [self frameMockWithCVPixelBuffer:YES]; 246*d9f75844SAndroid Build Coastguard Worker 247*d9f75844SAndroid Build Coastguard Worker OCMExpect([self.rendererNV12Mock drawFrame:self.frameMock]); 248*d9f75844SAndroid Build Coastguard Worker OCMExpect([self.classMock createNV12Renderer]).andReturn(self.rendererNV12Mock); 249*d9f75844SAndroid Build Coastguard Worker [[self.classMock reject] createI420Renderer]; 250*d9f75844SAndroid Build Coastguard Worker 251*d9f75844SAndroid Build Coastguard Worker RTC_OBJC_TYPE(RTCMTLVideoView) *realView = 252*d9f75844SAndroid Build Coastguard Worker [[RTC_OBJC_TYPE(RTCMTLVideoView) alloc] initWithFrame:CGRectMake(0, 0, 640, 480)]; 253*d9f75844SAndroid Build Coastguard Worker [realView renderFrame:self.frameMock]; 254*d9f75844SAndroid Build Coastguard Worker [realView drawInMTKView:realView.metalView]; 255*d9f75844SAndroid Build Coastguard Worker 256*d9f75844SAndroid Build Coastguard Worker [self.rendererNV12Mock verify]; 257*d9f75844SAndroid Build Coastguard Worker [self.classMock verify]; 258*d9f75844SAndroid Build Coastguard Worker 259*d9f75844SAndroid Build Coastguard Worker // Get new frame. 260*d9f75844SAndroid Build Coastguard Worker self.frameMock = [self frameMockWithCVPixelBuffer:YES]; 261*d9f75844SAndroid Build Coastguard Worker OCMExpect([self.rendererNV12Mock drawFrame:self.frameMock]); 262*d9f75844SAndroid Build Coastguard Worker 263*d9f75844SAndroid Build Coastguard Worker [realView renderFrame:self.frameMock]; 264*d9f75844SAndroid Build Coastguard Worker [realView drawInMTKView:realView.metalView]; 265*d9f75844SAndroid Build Coastguard Worker 266*d9f75844SAndroid Build Coastguard Worker [self.rendererNV12Mock verify]; 267*d9f75844SAndroid Build Coastguard Worker} 268*d9f75844SAndroid Build Coastguard Worker 269*d9f75844SAndroid Build Coastguard Worker- (void)testReportsSizeChangesToDelegate { 270*d9f75844SAndroid Build Coastguard Worker OCMStub([self.classMock isMetalAvailable]).andReturn(YES); 271*d9f75844SAndroid Build Coastguard Worker 272*d9f75844SAndroid Build Coastguard Worker id delegateMock = OCMProtocolMock(@protocol(RTC_OBJC_TYPE(RTCVideoViewDelegate))); 273*d9f75844SAndroid Build Coastguard Worker CGSize size = CGSizeMake(640, 480); 274*d9f75844SAndroid Build Coastguard Worker OCMExpect([delegateMock videoView:[OCMArg any] didChangeVideoSize:size]); 275*d9f75844SAndroid Build Coastguard Worker 276*d9f75844SAndroid Build Coastguard Worker RTC_OBJC_TYPE(RTCMTLVideoView) *realView = 277*d9f75844SAndroid Build Coastguard Worker [[RTC_OBJC_TYPE(RTCMTLVideoView) alloc] initWithFrame:CGRectMake(0, 0, 640, 480)]; 278*d9f75844SAndroid Build Coastguard Worker realView.delegate = delegateMock; 279*d9f75844SAndroid Build Coastguard Worker [realView setSize:size]; 280*d9f75844SAndroid Build Coastguard Worker 281*d9f75844SAndroid Build Coastguard Worker // Delegate method is invoked with a dispatch_async. 282*d9f75844SAndroid Build Coastguard Worker OCMVerifyAllWithDelay(delegateMock, 1); 283*d9f75844SAndroid Build Coastguard Worker} 284*d9f75844SAndroid Build Coastguard Worker 285*d9f75844SAndroid Build Coastguard Worker- (void)testSetContentMode { 286*d9f75844SAndroid Build Coastguard Worker OCMStub([self.classMock isMetalAvailable]).andReturn(YES); 287*d9f75844SAndroid Build Coastguard Worker id metalKitView = OCMClassMock([MTKView class]); 288*d9f75844SAndroid Build Coastguard Worker [[[[self.classMock stub] ignoringNonObjectArgs] andReturn:metalKitView] 289*d9f75844SAndroid Build Coastguard Worker createMetalView:CGRectZero]; 290*d9f75844SAndroid Build Coastguard Worker OCMExpect([metalKitView setContentMode:UIViewContentModeScaleAspectFill]); 291*d9f75844SAndroid Build Coastguard Worker 292*d9f75844SAndroid Build Coastguard Worker RTC_OBJC_TYPE(RTCMTLVideoView) *realView = [[RTC_OBJC_TYPE(RTCMTLVideoView) alloc] init]; 293*d9f75844SAndroid Build Coastguard Worker [realView setVideoContentMode:UIViewContentModeScaleAspectFill]; 294*d9f75844SAndroid Build Coastguard Worker 295*d9f75844SAndroid Build Coastguard Worker OCMVerify(metalKitView); 296*d9f75844SAndroid Build Coastguard Worker} 297*d9f75844SAndroid Build Coastguard Worker 298*d9f75844SAndroid Build Coastguard Worker@end 299