blob: 50f0b064f13dbfc6368e38a566622dde937e6613 [file] [log] [blame]
Eino-Ville Talvalafed0c022012-03-22 13:11:05 -07001/*
2 * Copyright (C) 2012 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
Eino-Ville Talvala567b4a22012-04-23 09:29:38 -070017#define LOG_TAG "Camera2_test"
18#define LOG_NDEBUG 0
19
20#include <utils/Log.h>
Eino-Ville Talvalafed0c022012-03-22 13:11:05 -070021#include <gtest/gtest.h>
22#include <iostream>
Eino-Ville Talvala567b4a22012-04-23 09:29:38 -070023#include <fstream>
24
25#include <utils/Vector.h>
26#include <gui/CpuConsumer.h>
27#include <system/camera_metadata.h>
28
29#include "camera2_utils.h"
30
31namespace android {
Eino-Ville Talvalafed0c022012-03-22 13:11:05 -070032
33class Camera2Test: public testing::Test {
34 public:
35 static void SetUpTestCase() {
36 int res;
37
38 hw_module_t *module = NULL;
39 res = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
40 (const hw_module_t **)&module);
41
42 ASSERT_EQ(0, res)
43 << "Failure opening camera hardware module: " << res;
44 ASSERT_TRUE(NULL != module)
45 << "No camera module was set by hw_get_module";
46
Eino-Ville Talvala567b4a22012-04-23 09:29:38 -070047 IF_ALOGV() {
48 std::cout << " Camera module name: "
49 << module->name << std::endl;
50 std::cout << " Camera module author: "
51 << module->author << std::endl;
52 std::cout << " Camera module API version: 0x" << std::hex
53 << module->module_api_version << std::endl;
54 std::cout << " Camera module HAL API version: 0x" << std::hex
55 << module->hal_api_version << std::endl;
56 }
Eino-Ville Talvalafed0c022012-03-22 13:11:05 -070057
58 int16_t version2_0 = CAMERA_MODULE_API_VERSION_2_0;
59 ASSERT_EQ(version2_0, module->module_api_version)
60 << "Camera module version is 0x"
61 << std::hex << module->module_api_version
62 << ", not 2.0. (0x"
63 << std::hex << CAMERA_MODULE_API_VERSION_2_0 << ")";
64
65 sCameraModule = reinterpret_cast<camera_module_t*>(module);
66
67 sNumCameras = sCameraModule->get_number_of_cameras();
68 ASSERT_LT(0, sNumCameras) << "No camera devices available!";
69
Eino-Ville Talvala567b4a22012-04-23 09:29:38 -070070 IF_ALOGV() {
71 std::cout << " Camera device count: " << sNumCameras << std::endl;
72 }
73
Eino-Ville Talvalafed0c022012-03-22 13:11:05 -070074 sCameraSupportsHal2 = new bool[sNumCameras];
75
76 for (int i = 0; i < sNumCameras; i++) {
77 camera_info info;
78 res = sCameraModule->get_camera_info(i, &info);
79 ASSERT_EQ(0, res)
80 << "Failure getting camera info for camera " << i;
Eino-Ville Talvala567b4a22012-04-23 09:29:38 -070081 IF_ALOGV() {
82 std::cout << " Camera device: " << std::dec
83 << i << std::endl;;
84 std::cout << " Facing: " << std::dec
85 << info.facing << std::endl;
86 std::cout << " Orientation: " << std::dec
87 << info.orientation << std::endl;
88 std::cout << " Version: 0x" << std::hex <<
89 info.device_version << std::endl;
90 }
Eino-Ville Talvalafed0c022012-03-22 13:11:05 -070091 if (info.device_version >= CAMERA_DEVICE_API_VERSION_2_0) {
92 sCameraSupportsHal2[i] = true;
93 ASSERT_TRUE(NULL != info.static_camera_characteristics);
Eino-Ville Talvala567b4a22012-04-23 09:29:38 -070094 IF_ALOGV() {
95 std::cout << " Static camera metadata:" << std::endl;
96 dump_camera_metadata(info.static_camera_characteristics,
97 0, 1);
98 }
Eino-Ville Talvalafed0c022012-03-22 13:11:05 -070099 } else {
100 sCameraSupportsHal2[i] = false;
101 }
102 }
103 }
104
105 static const camera_module_t *getCameraModule() {
106 return sCameraModule;
107 }
108
Eino-Ville Talvala567b4a22012-04-23 09:29:38 -0700109 static int getNumCameras() {
110 return sNumCameras;
111 }
112
113 static bool isHal2Supported(int id) {
114 return sCameraSupportsHal2[id];
115 }
116
117 static camera2_device_t *openCameraDevice(int id) {
118 ALOGV("Opening camera %d", id);
Eino-Ville Talvalafed0c022012-03-22 13:11:05 -0700119 if (NULL == sCameraSupportsHal2) return NULL;
120 if (id >= sNumCameras) return NULL;
121 if (!sCameraSupportsHal2[id]) return NULL;
122
123 hw_device_t *device = NULL;
124 const camera_module_t *cam_module = getCameraModule();
Eino-Ville Talvala567b4a22012-04-23 09:29:38 -0700125 if (cam_module == NULL) {
126 return NULL;
127 }
128
Eino-Ville Talvalafed0c022012-03-22 13:11:05 -0700129 char camId[10];
130 int res;
131
132 snprintf(camId, 10, "%d", id);
133 res = cam_module->common.methods->open(
134 (const hw_module_t*)cam_module,
135 camId,
136 &device);
Eino-Ville Talvala567b4a22012-04-23 09:29:38 -0700137 if (res != NO_ERROR || device == NULL) {
Eino-Ville Talvalafed0c022012-03-22 13:11:05 -0700138 return NULL;
139 }
140 camera2_device_t *cam_device =
141 reinterpret_cast<camera2_device_t*>(device);
142 return cam_device;
143 }
144
Eino-Ville Talvala567b4a22012-04-23 09:29:38 -0700145 static status_t configureCameraDevice(camera2_device_t *dev,
146 MetadataQueue &requestQueue,
147 MetadataQueue &frameQueue,
148 NotifierListener &listener) {
Eino-Ville Talvalafed0c022012-03-22 13:11:05 -0700149
Eino-Ville Talvala567b4a22012-04-23 09:29:38 -0700150 status_t err;
151
152 err = dev->ops->set_request_queue_src_ops(dev,
153 requestQueue.getToConsumerInterface());
154 if (err != OK) return err;
155
156 requestQueue.setFromConsumerInterface(dev);
157
158 err = dev->ops->set_frame_queue_dst_ops(dev,
159 frameQueue.getToProducerInterface());
160 if (err != OK) return err;
161
162 err = listener.getNotificationsFrom(dev);
163 if (err != OK) return err;
164
165 vendor_tag_query_ops_t *vendor_metadata_tag_ops;
166 err = dev->ops->get_metadata_vendor_tag_ops(dev, &vendor_metadata_tag_ops);
167 if (err != OK) return err;
168
169 err = set_camera_metadata_vendor_tag_ops(vendor_metadata_tag_ops);
170 if (err != OK) return err;
171
172 return OK;
173 }
174
175 static status_t closeCameraDevice(camera2_device_t *cam_dev) {
176 int res;
177 ALOGV("Closing camera %p", cam_dev);
178
179 hw_device_t *dev = reinterpret_cast<hw_device_t *>(cam_dev);
180 res = dev->close(dev);
181 return res;
182 }
183
184 void setUpCamera(int id) {
185 ASSERT_GT(sNumCameras, id);
186 status_t res;
187
188 if (mDevice != NULL) {
189 closeCameraDevice(mDevice);
190 }
191 mDevice = openCameraDevice(id);
192 ASSERT_TRUE(NULL != mDevice) << "Failed to open camera device";
193
194 camera_info info;
195 res = sCameraModule->get_camera_info(id, &info);
196 ASSERT_EQ(OK, res);
197
198 mStaticInfo = info.static_camera_characteristics;
199
200 res = configureCameraDevice(mDevice,
201 mRequests,
202 mFrames,
203 mNotifications);
204 ASSERT_EQ(OK, res) << "Failure to configure camera device";
205
206 }
207
208 void setUpStream(sp<ISurfaceTexture> consumer,
209 int width, int height, int format, int *id) {
210 status_t res;
211
212 StreamAdapter* stream = new StreamAdapter(consumer);
213
214 ALOGV("Creating stream, format 0x%x, %d x %d", format, width, height);
215 res = stream->connectToDevice(mDevice, width, height, format);
216 ASSERT_EQ(NO_ERROR, res) << "Failed to connect to stream: "
217 << strerror(-res);
218 mStreams.push_back(stream);
219
220 *id = stream->getId();
221 }
222
223 void disconnectStream(int id) {
224 status_t res;
225 unsigned int i=0;
226 for (; i < mStreams.size(); i++) {
227 if (mStreams[i]->getId() == id) {
228 res = mStreams[i]->disconnect();
229 ASSERT_EQ(NO_ERROR, res) <<
230 "Failed to disconnect stream " << id;
231 break;
232 }
233 }
234 ASSERT_GT(mStreams.size(), i) << "Stream id not found:" << id;
235 }
236
237 void getResolutionList(uint32_t format,
238 uint32_t **list,
239 size_t *count) {
240
241 uint32_t *availableFormats;
242 size_t availableFormatsCount;
243 status_t res;
244 res = find_camera_metadata_entry(mStaticInfo,
245 ANDROID_SCALER_AVAILABLE_FORMATS,
246 NULL,
247 (void**)&availableFormats,
248 &availableFormatsCount);
249 ASSERT_EQ(OK, res);
250
251 uint32_t formatIdx;
252 for (formatIdx=0; formatIdx < availableFormatsCount; formatIdx++) {
253 if (availableFormats[formatIdx] == format) break;
254 }
255 ASSERT_NE(availableFormatsCount, formatIdx)
256 << "No support found for format 0x" << std::hex << format;
257
258 uint32_t *availableSizesPerFormat;
259 size_t availableSizesPerFormatCount;
260 res = find_camera_metadata_entry(mStaticInfo,
261 ANDROID_SCALER_AVAILABLE_SIZES_PER_FORMAT,
262 NULL,
263 (void**)&availableSizesPerFormat,
264 &availableSizesPerFormatCount);
265 ASSERT_EQ(OK, res);
266
267 int size_offset = 0;
268 for (unsigned int i=0; i < formatIdx; i++) {
269 size_offset += availableSizesPerFormat[i];
270 }
271
272 uint32_t *availableSizes;
273 size_t availableSizesCount;
274 res = find_camera_metadata_entry(mStaticInfo,
275 ANDROID_SCALER_AVAILABLE_SIZES,
276 NULL,
277 (void**)&availableSizes,
278 &availableSizesCount);
279 ASSERT_EQ(OK, res);
280
281 *list = availableSizes + size_offset;
282 *count = availableSizesPerFormat[formatIdx];
283 }
284
285 virtual void SetUp() {
286 const ::testing::TestInfo* const testInfo =
287 ::testing::UnitTest::GetInstance()->current_test_info();
288
289 ALOGV("*** Starting test %s in test case %s", testInfo->name(), testInfo->test_case_name());
290 mDevice = NULL;
291 }
292
293 virtual void TearDown() {
294 for (unsigned int i = 0; i < mStreams.size(); i++) {
295 delete mStreams[i];
296 }
297 if (mDevice != NULL) {
298 closeCameraDevice(mDevice);
299 }
300 }
301
302 camera2_device *mDevice;
303 camera_metadata_t *mStaticInfo;
304
305 MetadataQueue mRequests;
306 MetadataQueue mFrames;
307 NotifierListener mNotifications;
308
309 Vector<StreamAdapter*> mStreams;
310
311 private:
Eino-Ville Talvalafed0c022012-03-22 13:11:05 -0700312 static camera_module_t *sCameraModule;
Eino-Ville Talvala567b4a22012-04-23 09:29:38 -0700313 static int sNumCameras;
314 static bool *sCameraSupportsHal2;
Eino-Ville Talvalafed0c022012-03-22 13:11:05 -0700315};
316
317camera_module_t *Camera2Test::sCameraModule = NULL;
Eino-Ville Talvala567b4a22012-04-23 09:29:38 -0700318bool *Camera2Test::sCameraSupportsHal2 = NULL;
319int Camera2Test::sNumCameras = 0;
320
321static const nsecs_t USEC = 1000;
322static const nsecs_t MSEC = 1000*USEC;
323static const nsecs_t SEC = 1000*MSEC;
Eino-Ville Talvalafed0c022012-03-22 13:11:05 -0700324
325
Eino-Ville Talvala567b4a22012-04-23 09:29:38 -0700326TEST_F(Camera2Test, OpenClose) {
327 status_t res;
328
329 for (int id = 0; id < getNumCameras(); id++) {
330 if (!isHal2Supported(id)) continue;
331
332 camera2_device_t *d = openCameraDevice(id);
333 ASSERT_TRUE(NULL != d) << "Failed to open camera device";
334
335 res = closeCameraDevice(d);
336 ASSERT_EQ(NO_ERROR, res) << "Failed to close camera device";
337 }
Eino-Ville Talvalafed0c022012-03-22 13:11:05 -0700338}
Eino-Ville Talvala567b4a22012-04-23 09:29:38 -0700339
340TEST_F(Camera2Test, Capture1Raw) {
341 status_t res;
342
343 for (int id = 0; id < getNumCameras(); id++) {
344 if (!isHal2Supported(id)) continue;
345
346 ASSERT_NO_FATAL_FAILURE(setUpCamera(id));
347
348 sp<CpuConsumer> rawConsumer = new CpuConsumer(1);
349 sp<FrameWaiter> rawWaiter = new FrameWaiter();
350 rawConsumer->setFrameAvailableListener(rawWaiter);
351
352 uint32_t *rawResolutions;
353 size_t rawResolutionsCount;
354
355 int format = HAL_PIXEL_FORMAT_RAW_SENSOR;
356
357 getResolutionList(format,
358 &rawResolutions, &rawResolutionsCount);
359 ASSERT_LT((uint32_t)0, rawResolutionsCount);
360
361 // Pick first available raw resolution
362 int width = rawResolutions[0];
363 int height = rawResolutions[1];
364
365 int streamId;
366 ASSERT_NO_FATAL_FAILURE(
367 setUpStream(rawConsumer->getProducerInterface(),
368 width, height, format, &streamId) );
369
370 camera_metadata_t *request;
371 request = allocate_camera_metadata(20, 2000);
372
373 uint8_t metadataMode = ANDROID_REQUEST_METADATA_FULL;
374 add_camera_metadata_entry(request,
375 ANDROID_REQUEST_METADATA_MODE,
376 (void**)&metadataMode, 1);
377 uint32_t outputStreams = streamId;
378 add_camera_metadata_entry(request,
379 ANDROID_REQUEST_OUTPUT_STREAMS,
380 (void**)&outputStreams, 1);
381
382 uint64_t exposureTime = 2*MSEC;
383 add_camera_metadata_entry(request,
384 ANDROID_SENSOR_EXPOSURE_TIME,
385 (void**)&exposureTime, 1);
386 uint64_t frameDuration = 30*MSEC;
387 add_camera_metadata_entry(request,
388 ANDROID_SENSOR_FRAME_DURATION,
389 (void**)&frameDuration, 1);
390 uint32_t sensitivity = 100;
391 add_camera_metadata_entry(request,
392 ANDROID_SENSOR_SENSITIVITY,
393 (void**)&sensitivity, 1);
394
395 uint32_t hourOfDay = 12;
396 add_camera_metadata_entry(request,
397 0x80000000, // EMULATOR_HOUROFDAY
398 &hourOfDay, 1);
399
400 IF_ALOGV() {
401 std::cout << "Input request: " << std::endl;
402 dump_camera_metadata(request, 0, 1);
403 }
404
405 res = mRequests.enqueue(request);
406 ASSERT_EQ(NO_ERROR, res) << "Can't enqueue request: " << strerror(-res);
407
408 res = mFrames.waitForBuffer(exposureTime + SEC);
409 ASSERT_EQ(NO_ERROR, res) << "No frame to get: " << strerror(-res);
410
411 camera_metadata_t *frame;
412 res = mFrames.dequeue(&frame);
413 ASSERT_EQ(NO_ERROR, res);
414 ASSERT_TRUE(frame != NULL);
415
416 IF_ALOGV() {
417 std::cout << "Output frame:" << std::endl;
418 dump_camera_metadata(frame, 0, 1);
419 }
420
421 res = rawWaiter->waitForFrame(exposureTime + SEC);
422 ASSERT_EQ(NO_ERROR, res);
423
424 CpuConsumer::LockedBuffer buffer;
425 res = rawConsumer->lockNextBuffer(&buffer);
426 ASSERT_EQ(NO_ERROR, res);
427
428 IF_ALOGV() {
429 const char *dumpname =
430 "/data/local/tmp/camera2_test-capture1raw-dump.raw";
431 ALOGV("Dumping raw buffer to %s", dumpname);
432 // Write to file
433 std::ofstream rawFile(dumpname);
434 for (unsigned int y = 0; y < buffer.height; y++) {
435 rawFile.write((const char *)(buffer.data + y * buffer.stride * 2),
436 buffer.width * 2);
437 }
438 rawFile.close();
439 }
440
441 res = rawConsumer->unlockBuffer(buffer);
442 ASSERT_EQ(NO_ERROR, res);
443
444 ASSERT_NO_FATAL_FAILURE(disconnectStream(streamId));
445
446 res = closeCameraDevice(mDevice);
447 ASSERT_EQ(NO_ERROR, res) << "Failed to close camera device";
448
449 }
450}
451
452TEST_F(Camera2Test, CaptureBurstRaw) {
453 status_t res;
454
455 for (int id = 0; id < getNumCameras(); id++) {
456 if (!isHal2Supported(id)) continue;
457
458 ASSERT_NO_FATAL_FAILURE(setUpCamera(id));
459
460 sp<CpuConsumer> rawConsumer = new CpuConsumer(1);
461 sp<FrameWaiter> rawWaiter = new FrameWaiter();
462 rawConsumer->setFrameAvailableListener(rawWaiter);
463
464 uint32_t *rawResolutions;
465 size_t rawResolutionsCount;
466
467 int format = HAL_PIXEL_FORMAT_RAW_SENSOR;
468
469 getResolutionList(format,
470 &rawResolutions, &rawResolutionsCount);
471 ASSERT_LT((uint32_t)0, rawResolutionsCount);
472
473 // Pick first available raw resolution
474 int width = rawResolutions[0];
475 int height = rawResolutions[1];
476
477 int streamId;
478 ASSERT_NO_FATAL_FAILURE(
479 setUpStream(rawConsumer->getProducerInterface(),
480 width, height, format, &streamId) );
481
482 camera_metadata_t *request;
483 request = allocate_camera_metadata(20, 2000);
484
485 uint8_t metadataMode = ANDROID_REQUEST_METADATA_FULL;
486 add_camera_metadata_entry(request,
487 ANDROID_REQUEST_METADATA_MODE,
488 (void**)&metadataMode, 1);
489 uint32_t outputStreams = streamId;
490 add_camera_metadata_entry(request,
491 ANDROID_REQUEST_OUTPUT_STREAMS,
492 (void**)&outputStreams, 1);
493
494 uint64_t frameDuration = 30*MSEC;
495 add_camera_metadata_entry(request,
496 ANDROID_SENSOR_FRAME_DURATION,
497 (void**)&frameDuration, 1);
498 uint32_t sensitivity = 100;
499 add_camera_metadata_entry(request,
500 ANDROID_SENSOR_SENSITIVITY,
501 (void**)&sensitivity, 1);
502
503 uint32_t hourOfDay = 12;
504 add_camera_metadata_entry(request,
505 0x80000000, // EMULATOR_HOUROFDAY
506 &hourOfDay, 1);
507
508 IF_ALOGV() {
509 std::cout << "Input request template: " << std::endl;
510 dump_camera_metadata(request, 0, 1);
511 }
512
513 int numCaptures = 10;
514
515 // Enqueue numCaptures requests with increasing exposure time
516
517 uint64_t exposureTime = 1 * MSEC;
518 for (int reqCount = 0; reqCount < numCaptures; reqCount++ ) {
519 camera_metadata_t *req;
520 req = allocate_camera_metadata(20, 2000);
521 append_camera_metadata(req, request);
522
523 add_camera_metadata_entry(req,
524 ANDROID_SENSOR_EXPOSURE_TIME,
525 (void**)&exposureTime, 1);
526 exposureTime *= 2;
527
528 res = mRequests.enqueue(req);
529 ASSERT_EQ(NO_ERROR, res) << "Can't enqueue request: "
530 << strerror(-res);
531 }
532
533 // Get frames and image buffers one by one
534 for (int frameCount = 0; frameCount < 10; frameCount++) {
535 res = mFrames.waitForBuffer(SEC);
536 ASSERT_EQ(NO_ERROR, res) << "No frame to get: " << strerror(-res);
537
538 camera_metadata_t *frame;
539 res = mFrames.dequeue(&frame);
540 ASSERT_EQ(NO_ERROR, res);
541 ASSERT_TRUE(frame != NULL);
542
543 uint32_t *frameNumber;
544 res = find_camera_metadata_entry(frame,
545 ANDROID_REQUEST_FRAME_COUNT,
546 NULL, (void**)&frameNumber, NULL);
547 ASSERT_EQ(NO_ERROR, res);
548 ASSERT_EQ(frameCount, *frameNumber);
549
550 res = rawWaiter->waitForFrame(SEC);
551 ASSERT_EQ(NO_ERROR, res) <<
552 "Never got raw data for capture " << frameCount;
553
554 CpuConsumer::LockedBuffer buffer;
555 res = rawConsumer->lockNextBuffer(&buffer);
556 ASSERT_EQ(NO_ERROR, res);
557
558 IF_ALOGV() {
559 char dumpname[60];
560 snprintf(dumpname, 60,
561 "/data/local/tmp/camera2_test-capture1raw-dump_%d.raw",
562 frameCount);
563 ALOGV("Dumping raw buffer to %s", dumpname);
564 // Write to file
565 std::ofstream rawFile(dumpname);
566 for (unsigned int y = 0; y < buffer.height; y++) {
567 rawFile.write(
568 (const char *)(buffer.data + y * buffer.stride * 2),
569 buffer.width * 2);
570 }
571 rawFile.close();
572 }
573
574 res = rawConsumer->unlockBuffer(buffer);
575 ASSERT_EQ(NO_ERROR, res);
576 }
577 }
578}
579
580} // namespace android