OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2016 The WebRTC project authors. All Rights Reserved. | |
3 * | |
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 | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 #import <Foundation/Foundation.h> | |
12 #import <OCMock/OCMock.h> | |
13 #include "avfoundationformatmapper.h" | |
tkchin_webrtc
2016/12/02 21:12:57
nit: include frameworks first, and then only inclu
daniela-webrtc
2016/12/05 12:55:51
Done.
| |
14 #include "webrtc/base/gunit.h" | |
15 | |
16 // Width and height don't play any role so lets use predefined values throughout | |
17 // the tests. | |
18 static const int kFormatWidth = 789; | |
19 static const int kFormatHeight = 987; | |
20 | |
21 // Hardcoded framrate to be used throughout the tests. | |
22 static const int kFramerate = 30; | |
23 | |
24 // Same width and height is used so it's ok to expect same cricket::VideoFormat | |
25 static cricket::VideoFormat expectedFormat = | |
26 cricket::VideoFormat(kFormatWidth, | |
27 kFormatHeight, | |
28 cricket::VideoFormat::FpsToInterval(kFramerate), | |
29 cricket::FOURCC_NV12); | |
30 | |
31 // Mock class for AVCaptureDeviceFormat. | |
32 // Custom implementation needed because OCMock cannot handle the | |
33 // CMVideoDescriptionRef mocking. | |
tkchin_webrtc
2016/12/02 21:12:57
ooc why not? It should just be a pointer type and
daniela-webrtc
2016/12/05 12:55:51
Yes, proper release can be done this way and that'
| |
34 @interface AVCaptureDeviceFormatMock : NSObject { | |
35 CMVideoFormatDescriptionRef _format; | |
tkchin_webrtc
2016/12/02 21:12:57
nit: declare these in the @implementation, or othe
daniela-webrtc
2016/12/05 12:55:51
Done.
| |
36 OCMockObject *_rangeMock; | |
37 } | |
38 | |
39 - (instancetype)initWithMediaSubtype:(FourCharCode)subtype | |
40 minFps:(float)minFps | |
41 maxFps:(float)maxFps; | |
42 + (instancetype)validFormat; | |
43 + (instancetype)invalidFpsFormat; | |
44 + (instancetype)invalidMediaSubtypeFormat; | |
45 | |
46 @end | |
47 | |
48 @implementation AVCaptureDeviceFormatMock | |
49 | |
50 - (instancetype)initWithMediaSubtype:(FourCharCode)subtype | |
51 minFps:(float)minFps | |
52 maxFps:(float)maxFps { | |
53 if (self = [super init]) { | |
54 CMVideoFormatDescriptionCreate(nil, subtype, kFormatWidth, kFormatHeight, | |
55 nil, &_format); | |
56 // We can use OCMock for the range. | |
57 _rangeMock = [OCMockObject mockForClass:[AVFrameRateRange class]]; | |
58 [[[_rangeMock stub] andReturnValue:@(minFps)] minFrameRate]; | |
tkchin_webrtc
2016/12/02 21:12:57
This is old OCMock format. Use OCMock3 if possible
daniela-webrtc
2016/12/05 12:55:51
The OCMock dependency is not updated to OCMock 3 y
| |
59 [[[_rangeMock stub] andReturnValue:@(maxFps)] maxFrameRate]; | |
60 } | |
61 | |
62 return self; | |
63 } | |
64 | |
65 + (instancetype)validFormat { | |
66 AVCaptureDeviceFormatMock *instance = [[AVCaptureDeviceFormatMock alloc] | |
67 initWithMediaSubtype:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange | |
68 minFps:0.0 | |
69 maxFps:30.0]; | |
70 return instance; | |
71 } | |
72 | |
73 + (instancetype)invalidFpsFormat { | |
74 AVCaptureDeviceFormatMock *instance = [[AVCaptureDeviceFormatMock alloc] | |
75 initWithMediaSubtype:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange | |
76 minFps:0.0 | |
77 maxFps:22.0]; | |
78 return instance; | |
79 } | |
80 | |
81 + (instancetype)invalidMediaSubtypeFormat { | |
82 AVCaptureDeviceFormatMock *instance = [[AVCaptureDeviceFormatMock alloc] | |
83 initWithMediaSubtype:kCVPixelFormatType_420YpCbCr8Planar | |
84 minFps:0.0 | |
85 maxFps:60.0]; | |
86 return instance; | |
87 } | |
88 | |
89 - (void)dealloc { | |
90 if (_rangeMock != nil) { | |
91 [_rangeMock dealloc]; | |
tkchin_webrtc
2016/12/02 21:12:57
I don't recall these needing explicit dealloc. The
daniela-webrtc
2016/12/05 12:55:51
You are right. This is not needed.
| |
92 _rangeMock = nil; | |
93 } | |
94 if (_format != nil) { | |
95 CFRelease(_format); | |
96 _format = nil; | |
97 } | |
98 [super dealloc]; | |
99 } | |
100 | |
101 // Redefinition of AVCaptureDevice methods we want to mock. | |
102 - (CMVideoFormatDescriptionRef)formatDescription { | |
103 return _format; | |
104 } | |
105 | |
106 - (NSArray *)videoSupportedFrameRateRanges { | |
107 return @[ _rangeMock ]; | |
108 } | |
109 | |
110 @end | |
111 | |
112 TEST(AVFormatMapperTest, SuportedCricketFormatsWithInvalidFramerateFormats) { | |
tkchin_webrtc
2016/12/02 21:12:57
xctest still not possible?
daniela-webrtc
2016/12/05 12:55:51
Not yet :(
| |
113 // given | |
114 id mockDevice = [OCMockObject mockForClass:[AVCaptureDevice class]]; | |
115 | |
116 // Valid media subtype, invalid framerate | |
117 AVCaptureDeviceFormatMock* mock = | |
118 [AVCaptureDeviceFormatMock invalidFpsFormat]; | |
119 | |
120 [[[mockDevice stub] andReturn:@[ mock ]] formats]; | |
121 | |
122 // when | |
123 std::set<cricket::VideoFormat> result = | |
124 webrtc::GetSupportedVideoFormatsForDevice(mockDevice); | |
125 | |
126 // then | |
127 EXPECT_TRUE(result.empty()); | |
128 } | |
129 | |
130 TEST(AVFormatMapperTest, SuportedCricketFormatsWithInvalidFormats) { | |
131 // given | |
132 id mockDevice = [OCMockObject mockForClass:[AVCaptureDevice class]]; | |
133 | |
134 // Invalid media subtype, valid framerate | |
135 AVCaptureDeviceFormatMock* mock = | |
136 [AVCaptureDeviceFormatMock invalidMediaSubtypeFormat]; | |
137 | |
138 [[[mockDevice stub] andReturn:@[ mock ]] formats]; | |
139 | |
140 // when | |
141 std::set<cricket::VideoFormat> result = | |
142 webrtc::GetSupportedVideoFormatsForDevice(mockDevice); | |
143 | |
144 // then | |
145 EXPECT_TRUE(result.empty()); | |
146 } | |
147 | |
148 TEST(AVFormatMapperTest, SuportedCricketFormats) { | |
149 // given | |
150 id mockDevice = [OCMockObject mockForClass:[AVCaptureDevice class]]; | |
151 | |
152 // valid media subtype, valid framerate | |
153 AVCaptureDeviceFormatMock* mock = [AVCaptureDeviceFormatMock validFormat]; | |
154 [[[mockDevice stub] andReturn:@[ mock ]] formats]; | |
155 | |
156 // when | |
157 std::set<cricket::VideoFormat> result = | |
158 webrtc::GetSupportedVideoFormatsForDevice(mockDevice); | |
159 | |
160 // then | |
161 EXPECT_EQ(1, result.size()); | |
162 | |
163 // make sure the set has the expected format | |
164 EXPECT_EQ(expectedFormat, *result.begin()); | |
165 } | |
166 | |
167 TEST(AVFormatMapperTest, MediaSubtypePreference) { | |
168 // given | |
169 id mockDevice = [OCMockObject mockForClass:[AVCaptureDevice class]]; | |
170 | |
171 // valid media subtype, valid framerate | |
172 AVCaptureDeviceFormatMock* mockOne = [[AVCaptureDeviceFormatMock alloc] | |
173 initWithMediaSubtype:kCVPixelFormatType_420YpCbCr8BiPlanarFullRange | |
174 minFps:0.0 | |
175 maxFps:30.0]; | |
176 | |
177 // valid media subtype, valid framerate. | |
178 // This media subtype should be the preffered one. | |
179 AVCaptureDeviceFormatMock* mockTwo = [[AVCaptureDeviceFormatMock alloc] | |
180 initWithMediaSubtype:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange | |
181 minFps:0.0 | |
182 maxFps:30.0]; | |
183 | |
184 [[[mockDevice stub] andReturnValue:@(YES)] | |
185 lockForConfiguration:[OCMArg setTo:nil]]; | |
186 [[mockDevice stub] unlockForConfiguration]; | |
187 | |
188 [[[mockDevice stub] andReturn:@[ mockOne, mockTwo ]] formats]; | |
189 | |
190 // to verify | |
191 [[mockDevice expect] setActiveFormat:(AVCaptureDeviceFormat*)mockTwo]; | |
192 [[mockDevice expect] | |
193 setActiveVideoMinFrameDuration:CMTimeMake(1, kFramerate)]; | |
194 | |
195 // when | |
196 bool resultFormat = | |
197 webrtc::SetFormatForCaptureDevice(mockDevice, nil, expectedFormat); | |
198 | |
199 // then | |
200 EXPECT_TRUE(resultFormat); | |
201 [mockDevice verify]; | |
202 } | |
203 | |
204 TEST(AVFormatMapperTest, SetFormatWhenDeviceCannotLock) { | |
205 // given | |
206 id mockDevice = [OCMockObject mockForClass:[AVCaptureDevice class]]; | |
207 [[[mockDevice stub] andReturnValue:@(NO)] | |
208 lockForConfiguration:[OCMArg setTo:nil]]; | |
209 | |
210 [[[mockDevice stub] andReturn:@[]] formats]; | |
211 | |
212 // when | |
213 bool resultFormat = webrtc::SetFormatForCaptureDevice(mockDevice, nil, | |
214 cricket::VideoFormat()); | |
215 | |
216 // then | |
217 EXPECT_FALSE(resultFormat); | |
218 } | |
219 | |
220 TEST(AVFormatMapperTest, SetFormatWhenFormatIsIncompatible) { | |
221 // given | |
222 id mockDevice = [OCMockObject mockForClass:[AVCaptureDevice class]]; | |
223 [[[mockDevice stub] andReturn:@[]] formats]; | |
224 [[[mockDevice stub] andReturnValue:@(YES)] | |
225 lockForConfiguration:[OCMArg setTo:nil]]; | |
226 | |
227 NSException* exception = | |
228 [NSException exceptionWithName:@"Test exception" | |
229 reason:@"Raised from unit tests" | |
230 userInfo:nil]; | |
231 [[[mockDevice stub] andThrow:exception] setActiveFormat:[OCMArg any]]; | |
232 [[mockDevice expect] unlockForConfiguration]; | |
233 | |
234 // when | |
235 bool resultFormat = webrtc::SetFormatForCaptureDevice(mockDevice, nil, | |
236 cricket::VideoFormat()); | |
237 | |
238 // then | |
239 EXPECT_FALSE(resultFormat); | |
240 [mockDevice verify]; | |
241 } | |
OLD | NEW |