2012-03-22 21:11:05 +01:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2012 The Android Open Source Project
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2012-04-23 18:29:38 +02:00
|
|
|
#define LOG_TAG "Camera2_test"
|
|
|
|
#define LOG_NDEBUG 0
|
|
|
|
|
|
|
|
#include <utils/Log.h>
|
2012-03-22 21:11:05 +01:00
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#include <iostream>
|
2012-04-23 18:29:38 +02:00
|
|
|
#include <fstream>
|
|
|
|
|
|
|
|
#include <utils/Vector.h>
|
|
|
|
#include <gui/CpuConsumer.h>
|
2012-05-22 19:41:20 +02:00
|
|
|
#include <ui/PixelFormat.h>
|
2012-04-23 18:29:38 +02:00
|
|
|
#include <system/camera_metadata.h>
|
|
|
|
|
|
|
|
#include "camera2_utils.h"
|
|
|
|
|
|
|
|
namespace android {
|
2012-11-05 20:14:49 +01:00
|
|
|
namespace camera2 {
|
|
|
|
namespace tests {
|
2012-03-22 21:11:05 +01:00
|
|
|
|
|
|
|
class Camera2Test: public testing::Test {
|
|
|
|
public:
|
|
|
|
static void SetUpTestCase() {
|
|
|
|
int res;
|
|
|
|
|
|
|
|
hw_module_t *module = NULL;
|
|
|
|
res = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
|
|
|
|
(const hw_module_t **)&module);
|
|
|
|
|
|
|
|
ASSERT_EQ(0, res)
|
|
|
|
<< "Failure opening camera hardware module: " << res;
|
|
|
|
ASSERT_TRUE(NULL != module)
|
|
|
|
<< "No camera module was set by hw_get_module";
|
|
|
|
|
2012-04-23 18:29:38 +02:00
|
|
|
IF_ALOGV() {
|
|
|
|
std::cout << " Camera module name: "
|
|
|
|
<< module->name << std::endl;
|
|
|
|
std::cout << " Camera module author: "
|
|
|
|
<< module->author << std::endl;
|
|
|
|
std::cout << " Camera module API version: 0x" << std::hex
|
|
|
|
<< module->module_api_version << std::endl;
|
|
|
|
std::cout << " Camera module HAL API version: 0x" << std::hex
|
|
|
|
<< module->hal_api_version << std::endl;
|
|
|
|
}
|
2012-03-22 21:11:05 +01:00
|
|
|
|
|
|
|
int16_t version2_0 = CAMERA_MODULE_API_VERSION_2_0;
|
|
|
|
ASSERT_EQ(version2_0, module->module_api_version)
|
|
|
|
<< "Camera module version is 0x"
|
|
|
|
<< std::hex << module->module_api_version
|
|
|
|
<< ", not 2.0. (0x"
|
|
|
|
<< std::hex << CAMERA_MODULE_API_VERSION_2_0 << ")";
|
|
|
|
|
|
|
|
sCameraModule = reinterpret_cast<camera_module_t*>(module);
|
|
|
|
|
|
|
|
sNumCameras = sCameraModule->get_number_of_cameras();
|
|
|
|
ASSERT_LT(0, sNumCameras) << "No camera devices available!";
|
|
|
|
|
2012-04-23 18:29:38 +02:00
|
|
|
IF_ALOGV() {
|
|
|
|
std::cout << " Camera device count: " << sNumCameras << std::endl;
|
|
|
|
}
|
|
|
|
|
2012-03-22 21:11:05 +01:00
|
|
|
sCameraSupportsHal2 = new bool[sNumCameras];
|
|
|
|
|
|
|
|
for (int i = 0; i < sNumCameras; i++) {
|
|
|
|
camera_info info;
|
|
|
|
res = sCameraModule->get_camera_info(i, &info);
|
|
|
|
ASSERT_EQ(0, res)
|
|
|
|
<< "Failure getting camera info for camera " << i;
|
2012-04-23 18:29:38 +02:00
|
|
|
IF_ALOGV() {
|
|
|
|
std::cout << " Camera device: " << std::dec
|
|
|
|
<< i << std::endl;;
|
|
|
|
std::cout << " Facing: " << std::dec
|
|
|
|
<< info.facing << std::endl;
|
|
|
|
std::cout << " Orientation: " << std::dec
|
|
|
|
<< info.orientation << std::endl;
|
|
|
|
std::cout << " Version: 0x" << std::hex <<
|
|
|
|
info.device_version << std::endl;
|
|
|
|
}
|
2012-03-22 21:11:05 +01:00
|
|
|
if (info.device_version >= CAMERA_DEVICE_API_VERSION_2_0) {
|
|
|
|
sCameraSupportsHal2[i] = true;
|
|
|
|
ASSERT_TRUE(NULL != info.static_camera_characteristics);
|
2012-04-23 18:29:38 +02:00
|
|
|
IF_ALOGV() {
|
|
|
|
std::cout << " Static camera metadata:" << std::endl;
|
2012-07-30 19:12:40 +02:00
|
|
|
dump_indented_camera_metadata(info.static_camera_characteristics,
|
|
|
|
0, 1, 6);
|
2012-04-23 18:29:38 +02:00
|
|
|
}
|
2012-03-22 21:11:05 +01:00
|
|
|
} else {
|
|
|
|
sCameraSupportsHal2[i] = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-05 20:14:49 +01:00
|
|
|
static void TearDownTestCase() {
|
|
|
|
hw_module_t *module = reinterpret_cast<hw_module_t*>(sCameraModule);
|
|
|
|
ASSERT_EQ(0, HWModuleHelpers::closeModule(module));
|
|
|
|
}
|
|
|
|
|
2012-03-22 21:11:05 +01:00
|
|
|
static const camera_module_t *getCameraModule() {
|
|
|
|
return sCameraModule;
|
|
|
|
}
|
|
|
|
|
2012-04-23 18:29:38 +02:00
|
|
|
static int getNumCameras() {
|
|
|
|
return sNumCameras;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool isHal2Supported(int id) {
|
|
|
|
return sCameraSupportsHal2[id];
|
|
|
|
}
|
|
|
|
|
|
|
|
static camera2_device_t *openCameraDevice(int id) {
|
|
|
|
ALOGV("Opening camera %d", id);
|
2012-03-22 21:11:05 +01:00
|
|
|
if (NULL == sCameraSupportsHal2) return NULL;
|
|
|
|
if (id >= sNumCameras) return NULL;
|
|
|
|
if (!sCameraSupportsHal2[id]) return NULL;
|
|
|
|
|
|
|
|
hw_device_t *device = NULL;
|
|
|
|
const camera_module_t *cam_module = getCameraModule();
|
2012-04-23 18:29:38 +02:00
|
|
|
if (cam_module == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-03-22 21:11:05 +01:00
|
|
|
char camId[10];
|
|
|
|
int res;
|
|
|
|
|
|
|
|
snprintf(camId, 10, "%d", id);
|
|
|
|
res = cam_module->common.methods->open(
|
|
|
|
(const hw_module_t*)cam_module,
|
|
|
|
camId,
|
|
|
|
&device);
|
2012-04-23 18:29:38 +02:00
|
|
|
if (res != NO_ERROR || device == NULL) {
|
2012-03-22 21:11:05 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
camera2_device_t *cam_device =
|
|
|
|
reinterpret_cast<camera2_device_t*>(device);
|
|
|
|
return cam_device;
|
|
|
|
}
|
|
|
|
|
2012-04-23 18:29:38 +02:00
|
|
|
static status_t configureCameraDevice(camera2_device_t *dev,
|
|
|
|
MetadataQueue &requestQueue,
|
|
|
|
MetadataQueue &frameQueue,
|
|
|
|
NotifierListener &listener) {
|
|
|
|
|
|
|
|
status_t err;
|
|
|
|
|
|
|
|
err = dev->ops->set_request_queue_src_ops(dev,
|
|
|
|
requestQueue.getToConsumerInterface());
|
|
|
|
if (err != OK) return err;
|
|
|
|
|
|
|
|
requestQueue.setFromConsumerInterface(dev);
|
|
|
|
|
|
|
|
err = dev->ops->set_frame_queue_dst_ops(dev,
|
|
|
|
frameQueue.getToProducerInterface());
|
|
|
|
if (err != OK) return err;
|
|
|
|
|
|
|
|
err = listener.getNotificationsFrom(dev);
|
|
|
|
if (err != OK) return err;
|
|
|
|
|
|
|
|
vendor_tag_query_ops_t *vendor_metadata_tag_ops;
|
|
|
|
err = dev->ops->get_metadata_vendor_tag_ops(dev, &vendor_metadata_tag_ops);
|
|
|
|
if (err != OK) return err;
|
|
|
|
|
|
|
|
err = set_camera_metadata_vendor_tag_ops(vendor_metadata_tag_ops);
|
|
|
|
if (err != OK) return err;
|
|
|
|
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static status_t closeCameraDevice(camera2_device_t *cam_dev) {
|
|
|
|
int res;
|
|
|
|
ALOGV("Closing camera %p", cam_dev);
|
|
|
|
|
|
|
|
hw_device_t *dev = reinterpret_cast<hw_device_t *>(cam_dev);
|
|
|
|
res = dev->close(dev);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setUpCamera(int id) {
|
|
|
|
ASSERT_GT(sNumCameras, id);
|
|
|
|
status_t res;
|
|
|
|
|
|
|
|
if (mDevice != NULL) {
|
|
|
|
closeCameraDevice(mDevice);
|
|
|
|
}
|
|
|
|
mDevice = openCameraDevice(id);
|
|
|
|
ASSERT_TRUE(NULL != mDevice) << "Failed to open camera device";
|
|
|
|
|
|
|
|
camera_info info;
|
|
|
|
res = sCameraModule->get_camera_info(id, &info);
|
|
|
|
ASSERT_EQ(OK, res);
|
2012-03-22 21:11:05 +01:00
|
|
|
|
2012-04-23 18:29:38 +02:00
|
|
|
mStaticInfo = info.static_camera_characteristics;
|
|
|
|
|
|
|
|
res = configureCameraDevice(mDevice,
|
|
|
|
mRequests,
|
|
|
|
mFrames,
|
|
|
|
mNotifications);
|
|
|
|
ASSERT_EQ(OK, res) << "Failure to configure camera device";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void setUpStream(sp<ISurfaceTexture> consumer,
|
|
|
|
int width, int height, int format, int *id) {
|
|
|
|
status_t res;
|
|
|
|
|
|
|
|
StreamAdapter* stream = new StreamAdapter(consumer);
|
|
|
|
|
|
|
|
ALOGV("Creating stream, format 0x%x, %d x %d", format, width, height);
|
|
|
|
res = stream->connectToDevice(mDevice, width, height, format);
|
|
|
|
ASSERT_EQ(NO_ERROR, res) << "Failed to connect to stream: "
|
|
|
|
<< strerror(-res);
|
|
|
|
mStreams.push_back(stream);
|
|
|
|
|
|
|
|
*id = stream->getId();
|
|
|
|
}
|
|
|
|
|
|
|
|
void disconnectStream(int id) {
|
|
|
|
status_t res;
|
|
|
|
unsigned int i=0;
|
|
|
|
for (; i < mStreams.size(); i++) {
|
|
|
|
if (mStreams[i]->getId() == id) {
|
|
|
|
res = mStreams[i]->disconnect();
|
|
|
|
ASSERT_EQ(NO_ERROR, res) <<
|
|
|
|
"Failed to disconnect stream " << id;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ASSERT_GT(mStreams.size(), i) << "Stream id not found:" << id;
|
|
|
|
}
|
|
|
|
|
2012-05-12 01:18:42 +02:00
|
|
|
void getResolutionList(int32_t format,
|
2012-08-24 21:32:17 +02:00
|
|
|
const int32_t **list,
|
2012-04-23 18:29:38 +02:00
|
|
|
size_t *count) {
|
2012-05-22 19:41:20 +02:00
|
|
|
ALOGV("Getting resolutions for format %x", format);
|
2012-04-23 18:29:38 +02:00
|
|
|
status_t res;
|
2012-08-28 23:01:26 +02:00
|
|
|
if (format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
|
2012-08-24 21:32:17 +02:00
|
|
|
camera_metadata_ro_entry_t availableFormats;
|
|
|
|
res = find_camera_metadata_ro_entry(mStaticInfo,
|
2012-05-21 02:25:53 +02:00
|
|
|
ANDROID_SCALER_AVAILABLE_FORMATS,
|
|
|
|
&availableFormats);
|
|
|
|
ASSERT_EQ(OK, res);
|
|
|
|
|
|
|
|
uint32_t formatIdx;
|
|
|
|
for (formatIdx=0; formatIdx < availableFormats.count; formatIdx++) {
|
|
|
|
if (availableFormats.data.i32[formatIdx] == format) break;
|
|
|
|
}
|
|
|
|
ASSERT_NE(availableFormats.count, formatIdx)
|
2012-04-23 18:29:38 +02:00
|
|
|
<< "No support found for format 0x" << std::hex << format;
|
|
|
|
}
|
|
|
|
|
2012-08-24 21:32:17 +02:00
|
|
|
camera_metadata_ro_entry_t availableSizes;
|
2012-05-21 02:25:53 +02:00
|
|
|
if (format == HAL_PIXEL_FORMAT_RAW_SENSOR) {
|
2012-08-24 21:32:17 +02:00
|
|
|
res = find_camera_metadata_ro_entry(mStaticInfo,
|
2012-05-21 02:25:53 +02:00
|
|
|
ANDROID_SCALER_AVAILABLE_RAW_SIZES,
|
|
|
|
&availableSizes);
|
2012-05-22 19:41:20 +02:00
|
|
|
} else if (format == HAL_PIXEL_FORMAT_BLOB) {
|
2012-08-24 21:32:17 +02:00
|
|
|
res = find_camera_metadata_ro_entry(mStaticInfo,
|
2012-05-22 19:41:20 +02:00
|
|
|
ANDROID_SCALER_AVAILABLE_JPEG_SIZES,
|
|
|
|
&availableSizes);
|
2012-05-21 02:25:53 +02:00
|
|
|
} else {
|
2012-08-24 21:32:17 +02:00
|
|
|
res = find_camera_metadata_ro_entry(mStaticInfo,
|
2012-05-21 02:25:53 +02:00
|
|
|
ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES,
|
|
|
|
&availableSizes);
|
|
|
|
}
|
2012-05-22 19:41:20 +02:00
|
|
|
ASSERT_EQ(OK, res);
|
2012-04-23 18:29:38 +02:00
|
|
|
|
2012-05-21 02:25:53 +02:00
|
|
|
*list = availableSizes.data.i32;
|
|
|
|
*count = availableSizes.count;
|
2012-04-23 18:29:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual void SetUp() {
|
|
|
|
const ::testing::TestInfo* const testInfo =
|
|
|
|
::testing::UnitTest::GetInstance()->current_test_info();
|
|
|
|
|
|
|
|
ALOGV("*** Starting test %s in test case %s", testInfo->name(), testInfo->test_case_name());
|
|
|
|
mDevice = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void TearDown() {
|
|
|
|
for (unsigned int i = 0; i < mStreams.size(); i++) {
|
|
|
|
delete mStreams[i];
|
|
|
|
}
|
|
|
|
if (mDevice != NULL) {
|
|
|
|
closeCameraDevice(mDevice);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
camera2_device *mDevice;
|
2012-08-24 21:32:17 +02:00
|
|
|
const camera_metadata_t *mStaticInfo;
|
2012-04-23 18:29:38 +02:00
|
|
|
|
|
|
|
MetadataQueue mRequests;
|
|
|
|
MetadataQueue mFrames;
|
|
|
|
NotifierListener mNotifications;
|
|
|
|
|
|
|
|
Vector<StreamAdapter*> mStreams;
|
|
|
|
|
|
|
|
private:
|
2012-03-22 21:11:05 +01:00
|
|
|
static camera_module_t *sCameraModule;
|
2012-04-23 18:29:38 +02:00
|
|
|
static int sNumCameras;
|
|
|
|
static bool *sCameraSupportsHal2;
|
2012-03-22 21:11:05 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
camera_module_t *Camera2Test::sCameraModule = NULL;
|
2012-04-23 18:29:38 +02:00
|
|
|
bool *Camera2Test::sCameraSupportsHal2 = NULL;
|
|
|
|
int Camera2Test::sNumCameras = 0;
|
2012-03-22 21:11:05 +01:00
|
|
|
|
2012-04-23 18:29:38 +02:00
|
|
|
static const nsecs_t USEC = 1000;
|
|
|
|
static const nsecs_t MSEC = 1000*USEC;
|
|
|
|
static const nsecs_t SEC = 1000*MSEC;
|
2012-03-22 21:11:05 +01:00
|
|
|
|
2012-04-23 18:29:38 +02:00
|
|
|
|
|
|
|
TEST_F(Camera2Test, OpenClose) {
|
|
|
|
status_t res;
|
|
|
|
|
|
|
|
for (int id = 0; id < getNumCameras(); id++) {
|
|
|
|
if (!isHal2Supported(id)) continue;
|
|
|
|
|
|
|
|
camera2_device_t *d = openCameraDevice(id);
|
|
|
|
ASSERT_TRUE(NULL != d) << "Failed to open camera device";
|
|
|
|
|
|
|
|
res = closeCameraDevice(d);
|
|
|
|
ASSERT_EQ(NO_ERROR, res) << "Failed to close camera device";
|
|
|
|
}
|
2012-03-22 21:11:05 +01:00
|
|
|
}
|
2012-04-23 18:29:38 +02:00
|
|
|
|
|
|
|
TEST_F(Camera2Test, Capture1Raw) {
|
|
|
|
status_t res;
|
|
|
|
|
|
|
|
for (int id = 0; id < getNumCameras(); id++) {
|
|
|
|
if (!isHal2Supported(id)) continue;
|
|
|
|
|
|
|
|
ASSERT_NO_FATAL_FAILURE(setUpCamera(id));
|
|
|
|
|
|
|
|
sp<CpuConsumer> rawConsumer = new CpuConsumer(1);
|
|
|
|
sp<FrameWaiter> rawWaiter = new FrameWaiter();
|
|
|
|
rawConsumer->setFrameAvailableListener(rawWaiter);
|
|
|
|
|
2012-08-24 21:32:17 +02:00
|
|
|
const int32_t *rawResolutions;
|
2012-05-12 01:18:42 +02:00
|
|
|
size_t rawResolutionsCount;
|
2012-04-23 18:29:38 +02:00
|
|
|
|
|
|
|
int format = HAL_PIXEL_FORMAT_RAW_SENSOR;
|
|
|
|
|
|
|
|
getResolutionList(format,
|
|
|
|
&rawResolutions, &rawResolutionsCount);
|
2012-05-12 01:18:42 +02:00
|
|
|
ASSERT_LT((size_t)0, rawResolutionsCount);
|
2012-04-23 18:29:38 +02:00
|
|
|
|
|
|
|
// Pick first available raw resolution
|
|
|
|
int width = rawResolutions[0];
|
|
|
|
int height = rawResolutions[1];
|
|
|
|
|
|
|
|
int streamId;
|
|
|
|
ASSERT_NO_FATAL_FAILURE(
|
|
|
|
setUpStream(rawConsumer->getProducerInterface(),
|
|
|
|
width, height, format, &streamId) );
|
|
|
|
|
|
|
|
camera_metadata_t *request;
|
|
|
|
request = allocate_camera_metadata(20, 2000);
|
|
|
|
|
|
|
|
uint8_t metadataMode = ANDROID_REQUEST_METADATA_FULL;
|
|
|
|
add_camera_metadata_entry(request,
|
|
|
|
ANDROID_REQUEST_METADATA_MODE,
|
|
|
|
(void**)&metadataMode, 1);
|
|
|
|
uint32_t outputStreams = streamId;
|
|
|
|
add_camera_metadata_entry(request,
|
|
|
|
ANDROID_REQUEST_OUTPUT_STREAMS,
|
|
|
|
(void**)&outputStreams, 1);
|
|
|
|
|
2012-05-21 02:25:53 +02:00
|
|
|
uint64_t exposureTime = 10*MSEC;
|
2012-04-23 18:29:38 +02:00
|
|
|
add_camera_metadata_entry(request,
|
|
|
|
ANDROID_SENSOR_EXPOSURE_TIME,
|
|
|
|
(void**)&exposureTime, 1);
|
|
|
|
uint64_t frameDuration = 30*MSEC;
|
|
|
|
add_camera_metadata_entry(request,
|
|
|
|
ANDROID_SENSOR_FRAME_DURATION,
|
|
|
|
(void**)&frameDuration, 1);
|
|
|
|
uint32_t sensitivity = 100;
|
|
|
|
add_camera_metadata_entry(request,
|
|
|
|
ANDROID_SENSOR_SENSITIVITY,
|
|
|
|
(void**)&sensitivity, 1);
|
|
|
|
|
2012-05-21 02:25:53 +02:00
|
|
|
uint32_t hourOfDay = 12;
|
2012-04-23 18:29:38 +02:00
|
|
|
add_camera_metadata_entry(request,
|
|
|
|
0x80000000, // EMULATOR_HOUROFDAY
|
|
|
|
&hourOfDay, 1);
|
|
|
|
|
|
|
|
IF_ALOGV() {
|
|
|
|
std::cout << "Input request: " << std::endl;
|
2012-07-30 19:12:40 +02:00
|
|
|
dump_indented_camera_metadata(request, 0, 1, 2);
|
2012-04-23 18:29:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
res = mRequests.enqueue(request);
|
|
|
|
ASSERT_EQ(NO_ERROR, res) << "Can't enqueue request: " << strerror(-res);
|
|
|
|
|
|
|
|
res = mFrames.waitForBuffer(exposureTime + SEC);
|
|
|
|
ASSERT_EQ(NO_ERROR, res) << "No frame to get: " << strerror(-res);
|
|
|
|
|
|
|
|
camera_metadata_t *frame;
|
|
|
|
res = mFrames.dequeue(&frame);
|
|
|
|
ASSERT_EQ(NO_ERROR, res);
|
|
|
|
ASSERT_TRUE(frame != NULL);
|
|
|
|
|
|
|
|
IF_ALOGV() {
|
|
|
|
std::cout << "Output frame:" << std::endl;
|
2012-07-30 19:12:40 +02:00
|
|
|
dump_indented_camera_metadata(frame, 0, 1, 2);
|
2012-04-23 18:29:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
res = rawWaiter->waitForFrame(exposureTime + SEC);
|
|
|
|
ASSERT_EQ(NO_ERROR, res);
|
|
|
|
|
|
|
|
CpuConsumer::LockedBuffer buffer;
|
|
|
|
res = rawConsumer->lockNextBuffer(&buffer);
|
|
|
|
ASSERT_EQ(NO_ERROR, res);
|
|
|
|
|
|
|
|
IF_ALOGV() {
|
|
|
|
const char *dumpname =
|
|
|
|
"/data/local/tmp/camera2_test-capture1raw-dump.raw";
|
|
|
|
ALOGV("Dumping raw buffer to %s", dumpname);
|
|
|
|
// Write to file
|
|
|
|
std::ofstream rawFile(dumpname);
|
2012-05-22 19:41:20 +02:00
|
|
|
size_t bpp = 2;
|
2012-04-23 18:29:38 +02:00
|
|
|
for (unsigned int y = 0; y < buffer.height; y++) {
|
2012-05-22 19:41:20 +02:00
|
|
|
rawFile.write(
|
|
|
|
(const char *)(buffer.data + y * buffer.stride * bpp),
|
|
|
|
buffer.width * bpp);
|
2012-04-23 18:29:38 +02:00
|
|
|
}
|
|
|
|
rawFile.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
res = rawConsumer->unlockBuffer(buffer);
|
|
|
|
ASSERT_EQ(NO_ERROR, res);
|
|
|
|
|
|
|
|
ASSERT_NO_FATAL_FAILURE(disconnectStream(streamId));
|
|
|
|
|
|
|
|
res = closeCameraDevice(mDevice);
|
|
|
|
ASSERT_EQ(NO_ERROR, res) << "Failed to close camera device";
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(Camera2Test, CaptureBurstRaw) {
|
|
|
|
status_t res;
|
|
|
|
|
|
|
|
for (int id = 0; id < getNumCameras(); id++) {
|
|
|
|
if (!isHal2Supported(id)) continue;
|
|
|
|
|
|
|
|
ASSERT_NO_FATAL_FAILURE(setUpCamera(id));
|
|
|
|
|
|
|
|
sp<CpuConsumer> rawConsumer = new CpuConsumer(1);
|
|
|
|
sp<FrameWaiter> rawWaiter = new FrameWaiter();
|
|
|
|
rawConsumer->setFrameAvailableListener(rawWaiter);
|
|
|
|
|
2012-08-24 21:32:17 +02:00
|
|
|
const int32_t *rawResolutions;
|
2012-04-23 18:29:38 +02:00
|
|
|
size_t rawResolutionsCount;
|
|
|
|
|
|
|
|
int format = HAL_PIXEL_FORMAT_RAW_SENSOR;
|
|
|
|
|
|
|
|
getResolutionList(format,
|
|
|
|
&rawResolutions, &rawResolutionsCount);
|
|
|
|
ASSERT_LT((uint32_t)0, rawResolutionsCount);
|
|
|
|
|
|
|
|
// Pick first available raw resolution
|
|
|
|
int width = rawResolutions[0];
|
|
|
|
int height = rawResolutions[1];
|
|
|
|
|
|
|
|
int streamId;
|
|
|
|
ASSERT_NO_FATAL_FAILURE(
|
|
|
|
setUpStream(rawConsumer->getProducerInterface(),
|
|
|
|
width, height, format, &streamId) );
|
|
|
|
|
|
|
|
camera_metadata_t *request;
|
|
|
|
request = allocate_camera_metadata(20, 2000);
|
|
|
|
|
|
|
|
uint8_t metadataMode = ANDROID_REQUEST_METADATA_FULL;
|
|
|
|
add_camera_metadata_entry(request,
|
|
|
|
ANDROID_REQUEST_METADATA_MODE,
|
|
|
|
(void**)&metadataMode, 1);
|
|
|
|
uint32_t outputStreams = streamId;
|
|
|
|
add_camera_metadata_entry(request,
|
|
|
|
ANDROID_REQUEST_OUTPUT_STREAMS,
|
|
|
|
(void**)&outputStreams, 1);
|
|
|
|
|
|
|
|
uint64_t frameDuration = 30*MSEC;
|
|
|
|
add_camera_metadata_entry(request,
|
|
|
|
ANDROID_SENSOR_FRAME_DURATION,
|
|
|
|
(void**)&frameDuration, 1);
|
|
|
|
uint32_t sensitivity = 100;
|
|
|
|
add_camera_metadata_entry(request,
|
|
|
|
ANDROID_SENSOR_SENSITIVITY,
|
|
|
|
(void**)&sensitivity, 1);
|
|
|
|
|
|
|
|
uint32_t hourOfDay = 12;
|
|
|
|
add_camera_metadata_entry(request,
|
|
|
|
0x80000000, // EMULATOR_HOUROFDAY
|
|
|
|
&hourOfDay, 1);
|
|
|
|
|
|
|
|
IF_ALOGV() {
|
|
|
|
std::cout << "Input request template: " << std::endl;
|
2012-07-30 19:12:40 +02:00
|
|
|
dump_indented_camera_metadata(request, 0, 1, 2);
|
2012-04-23 18:29:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int numCaptures = 10;
|
|
|
|
|
|
|
|
// Enqueue numCaptures requests with increasing exposure time
|
|
|
|
|
2012-05-12 01:18:42 +02:00
|
|
|
uint64_t exposureTime = 100 * USEC;
|
2012-04-23 18:29:38 +02:00
|
|
|
for (int reqCount = 0; reqCount < numCaptures; reqCount++ ) {
|
|
|
|
camera_metadata_t *req;
|
|
|
|
req = allocate_camera_metadata(20, 2000);
|
|
|
|
append_camera_metadata(req, request);
|
|
|
|
|
|
|
|
add_camera_metadata_entry(req,
|
|
|
|
ANDROID_SENSOR_EXPOSURE_TIME,
|
|
|
|
(void**)&exposureTime, 1);
|
|
|
|
exposureTime *= 2;
|
|
|
|
|
|
|
|
res = mRequests.enqueue(req);
|
|
|
|
ASSERT_EQ(NO_ERROR, res) << "Can't enqueue request: "
|
|
|
|
<< strerror(-res);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get frames and image buffers one by one
|
2012-05-12 01:18:42 +02:00
|
|
|
uint64_t expectedExposureTime = 100 * USEC;
|
2012-04-23 18:29:38 +02:00
|
|
|
for (int frameCount = 0; frameCount < 10; frameCount++) {
|
2012-05-12 01:18:42 +02:00
|
|
|
res = mFrames.waitForBuffer(SEC + expectedExposureTime);
|
2012-04-23 18:29:38 +02:00
|
|
|
ASSERT_EQ(NO_ERROR, res) << "No frame to get: " << strerror(-res);
|
|
|
|
|
|
|
|
camera_metadata_t *frame;
|
|
|
|
res = mFrames.dequeue(&frame);
|
|
|
|
ASSERT_EQ(NO_ERROR, res);
|
|
|
|
ASSERT_TRUE(frame != NULL);
|
|
|
|
|
2012-05-12 01:18:42 +02:00
|
|
|
camera_metadata_entry_t frameNumber;
|
2012-04-23 18:29:38 +02:00
|
|
|
res = find_camera_metadata_entry(frame,
|
|
|
|
ANDROID_REQUEST_FRAME_COUNT,
|
2012-05-12 01:18:42 +02:00
|
|
|
&frameNumber);
|
2012-04-23 18:29:38 +02:00
|
|
|
ASSERT_EQ(NO_ERROR, res);
|
2012-05-12 01:18:42 +02:00
|
|
|
ASSERT_EQ(frameCount, *frameNumber.data.i32);
|
2012-04-23 18:29:38 +02:00
|
|
|
|
2012-05-12 01:18:42 +02:00
|
|
|
res = rawWaiter->waitForFrame(SEC + expectedExposureTime);
|
2012-04-23 18:29:38 +02:00
|
|
|
ASSERT_EQ(NO_ERROR, res) <<
|
|
|
|
"Never got raw data for capture " << frameCount;
|
|
|
|
|
|
|
|
CpuConsumer::LockedBuffer buffer;
|
|
|
|
res = rawConsumer->lockNextBuffer(&buffer);
|
|
|
|
ASSERT_EQ(NO_ERROR, res);
|
|
|
|
|
|
|
|
IF_ALOGV() {
|
|
|
|
char dumpname[60];
|
|
|
|
snprintf(dumpname, 60,
|
2012-05-12 01:18:42 +02:00
|
|
|
"/data/local/tmp/camera2_test-"
|
|
|
|
"captureBurstRaw-dump_%d.raw",
|
2012-04-23 18:29:38 +02:00
|
|
|
frameCount);
|
|
|
|
ALOGV("Dumping raw buffer to %s", dumpname);
|
|
|
|
// Write to file
|
|
|
|
std::ofstream rawFile(dumpname);
|
|
|
|
for (unsigned int y = 0; y < buffer.height; y++) {
|
|
|
|
rawFile.write(
|
|
|
|
(const char *)(buffer.data + y * buffer.stride * 2),
|
|
|
|
buffer.width * 2);
|
|
|
|
}
|
|
|
|
rawFile.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
res = rawConsumer->unlockBuffer(buffer);
|
|
|
|
ASSERT_EQ(NO_ERROR, res);
|
2012-05-12 01:18:42 +02:00
|
|
|
|
|
|
|
expectedExposureTime *= 2;
|
2012-04-23 18:29:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-15 00:25:27 +02:00
|
|
|
TEST_F(Camera2Test, ConstructDefaultRequests) {
|
|
|
|
status_t res;
|
|
|
|
|
|
|
|
for (int id = 0; id < getNumCameras(); id++) {
|
|
|
|
if (!isHal2Supported(id)) continue;
|
|
|
|
|
|
|
|
ASSERT_NO_FATAL_FAILURE(setUpCamera(id));
|
|
|
|
|
|
|
|
for (int i = CAMERA2_TEMPLATE_PREVIEW; i < CAMERA2_TEMPLATE_COUNT;
|
|
|
|
i++) {
|
|
|
|
camera_metadata_t *request = NULL;
|
|
|
|
res = mDevice->ops->construct_default_request(mDevice,
|
|
|
|
i,
|
|
|
|
&request);
|
|
|
|
EXPECT_EQ(NO_ERROR, res) <<
|
|
|
|
"Unable to construct request from template type %d", i;
|
|
|
|
EXPECT_TRUE(request != NULL);
|
|
|
|
EXPECT_LT((size_t)0, get_camera_metadata_entry_count(request));
|
|
|
|
EXPECT_LT((size_t)0, get_camera_metadata_data_count(request));
|
|
|
|
|
|
|
|
IF_ALOGV() {
|
|
|
|
std::cout << " ** Template type " << i << ":"<<std::endl;
|
2012-07-30 19:12:40 +02:00
|
|
|
dump_indented_camera_metadata(request, 0, 2, 4);
|
2012-05-15 00:25:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
free_camera_metadata(request);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-05 20:14:49 +01:00
|
|
|
TEST_F(Camera2Test, DISABLED_Capture1Jpeg) {
|
2012-05-22 19:41:20 +02:00
|
|
|
status_t res;
|
|
|
|
|
|
|
|
for (int id = 0; id < getNumCameras(); id++) {
|
|
|
|
if (!isHal2Supported(id)) continue;
|
|
|
|
|
|
|
|
ASSERT_NO_FATAL_FAILURE(setUpCamera(id));
|
|
|
|
|
|
|
|
sp<CpuConsumer> jpegConsumer = new CpuConsumer(1);
|
|
|
|
sp<FrameWaiter> jpegWaiter = new FrameWaiter();
|
|
|
|
jpegConsumer->setFrameAvailableListener(jpegWaiter);
|
|
|
|
|
2012-08-24 21:32:17 +02:00
|
|
|
const int32_t *jpegResolutions;
|
2012-05-22 19:41:20 +02:00
|
|
|
size_t jpegResolutionsCount;
|
|
|
|
|
|
|
|
int format = HAL_PIXEL_FORMAT_BLOB;
|
|
|
|
|
|
|
|
getResolutionList(format,
|
|
|
|
&jpegResolutions, &jpegResolutionsCount);
|
|
|
|
ASSERT_LT((size_t)0, jpegResolutionsCount);
|
|
|
|
|
|
|
|
// Pick first available JPEG resolution
|
|
|
|
int width = jpegResolutions[0];
|
|
|
|
int height = jpegResolutions[1];
|
|
|
|
|
|
|
|
int streamId;
|
|
|
|
ASSERT_NO_FATAL_FAILURE(
|
|
|
|
setUpStream(jpegConsumer->getProducerInterface(),
|
|
|
|
width, height, format, &streamId) );
|
|
|
|
|
|
|
|
camera_metadata_t *request;
|
|
|
|
request = allocate_camera_metadata(20, 2000);
|
|
|
|
|
|
|
|
uint8_t metadataMode = ANDROID_REQUEST_METADATA_FULL;
|
|
|
|
add_camera_metadata_entry(request,
|
|
|
|
ANDROID_REQUEST_METADATA_MODE,
|
|
|
|
(void**)&metadataMode, 1);
|
|
|
|
uint32_t outputStreams = streamId;
|
|
|
|
add_camera_metadata_entry(request,
|
|
|
|
ANDROID_REQUEST_OUTPUT_STREAMS,
|
|
|
|
(void**)&outputStreams, 1);
|
|
|
|
|
|
|
|
uint64_t exposureTime = 10*MSEC;
|
|
|
|
add_camera_metadata_entry(request,
|
|
|
|
ANDROID_SENSOR_EXPOSURE_TIME,
|
|
|
|
(void**)&exposureTime, 1);
|
|
|
|
uint64_t frameDuration = 30*MSEC;
|
|
|
|
add_camera_metadata_entry(request,
|
|
|
|
ANDROID_SENSOR_FRAME_DURATION,
|
|
|
|
(void**)&frameDuration, 1);
|
|
|
|
uint32_t sensitivity = 100;
|
|
|
|
add_camera_metadata_entry(request,
|
|
|
|
ANDROID_SENSOR_SENSITIVITY,
|
|
|
|
(void**)&sensitivity, 1);
|
|
|
|
|
|
|
|
uint32_t hourOfDay = 12;
|
|
|
|
add_camera_metadata_entry(request,
|
|
|
|
0x80000000, // EMULATOR_HOUROFDAY
|
|
|
|
&hourOfDay, 1);
|
|
|
|
|
|
|
|
IF_ALOGV() {
|
|
|
|
std::cout << "Input request: " << std::endl;
|
2012-07-30 19:12:40 +02:00
|
|
|
dump_indented_camera_metadata(request, 0, 1, 4);
|
2012-05-22 19:41:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
res = mRequests.enqueue(request);
|
|
|
|
ASSERT_EQ(NO_ERROR, res) << "Can't enqueue request: " << strerror(-res);
|
|
|
|
|
|
|
|
res = mFrames.waitForBuffer(exposureTime + SEC);
|
|
|
|
ASSERT_EQ(NO_ERROR, res) << "No frame to get: " << strerror(-res);
|
|
|
|
|
|
|
|
camera_metadata_t *frame;
|
|
|
|
res = mFrames.dequeue(&frame);
|
|
|
|
ASSERT_EQ(NO_ERROR, res);
|
|
|
|
ASSERT_TRUE(frame != NULL);
|
|
|
|
|
|
|
|
IF_ALOGV() {
|
|
|
|
std::cout << "Output frame:" << std::endl;
|
2012-07-30 19:12:40 +02:00
|
|
|
dump_indented_camera_metadata(frame, 0, 1, 4);
|
2012-05-22 19:41:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
res = jpegWaiter->waitForFrame(exposureTime + SEC);
|
|
|
|
ASSERT_EQ(NO_ERROR, res);
|
|
|
|
|
|
|
|
CpuConsumer::LockedBuffer buffer;
|
|
|
|
res = jpegConsumer->lockNextBuffer(&buffer);
|
|
|
|
ASSERT_EQ(NO_ERROR, res);
|
|
|
|
|
|
|
|
IF_ALOGV() {
|
|
|
|
const char *dumpname =
|
|
|
|
"/data/local/tmp/camera2_test-capture1jpeg-dump.jpeg";
|
|
|
|
ALOGV("Dumping raw buffer to %s", dumpname);
|
|
|
|
// Write to file
|
|
|
|
std::ofstream jpegFile(dumpname);
|
|
|
|
size_t bpp = 1;
|
|
|
|
for (unsigned int y = 0; y < buffer.height; y++) {
|
|
|
|
jpegFile.write(
|
|
|
|
(const char *)(buffer.data + y * buffer.stride * bpp),
|
|
|
|
buffer.width * bpp);
|
|
|
|
}
|
|
|
|
jpegFile.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
res = jpegConsumer->unlockBuffer(buffer);
|
|
|
|
ASSERT_EQ(NO_ERROR, res);
|
|
|
|
|
|
|
|
ASSERT_NO_FATAL_FAILURE(disconnectStream(streamId));
|
|
|
|
|
|
|
|
res = closeCameraDevice(mDevice);
|
|
|
|
ASSERT_EQ(NO_ERROR, res) << "Failed to close camera device";
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-05 20:14:49 +01:00
|
|
|
} // namespace tests
|
|
|
|
} // namespace camera2
|
2012-04-23 18:29:38 +02:00
|
|
|
} // namespace android
|