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" | |
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 SupportedCricketVideoFormat() { | |
magjed_webrtc
2016/11/29 13:34:01
It should be possible to just have a constant for
daniela-webrtc
2016/11/29 16:13:57
Done.
| |
26 return cricket::VideoFormat(kFormatWidth, kFormatHeight, | |
27 cricket::VideoFormat::FpsToInterval(kFramerate), | |
28 cricket::FOURCC_NV12); | |
29 } | |
30 | |
31 // Mock class for AVCaptureDeviceFormat. | |
32 // Custom implementation needed because OCMock cannot handle the | |
33 // CMVideoDescriptionRef mocking. | |
34 @interface AVCaptureDeviceFormatMock : NSObject { | |
35 CMVideoFormatDescriptionRef _format; | |
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]; | |
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]; | |
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 class AVFormatMapperTest : public ::testing::Test { | |
113 protected: | |
114 void testSuportedCricketFormatsWithInvalidFramerateFormats() { | |
115 // given | |
116 id mockDevice = [OCMockObject mockForClass:[AVCaptureDevice class]]; | |
117 | |
118 // Valid media subtype, invalid framerate | |
119 AVCaptureDeviceFormatMock* mockOne = | |
120 [AVCaptureDeviceFormatMock invalidFpsFormat]; | |
121 // Valid media subtype, valid framerate | |
122 AVCaptureDeviceFormatMock* mockTwo = | |
123 [AVCaptureDeviceFormatMock validFormat]; | |
124 | |
125 [[[mockDevice stub] andReturn:@[ mockOne, mockTwo ]] formats]; | |
126 | |
127 cricket::VideoFormat expected = SupportedCricketVideoFormat(); | |
128 | |
129 // when | |
130 std::set<cricket::VideoFormat> result = | |
131 webrtc::GetSupportedVideoFormatsForDevice(mockDevice); | |
132 | |
133 // then | |
134 EXPECT_EQ(1, result.size()); | |
135 EXPECT_EQ(1u, result.count(expected)); | |
136 } | |
137 | |
138 void testSuportedCricketFormatsWithInvalidMediaSubtypeFormats() { | |
139 // given | |
140 id mockDevice = [OCMockObject mockForClass:[AVCaptureDevice class]]; | |
141 | |
142 // Invalid media subtype, valid framerate | |
143 AVCaptureDeviceFormatMock* mockOne = | |
144 [AVCaptureDeviceFormatMock invalidMediaSubtypeFormat]; | |
145 // Valid media subtype, valid framerate | |
146 AVCaptureDeviceFormatMock* mockTwo = | |
147 [AVCaptureDeviceFormatMock validFormat]; | |
148 | |
149 [[[mockDevice stub] andReturn:@[ mockOne, mockTwo ]] formats]; | |
150 | |
151 cricket::VideoFormat expected = SupportedCricketVideoFormat(); | |
152 | |
153 // when | |
154 std::set<cricket::VideoFormat> result = | |
155 webrtc::GetSupportedVideoFormatsForDevice(mockDevice); | |
156 | |
157 // then | |
158 EXPECT_EQ(1, result.size()); | |
159 EXPECT_EQ(1u, result.count(expected)); | |
160 } | |
161 | |
162 void testSuportedCricketFormats() { | |
163 // given | |
164 id mockDevice = [OCMockObject mockForClass:[AVCaptureDevice class]]; | |
165 | |
166 // valid media subtype, valid framerate | |
167 AVCaptureDeviceFormatMock* mockOne = | |
168 [AVCaptureDeviceFormatMock validFormat]; | |
169 [[[mockDevice stub] andReturn:@[ mockOne ]] formats]; | |
170 | |
171 cricket::VideoFormat expectedFormat = SupportedCricketVideoFormat(); | |
172 | |
173 // when | |
174 std::set<cricket::VideoFormat> result = | |
175 webrtc::GetSupportedVideoFormatsForDevice(mockDevice); | |
176 | |
177 // then | |
178 EXPECT_EQ(1, result.size()); | |
179 | |
180 // make sure the set has the expected format | |
181 EXPECT_EQ(1u, result.count(expectedFormat)); | |
182 } | |
183 | |
184 void testAVFormatForCricketFormat() { | |
magjed_webrtc
2016/11/29 13:34:01
nit: I would like to rename this test to something
daniela-webrtc
2016/11/29 16:13:57
Done.
| |
185 // given | |
186 id mockDevice = [OCMockObject mockForClass:[AVCaptureDevice class]]; | |
187 | |
188 // valid media subtype, valid framerate | |
189 AVCaptureDeviceFormatMock* mockOne = [[AVCaptureDeviceFormatMock alloc] | |
190 initWithMediaSubtype:kCVPixelFormatType_420YpCbCr8BiPlanarFullRange | |
191 minFps:0.0 | |
192 maxFps:30.0]; | |
193 | |
194 // valid media subtype, valid framerate. | |
195 // This media subtype should be the preffered one. | |
196 AVCaptureDeviceFormatMock* mockTwo = [[AVCaptureDeviceFormatMock alloc] | |
197 initWithMediaSubtype:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange | |
198 minFps:0.0 | |
199 maxFps:30.0]; | |
200 | |
201 [[[mockDevice stub] andReturnValue:@(YES)] | |
202 lockForConfiguration:[OCMArg setTo:nil]]; | |
203 [[mockDevice stub] unlockForConfiguration]; | |
204 | |
205 [[[mockDevice stub] andReturn:@[ mockOne, mockTwo ]] formats]; | |
206 | |
207 cricket::VideoFormat inputFormat = SupportedCricketVideoFormat(); | |
208 | |
209 // to verify | |
210 [[mockDevice expect] setActiveFormat:(AVCaptureDeviceFormat*)mockTwo]; | |
211 [[mockDevice expect] | |
212 setActiveVideoMinFrameDuration:CMTimeMake(1, kFramerate)]; | |
213 | |
214 // when | |
215 bool resultFormat = | |
216 webrtc::SetFormatForCaptureDevice(mockDevice, nil, inputFormat); | |
217 | |
218 // then | |
219 EXPECT_TRUE(resultFormat); | |
220 [mockDevice verify]; | |
221 } | |
222 | |
223 void testSetFormatWhenDeviceCannotLock() { | |
224 // given | |
225 id mockDevice = [OCMockObject mockForClass:[AVCaptureDevice class]]; | |
226 [[[mockDevice stub] andReturnValue:@(NO)] | |
227 lockForConfiguration:[OCMArg setTo:nil]]; | |
228 | |
229 [[[mockDevice stub] andReturn:@[]] formats]; | |
230 | |
231 // when | |
232 bool resultFormat = webrtc::SetFormatForCaptureDevice( | |
233 mockDevice, nil, cricket::VideoFormat()); | |
234 | |
235 // then | |
236 EXPECT_FALSE(resultFormat); | |
237 } | |
238 | |
239 void testSetFormatWhenFormatIsIncompatible() { | |
240 // given | |
241 id mockDevice = [OCMockObject mockForClass:[AVCaptureDevice class]]; | |
242 [[[mockDevice stub] andReturn:@[]] formats]; | |
243 [[[mockDevice stub] andReturnValue:@(YES)] | |
244 lockForConfiguration:[OCMArg setTo:nil]]; | |
245 | |
246 NSException* exception = | |
247 [NSException exceptionWithName:@"Test exception" | |
248 reason:@"Raised from unit tests" | |
249 userInfo:nil]; | |
250 [[[mockDevice stub] andThrow:exception] setActiveFormat:[OCMArg any]]; | |
251 [[mockDevice expect] unlockForConfiguration]; | |
252 | |
253 // when | |
254 bool resultFormat = webrtc::SetFormatForCaptureDevice( | |
255 mockDevice, nil, cricket::VideoFormat()); | |
256 | |
257 // then | |
258 EXPECT_FALSE(resultFormat); | |
259 [mockDevice verify]; | |
260 } | |
261 }; | |
262 | |
263 TEST_F(AVFormatMapperTest, SuportedCricketFormatsWithInvalidFramerateFormats) { | |
264 testSuportedCricketFormatsWithInvalidFramerateFormats(); | |
265 } | |
266 | |
267 TEST_F(AVFormatMapperTest, SuportedCricketFormatsWithInvalidFormats) { | |
268 testSuportedCricketFormatsWithInvalidMediaSubtypeFormats(); | |
269 } | |
270 | |
271 TEST_F(AVFormatMapperTest, SuportedCricketFormats) { | |
272 testSuportedCricketFormats(); | |
273 } | |
274 | |
275 TEST_F(AVFormatMapperTest, AVFormatForCricketFormat) { | |
276 testAVFormatForCricketFormat(); | |
277 } | |
278 | |
279 TEST_F(AVFormatMapperTest, SetFormatWhenDeviceCannotLock) { | |
280 testSetFormatWhenDeviceCannotLock(); | |
281 } | |
282 | |
283 TEST_F(AVFormatMapperTest, SetFormatWhenFormatIsIncompatible) { | |
284 testSetFormatWhenFormatIsIncompatible(); | |
285 } | |
OLD | NEW |