blob: 4e949916b88c1b3fb2f4ed5ae8a4b2b8d18dbe1e [file] [log] [blame]
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -08001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_NDEBUG 0
18#define LOG_TAG "ZoomRatioMapperTest"
19
20#include <gtest/gtest.h>
21#include <utils/Errors.h>
22
23#include "../device3/ZoomRatioMapper.h"
24
25using namespace std;
26using namespace android;
27using namespace android::camera3;
28
29constexpr int kMaxAllowedPixelError = 1;
30constexpr float kMaxAllowedRatioError = 0.1;
31
32constexpr int32_t testActiveArraySize[] = {100, 100, 1024, 768};
33constexpr int32_t testPreCorrActiveArraySize[] = {90, 90, 1044, 788};
34
35constexpr int32_t testDefaultCropSize[][4] = {
36 {0, 0, 1024, 768}, // active array default crop
37 {0, 0, 1044, 788}, // preCorrection active array default crop
38};
39
40constexpr int32_t test2xCropRegion[][4] = {
41 {256, 192, 512, 384}, // active array 2x zoom crop
42 {261, 197, 522, 394}, // preCorrection active array default crop
43};
44
45constexpr int32_t testLetterBoxSize[][4] = {
46 {0, 96, 1024, 576}, // active array 2x zoom crop
47 {0, 106, 1024, 576}, // preCorrection active array default crop
48};
49
50status_t setupTestMapper(ZoomRatioMapper *m, float maxDigitalZoom,
51 const int32_t activeArray[4], const int32_t preCorrectArray[4],
52 bool hasZoomRatioRange, float zoomRatioRange[2],
53 bool usePreCorrectArray) {
54 CameraMetadata deviceInfo;
55
56 deviceInfo.update(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, activeArray, 4);
57 deviceInfo.update(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE, preCorrectArray, 4);
58 deviceInfo.update(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, &maxDigitalZoom, 1);
59 if (hasZoomRatioRange) {
60 deviceInfo.update(ANDROID_CONTROL_ZOOM_RATIO_RANGE, zoomRatioRange, 2);
61 }
62
63 bool supportNativeZoomRatio;
64 status_t res = ZoomRatioMapper::overrideZoomRatioTags(&deviceInfo, &supportNativeZoomRatio);
65 if (res != OK) {
66 return res;
67 }
68
Shuzhen Wang1c834da2019-12-18 11:17:03 -080069 *m = ZoomRatioMapper(&deviceInfo, hasZoomRatioRange, usePreCorrectArray);
70 return OK;
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -080071}
72
73TEST(ZoomRatioTest, Initialization) {
74 CameraMetadata deviceInfo;
75 status_t res;
76 camera_metadata_entry_t entry;
77
78 deviceInfo.update(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE,
79 testPreCorrActiveArraySize, 4);
80 deviceInfo.update(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, testActiveArraySize, 4);
81
82 // Test initialization from devices not supporting zoomRange
83 float maxDigitalZoom = 4.0f;
84 ZoomRatioMapper mapperNoZoomRange;
85 deviceInfo.update(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, &maxDigitalZoom, 1);
86 bool supportNativeZoomRatio;
87 res = ZoomRatioMapper::overrideZoomRatioTags(&deviceInfo, &supportNativeZoomRatio);
88 ASSERT_EQ(res, OK);
89 ASSERT_EQ(supportNativeZoomRatio, false);
Shuzhen Wang1c834da2019-12-18 11:17:03 -080090 mapperNoZoomRange = ZoomRatioMapper(&deviceInfo,
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -080091 supportNativeZoomRatio, true/*usePreCorrectArray*/);
Shuzhen Wang1c834da2019-12-18 11:17:03 -080092 ASSERT_TRUE(mapperNoZoomRange.isValid());
93 mapperNoZoomRange = ZoomRatioMapper(&deviceInfo,
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -080094 supportNativeZoomRatio, false/*usePreCorrectArray*/);
Shuzhen Wang1c834da2019-12-18 11:17:03 -080095 ASSERT_TRUE(mapperNoZoomRange.isValid());
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -080096
97 entry = deviceInfo.find(ANDROID_CONTROL_ZOOM_RATIO_RANGE);
98 ASSERT_EQ(entry.count, 2U);
99 ASSERT_EQ(entry.data.f[0], 1.0);
100 ASSERT_EQ(entry.data.f[1], maxDigitalZoom);
101
102 entry = deviceInfo.find(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
103 ASSERT_GT(entry.count, 0U);
104 ASSERT_NE(std::find(entry.data.i32, entry.data.i32 + entry.count,
105 ANDROID_CONTROL_ZOOM_RATIO_RANGE), entry.data.i32 + entry.count);
106
107 entry = deviceInfo.find(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS);
108 ASSERT_GT(entry.count, 0U);
109 ASSERT_NE(std::find(entry.data.i32, entry.data.i32 + entry.count,
110 ANDROID_CONTROL_ZOOM_RATIO), entry.data.i32 + entry.count);
111
112 entry = deviceInfo.find(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS);
113 ASSERT_GT(entry.count, 0U);
114 ASSERT_NE(std::find(entry.data.i32, entry.data.i32 + entry.count,
115 ANDROID_CONTROL_ZOOM_RATIO), entry.data.i32 + entry.count);
116
117 // Test initialization from devices supporting zoomRange
118 float ratioRange[2] = {0.2f, maxDigitalZoom};
119 deviceInfo.update(ANDROID_CONTROL_ZOOM_RATIO_RANGE, ratioRange, 2);
120 res = ZoomRatioMapper::overrideZoomRatioTags(&deviceInfo, &supportNativeZoomRatio);
121 ASSERT_EQ(res, OK);
122 ASSERT_EQ(supportNativeZoomRatio, true);
123 ZoomRatioMapper mapperWithZoomRange;
Shuzhen Wang1c834da2019-12-18 11:17:03 -0800124 mapperWithZoomRange = ZoomRatioMapper(&deviceInfo,
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800125 supportNativeZoomRatio, true/*usePreCorrectArray*/);
Shuzhen Wang1c834da2019-12-18 11:17:03 -0800126 ASSERT_TRUE(mapperWithZoomRange.isValid());
127 mapperWithZoomRange = ZoomRatioMapper(&deviceInfo,
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800128 supportNativeZoomRatio, false/*usePreCorrectArray*/);
Shuzhen Wang1c834da2019-12-18 11:17:03 -0800129 ASSERT_TRUE(mapperWithZoomRange.isValid());
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800130
131 entry = deviceInfo.find(ANDROID_CONTROL_ZOOM_RATIO_RANGE);
132 ASSERT_EQ(entry.count, 2U);
133 ASSERT_EQ(entry.data.f[0], ratioRange[0]);
134 ASSERT_EQ(entry.data.f[1], ratioRange[1]);
135
136 // Test default zoom ratio in template
137 CameraMetadata requestTemplate;
138 res = ZoomRatioMapper::initZoomRatioInTemplate(&requestTemplate);
139 ASSERT_EQ(res, OK);
140 entry = requestTemplate.find(ANDROID_CONTROL_ZOOM_RATIO);
141 ASSERT_EQ(entry.count, 1U);
142 ASSERT_EQ(entry.data.f[0], 1.0f);
143
144 float customRatio = 0.5f;
145 res = requestTemplate.update(ANDROID_CONTROL_ZOOM_RATIO, &customRatio, 1);
146 ASSERT_EQ(res, OK);
147 res = ZoomRatioMapper::initZoomRatioInTemplate(&requestTemplate);
148 ASSERT_EQ(res, OK);
149 entry = requestTemplate.find(ANDROID_CONTROL_ZOOM_RATIO);
150 ASSERT_EQ(entry.count, 1U);
151 ASSERT_EQ(entry.data.f[0], customRatio);
152}
153
154void subScaleCoordinatesTest(bool usePreCorrectArray) {
155 ZoomRatioMapper mapper;
156 float maxDigitalZoom = 4.0f;
157 float zoomRatioRange[2];
158 ASSERT_EQ(OK, setupTestMapper(&mapper, maxDigitalZoom,
159 testActiveArraySize, testPreCorrActiveArraySize,
160 false/*hasZoomRatioRange*/, zoomRatioRange,
161 usePreCorrectArray));
162
163 size_t index = 0;
164 int32_t width = testActiveArraySize[2];
165 int32_t height = testActiveArraySize[3];
166 if (usePreCorrectArray) {
167 index = 1;
168 width = testPreCorrActiveArraySize[2];
169 height = testPreCorrActiveArraySize[3];
170 }
171
172 std::array<int32_t, 16> originalCoords = {
173 0, 0, // top-left
Shuzhen Wang9b0d9532020-04-14 17:14:20 -0700174 width - 1, 0, // top-right
175 0, height - 1, // bottom-left
176 width - 1, height - 1, // bottom-right
177 (width - 1) / 2, (height - 1) / 2, // center
178 (width - 1) / 4, (height - 1) / 4, // top-left after 2x
179 (width - 1) / 3, (height - 1) * 2 / 3, // bottom-left after 3x zoom
180 (width - 1) * 7 / 8, (height - 1) / 2, // middle-right after 1.33x zoom
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800181 };
182
183 // Verify 1.0x zoom doesn't change the coordinates
184 auto coords = originalCoords;
Shuzhen Wang9b0d9532020-04-14 17:14:20 -0700185 mapper.scaleCoordinates(coords.data(), coords.size()/2, 1.0f, false /*clamp*/);
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800186 for (size_t i = 0; i < coords.size(); i++) {
187 EXPECT_EQ(coords[i], originalCoords[i]);
188 }
189
190 // Verify 2.0x zoom work as expected (no clamping)
191 std::array<float, 16> expected2xCoords = {
Shuzhen Wang9b0d9532020-04-14 17:14:20 -0700192 - (width - 1) / 2.0f, - (height - 1) / 2.0f,// top-left
193 (width - 1) * 3 / 2.0f, - (height - 1) / 2.0f, // top-right
194 - (width - 1) / 2.0f, (height - 1) * 3 / 2.0f, // bottom-left
195 (width - 1) * 3 / 2.0f, (height - 1) * 3 / 2.0f, // bottom-right
196 (width - 1) / 2.0f, (height - 1) / 2.0f, // center
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800197 0, 0, // top-left after 2x
Shuzhen Wang9b0d9532020-04-14 17:14:20 -0700198 (width - 1) / 6.0f, (height - 1) * 5.0f / 6.0f, // bottom-left after 3x zoom
199 (width - 1) * 5.0f / 4.0f, (height - 1) / 2.0f, // middle-right after 1.33x zoom
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800200 };
201 coords = originalCoords;
Shuzhen Wang9b0d9532020-04-14 17:14:20 -0700202 mapper.scaleCoordinates(coords.data(), coords.size()/2, 2.0f, false /*clamp*/);
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800203 for (size_t i = 0; i < coords.size(); i++) {
204 EXPECT_LE(std::abs(coords[i] - expected2xCoords[i]), kMaxAllowedPixelError);
205 }
206
207 // Verify 2.0x zoom work as expected (with inclusive clamping)
208 std::array<float, 16> expected2xCoordsClampedInc = {
209 0, 0, // top-left
Shuzhen Wang9b0d9532020-04-14 17:14:20 -0700210 width - 1.0f, 0, // top-right
211 0, height - 1.0f, // bottom-left
212 width - 1.0f, height - 1.0f, // bottom-right
213 (width - 1) / 2.0f, (height - 1) / 2.0f, // center
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800214 0, 0, // top-left after 2x
Shuzhen Wang9b0d9532020-04-14 17:14:20 -0700215 (width - 1) / 6.0f, (height - 1) * 5.0f / 6.0f , // bottom-left after 3x zoom
216 width - 1.0f, (height - 1) / 2.0f, // middle-right after 1.33x zoom
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800217 };
218 coords = originalCoords;
Shuzhen Wang9b0d9532020-04-14 17:14:20 -0700219 mapper.scaleCoordinates(coords.data(), coords.size()/2, 2.0f, true /*clamp*/);
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800220 for (size_t i = 0; i < coords.size(); i++) {
221 EXPECT_LE(std::abs(coords[i] - expected2xCoordsClampedInc[i]), kMaxAllowedPixelError);
222 }
223
224 // Verify 2.0x zoom work as expected (with exclusive clamping)
225 std::array<float, 16> expected2xCoordsClampedExc = {
226 0, 0, // top-left
Shuzhen Wang9b0d9532020-04-14 17:14:20 -0700227 width - 1.0f, 0, // top-right
228 0, height - 1.0f, // bottom-left
229 width - 1.0f, height - 1.0f, // bottom-right
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800230 width / 2.0f, height / 2.0f, // center
231 0, 0, // top-left after 2x
Shuzhen Wang9b0d9532020-04-14 17:14:20 -0700232 (width - 1) / 6.0f, (height - 1) * 5.0f / 6.0f , // bottom-left after 3x zoom
233 width - 1.0f, height / 2.0f, // middle-right after 1.33x zoom
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800234 };
235 coords = originalCoords;
Shuzhen Wang9b0d9532020-04-14 17:14:20 -0700236 mapper.scaleCoordinates(coords.data(), coords.size()/2, 2.0f, true /*clamp*/);
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800237 for (size_t i = 0; i < coords.size(); i++) {
238 EXPECT_LE(std::abs(coords[i] - expected2xCoordsClampedExc[i]), kMaxAllowedPixelError);
239 }
240
241 // Verify 0.33x zoom work as expected
242 std::array<float, 16> expectedZoomOutCoords = {
Shuzhen Wang9b0d9532020-04-14 17:14:20 -0700243 (width - 1) / 3.0f, (height - 1) / 3.0f, // top-left
244 (width - 1) * 2 / 3.0f, (height - 1) / 3.0f, // top-right
245 (width - 1) / 3.0f, (height - 1) * 2 / 3.0f, // bottom-left
246 (width - 1) * 2 / 3.0f, (height - 1) * 2 / 3.0f, // bottom-right
247 (width - 1) / 2.0f, (height - 1) / 2.0f, // center
248 (width - 1) * 5 / 12.0f, (height - 1) * 5 / 12.0f, // top-left after 2x
249 (width - 1) * 4 / 9.0f, (height - 1) * 5 / 9.0f, // bottom-left after 3x zoom-in
250 (width - 1) * 5 / 8.0f, (height - 1) / 2.0f, // middle-right after 1.33x zoom-in
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800251 };
252 coords = originalCoords;
Shuzhen Wang9b0d9532020-04-14 17:14:20 -0700253 mapper.scaleCoordinates(coords.data(), coords.size()/2, 1.0f/3, false /*clamp*/);
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800254 for (size_t i = 0; i < coords.size(); i++) {
255 EXPECT_LE(std::abs(coords[i] - expectedZoomOutCoords[i]), kMaxAllowedPixelError);
256 }
257}
258
259TEST(ZoomRatioTest, scaleCoordinatesTest) {
260 subScaleCoordinatesTest(false/*usePreCorrectArray*/);
261 subScaleCoordinatesTest(true/*usePreCorrectArray*/);
262}
263
264void subCropOverMaxDigitalZoomTest(bool usePreCorrectArray) {
265 status_t res;
266 ZoomRatioMapper mapper;
267 float noZoomRatioRange[2];
268 res = setupTestMapper(&mapper, 4.0/*maxDigitalZoom*/,
269 testActiveArraySize, testPreCorrActiveArraySize,
270 false/*hasZoomRatioRange*/, noZoomRatioRange,
271 usePreCorrectArray);
272 ASSERT_EQ(res, OK);
273
274 CameraMetadata metadata;
275 camera_metadata_entry_t entry;
276
277 size_t index = usePreCorrectArray ? 1 : 0;
278 metadata.update(ANDROID_SCALER_CROP_REGION, testDefaultCropSize[index], 4);
279 res = mapper.updateCaptureRequest(&metadata);
280 ASSERT_EQ(res, OK);
281 entry = metadata.find(ANDROID_SCALER_CROP_REGION);
282 ASSERT_EQ(entry.count, 4U);
283 for (int i = 0; i < 4; i ++) {
284 EXPECT_EQ(entry.data.i32[i], testDefaultCropSize[index][i]);
285 }
286
287 metadata.update(ANDROID_SCALER_CROP_REGION, test2xCropRegion[index], 4);
288 res = mapper.updateCaptureResult(&metadata, true/*requestedZoomRatioIs1*/);
289 ASSERT_EQ(res, OK);
290 entry = metadata.find(ANDROID_SCALER_CROP_REGION);
291 ASSERT_EQ(entry.count, 4U);
292 for (int i = 0; i < 4; i ++) {
293 EXPECT_EQ(entry.data.i32[i], test2xCropRegion[index][i]);
294 }
295 entry = metadata.find(ANDROID_CONTROL_ZOOM_RATIO);
296 ASSERT_TRUE(entry.count == 0 || (entry.count == 1 && entry.data.f[0] == 1.0f));
297}
298
299TEST(ZoomRatioTest, CropOverMaxDigitalZoomTest) {
300 subCropOverMaxDigitalZoomTest(false/*usePreCorrectArray*/);
301 subCropOverMaxDigitalZoomTest(true/*usePreCorrectArray*/);
302}
303
304void subCropOverZoomRangeTest(bool usePreCorrectArray) {
305 status_t res;
306 ZoomRatioMapper mapper;
307 float zoomRatioRange[2] = {0.5f, 4.0f};
308 res = setupTestMapper(&mapper, 4.0/*maxDigitalZoom*/,
309 testActiveArraySize, testPreCorrActiveArraySize,
310 true/*hasZoomRatioRange*/, zoomRatioRange,
311 usePreCorrectArray);
312 ASSERT_EQ(res, OK);
313
314 CameraMetadata metadata;
315 camera_metadata_entry_t entry;
316
317 size_t index = usePreCorrectArray ? 1 : 0;
318
319 // 2x zoom crop region, zoomRatio is 1.0f
320 metadata.update(ANDROID_SCALER_CROP_REGION, test2xCropRegion[index], 4);
321 res = mapper.updateCaptureRequest(&metadata);
322 ASSERT_EQ(res, OK);
323 entry = metadata.find(ANDROID_SCALER_CROP_REGION);
324 ASSERT_EQ(entry.count, 4U);
325 for (int i = 0; i < 4; i++) {
Shuzhen Wang9b0d9532020-04-14 17:14:20 -0700326 EXPECT_LE(std::abs(entry.data.i32[i] - testDefaultCropSize[index][i]),
327 kMaxAllowedPixelError);
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800328 }
329 entry = metadata.find(ANDROID_CONTROL_ZOOM_RATIO);
330 EXPECT_NEAR(entry.data.f[0], 2.0f, kMaxAllowedRatioError);
331
332 res = mapper.updateCaptureResult(&metadata, true/*requestedZoomRatioIs1*/);
333 ASSERT_EQ(res, OK);
334 entry = metadata.find(ANDROID_CONTROL_ZOOM_RATIO);
335 EXPECT_NEAR(entry.data.f[0], 1.0f, kMaxAllowedRatioError);
336 entry = metadata.find(ANDROID_SCALER_CROP_REGION);
337 ASSERT_EQ(entry.count, 4U);
338 for (int i = 0; i < 4; i++) {
Shuzhen Wang9b0d9532020-04-14 17:14:20 -0700339 EXPECT_LE(std::abs(entry.data.i32[i] - test2xCropRegion[index][i]), kMaxAllowedPixelError);
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800340 }
341
342 // Letter boxing crop region, zoomRatio is 1.0
343 float zoomRatio = 1.0f;
344 metadata.update(ANDROID_CONTROL_ZOOM_RATIO, &zoomRatio, 1);
345 metadata.update(ANDROID_SCALER_CROP_REGION, testLetterBoxSize[index], 4);
346 res = mapper.updateCaptureRequest(&metadata);
347 ASSERT_EQ(res, OK);
348 entry = metadata.find(ANDROID_SCALER_CROP_REGION);
349 ASSERT_EQ(entry.count, 4U);
350 for (int i = 0; i < 4; i++) {
351 EXPECT_EQ(entry.data.i32[i], testLetterBoxSize[index][i]);
352 }
353 entry = metadata.find(ANDROID_CONTROL_ZOOM_RATIO);
354 EXPECT_NEAR(entry.data.f[0], 1.0f, kMaxAllowedRatioError);
355
356 res = mapper.updateCaptureResult(&metadata, true/*requestedZoomRatioIs1*/);
357 ASSERT_EQ(res, OK);
358 entry = metadata.find(ANDROID_SCALER_CROP_REGION);
359 ASSERT_EQ(entry.count, 4U);
360 for (int i = 0; i < 4; i++) {
361 EXPECT_EQ(entry.data.i32[i], testLetterBoxSize[index][i]);
362 }
363 entry = metadata.find(ANDROID_CONTROL_ZOOM_RATIO);
364 EXPECT_NEAR(entry.data.f[0], 1.0f, kMaxAllowedRatioError);
365}
366
367TEST(ZoomRatioTest, CropOverZoomRangeTest) {
368 subCropOverZoomRangeTest(false/*usePreCorrectArray*/);
369 subCropOverZoomRangeTest(true/*usePreCorrectArray*/);
370}
371
372void subZoomOverMaxDigitalZoomTest(bool usePreCorrectArray) {
373 status_t res;
374 ZoomRatioMapper mapper;
375 float noZoomRatioRange[2];
376 res = setupTestMapper(&mapper, 4.0/*maxDigitalZoom*/,
377 testActiveArraySize, testPreCorrActiveArraySize,
378 false/*hasZoomRatioRange*/, noZoomRatioRange,
379 usePreCorrectArray);
380 ASSERT_EQ(res, OK);
381
382 CameraMetadata metadata;
383 float zoomRatio = 3.0f;
384 camera_metadata_entry_t entry;
385
386 size_t index = usePreCorrectArray ? 1 : 0;
387
388 // Full active array crop, zoomRatio is 3.0f
389 metadata.update(ANDROID_SCALER_CROP_REGION, testDefaultCropSize[index], 4);
390 metadata.update(ANDROID_CONTROL_ZOOM_RATIO, &zoomRatio, 1);
391 res = mapper.updateCaptureRequest(&metadata);
392 ASSERT_EQ(res, OK);
393 entry = metadata.find(ANDROID_SCALER_CROP_REGION);
394 ASSERT_EQ(entry.count, 4U);
395 std::array<float, 4> expectedCrop = {
396 testDefaultCropSize[index][2] / 3.0f, /*x*/
397 testDefaultCropSize[index][3] / 3.0f, /*y*/
398 testDefaultCropSize[index][2] / 3.0f, /*width*/
399 testDefaultCropSize[index][3] / 3.0f, /*height*/
400 };
401 for (int i = 0; i < 4; i++) {
402 EXPECT_LE(std::abs(entry.data.i32[i] - expectedCrop[i]), kMaxAllowedPixelError);
403 }
404
405 entry = metadata.find(ANDROID_CONTROL_ZOOM_RATIO);
406 if (entry.count == 1) {
407 EXPECT_NEAR(entry.data.f[0], 1.0f, kMaxAllowedRatioError);
408 }
409}
410
411TEST(ZoomRatioTest, ZoomOverMaxDigitalZoomTest) {
412 subZoomOverMaxDigitalZoomTest(false/*usePreCorrectArray*/);
413 subZoomOverMaxDigitalZoomTest(true/*usePreCorrectArray*/);
414}
415
416void subZoomOverZoomRangeTest(bool usePreCorrectArray) {
417 status_t res;
418 ZoomRatioMapper mapper;
419 float zoomRatioRange[2] = {1.0f, 4.0f};
420 res = setupTestMapper(&mapper, 4.0/*maxDigitalZoom*/,
421 testActiveArraySize, testPreCorrActiveArraySize,
422 true/*hasZoomRatioRange*/, zoomRatioRange,
423 usePreCorrectArray);
424 ASSERT_EQ(res, OK);
425
426 CameraMetadata metadata;
427 float zoomRatio = 3.0f;
428 camera_metadata_entry_t entry;
429 size_t index = usePreCorrectArray ? 1 : 0;
430
431 // Full active array crop, zoomRatio is 3.0f
432 metadata.update(ANDROID_SCALER_CROP_REGION, testDefaultCropSize[index], 4);
433 metadata.update(ANDROID_CONTROL_ZOOM_RATIO, &zoomRatio, 1);
434 res = mapper.updateCaptureRequest(&metadata);
435 ASSERT_EQ(res, OK);
436 entry = metadata.find(ANDROID_SCALER_CROP_REGION);
437 ASSERT_EQ(entry.count, 4U);
438 for (int i = 0; i < 4; i ++) {
439 EXPECT_EQ(entry.data.i32[i], testDefaultCropSize[index][i]);
440 }
441 entry = metadata.find(ANDROID_CONTROL_ZOOM_RATIO);
442 ASSERT_EQ(entry.data.f[0], zoomRatio);
443
444 res = mapper.updateCaptureResult(&metadata, false/*requestedZoomRatioIs1*/);
445 ASSERT_EQ(res, OK);
446 entry = metadata.find(ANDROID_SCALER_CROP_REGION);
447 ASSERT_EQ(entry.count, 4U);
448 for (int i = 0; i < 4; i ++) {
449 EXPECT_EQ(entry.data.i32[i], testDefaultCropSize[index][i]);
450 }
451 entry = metadata.find(ANDROID_CONTROL_ZOOM_RATIO);
452 ASSERT_EQ(entry.data.f[0], zoomRatio);
453}
454
455TEST(ZoomRatioTest, ZoomOverZoomRangeTest) {
456 subZoomOverZoomRangeTest(false/*usePreCorrectArray*/);
457 subZoomOverZoomRangeTest(true/*usePreCorrectArray*/);
458}