blob: eb64db1f08fe05c6230a742cbf3664ac52baa6e6 [file] [log] [blame]
Zhijun He8ef01442013-08-13 17:36:17 -07001/*
2 * Copyright (C) 2013 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
Sasha Levitskiy0ab4c962014-04-21 14:49:12 -070017#include <inttypes.h>
Zhijun He8ef01442013-08-13 17:36:17 -070018#define LOG_TAG "CameraMultiStreamTest"
19//#define LOG_NDEBUG 0
20#include "CameraStreamFixture.h"
21#include "TestExtensions.h"
22
23#include <gtest/gtest.h>
24#include <utils/Log.h>
25#include <utils/StrongPointer.h>
26#include <common/CameraDeviceBase.h>
27#include <hardware/hardware.h>
28#include <hardware/camera2.h>
29#include <gui/SurfaceComposerClient.h>
30#include <gui/Surface.h>
31
32#define DEFAULT_FRAME_DURATION 33000000LL // 33ms
33#define CAMERA_HEAP_COUNT 1
34#define CAMERA_EXPOSURE_FORMAT CAMERA_STREAM_AUTO_CPU_FORMAT
35#define CAMERA_DISPLAY_FORMAT HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED
36#define CAMERA_MULTI_STREAM_DEBUGGING 0
37#define CAMERA_FRAME_TIMEOUT 1000000000LL // nsecs (1 secs)
38#define PREVIEW_RENDERING_TIME_INTERVAL 200000 // in unit of us, 200ms
Gaurav Batraa1bef2b2014-03-28 17:03:36 -070039// 1% tolerance margin for exposure sanity check against metadata
40#define TOLERANCE_MARGIN_METADATA 0.01
41// 5% tolerance margin for exposure sanity check against capture times
42#define TOLERANCE_MARGIN_CAPTURE 0.05
Zhijun He8ef01442013-08-13 17:36:17 -070043/* constants for display */
44#define DISPLAY_BUFFER_HEIGHT 1024
45#define DISPLAY_BUFFER_WIDTH 1024
46#define DISPLAY_BUFFER_FORMAT PIXEL_FORMAT_RGB_888
47
48// This test intends to test large preview size but less than 1080p.
49#define PREVIEW_WIDTH_CAP 1920
50#define PREVIEW_HEIGHT_CAP 1080
51// This test intends to test small metering burst size that is less than 640x480
52#define METERING_WIDTH_CAP 640
53#define METERING_HEIGHT_CAP 480
54
55#define EXP_WAIT_MULTIPLIER 2
56
57namespace android {
58namespace camera2 {
59namespace tests {
60
61static const CameraStreamParams DEFAULT_STREAM_PARAMETERS = {
62 /*mFormat*/ CAMERA_EXPOSURE_FORMAT,
63 /*mHeapCount*/ CAMERA_HEAP_COUNT
64};
65
66static const CameraStreamParams DISPLAY_STREAM_PARAMETERS = {
67 /*mFormat*/ CAMERA_DISPLAY_FORMAT,
68 /*mHeapCount*/ CAMERA_HEAP_COUNT
69};
70
71class CameraMultiStreamTest
72 : public ::testing::Test,
73 public CameraStreamFixture {
74
75public:
76 CameraMultiStreamTest() : CameraStreamFixture(DEFAULT_STREAM_PARAMETERS) {
77 TEST_EXTENSION_FORKING_CONSTRUCTOR;
78
79 if (HasFatalFailure()) {
80 return;
81 }
82 /**
83 * Don't create default stream, each test is in charge of creating
84 * its own streams.
85 */
86 }
87
88 ~CameraMultiStreamTest() {
89 TEST_EXTENSION_FORKING_DESTRUCTOR;
90 }
91
92 sp<SurfaceComposerClient> mComposerClient;
93 sp<SurfaceControl> mSurfaceControl;
94
Eino-Ville Talvalacd6984e2015-06-09 15:23:34 -070095 void CreateOnScreenSurface(sp<Surface>& surface) {
Zhijun He8ef01442013-08-13 17:36:17 -070096 mComposerClient = new SurfaceComposerClient;
97 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
98
99 mSurfaceControl = mComposerClient->createSurface(
100 String8("CameraMultiStreamTest StreamingImage Surface"),
101 DISPLAY_BUFFER_HEIGHT, DISPLAY_BUFFER_WIDTH,
102 DISPLAY_BUFFER_FORMAT, 0);
103
104 ASSERT_NE((void*)NULL, mSurfaceControl.get());
105 ASSERT_TRUE(mSurfaceControl->isValid());
106
107 SurfaceComposerClient::openGlobalTransaction();
108 ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
109 ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
110 SurfaceComposerClient::closeGlobalTransaction();
111
112 surface = mSurfaceControl->getSurface();
113
114 ASSERT_NE((void*)NULL, surface.get());
115 }
116
117 struct Size {
118 int32_t width;
119 int32_t height;
120 };
121
122 // Select minimal size by number of pixels.
123 void GetMinSize(const int32_t* data, size_t count,
124 Size* min, int32_t* idx) {
125 ASSERT_NE((int32_t*)NULL, data);
126 int32_t minIdx = 0;
127 int32_t minSize = INT_MAX, tempSize;
128 for (size_t i = 0; i < count; i+=2) {
129 tempSize = data[i] * data[i+1];
130 if (minSize > tempSize) {
131 minSize = tempSize;
132 minIdx = i;
133 }
134 }
135 min->width = data[minIdx];
136 min->height = data[minIdx + 1];
137 *idx = minIdx;
138 }
139
140 // Select maximal size by number of pixels.
141 void GetMaxSize(const int32_t* data, size_t count,
142 Size* max, int32_t* idx) {
143 ASSERT_NE((int32_t*)NULL, data);
144 int32_t maxIdx = 0;
145 int32_t maxSize = INT_MIN, tempSize;
146 for (size_t i = 0; i < count; i+=2) {
147 tempSize = data[i] * data[i+1];
148 if (maxSize < tempSize) {
149 maxSize = tempSize;
150 maxIdx = i;
151 }
152 }
153 max->width = data[maxIdx];
154 max->height = data[maxIdx + 1];
155 *idx = maxIdx;
156 }
157
158 // Cap size by number of pixels.
159 Size CapSize(Size cap, Size input) {
160 if (input.width * input.height > cap.width * cap.height) {
161 return cap;
162 }
163 return input;
164 }
165
166 struct CameraStream : public RefBase {
167
168 public:
169 /**
170 * Only initialize the variables here, do the ASSERT check in
171 * SetUp function. To make this stream useful, the SetUp must
172 * be called before using it.
173 */
174 CameraStream(
175 int width,
176 int height,
177 const sp<CameraDeviceBase>& device,
Eino-Ville Talvalacd6984e2015-06-09 15:23:34 -0700178 CameraStreamParams param, sp<Surface> surface,
Zhijun He8ef01442013-08-13 17:36:17 -0700179 bool useCpuConsumer)
180 : mDevice(device),
181 mWidth(width),
182 mHeight(height) {
183 mFormat = param.mFormat;
184 if (useCpuConsumer) {
Dan Stoza5dce9e42014-04-07 13:39:37 -0700185 sp<IGraphicBufferProducer> producer;
186 sp<IGraphicBufferConsumer> consumer;
187 BufferQueue::createBufferQueue(&producer, &consumer);
188 mCpuConsumer = new CpuConsumer(consumer, param.mHeapCount);
Zhijun He8ef01442013-08-13 17:36:17 -0700189 mCpuConsumer->setName(String8(
190 "CameraMultiStreamTest::mCpuConsumer"));
Eino-Ville Talvalacd6984e2015-06-09 15:23:34 -0700191 mSurface = new Surface(producer);
Zhijun He8ef01442013-08-13 17:36:17 -0700192 } else {
193 // Render the stream to screen.
194 mCpuConsumer = NULL;
Eino-Ville Talvalacd6984e2015-06-09 15:23:34 -0700195 mSurface = surface;
Zhijun He8ef01442013-08-13 17:36:17 -0700196 }
197
198 mFrameListener = new FrameListener();
199 if (mCpuConsumer != 0) {
200 mCpuConsumer->setFrameAvailableListener(mFrameListener);
201 }
202 }
203
204 /**
205 * Finally create camera stream, and do the ASSERT check, since we
206 * can not do it in ctor.
207 */
208 void SetUp() {
209 ASSERT_EQ(OK,
Eino-Ville Talvalacd6984e2015-06-09 15:23:34 -0700210 mDevice->createStream(mSurface,
Eino-Ville Talvala898ad172015-03-06 13:23:18 -0800211 mWidth, mHeight, mFormat, HAL_DATASPACE_UNKNOWN,
Yin-Chia Yeh5407ef12015-03-12 15:09:27 -0700212 CAMERA3_STREAM_ROTATION_0, &mStreamId));
Zhijun He8ef01442013-08-13 17:36:17 -0700213
214 ASSERT_NE(-1, mStreamId);
215 }
216
217 int GetStreamId() { return mStreamId; }
218 sp<CpuConsumer> GetConsumer() { return mCpuConsumer; }
219 sp<FrameListener> GetFrameListener() { return mFrameListener; }
220
221 protected:
222 ~CameraStream() {
223 if (mDevice.get()) {
224 mDevice->waitUntilDrained();
225 mDevice->deleteStream(mStreamId);
226 }
227 // Clear producer before consumer.
Eino-Ville Talvalacd6984e2015-06-09 15:23:34 -0700228 mSurface.clear();
Zhijun He8ef01442013-08-13 17:36:17 -0700229 mCpuConsumer.clear();
230 }
231
232 private:
233 sp<FrameListener> mFrameListener;
234 sp<CpuConsumer> mCpuConsumer;
Eino-Ville Talvalacd6984e2015-06-09 15:23:34 -0700235 sp<Surface> mSurface;
Zhijun He8ef01442013-08-13 17:36:17 -0700236 sp<CameraDeviceBase> mDevice;
237 int mStreamId;
238 int mWidth;
239 int mHeight;
240 int mFormat;
241 };
242
243 int64_t GetExposureValue(const CameraMetadata& metaData) {
244 camera_metadata_ro_entry_t entry =
245 metaData.find(ANDROID_SENSOR_EXPOSURE_TIME);
246 EXPECT_EQ(1u, entry.count);
247 if (entry.count == 1) {
248 return entry.data.i64[0];
249 }
250 return -1;
251 }
252
253 int32_t GetSensitivity(const CameraMetadata& metaData) {
254 camera_metadata_ro_entry_t entry =
255 metaData.find(ANDROID_SENSOR_SENSITIVITY);
256 EXPECT_EQ(1u, entry.count);
257 if (entry.count == 1) {
258 return entry.data.i32[0];
259 }
260 return -1;
261 }
262
263 int64_t GetFrameDuration(const CameraMetadata& metaData) {
264 camera_metadata_ro_entry_t entry =
265 metaData.find(ANDROID_SENSOR_FRAME_DURATION);
266 EXPECT_EQ(1u, entry.count);
267 if (entry.count == 1) {
268 return entry.data.i64[0];
269 }
270 return -1;
271 }
272
273 void CreateRequests(CameraMetadata& previewRequest,
274 CameraMetadata& meteringRequest,
275 CameraMetadata& captureRequest,
276 int previewStreamId,
277 int meteringStreamId,
278 int captureStreamId) {
Zhijun He914226c2013-09-08 10:56:24 -0700279 int32_t requestId = 0;
280 Vector<int32_t> previewStreamIds;
281 previewStreamIds.push(previewStreamId);
282 ASSERT_EQ(OK, mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
283 &previewRequest));
284 ASSERT_EQ(OK, previewRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
285 previewStreamIds));
286 ASSERT_EQ(OK, previewRequest.update(ANDROID_REQUEST_ID,
287 &requestId, 1));
Zhijun He8ef01442013-08-13 17:36:17 -0700288
Zhijun He914226c2013-09-08 10:56:24 -0700289 // Create metering request, manual settings
290 // Manual control: Disable 3A, noise reduction, edge sharping
291 uint8_t cmOff = static_cast<uint8_t>(ANDROID_CONTROL_MODE_OFF);
292 uint8_t nrOff = static_cast<uint8_t>(ANDROID_NOISE_REDUCTION_MODE_OFF);
293 uint8_t sharpOff = static_cast<uint8_t>(ANDROID_EDGE_MODE_OFF);
294 Vector<int32_t> meteringStreamIds;
295 meteringStreamIds.push(meteringStreamId);
296 ASSERT_EQ(OK, mDevice->createDefaultRequest(
297 CAMERA2_TEMPLATE_PREVIEW,
298 &meteringRequest));
299 ASSERT_EQ(OK, meteringRequest.update(
300 ANDROID_REQUEST_OUTPUT_STREAMS,
301 meteringStreamIds));
302 ASSERT_EQ(OK, meteringRequest.update(
303 ANDROID_CONTROL_MODE,
304 &cmOff, 1));
305 ASSERT_EQ(OK, meteringRequest.update(
306 ANDROID_NOISE_REDUCTION_MODE,
307 &nrOff, 1));
308 ASSERT_EQ(OK, meteringRequest.update(
309 ANDROID_EDGE_MODE,
310 &sharpOff, 1));
Zhijun He8ef01442013-08-13 17:36:17 -0700311
Zhijun He914226c2013-09-08 10:56:24 -0700312 // Create capture request, manual settings
313 Vector<int32_t> captureStreamIds;
314 captureStreamIds.push(captureStreamId);
315 ASSERT_EQ(OK, mDevice->createDefaultRequest(
316 CAMERA2_TEMPLATE_PREVIEW,
317 &captureRequest));
318 ASSERT_EQ(OK, captureRequest.update(
319 ANDROID_REQUEST_OUTPUT_STREAMS,
320 captureStreamIds));
321 ASSERT_EQ(OK, captureRequest.update(
322 ANDROID_CONTROL_MODE,
323 &cmOff, 1));
324 ASSERT_EQ(OK, captureRequest.update(
325 ANDROID_NOISE_REDUCTION_MODE,
326 &nrOff, 1));
327 ASSERT_EQ(OK, captureRequest.update(
328 ANDROID_EDGE_MODE,
329 &sharpOff, 1));
Zhijun He8ef01442013-08-13 17:36:17 -0700330 }
331
332 sp<CameraStream> CreateStream(
333 int width,
334 int height,
335 const sp<CameraDeviceBase>& device,
336 CameraStreamParams param = DEFAULT_STREAM_PARAMETERS,
Eino-Ville Talvalacd6984e2015-06-09 15:23:34 -0700337 sp<Surface> surface = NULL,
Zhijun He8ef01442013-08-13 17:36:17 -0700338 bool useCpuConsumer = true) {
339 param.mFormat = MapAutoFormat(param.mFormat);
340 return new CameraStream(width, height, device,
341 param, surface, useCpuConsumer);
342 }
343
344 void CaptureBurst(CameraMetadata& request, size_t requestCount,
345 const Vector<int64_t>& exposures,
346 const Vector<int32_t>& sensitivities,
347 const sp<CameraStream>& stream,
Zhijun He914226c2013-09-08 10:56:24 -0700348 int64_t minFrameDuration,
349 int32_t* requestIdStart) {
Zhijun He8ef01442013-08-13 17:36:17 -0700350 ASSERT_EQ(OK, request.update(ANDROID_SENSOR_FRAME_DURATION,
351 &minFrameDuration, 1));
352 // Submit a series of requests with the specified exposure/gain values.
Zhijun He914226c2013-09-08 10:56:24 -0700353 int32_t targetRequestId = *requestIdStart;
Zhijun He8ef01442013-08-13 17:36:17 -0700354 for (size_t i = 0; i < requestCount; i++) {
Zhijun He914226c2013-09-08 10:56:24 -0700355 ASSERT_EQ(OK, request.update(ANDROID_REQUEST_ID, requestIdStart, 1));
356 ASSERT_EQ(OK, request.update(ANDROID_SENSOR_EXPOSURE_TIME, &exposures[i], 1));
357 ASSERT_EQ(OK, request.update(ANDROID_SENSOR_SENSITIVITY, &sensitivities[i], 1));
Zhijun He8ef01442013-08-13 17:36:17 -0700358 ASSERT_EQ(OK, mDevice->capture(request));
Bernhard Rosenkränzer1f1d7972014-12-12 22:16:55 +0100359 ALOGV("Submitting request with: id %d with exposure %" PRId64 ", sensitivity %d",
Zhijun He914226c2013-09-08 10:56:24 -0700360 *requestIdStart, exposures[i], sensitivities[i]);
Zhijun He8ef01442013-08-13 17:36:17 -0700361 if (CAMERA_MULTI_STREAM_DEBUGGING) {
362 request.dump(STDOUT_FILENO);
363 }
Zhijun He914226c2013-09-08 10:56:24 -0700364 (*requestIdStart)++;
Zhijun He8ef01442013-08-13 17:36:17 -0700365 }
366 // Get capture burst results.
367 Vector<nsecs_t> captureBurstTimes;
368 sp<CpuConsumer> consumer = stream->GetConsumer();
369 sp<FrameListener> listener = stream->GetFrameListener();
370
371 // Set wait limit based on expected frame duration.
372 int64_t waitLimit = CAMERA_FRAME_TIMEOUT;
373 for (size_t i = 0; i < requestCount; i++) {
Sasha Levitskiy0ab4c962014-04-21 14:49:12 -0700374 ALOGV("Reading request result %zu", i);
Zhijun He8ef01442013-08-13 17:36:17 -0700375
376 /**
377 * Raise the timeout to be at least twice as long as the exposure
378 * time. to avoid a false positive when the timeout is too short.
379 */
380 if ((exposures[i] * EXP_WAIT_MULTIPLIER) > waitLimit) {
381 waitLimit = exposures[i] * EXP_WAIT_MULTIPLIER;
382 }
383
Jianing Weif816eea2014-04-10 14:17:57 -0700384 CaptureResult result;
Zhijun He8ef01442013-08-13 17:36:17 -0700385 CameraMetadata frameMetadata;
Zhijun He914226c2013-09-08 10:56:24 -0700386 int32_t resultRequestId;
387 do {
388 ASSERT_EQ(OK, mDevice->waitForNextFrame(waitLimit));
Jianing Weif816eea2014-04-10 14:17:57 -0700389 ASSERT_EQ(OK, mDevice->getNextResult(&result));
390 frameMetadata = result.mMetadata;
Zhijun He914226c2013-09-08 10:56:24 -0700391
392 camera_metadata_entry_t resultEntry = frameMetadata.find(ANDROID_REQUEST_ID);
393 ASSERT_EQ(1u, resultEntry.count);
394 resultRequestId = resultEntry.data.i32[0];
395 if (CAMERA_MULTI_STREAM_DEBUGGING) {
396 std::cout << "capture result req id: " << resultRequestId << std::endl;
397 }
398 } while (resultRequestId != targetRequestId);
399 targetRequestId++;
Sasha Levitskiy0ab4c962014-04-21 14:49:12 -0700400 ALOGV("Got capture burst result for request %zu", i);
Zhijun He914226c2013-09-08 10:56:24 -0700401
Zhijun He8ef01442013-08-13 17:36:17 -0700402 // Validate capture result
403 if (CAMERA_MULTI_STREAM_DEBUGGING) {
404 frameMetadata.dump(STDOUT_FILENO);
405 }
406
407 // TODO: Need revisit it to figure out an accurate margin.
Zhijun He914226c2013-09-08 10:56:24 -0700408 int64_t resultExposure = GetExposureValue(frameMetadata);
409 int32_t resultSensitivity = GetSensitivity(frameMetadata);
Gaurav Batraa1bef2b2014-03-28 17:03:36 -0700410 EXPECT_LE(sensitivities[i] * (1.0 - TOLERANCE_MARGIN_METADATA), resultSensitivity);
411 EXPECT_GE(sensitivities[i] * (1.0 + TOLERANCE_MARGIN_METADATA), resultSensitivity);
412 EXPECT_LE(exposures[i] * (1.0 - TOLERANCE_MARGIN_METADATA), resultExposure);
413 EXPECT_GE(exposures[i] * (1.0 + TOLERANCE_MARGIN_METADATA), resultExposure);
Zhijun He8ef01442013-08-13 17:36:17 -0700414
415 ASSERT_EQ(OK, listener->waitForFrame(waitLimit));
416 captureBurstTimes.push_back(systemTime());
417 CpuConsumer::LockedBuffer imgBuffer;
418 ASSERT_EQ(OK, consumer->lockNextBuffer(&imgBuffer));
Sasha Levitskiy0ab4c962014-04-21 14:49:12 -0700419 ALOGV("Got capture buffer for request %zu", i);
Zhijun He8ef01442013-08-13 17:36:17 -0700420
421 /**
422 * TODO: Validate capture buffer. Current brightness calculation
423 * is too slow, it also doesn't account for saturation effects,
424 * which is quite common since we are going over a significant
425 * range of EVs. we need figure out some reliable way to validate
426 * buffer data.
427 */
428
429 ASSERT_EQ(OK, consumer->unlockBuffer(imgBuffer));
430 if (i > 0) {
431 nsecs_t timeDelta =
432 captureBurstTimes[i] - captureBurstTimes[i-1];
Gaurav Batraa1bef2b2014-03-28 17:03:36 -0700433 EXPECT_GE(timeDelta * ( 1 + TOLERANCE_MARGIN_CAPTURE), exposures[i]);
Zhijun He8ef01442013-08-13 17:36:17 -0700434 }
435 }
436 }
437
438 /**
439 * Intentionally shadow default CreateStream function from base class,
440 * because we don't want any test in this class to use the default
441 * stream creation function.
442 */
443 void CreateStream() {
444 }
445};
446
447/**
448 * This test adds multiple stream use case test, basically, test 3
449 * streams:
450 *
451 * 1. Preview stream, with large size that is no bigger than 1080p
452 * we render this stream to display and vary the exposure time for
453 * for certain amount of time for visualization purpose.
454 *
455 * 2. Metering stream, with small size that is no bigger than VGA size.
456 * a burst is issued for different exposure times and analog gains
457 * (or analog gain implemented sensitivities) then check if the capture
458 * result metadata matches the request.
459 *
460 * 3. Capture stream, this is basically similar as meterting stream, but
461 * has large size, which is the largest supported JPEG capture size.
462 *
463 * This multiple stream test is to test if HAL supports:
464 *
465 * 1. Multiple streams like above, HAL should support at least 3 streams
466 * concurrently: one preview stream, 2 other YUV stream.
467 *
468 * 2. Manual control(gain/exposure) of mutiple burst capture.
469 */
Zhijun Heb5ac45f2014-08-07 16:25:41 -0700470// Disable this test for now, as we need cleanup the usage of the deprecated tag quite a bit.
471TEST_F(CameraMultiStreamTest, DISABLED_MultiBurst) {
Zhijun He8ef01442013-08-13 17:36:17 -0700472
473 TEST_EXTENSION_FORKING_INIT;
474
Yin-Chia Yeh8df990b2014-10-31 15:10:11 -0700475 const int32_t* implDefData;
476 size_t implDefCount;
477 const int32_t* jpegData;
478 size_t jpegCount;
479 if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_2) {
480 camera_metadata_ro_entry availableProcessedSizes =
481 GetStaticEntry(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
482 ASSERT_EQ(0u, availableProcessedSizes.count % 2);
483 ASSERT_GE(availableProcessedSizes.count, 2u);
484 camera_metadata_ro_entry availableProcessedMinFrameDurations =
485 GetStaticEntry(ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS);
486 EXPECT_EQ(availableProcessedSizes.count,
487 availableProcessedMinFrameDurations.count * 2);
Zhijun He8ef01442013-08-13 17:36:17 -0700488
Yin-Chia Yeh8df990b2014-10-31 15:10:11 -0700489 camera_metadata_ro_entry availableJpegSizes =
490 GetStaticEntry(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
491 ASSERT_EQ(0u, availableJpegSizes.count % 2);
492 ASSERT_GE(availableJpegSizes.count, 2u);
493 implDefData = availableProcessedSizes.data.i32;
494 implDefCount = availableProcessedSizes.count;
495 jpegData = availableJpegSizes.data.i32;
496 jpegCount = availableJpegSizes.count;
497 } else {
Yin-Chia Yeh8df990b2014-10-31 15:10:11 -0700498 getResolutionList(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, &implDefData, &implDefCount);
499 ASSERT_NE(0u, implDefCount)
500 << "Missing implementation defined sizes";
501 ASSERT_EQ(0u, implDefCount % 2);
502 ASSERT_GE(implDefCount, 2u);
503
504 getResolutionList(HAL_PIXEL_FORMAT_BLOB, &jpegData, &jpegCount);
505 ASSERT_EQ(0u, jpegCount % 2);
506 ASSERT_GE(jpegCount, 2u);
507 }
Zhijun He8ef01442013-08-13 17:36:17 -0700508
Zhijun He3bf3b452013-09-18 23:42:12 -0700509 camera_metadata_ro_entry hardwareLevel =
510 GetStaticEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL);
511 ASSERT_EQ(1u, hardwareLevel.count);
512 uint8_t level = hardwareLevel.data.u8[0];
513 ASSERT_GE(level, ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED);
514 ASSERT_LE(level, ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL);
515 if (level == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED) {
516 const ::testing::TestInfo* const test_info =
517 ::testing::UnitTest::GetInstance()->current_test_info();
518 std::cerr << "Skipping test "
519 << test_info->test_case_name() << "."
520 << test_info->name()
521 << " because HAL hardware supported level is limited "
522 << std::endl;
523 return;
524 }
525
Zhijun He8ef01442013-08-13 17:36:17 -0700526 // Find the right sizes for preview, metering, and capture streams
Zhijun He8ef01442013-08-13 17:36:17 -0700527 int64_t minFrameDuration = DEFAULT_FRAME_DURATION;
Yin-Chia Yehc2537652015-03-24 10:48:08 -0700528 Size processedMinSize = {0, 0}, processedMaxSize = {0, 0};
529 Size jpegMaxSize = {0, 0};
Zhijun He8ef01442013-08-13 17:36:17 -0700530
531 int32_t minIdx, maxIdx;
Yin-Chia Yeh8df990b2014-10-31 15:10:11 -0700532 GetMinSize(implDefData, implDefCount, &processedMinSize, &minIdx);
533 GetMaxSize(implDefData, implDefCount, &processedMaxSize, &maxIdx);
Zhijun He8ef01442013-08-13 17:36:17 -0700534 ALOGV("Found processed max size: %dx%d, min size = %dx%d",
535 processedMaxSize.width, processedMaxSize.height,
536 processedMinSize.width, processedMinSize.height);
537
Yin-Chia Yeh8df990b2014-10-31 15:10:11 -0700538 if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_2) {
539 camera_metadata_ro_entry availableProcessedMinFrameDurations =
540 GetStaticEntry(ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS);
Zhijun He8ef01442013-08-13 17:36:17 -0700541 minFrameDuration =
542 availableProcessedMinFrameDurations.data.i64[maxIdx / 2];
Yin-Chia Yeh8df990b2014-10-31 15:10:11 -0700543 } else {
544 minFrameDuration = getMinFrameDurationFor(
545 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
546 processedMaxSize.width, processedMaxSize.height);
Zhijun He8ef01442013-08-13 17:36:17 -0700547 }
548
549 EXPECT_GT(minFrameDuration, 0);
550
551 if (minFrameDuration <= 0) {
552 minFrameDuration = DEFAULT_FRAME_DURATION;
553 }
554
Bernhard Rosenkränzer1f1d7972014-12-12 22:16:55 +0100555 ALOGV("targeted minimal frame duration is: %" PRId64 "ns", minFrameDuration);
Zhijun He8ef01442013-08-13 17:36:17 -0700556
Yin-Chia Yeh8df990b2014-10-31 15:10:11 -0700557 GetMaxSize(jpegData, jpegCount, &jpegMaxSize, &maxIdx);
Zhijun He8ef01442013-08-13 17:36:17 -0700558 ALOGV("Found Jpeg size max idx = %d", maxIdx);
559
560 // Max Jpeg size should be available in processed sizes. Use it for
561 // YUV capture anyway.
562 EXPECT_EQ(processedMaxSize.width, jpegMaxSize.width);
563 EXPECT_EQ(processedMaxSize.height, jpegMaxSize.height);
564
565 // Cap preview size.
566 Size previewLimit = { PREVIEW_WIDTH_CAP, PREVIEW_HEIGHT_CAP };
567 // FIXME: need make sure the previewLimit is supported by HAL.
568 Size previewSize = CapSize(previewLimit, processedMaxSize);
569 // Cap Metering size.
570 Size meteringLimit = { METERING_WIDTH_CAP, METERING_HEIGHT_CAP };
571 // Cap metering size to VGA (VGA is mandatory by CDD)
572 Size meteringSize = CapSize(meteringLimit, processedMinSize);
573 // Capture stream should be the max size of jpeg sizes.
574 ALOGV("preview size: %dx%d, metering size: %dx%d, capture size: %dx%d",
575 previewSize.width, previewSize.height,
576 meteringSize.width, meteringSize.height,
577 jpegMaxSize.width, jpegMaxSize.height);
578
579 // Create streams
580 // Preview stream: small resolution, render on the screen.
581 sp<CameraStream> previewStream;
582 {
Eino-Ville Talvalacd6984e2015-06-09 15:23:34 -0700583 sp<Surface> surface;
Zhijun He8ef01442013-08-13 17:36:17 -0700584 ASSERT_NO_FATAL_FAILURE(CreateOnScreenSurface(/*out*/surface));
585 previewStream = CreateStream(
586 previewSize.width,
587 previewSize.height,
588 mDevice,
589 DISPLAY_STREAM_PARAMETERS,
590 surface,
591 false);
592 ASSERT_NE((void*)NULL, previewStream.get());
593 ASSERT_NO_FATAL_FAILURE(previewStream->SetUp());
594 }
595 // Metering burst stream: small resolution yuv stream
596 sp<CameraStream> meteringStream =
597 CreateStream(
598 meteringSize.width,
599 meteringSize.height,
600 mDevice);
601 ASSERT_NE((void*)NULL, meteringStream.get());
602 ASSERT_NO_FATAL_FAILURE(meteringStream->SetUp());
603 // Capture burst stream: full resolution yuv stream
604 sp<CameraStream> captureStream =
605 CreateStream(
606 jpegMaxSize.width,
607 jpegMaxSize.height,
608 mDevice);
609 ASSERT_NE((void*)NULL, captureStream.get());
610 ASSERT_NO_FATAL_FAILURE(captureStream->SetUp());
611
612 // Create Preview request.
613 CameraMetadata previewRequest, meteringRequest, captureRequest;
614 ASSERT_NO_FATAL_FAILURE(CreateRequests(previewRequest, meteringRequest,
615 captureRequest, previewStream->GetStreamId(),
616 meteringStream->GetStreamId(), captureStream->GetStreamId()));
617
618 // Start preview
619 if (CAMERA_MULTI_STREAM_DEBUGGING) {
620 previewRequest.dump(STDOUT_FILENO);
621 }
622
623 // Generate exposure and sensitivity lists
624 camera_metadata_ro_entry exposureTimeRange =
625 GetStaticEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE);
626 ASSERT_EQ(exposureTimeRange.count, 2u);
627 int64_t minExp = exposureTimeRange.data.i64[0];
628 int64_t maxExp = exposureTimeRange.data.i64[1];
629 ASSERT_GT(maxExp, minExp);
630
631 camera_metadata_ro_entry sensivityRange =
632 GetStaticEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE);
633 ASSERT_EQ(2u, sensivityRange.count);
634 int32_t minSensitivity = sensivityRange.data.i32[0];
635 int32_t maxSensitivity = sensivityRange.data.i32[1];
636 camera_metadata_ro_entry maxAnalogSenEntry =
637 GetStaticEntry(ANDROID_SENSOR_MAX_ANALOG_SENSITIVITY);
638 EXPECT_EQ(1u, maxAnalogSenEntry.count);
639 int32_t maxAnalogSensitivity = maxAnalogSenEntry.data.i32[0];
640 EXPECT_LE(maxAnalogSensitivity, maxSensitivity);
641 // Only test the sensitivity implemented by analog gain.
642 if (maxAnalogSensitivity > maxSensitivity) {
643 // Fallback to maxSensitity
644 maxAnalogSensitivity = maxSensitivity;
645 }
646
647 // sensitivity list, only include the sensitivities that are implemented
648 // purely by analog gain if possible.
649 Vector<int32_t> sensitivities;
650 Vector<int64_t> exposures;
Yin-Chia Yeh8df990b2014-10-31 15:10:11 -0700651 size_t count = (maxAnalogSensitivity - minSensitivity + 99) / 100;
Zhijun He8ef01442013-08-13 17:36:17 -0700652 sensitivities.push_back(minSensitivity);
653 for (size_t i = 1; i < count; i++) {
654 sensitivities.push_back(minSensitivity + i * 100);
655 }
656 sensitivities.push_back(maxAnalogSensitivity);
657 ALOGV("Sensitivity Range: min=%d, max=%d", minSensitivity,
658 maxAnalogSensitivity);
659 int64_t exp = minExp;
660 while (exp < maxExp) {
661 exposures.push_back(exp);
662 exp *= 2;
663 }
664 // Sweep the exposure value for preview, just for visual inspection purpose.
665 uint8_t cmOff = static_cast<uint8_t>(ANDROID_CONTROL_MODE_OFF);
666 for (size_t i = 0; i < exposures.size(); i++) {
667 ASSERT_EQ(OK, previewRequest.update(
668 ANDROID_CONTROL_MODE,
669 &cmOff, 1));
670 ASSERT_EQ(OK, previewRequest.update(
671 ANDROID_SENSOR_EXPOSURE_TIME,
672 &exposures[i], 1));
Bernhard Rosenkränzer1f1d7972014-12-12 22:16:55 +0100673 ALOGV("Submitting preview request %zu with exposure %" PRId64,
Zhijun He8ef01442013-08-13 17:36:17 -0700674 i, exposures[i]);
675
676 ASSERT_EQ(OK, mDevice->setStreamingRequest(previewRequest));
677
678 // Let preview run 200ms on screen for each exposure time.
679 usleep(PREVIEW_RENDERING_TIME_INTERVAL);
680 }
681
682 size_t requestCount = sensitivities.size();
683 if (requestCount > exposures.size()) {
684 requestCount = exposures.size();
685 }
686
Zhijun He914226c2013-09-08 10:56:24 -0700687 // To maintain the request id uniqueness (preview request id is 0), make burst capture start
688 // request id 1 here.
689 int32_t requestIdStart = 1;
Zhijun He8ef01442013-08-13 17:36:17 -0700690 /**
691 * Submit metering request, set default frame duration to minimal possible
692 * value, we want the capture to run as fast as possible. HAL should adjust
693 * the frame duration to minimal necessary value to support the requested
694 * exposure value if exposure is larger than frame duration.
695 */
696 CaptureBurst(meteringRequest, requestCount, exposures, sensitivities,
Zhijun He914226c2013-09-08 10:56:24 -0700697 meteringStream, minFrameDuration, &requestIdStart);
Zhijun He8ef01442013-08-13 17:36:17 -0700698
699 /**
700 * Submit capture request, set default frame duration to minimal possible
701 * value, we want the capture to run as fast as possible. HAL should adjust
702 * the frame duration to minimal necessary value to support the requested
703 * exposure value if exposure is larger than frame duration.
704 */
705 CaptureBurst(captureRequest, requestCount, exposures, sensitivities,
Zhijun He914226c2013-09-08 10:56:24 -0700706 captureStream, minFrameDuration, &requestIdStart);
Zhijun He8ef01442013-08-13 17:36:17 -0700707
708 ASSERT_EQ(OK, mDevice->clearStreamingRequest());
709}
710
711}
712}
713}