platform_hardware_libhardware/tests/camera2/camera2.cpp

820 lines
27 KiB
C++
Raw Normal View History

/*
* 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.
*/
#define LOG_TAG "Camera2_test"
//#define LOG_NDEBUG 0
#include <utils/Log.h>
#include <gtest/gtest.h>
#include <iostream>
#include <fstream>
#include <utils/Vector.h>
#include <gui/CpuConsumer.h>
#include <ui/PixelFormat.h>
#include <system/camera_metadata.h>
#include "camera2_utils.h"
#include "TestExtensions.h"
namespace android {
namespace camera2 {
namespace tests {
class Camera2Test: public testing::Test {
public:
void SetUpModule() {
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";
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;
}
int16_t version2_0 = CAMERA_MODULE_API_VERSION_2_0;
ASSERT_LE(version2_0, module->module_api_version)
<< "Camera module version is 0x"
<< std::hex << module->module_api_version
<< ", should be at least 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!";
IF_ALOGV() {
std::cout << " Camera device count: " << sNumCameras << std::endl;
}
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;
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;
}
if (info.device_version >= CAMERA_DEVICE_API_VERSION_2_0 &&
info.device_version < CAMERA_DEVICE_API_VERSION_3_0) {
sCameraSupportsHal2[i] = true;
ASSERT_TRUE(NULL != info.static_camera_characteristics);
IF_ALOGV() {
std::cout << " Static camera metadata:" << std::endl;
dump_indented_camera_metadata(info.static_camera_characteristics,
0, 1, 6);
}
} else {
sCameraSupportsHal2[i] = false;
}
}
}
void TearDownModule() {
hw_module_t *module = reinterpret_cast<hw_module_t*>(sCameraModule);
ASSERT_EQ(0, HWModuleHelpers::closeModule(module));
}
static const camera_module_t *getCameraModule() {
return sCameraModule;
}
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);
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();
if (cam_module == NULL) {
return NULL;
}
char camId[10];
int res;
snprintf(camId, 10, "%d", id);
res = cam_module->common.methods->open(
(const hw_module_t*)cam_module,
camId,
&device);
if (res != NO_ERROR || device == NULL) {
return NULL;
}
camera2_device_t *cam_device =
reinterpret_cast<camera2_device_t*>(device);
return cam_device;
}
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;
if (*cam_dev == NULL ) return OK;
ALOGV("Closing camera %p", cam_dev);
hw_device_t *dev = reinterpret_cast<hw_device_t *>(*cam_dev);
res = dev->close(dev);
*cam_dev = NULL;
return res;
}
void setUpCamera(int id) {
ASSERT_GT(sNumCameras, id);
status_t res;
if (mDevice != NULL) {
closeCameraDevice(&mDevice);
}
mId = id;
mDevice = openCameraDevice(mId);
ASSERT_TRUE(NULL != mDevice) << "Failed to open camera device";
camera_info info;
res = sCameraModule->get_camera_info(id, &info);
ASSERT_EQ(OK, res);
mStaticInfo = info.static_camera_characteristics;
res = configureCameraDevice(mDevice,
mRequests,
mFrames,
mNotifications);
ASSERT_EQ(OK, res) << "Failure to configure camera device";
}
void setUpStream(sp<IGraphicBufferProducer> 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;
}
void getResolutionList(int32_t format,
const int32_t **list,
size_t *count) {
ALOGV("Getting resolutions for format %x", format);
status_t res;
if (format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
camera_metadata_ro_entry_t availableFormats;
res = find_camera_metadata_ro_entry(mStaticInfo,
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)
<< "No support found for format 0x" << std::hex << format;
}
camera_metadata_ro_entry_t availableSizes;
if (format == HAL_PIXEL_FORMAT_RAW_SENSOR) {
res = find_camera_metadata_ro_entry(mStaticInfo,
ANDROID_SCALER_AVAILABLE_RAW_SIZES,
&availableSizes);
} else if (format == HAL_PIXEL_FORMAT_BLOB) {
res = find_camera_metadata_ro_entry(mStaticInfo,
ANDROID_SCALER_AVAILABLE_JPEG_SIZES,
&availableSizes);
} else {
res = find_camera_metadata_ro_entry(mStaticInfo,
ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES,
&availableSizes);
}
ASSERT_EQ(OK, res);
*list = availableSizes.data.i32;
*count = availableSizes.count;
}
status_t waitUntilDrained() {
static const uint32_t kSleepTime = 50000; // 50 ms
static const uint32_t kMaxSleepTime = 10000000; // 10 s
ALOGV("%s: Camera %d: Starting wait", __FUNCTION__, mId);
// TODO: Set up notifications from HAL, instead of sleeping here
uint32_t totalTime = 0;
while (mDevice->ops->get_in_progress_count(mDevice) > 0) {
usleep(kSleepTime);
totalTime += kSleepTime;
if (totalTime > kMaxSleepTime) {
ALOGE("%s: Waited %d us, %d requests still in flight", __FUNCTION__,
mDevice->ops->get_in_progress_count(mDevice), totalTime);
return TIMED_OUT;
}
}
ALOGV("%s: Camera %d: HAL is idle", __FUNCTION__, mId);
return OK;
}
virtual void SetUp() {
TEST_EXTENSION_FORKING_SET_UP;
SetUpModule();
const ::testing::TestInfo* const testInfo =
::testing::UnitTest::GetInstance()->current_test_info();
(void)testInfo;
ALOGV("*** Starting test %s in test case %s", testInfo->name(),
testInfo->test_case_name());
mDevice = NULL;
}
virtual void TearDown() {
TEST_EXTENSION_FORKING_TEAR_DOWN;
for (unsigned int i = 0; i < mStreams.size(); i++) {
delete mStreams[i];
}
if (mDevice != NULL) {
closeCameraDevice(&mDevice);
}
TearDownModule();
}
int mId;
camera2_device *mDevice;
const camera_metadata_t *mStaticInfo;
MetadataQueue mRequests;
MetadataQueue mFrames;
NotifierListener mNotifications;
Vector<StreamAdapter*> mStreams;
private:
static camera_module_t *sCameraModule;
static int sNumCameras;
static bool *sCameraSupportsHal2;
};
camera_module_t *Camera2Test::sCameraModule = NULL;
bool *Camera2Test::sCameraSupportsHal2 = NULL;
int Camera2Test::sNumCameras = 0;
static const nsecs_t USEC = 1000;
static const nsecs_t MSEC = 1000*USEC;
static const nsecs_t SEC = 1000*MSEC;
TEST_F(Camera2Test, OpenClose) {
TEST_EXTENSION_FORKING_INIT;
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";
}
}
TEST_F(Camera2Test, Capture1Raw) {
TEST_EXTENSION_FORKING_INIT;
status_t res;
for (int id = 0; id < getNumCameras(); id++) {
if (!isHal2Supported(id)) continue;
ASSERT_NO_FATAL_FAILURE(setUpCamera(id));
sp<BufferQueue> bq = new BufferQueue();
sp<CpuConsumer> rawConsumer = new CpuConsumer(bq, 1);
sp<FrameWaiter> rawWaiter = new FrameWaiter();
rawConsumer->setFrameAvailableListener(rawWaiter);
const int32_t *rawResolutions;
size_t rawResolutionsCount;
int format = HAL_PIXEL_FORMAT_RAW_SENSOR;
getResolutionList(format,
&rawResolutions, &rawResolutionsCount);
if (rawResolutionsCount <= 0) {
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
std::cerr << "Skipping test "
<< test_info->test_case_name() << "."
<< test_info->name()
<< " because the optional format was not available: "
<< "RAW_SENSOR" << std::endl;
return;
}
ASSERT_LT((size_t)0, rawResolutionsCount);
// Pick first available raw resolution
int width = rawResolutions[0];
int height = rawResolutions[1];
int streamId;
ASSERT_NO_FATAL_FAILURE(
setUpStream(bq, width, height, format, &streamId) );
camera_metadata_t *request;
request = allocate_camera_metadata(20, 2000);
uint8_t metadataMode = ANDROID_REQUEST_METADATA_MODE_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);
uint8_t requestType = ANDROID_REQUEST_TYPE_CAPTURE;
add_camera_metadata_entry(request,
ANDROID_REQUEST_TYPE,
(void**)&requestType, 1);
uint32_t hourOfDay = 12;
add_camera_metadata_entry(request,
0x80000000, // EMULATOR_HOUROFDAY
&hourOfDay, 1);
IF_ALOGV() {
std::cout << "Input request: " << std::endl;
dump_indented_camera_metadata(request, 0, 1, 2);
}
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;
dump_indented_camera_metadata(frame, 0, 1, 2);
}
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);
size_t bpp = 2;
for (unsigned int y = 0; y < buffer.height; y++) {
rawFile.write(
(const char *)(buffer.data + y * buffer.stride * bpp),
buffer.width * bpp);
}
rawFile.close();
}
res = rawConsumer->unlockBuffer(buffer);
ASSERT_EQ(NO_ERROR, res);
ASSERT_EQ(OK, waitUntilDrained());
ASSERT_NO_FATAL_FAILURE(disconnectStream(streamId));
res = closeCameraDevice(&mDevice);
ASSERT_EQ(NO_ERROR, res) << "Failed to close camera device";
}
}
TEST_F(Camera2Test, CaptureBurstRaw) {
TEST_EXTENSION_FORKING_INIT;
status_t res;
for (int id = 0; id < getNumCameras(); id++) {
if (!isHal2Supported(id)) continue;
ASSERT_NO_FATAL_FAILURE(setUpCamera(id));
sp<BufferQueue> bq = new BufferQueue();
sp<CpuConsumer> rawConsumer = new CpuConsumer(bq, 1);
sp<FrameWaiter> rawWaiter = new FrameWaiter();
rawConsumer->setFrameAvailableListener(rawWaiter);
const int32_t *rawResolutions;
size_t rawResolutionsCount;
int format = HAL_PIXEL_FORMAT_RAW_SENSOR;
getResolutionList(format,
&rawResolutions, &rawResolutionsCount);
if (rawResolutionsCount <= 0) {
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
std::cerr << "Skipping test "
<< test_info->test_case_name() << "."
<< test_info->name()
<< " because the optional format was not available: "
<< "RAW_SENSOR" << std::endl;
return;
}
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(bq, width, height, format, &streamId) );
camera_metadata_t *request;
request = allocate_camera_metadata(20, 2000);
uint8_t metadataMode = ANDROID_REQUEST_METADATA_MODE_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);
uint8_t requestType = ANDROID_REQUEST_TYPE_CAPTURE;
add_camera_metadata_entry(request,
ANDROID_REQUEST_TYPE,
(void**)&requestType, 1);
uint32_t hourOfDay = 12;
add_camera_metadata_entry(request,
0x80000000, // EMULATOR_HOUROFDAY
&hourOfDay, 1);
IF_ALOGV() {
std::cout << "Input request template: " << std::endl;
dump_indented_camera_metadata(request, 0, 1, 2);
}
int numCaptures = 10;
// Enqueue numCaptures requests with increasing exposure time
uint64_t exposureTime = 100 * USEC;
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
uint64_t expectedExposureTime = 100 * USEC;
for (int frameCount = 0; frameCount < 10; frameCount++) {
res = mFrames.waitForBuffer(SEC + expectedExposureTime);
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);
camera_metadata_entry_t frameNumber;
res = find_camera_metadata_entry(frame,
ANDROID_REQUEST_FRAME_COUNT,
&frameNumber);
ASSERT_EQ(NO_ERROR, res);
ASSERT_EQ(frameCount, *frameNumber.data.i32);
res = rawWaiter->waitForFrame(SEC + expectedExposureTime);
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,
"/data/local/tmp/camera2_test-"
"captureBurstRaw-dump_%d.raw",
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);
expectedExposureTime *= 2;
}
}
}
TEST_F(Camera2Test, ConstructDefaultRequests) {
TEST_EXTENSION_FORKING_INIT;
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 " << 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;
dump_indented_camera_metadata(request, 0, 2, 4);
}
free_camera_metadata(request);
}
}
}
TEST_F(Camera2Test, Capture1Jpeg) {
status_t res;
for (int id = 0; id < getNumCameras(); id++) {
if (!isHal2Supported(id)) continue;
ASSERT_NO_FATAL_FAILURE(setUpCamera(id));
sp<BufferQueue> bq = new BufferQueue();
sp<CpuConsumer> jpegConsumer = new CpuConsumer(bq, 1);
sp<FrameWaiter> jpegWaiter = new FrameWaiter();
jpegConsumer->setFrameAvailableListener(jpegWaiter);
const int32_t *jpegResolutions;
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(bq, width, height, format, &streamId) );
camera_metadata_t *request;
request = allocate_camera_metadata(20, 2000);
uint8_t metadataMode = ANDROID_REQUEST_METADATA_MODE_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);
uint8_t requestType = ANDROID_REQUEST_TYPE_CAPTURE;
add_camera_metadata_entry(request,
ANDROID_REQUEST_TYPE,
(void**)&requestType, 1);
uint32_t hourOfDay = 12;
add_camera_metadata_entry(request,
0x80000000, // EMULATOR_HOUROFDAY
&hourOfDay, 1);
IF_ALOGV() {
std::cout << "Input request: " << std::endl;
dump_indented_camera_metadata(request, 0, 1, 4);
}
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;
dump_indented_camera_metadata(frame, 0, 1, 4);
}
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_EQ(OK, waitUntilDrained());
ASSERT_NO_FATAL_FAILURE(disconnectStream(streamId));
res = closeCameraDevice(&mDevice);
ASSERT_EQ(NO_ERROR, res) << "Failed to close camera device";
}
}
} // namespace tests
} // namespace camera2
} // namespace android