| 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 <Foundation/Foundation.h> | 11 #import <Foundation/Foundation.h> |
| 12 #import <OCMock/OCMock.h> | 12 #import <OCMock/OCMock.h> |
| 13 | 13 |
| 14 #include "webrtc/base/gunit.h" | 14 #include "webrtc/base/gunit.h" |
| 15 | 15 |
| 16 #include <Metal/RTCMTLNV12Renderer.h> | 16 #include <Metal/RTCMTLNV12Renderer.h> |
| 17 #include <WebRTC/RTCMTLVideoView.h> | 17 #include <WebRTC/RTCMTLVideoView.h> |
| 18 | 18 |
| 19 // Extension of RTCMTLVideoView for testing purposes. | 19 // Extension of RTCMTLVideoView for testing purposes. |
| 20 @interface RTCMTLVideoView (Testing) | 20 @interface RTCMTLVideoView (Testing) |
| 21 @property(nonatomic, strong) id<RTCMTLRenderer> renderer; | 21 @property(nonatomic, strong) id<RTCMTLRenderer> rendererI420; |
| 22 @property(nonatomic, strong) id<RTCMTLRenderer> rendererNV12; |
| 22 @property(nonatomic, strong) UIView* metalView; | 23 @property(nonatomic, strong) UIView* metalView; |
| 23 @property(atomic, strong) RTCVideoFrame* videoFrame; | 24 @property(atomic, strong) RTCVideoFrame* videoFrame; |
| 24 | 25 |
| 25 + (BOOL)isMetalAvailable; | 26 + (BOOL)isMetalAvailable; |
| 26 + (UIView*)createMetalView:(CGRect)frame; | 27 + (UIView*)createMetalView:(CGRect)frame; |
| 27 + (id<RTCMTLRenderer>)createMetalRenderer; | 28 + (id<RTCMTLRenderer>)createNV12Renderer; |
| 29 + (id<RTCMTLRenderer>)createI420Renderer; |
| 28 - (void)drawInMTKView:(id)view; | 30 - (void)drawInMTKView:(id)view; |
| 29 @end | 31 @end |
| 30 | 32 |
| 31 @interface RTCMTLVideoViewTests : NSObject | 33 @interface RTCMTLVideoViewTests : NSObject |
| 32 @property(nonatomic, strong) id classMock; | 34 @property(nonatomic, strong) id classMock; |
| 33 @property(nonatomic, strong) id metalViewMock; | 35 @property(nonatomic, strong) id metalViewMock; |
| 34 @property(nonatomic, strong) id rendererMock; | 36 @property(nonatomic, strong) id rendererNV12Mock; |
| 37 @property(nonatomic, strong) id rendererI420Mock; |
| 35 @end | 38 @end |
| 36 | 39 |
| 37 @implementation RTCMTLVideoViewTests | 40 @implementation RTCMTLVideoViewTests |
| 38 | 41 |
| 39 @synthesize classMock = _classMock; | 42 @synthesize classMock = _classMock; |
| 40 @synthesize metalViewMock = _metalViewMock; | 43 @synthesize metalViewMock = _metalViewMock; |
| 41 @synthesize rendererMock = _rendererMock; | 44 @synthesize rendererNV12Mock = _rendererNV12Mock; |
| 45 @synthesize rendererI420Mock = _rendererI420Mock; |
| 42 | 46 |
| 43 - (void)setup { | 47 - (void)setup { |
| 44 self.classMock = OCMClassMock([RTCMTLVideoView class]); | 48 self.classMock = OCMClassMock([RTCMTLVideoView class]); |
| 45 | 49 |
| 46 self.metalViewMock = OCMClassMock([RTCMTLVideoViewTests class]); | 50 self.metalViewMock = OCMClassMock([RTCMTLVideoViewTests class]); |
| 47 // NOTE: OCMock doesen't provide modern syntax for -ignoringNonObjectArgs. | 51 // NOTE: OCMock doesen't provide modern syntax for -ignoringNonObjectArgs. |
| 48 [[[[self.classMock stub] ignoringNonObjectArgs] andReturn:self.metalViewMock] | 52 [[[[self.classMock stub] ignoringNonObjectArgs] andReturn:self.metalViewMock] |
| 49 createMetalView:CGRectZero]; | 53 createMetalView:CGRectZero]; |
| 50 | 54 |
| 51 self.rendererMock = OCMProtocolMock(@protocol(RTCMTLRenderer)); | 55 self.rendererNV12Mock = OCMProtocolMock(@protocol(RTCMTLRenderer)); |
| 52 OCMStub([self.classMock createMetalRenderer]).andReturn(self.rendererMock); | 56 OCMStub([self.classMock createI420Renderer]).andReturn(self.rendererI420Mock); |
| 57 self.rendererI420Mock = OCMProtocolMock(@protocol(RTCMTLRenderer)); |
| 58 OCMStub([self.classMock createNV12Renderer]).andReturn(self.rendererNV12Mock); |
| 53 } | 59 } |
| 54 | 60 |
| 55 - (void)tearDown { | 61 - (void)tearDown { |
| 56 [self.classMock stopMocking]; | 62 [self.classMock stopMocking]; |
| 57 [self.rendererMock stopMocking]; | 63 [self.rendererI420Mock stopMocking]; |
| 64 [self.rendererNV12Mock stopMocking]; |
| 58 [self.metalViewMock stopMocking]; | 65 [self.metalViewMock stopMocking]; |
| 59 self.classMock = nil; | 66 self.classMock = nil; |
| 60 self.rendererMock = nil; | 67 self.rendererI420Mock = nil; |
| 68 self.rendererNV12Mock = nil; |
| 61 self.metalViewMock = nil; | 69 self.metalViewMock = nil; |
| 62 } | 70 } |
| 63 | 71 |
| 64 - (void)testMetalConfigureNotExecuted { | 72 - (void)testMetalConfigureNotExecuted { |
| 65 // when | 73 // when |
| 66 OCMStub([self.classMock isMetalAvailable]).andReturn(NO); | 74 OCMStub([self.classMock isMetalAvailable]).andReturn(NO); |
| 67 RTCMTLVideoView *realView = [[RTCMTLVideoView alloc] init]; | 75 RTCMTLVideoView *realView = [[RTCMTLVideoView alloc] init]; |
| 68 | 76 |
| 69 // then | 77 // then |
| 70 EXPECT_TRUE(realView.renderer == nil); | 78 EXPECT_EQ(realView.rendererI420, nil); |
| 71 EXPECT_TRUE(realView.metalView == nil); | 79 EXPECT_EQ(realView.rendererNV12, nil); |
| 80 EXPECT_EQ(realView.metalView, nil); |
| 72 } | 81 } |
| 73 | 82 |
| 74 - (void)testMetalConfigureExecuted { | 83 - (void)testMetalConfigureExecuted { |
| 75 // given | 84 // given |
| 76 OCMStub([self.classMock isMetalAvailable]).andReturn(YES); | 85 OCMStub([self.classMock isMetalAvailable]).andReturn(YES); |
| 77 OCMStub([self.rendererMock addRenderingDestination:self.metalViewMock]) | 86 OCMStub([self.rendererNV12Mock addRenderingDestination:self.metalViewMock]).an
dReturn(NO); |
| 78 .andReturn(NO); | 87 OCMStub([self.rendererI420Mock addRenderingDestination:self.metalViewMock]).an
dReturn(NO); |
| 79 | 88 |
| 80 // when | 89 // when |
| 81 RTCMTLVideoView *realView = [[RTCMTLVideoView alloc] init]; | 90 RTCMTLVideoView *realView = [[RTCMTLVideoView alloc] init]; |
| 82 | 91 |
| 83 // then | 92 // then |
| 84 EXPECT_TRUE(realView.renderer == nil); | 93 EXPECT_EQ(realView.rendererI420, nil); |
| 94 EXPECT_EQ(realView.rendererNV12, nil); |
| 85 EXPECT_TRUE(realView.metalView != nil); | 95 EXPECT_TRUE(realView.metalView != nil); |
| 86 } | 96 } |
| 87 | 97 |
| 88 - (void)testMetalDrawCallback { | |
| 89 // given | |
| 90 OCMStub([self.classMock isMetalAvailable]).andReturn(NO); | |
| 91 OCMExpect([self.rendererMock drawFrame:[OCMArg any]]); | |
| 92 RTCMTLVideoView *realView = [[RTCMTLVideoView alloc] init]; | |
| 93 realView.metalView = self.metalViewMock; | |
| 94 realView.renderer = self.rendererMock; | |
| 95 | |
| 96 // when | |
| 97 [realView drawInMTKView:self.metalViewMock]; | |
| 98 | |
| 99 // then | |
| 100 [self.rendererMock verify]; | |
| 101 } | |
| 102 | |
| 103 - (void)testRTCVideoRenderNilFrameCallback { | 98 - (void)testRTCVideoRenderNilFrameCallback { |
| 104 // given | 99 // given |
| 105 OCMStub([self.classMock isMetalAvailable]).andReturn(NO); | |
| 106 RTCMTLVideoView *realView = [[RTCMTLVideoView alloc] init]; | 100 RTCMTLVideoView *realView = [[RTCMTLVideoView alloc] init]; |
| 107 | 101 |
| 108 // when | 102 // when |
| 109 [realView renderFrame:nil]; | 103 [realView renderFrame:nil]; |
| 110 | 104 |
| 111 // then | 105 // then |
| 112 EXPECT_TRUE(realView.videoFrame == nil); | 106 EXPECT_TRUE(realView.videoFrame == nil); |
| 113 } | 107 } |
| 114 | 108 |
| 115 - (void)testRTCVideoRenderFrameCallback { | 109 - (void)testRTCVideoRenderFrameCallbackI420 { |
| 116 // given | 110 // given |
| 117 OCMStub([self.classMock isMetalAvailable]).andReturn(NO); | |
| 118 RTCMTLVideoView *realView = [[RTCMTLVideoView alloc] init]; | 111 RTCMTLVideoView *realView = [[RTCMTLVideoView alloc] init]; |
| 119 id frame = OCMClassMock([RTCVideoFrame class]); | 112 id frame = OCMClassMock([RTCVideoFrame class]); |
| 113 |
| 120 realView.metalView = self.metalViewMock; | 114 realView.metalView = self.metalViewMock; |
| 121 realView.renderer = self.rendererMock; | 115 realView.rendererI420 = self.rendererI420Mock; |
| 122 OCMExpect([self.rendererMock drawFrame:frame]); | 116 OCMExpect([self.rendererI420Mock drawFrame:frame]); |
| 123 | 117 |
| 124 // when | 118 // when |
| 125 [realView renderFrame:frame]; | 119 [realView renderFrame:frame]; |
| 120 [realView drawInMTKView:self.metalViewMock]; |
| 121 |
| 122 // then |
| 123 EXPECT_EQ(realView.videoFrame, frame); |
| 124 [self.rendererI420Mock verify]; |
| 125 } |
| 126 |
| 127 - (void)testRTCVideoRenderFrameCallbackNV12 { |
| 128 // given |
| 129 RTCMTLVideoView *realView = [[RTCMTLVideoView alloc] init]; |
| 130 id frame = OCMClassMock([RTCVideoFrame class]); |
| 131 OCMStub([frame nativeHandle]).andReturn((CVPixelBufferRef)[OCMArg anyPointer])
; |
| 132 |
| 133 realView.metalView = self.metalViewMock; |
| 134 realView.rendererNV12 = self.rendererNV12Mock; |
| 135 OCMExpect([self.rendererNV12Mock drawFrame:frame]); |
| 136 |
| 137 // when |
| 138 [realView renderFrame:frame]; |
| 126 [realView drawInMTKView:self.metalViewMock]; | 139 [realView drawInMTKView:self.metalViewMock]; |
| 127 | 140 |
| 128 // then | 141 // then |
| 129 EXPECT_EQ(realView.videoFrame, frame); | 142 EXPECT_EQ(realView.videoFrame, frame); |
| 130 [self.rendererMock verify]; | 143 [self.rendererNV12Mock verify]; |
| 131 } | 144 } |
| 132 @end | 145 @end |
| 133 | 146 |
| 134 TEST(RTCMTLVideoViewTests, MetalConfigureNotExecuted) { | 147 TEST(RTCMTLVideoViewTests, MetalConfigureNotExecuted) { |
| 135 RTCMTLVideoViewTests *test = [[RTCMTLVideoViewTests alloc] init]; | 148 RTCMTLVideoViewTests *test = [[RTCMTLVideoViewTests alloc] init]; |
| 136 [test setup]; | 149 [test setup]; |
| 137 [test testMetalConfigureNotExecuted]; | 150 [test testMetalConfigureNotExecuted]; |
| 138 [test tearDown]; | 151 [test tearDown]; |
| 139 } | 152 } |
| 140 | 153 |
| 141 | 154 |
| 142 TEST(RTCMTLVideoViewTests, MetalConfigureExecuted) { | 155 TEST(RTCMTLVideoViewTests, MetalConfigureExecuted) { |
| 143 RTCMTLVideoViewTests *test = [[RTCMTLVideoViewTests alloc] init]; | 156 RTCMTLVideoViewTests *test = [[RTCMTLVideoViewTests alloc] init]; |
| 144 [test setup]; | 157 [test setup]; |
| 145 [test testMetalConfigureExecuted]; | 158 [test testMetalConfigureExecuted]; |
| 146 [test tearDown]; | 159 [test tearDown]; |
| 147 } | 160 } |
| 148 | 161 |
| 149 TEST(RTCMTLVideoViewTests, MetalDrawCallback) { | |
| 150 RTCMTLVideoViewTests *test = [[RTCMTLVideoViewTests alloc] init]; | |
| 151 [test setup]; | |
| 152 [test testMetalDrawCallback]; | |
| 153 [test tearDown]; | |
| 154 } | |
| 155 | |
| 156 TEST(RTCMTLVideoViewTests, RTCVideoRenderNilFrameCallback) { | 162 TEST(RTCMTLVideoViewTests, RTCVideoRenderNilFrameCallback) { |
| 157 RTCMTLVideoViewTests *test = [[RTCMTLVideoViewTests alloc] init]; | 163 RTCMTLVideoViewTests *test = [[RTCMTLVideoViewTests alloc] init]; |
| 158 [test setup]; | 164 [test setup]; |
| 159 [test testRTCVideoRenderNilFrameCallback]; | 165 [test testRTCVideoRenderNilFrameCallback]; |
| 160 [test tearDown]; | 166 [test tearDown]; |
| 161 } | 167 } |
| 162 | 168 |
| 163 TEST(RTCMTLVideoViewTests, RTCVideoRenderFrameCallback) { | 169 TEST(RTCMTLVideoViewTests, RTCVideoRenderFrameCallbackI420) { |
| 164 RTCMTLVideoViewTests *test = [[RTCMTLVideoViewTests alloc] init]; | 170 RTCMTLVideoViewTests *test = [[RTCMTLVideoViewTests alloc] init]; |
| 165 [test setup]; | 171 [test setup]; |
| 166 [test testRTCVideoRenderFrameCallback]; | 172 [test testRTCVideoRenderFrameCallbackI420]; |
| 167 [test tearDown]; | 173 [test tearDown]; |
| 168 } | 174 } |
| 175 |
| 176 TEST(RTCMTLVideoViewTests, RTCVideoRenderFrameCallbackNV12) { |
| 177 RTCMTLVideoViewTests *test = [[RTCMTLVideoViewTests alloc] init]; |
| 178 [test setup]; |
| 179 [test testRTCVideoRenderFrameCallbackNV12]; |
| 180 [test tearDown]; |
| 181 } |
| OLD | NEW |