/* Copyright (c) 2012-2013, The Linux Foundataion. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <semaphore.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <ui/DisplayInfo.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/ISurfaceComposer.h>
#include <system/camera.h>
#include <camera/Camera.h>
#include <camera/ICamera.h>
#include <camera/CameraParameters.h>
#include <utils/RefBase.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <cutils/properties.h>
#include <cutils/memory.h>
#include "qcamera_test.h"
namespace qcamera {
using namespace android;
int CameraContext::JpegIdx = 0;
/*===========================================================================
* FUNCTION : previewCallback
*
* DESCRIPTION: preview callback preview mesages are enabled
*
* PARAMETERS :
* @mem : preview buffer
*
* RETURN : None
*==========================================================================*/
void CameraContext::previewCallback(const sp<IMemory>& mem)
{
printf("PREVIEW Callback 0x%x", ( unsigned int ) mem->pointer());
uint8_t *ptr = (uint8_t*) mem->pointer();
printf("PRV_CB: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
ptr[0],
ptr[1],
ptr[2],
ptr[3],
ptr[4],
ptr[5],
ptr[6],
ptr[7],
ptr[8],
ptr[9]);
}
/*===========================================================================
* FUNCTION : saveFile
*
* DESCRIPTION: helper function for saving buffers on filesystem
*
* PARAMETERS :
* @mem : buffer to save to filesystem
* @path: File path
*
* RETURN : status_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
status_t CameraContext::saveFile(const sp<IMemory>& mem, String8 path)
{
unsigned char *buff = NULL;
int size;
int fd = -1;
if (mem == NULL) {
return BAD_VALUE;
}
fd = open(path, O_CREAT | O_WRONLY | O_TRUNC, 0655);
if(fd < 0) {
printf("Unable to open file %s %s\n", path.string(), strerror(fd));
return -errno;
}
size = mem->size();
if (size <= 0) {
printf("IMemory object is of zero size\n");
close(fd);
return BAD_VALUE;
}
buff = (unsigned char *)mem->pointer();
if (!buff) {
printf("Buffer pointer is invalid\n");
close(fd);
return BAD_VALUE;
}
if ( size != write(fd, buff, size) ) {
printf("Bad Write error (%d)%s\n",
errno,
strerror(errno));
close(fd);
return INVALID_OPERATION;
}
printf("%s: buffer=%08X, size=%d stored at %s\n",
__FUNCTION__, (int)buff, size, path.string());
if (fd >= 0)
close(fd);
return NO_ERROR;
}
/*===========================================================================
* FUNCTION : notify
*
* DESCRIPTION: notify callback
*
* PARAMETERS :
* @msgType : type of callback
* @ext1: extended parameters
* @ext2: extended parameters
*
* RETURN : None
*==========================================================================*/
void CameraContext::notify(int32_t msgType, int32_t ext1, int32_t ext2)
{
printf("Notify cb: %d %d %d\n", msgType, ext1, ext2);
if ( msgType & CAMERA_MSG_FOCUS ) {
printf("AutoFocus %s \n",
(ext1) ? "OK" : "FAIL");
}
if ( msgType & CAMERA_MSG_SHUTTER ) {
printf("Shutter done \n");
}
if ( msgType & CAMERA_MSG_ERROR) {
printf("Camera Test CAMERA_MSG_ERROR\n");
stopPreview();
closeCamera();
}
}
/*===========================================================================
* FUNCTION : postData
*
* DESCRIPTION: handles data callbacks
*
* PARAMETERS :
* @msgType : type of callback
* @dataPtr: buffer data
* @metadata: additional metadata where available
*
* RETURN : None
*==========================================================================*/
void CameraContext::postData(int32_t msgType,
const sp<IMemory>& dataPtr,
camera_frame_metadata_t *metadata)
{
printf("Data cb: %d\n", msgType);
if ( msgType & CAMERA_MSG_PREVIEW_FRAME ) {
previewCallback(dataPtr);
}
if ( msgType & CAMERA_MSG_RAW_IMAGE ) {
printf("RAW done \n");
}
if (msgType & CAMERA_MSG_POSTVIEW_FRAME) {
printf("Postview frame \n");
}
if (msgType & CAMERA_MSG_COMPRESSED_IMAGE ) {
printf("JPEG done\n");
String8 jpegPath;
jpegPath = jpegPath.format("/sdcard/img_%d.jpg", JpegIdx);
saveFile(dataPtr, jpegPath);
JpegIdx++;
}
if ( ( msgType & CAMERA_MSG_PREVIEW_METADATA ) &&
( NULL != metadata ) ) {
printf("Face detected %d \n", metadata->number_of_faces);
}
}
/*===========================================================================
* FUNCTION : postDataTimestamp
*
* DESCRIPTION: handles recording callbacks
*
* PARAMETERS :
* @timestamp : timestamp of buffer
* @msgType : type of buffer
* @dataPtr : buffer data
*
* RETURN : None
*==========================================================================*/
void CameraContext::postDataTimestamp(nsecs_t timestamp,
int32_t msgType,
const sp<IMemory>& dataPtr)
{
printf("Recording cb: %d %lld %p\n", msgType, timestamp, dataPtr.get());
}
/*===========================================================================
* FUNCTION : printSupportedParams
*
* DESCRIPTION: dump common supported parameters
*
* PARAMETERS : None
*
* RETURN : None
*==========================================================================*/
void CameraContext::printSupportedParams()
{
printf("\n\r\tSupported Cameras: %s",
mParams.get("camera-indexes")? mParams.get("camera-indexes") : "NULL");
printf("\n\r\tSupported Picture Sizes: %s",
mParams.get(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES)?
mParams.get(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES) : "NULL");
printf("\n\r\tSupported Picture Formats: %s",
mParams.get(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS)?
mParams.get(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS) : "NULL");
printf("\n\r\tSupported Preview Sizes: %s",
mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES)?
mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES) : "NULL");
printf("\n\r\tSupported Preview Formats: %s",
mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS)?
mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS) : "NULL");
printf("\n\r\tSupported Preview Frame Rates: %s",
mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES)?
mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES) : "NULL");
printf("\n\r\tSupported Thumbnail Sizes: %s",
mParams.get(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES)?
mParams.get(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES) : "NULL");
printf("\n\r\tSupported Whitebalance Modes: %s",
mParams.get(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE)?
mParams.get(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE) : "NULL");
printf("\n\r\tSupported Effects: %s",
mParams.get(CameraParameters::KEY_SUPPORTED_EFFECTS)?
mParams.get(CameraParameters::KEY_SUPPORTED_EFFECTS) : "NULL");
printf("\n\r\tSupported Scene Modes: %s",
mParams.get(CameraParameters::KEY_SUPPORTED_SCENE_MODES)?
mParams.get(CameraParameters::KEY_SUPPORTED_SCENE_MODES) : "NULL");
printf("\n\r\tSupported Focus Modes: %s",
mParams.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES)?
mParams.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES) : "NULL");
printf("\n\r\tSupported Antibanding Options: %s",
mParams.get(CameraParameters::KEY_SUPPORTED_ANTIBANDING)?
mParams.get(CameraParameters::KEY_SUPPORTED_ANTIBANDING) : "NULL");
printf("\n\r\tSupported Flash Modes: %s",
mParams.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES)?
mParams.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES) : "NULL");
printf("\n\r\tSupported Focus Areas: %d",
mParams.getInt(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS));
printf("\n\r\tSupported FPS ranges : %s",
mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE)?
mParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE) : "NULL");
printf("\n\r\tFocus Distances: %s \n",
mParams.get(CameraParameters::KEY_FOCUS_DISTANCES)?
mParams.get(CameraParameters::KEY_FOCUS_DISTANCES) : "NULL");
}
/*===========================================================================
* FUNCTION : createPreviewSurface
*
* DESCRIPTION: helper function for creating preview surfaces
*
* PARAMETERS :
* @width : preview width
* @height: preview height
* @pixFormat : surface pixelformat
*
* RETURN : status_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
status_t CameraContext::createPreviewSurface(unsigned int width,
unsigned int height,
int32_t pixFormat)
{
int ret = NO_ERROR;
DisplayInfo dinfo;
sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(
ISurfaceComposer::eDisplayIdMain));
SurfaceComposerClient::getDisplayInfo(display, &dinfo);
unsigned int previewWidth, previewHeight;
if ( dinfo.w < width ) {
previewWidth = dinfo.w;
} else {
previewWidth = width;
}
if ( dinfo.h < height ) {
previewHeight = dinfo.h;
} else {
previewHeight = height;
}
mClient = new SurfaceComposerClient();
if ( NULL == mClient.get() ) {
printf("Unable to establish connection to Surface Composer \n");
return NO_INIT;
}
mSurfaceControl = mClient->createSurface(String8("QCamera_Test"),
previewWidth,
previewHeight,
pixFormat,
0);
if ( NULL == mSurfaceControl.get() ) {
printf("Unable to create preview surface \n");
return NO_INIT;
}
mPreviewSurface = mSurfaceControl->getSurface();
if ( NULL != mPreviewSurface.get() ) {
mClient->openGlobalTransaction();
ret |= mSurfaceControl->setLayer(0x7fffffff);
ret |= mSurfaceControl->setPosition(0, 0);
ret |= mSurfaceControl->setSize(previewWidth, previewHeight);
ret |= mSurfaceControl->show();
mClient->closeGlobalTransaction();
if ( NO_ERROR != ret ) {
printf("Preview surface configuration failed! \n");
}
} else {
ret = NO_INIT;
}
return ret;
}
/*===========================================================================
* FUNCTION : destroyPreviewSurface
*
* DESCRIPTION: closes previously open preview surface
*
* PARAMETERS : None
*
* RETURN : status_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
status_t CameraContext::destroyPreviewSurface()
{
if ( NULL != mPreviewSurface.get() ) {
mPreviewSurface.clear();
}
if ( NULL != mSurfaceControl.get() ) {
mSurfaceControl->clear();
mSurfaceControl.clear();
}
if ( NULL != mClient.get() ) {
mClient->dispose();
mClient.clear();
}
return NO_ERROR;
}
/*===========================================================================
* FUNCTION : ~CameraContext
*
* DESCRIPTION: camera context destructor
*
* PARAMETERS : None
*
* RETURN : None
*==========================================================================*/
CameraContext::~CameraContext()
{
stopPreview();
closeCamera();
}
/*===========================================================================
* FUNCTION : openCamera
*
* DESCRIPTION: connects to and initializes camera
*
* PARAMETERS : None
*
* RETURN : status_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
status_t CameraContext::openCamera()
{
if ( NULL != mCamera.get() ) {
printf("Camera already open! \n");
return NO_ERROR;
}
printf("openCamera(camera_index=%d)\n", mCameraIndex);
mCamera = Camera::connect(mCameraIndex);
if ( NULL == mCamera.get() ) {
printf("Unable to connect to CameraService\n");
return NO_INIT;
}
mParams = mCamera->getParameters();
mParams.getSupportedPreviewSizes(mSupportedPreviewSizes);
mParams.getSupportedPictureSizes(mSupportedPictureSizes);
mCurrentPictureSizeIdx = mSupportedPictureSizes.size() / 2;
mCurrentPreviewSizeIdx = mSupportedPreviewSizes.size() / 2;
mCamera->setListener(this);
mHardwareActive = true;
return NO_ERROR;
}
/*===========================================================================
* FUNCTION : getNumberOfCameras
*
* DESCRIPTION: returns the number of supported camera by the system
*
* PARAMETERS : None
*
* RETURN : supported camera count
*==========================================================================*/
int CameraContext::getNumberOfCameras()
{
int ret = -1;
if ( NULL != mCamera.get() ) {
ret = mCamera->getNumberOfCameras();
}
return ret;
}
/*===========================================================================
* FUNCTION : closeCamera
*
* DESCRIPTION: closes a previously the initialized camera reference
*
* PARAMETERS : None
*
* RETURN : status_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
status_t CameraContext::closeCamera()
{
if ( NULL == mCamera.get() ) {
return NO_INIT;
}
mCamera->disconnect();
mCamera.clear();
mHardwareActive = false;
mPreviewRunning = false;
return NO_ERROR;
}
/*===========================================================================
* FUNCTION : startPreview
*
* DESCRIPTION: starts camera preview
*
* PARAMETERS : None
*
* RETURN : status_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
status_t CameraContext::startPreview()
{
int ret = NO_ERROR;
int previewWidth, previewHeight;
Size currentPreviewSize = mSupportedPreviewSizes.itemAt(mCurrentPreviewSizeIdx);
Size currentPictureSize = mSupportedPictureSizes.itemAt(mCurrentPictureSizeIdx);
if ( mPreviewRunning || !mHardwareActive ) {
printf("Preview already running or camera not active! \n");
return NO_INIT;
}
if (mResizePreview) {
previewWidth = currentPreviewSize.width;
previewHeight = currentPreviewSize.height;
ret = createPreviewSurface(previewWidth,
previewHeight,
HAL_PIXEL_FORMAT_YCrCb_420_SP);
if ( NO_ERROR != ret ) {
printf("Error while creating preview surface\n");
return ret;
}
mParams.setPreviewSize(previewWidth, previewHeight);
mParams.setPictureSize(currentPictureSize.width, currentPictureSize.height);
ret |= mCamera->setParameters(mParams.flatten());
ret |= mCamera->setPreviewDisplay(mPreviewSurface);
ret |= mCamera->startPreview();
if ( NO_ERROR != ret ) {
printf("Preview start failed! \n");
return ret;
}
mPreviewRunning = true;
mResizePreview = false;
}
return ret;
}
/*===========================================================================
* FUNCTION : autoFocus
*
* DESCRIPTION: Triggers autofocus
*
* PARAMETERS : None
*
* RETURN : status_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
status_t CameraContext::autoFocus()
{
status_t ret = NO_ERROR;
if ( mPreviewRunning ) {
ret = mCamera->autoFocus();
}
return ret;
}
/*===========================================================================
* FUNCTION : enablePreviewCallbacks
*
* DESCRIPTION: Enables preview callback messages
*
* PARAMETERS : None
*
* RETURN : status_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
status_t CameraContext::enablePreviewCallbacks()
{
if ( mHardwareActive ) {
mCamera->setPreviewCallbackFlags(CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK);
}
return NO_ERROR;
}
/*===========================================================================
* FUNCTION : takePicture
*
* DESCRIPTION: triggers image capture
*
* PARAMETERS : None
*
* RETURN : status_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
status_t CameraContext::takePicture()
{
status_t ret = NO_ERROR;
if ( mPreviewRunning ) {
ret = mCamera->takePicture(CAMERA_MSG_COMPRESSED_IMAGE|CAMERA_MSG_RAW_IMAGE);
}
return ret;
}
/*===========================================================================
* FUNCTION : stopPreview
*
* DESCRIPTION: stops camera preview
*
* PARAMETERS : None
*
* RETURN : status_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
status_t CameraContext::stopPreview()
{
status_t ret = NO_ERROR;
if ( mHardwareActive ) {
mCamera->stopPreview();
ret = destroyPreviewSurface();
}
mPreviewRunning = false;
mResizePreview = true;
return ret;
}
/*===========================================================================
* FUNCTION : resumePreview
*
* DESCRIPTION: resumes camera preview after image capture
*
* PARAMETERS : None
*
* RETURN : status_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
status_t CameraContext::resumePreview()
{
status_t ret = NO_ERROR;
if ( mHardwareActive ) {
ret = mCamera->startPreview();
} else {
ret = NO_INIT;
}
return ret;
}
/*===========================================================================
* FUNCTION : nextPreviewSize
*
* DESCRIPTION: Iterates through all supported preview sizes.
*
* PARAMETERS : None
*
* RETURN : status_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
status_t CameraContext::nextPreviewSize()
{
if ( mHardwareActive ) {
mCurrentPreviewSizeIdx += 1;
mCurrentPreviewSizeIdx %= mSupportedPreviewSizes.size();
Size previewSize = mSupportedPreviewSizes.itemAt(mCurrentPreviewSizeIdx);
mParams.setPreviewSize(previewSize.width,
previewSize.height);
mResizePreview = true;
if ( mPreviewRunning ) {
mCamera->stopPreview();
mCamera->setParameters(mParams.flatten());
mCamera->startPreview();
} else {
mCamera->setParameters(mParams.flatten());
}
}
return NO_ERROR;
}
/*===========================================================================
* FUNCTION : getCurrentPreviewSize
*
* DESCRIPTION: queries the currently configured preview size
*
* PARAMETERS :
* @previewSize : preview size currently configured
*
* RETURN : status_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
status_t CameraContext::getCurrentPreviewSize(Size &previewSize)
{
if ( mHardwareActive ) {
previewSize = mSupportedPreviewSizes.itemAt(mCurrentPreviewSizeIdx);
}
return NO_ERROR;
}
/*===========================================================================
* FUNCTION : nextPictureSize
*
* DESCRIPTION: Iterates through all supported picture sizes.
*
* PARAMETERS : None
*
* RETURN : status_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
status_t CameraContext::nextPictureSize()
{
if ( mHardwareActive ) {
mCurrentPictureSizeIdx += 1;
mCurrentPictureSizeIdx %= mSupportedPictureSizes.size();
Size pictureSize = mSupportedPictureSizes.itemAt(mCurrentPictureSizeIdx);
mParams.setPictureSize(pictureSize.width,
pictureSize.height);
mCamera->setParameters(mParams.flatten());
}
return NO_ERROR;
}
/*===========================================================================
* FUNCTION : getCurrentPictureSize
*
* DESCRIPTION: queries the currently configured picture size
*
* PARAMETERS :
* @pictureSize : picture size currently configured
*
* RETURN : status_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
status_t CameraContext::getCurrentPictureSize(Size &pictureSize)
{
if ( mHardwareActive ) {
pictureSize = mSupportedPictureSizes.itemAt(mCurrentPictureSizeIdx);
}
return NO_ERROR;
}
}; //namespace qcamera ends here
using namespace qcamera;
/*===========================================================================
* FUNCTION : printMenu
*
* DESCRIPTION: prints the available camera options
*
* PARAMETERS :
* @currentCamera : camera context currently being used
*
* RETURN : None
*==========================================================================*/
void printMenu(sp<CameraContext> currentCamera)
{
Size currentPictureSize, currentPreviewSize;
assert(currentCamera.get());
currentCamera->getCurrentPictureSize(currentPictureSize);
currentCamera->getCurrentPreviewSize(currentPreviewSize);
printf("\n\n=========== FUNCTIONAL TEST MENU ===================\n\n");
printf(" \n\nSTART / STOP / GENERAL SERVICES \n");
printf(" -----------------------------\n");
printf(" %c. Switch camera - Current Index: %d\n",
SWITCH_CAMERA_CMD,
currentCamera->getCameraIndex());
printf(" %c. Resume Preview after capture \n",
RESUME_PREVIEW_CMD);
printf(" %c. Quit \n",
EXIT_CMD);
printf(" %c. Camera Capability Dump",
DUMP_CAPS_CMD);
printf(" \n\n PREVIEW SUB MENU \n");
printf(" -----------------------------\n");
printf(" %c. Start Preview\n",
START_PREVIEW_CMD);
printf(" %c. Stop Preview\n",
STOP_PREVIEW_CMD);
printf(" %c. Preview size: %dx%d\n",
CHANGE_PREVIEW_SIZE_CMD,
currentPreviewSize.width,
currentPreviewSize.height);
printf(" %c. Enable preview frames\n",
ENABLE_PRV_CALLBACKS_CMD);
printf(" %c. Trigger autofocus \n",
AUTOFOCUS_CMD);
printf(" \n\n IMAGE CAPTURE SUB MENU \n");
printf(" -----------------------------\n");
printf(" %c. Take picture/Full Press\n",
TAKEPICTURE_CMD);
printf(" %c. Picture size: %dx%d\n",
CHANGE_PICTURE_SIZE_CMD,
currentPictureSize.width,
currentPictureSize.height);
printf("\n");
printf(" Choice: ");
}
/*===========================================================================
* FUNCTION : functionalTest
*
* DESCRIPTION: queries and executes client supplied commands for testing a
* particular camera.
*
* PARAMETERS :
* @availableCameras : List with all cameras supported
*
* RETURN : status_t type of status
* NO_ERROR -- continue testing
* none-zero -- quit test
*==========================================================================*/
status_t functionalTest(Vector< sp<CameraContext> > &availableCameras)
{
int cmd;
status_t stat = NO_ERROR;
static int currentCameraIdx = 0;
assert(availableCameras.size());
sp<CameraContext> currentCamera = availableCameras.itemAt(currentCameraIdx);
printMenu(currentCamera);
cmd = getchar();
switch (cmd) {
case SWITCH_CAMERA_CMD:
{
currentCameraIdx++;
currentCameraIdx %= availableCameras.size();
currentCamera = availableCameras.itemAt(currentCameraIdx);
}
break;
case RESUME_PREVIEW_CMD:
{
stat = currentCamera->resumePreview();
}
break;
case START_PREVIEW_CMD:
{
stat = currentCamera->startPreview();
}
break;
case STOP_PREVIEW_CMD:
{
stat = currentCamera->stopPreview();
}
break;
case CHANGE_PREVIEW_SIZE_CMD:
{
stat = currentCamera->nextPreviewSize();
}
break;
case CHANGE_PICTURE_SIZE_CMD:
{
stat = currentCamera->nextPictureSize();
}
break;
case DUMP_CAPS_CMD:
{
currentCamera->printSupportedParams();
}
break;
case AUTOFOCUS_CMD:
{
stat = currentCamera->autoFocus();
}
break;
case TAKEPICTURE_CMD:
{
stat = currentCamera->takePicture();
}
break;
case ENABLE_PRV_CALLBACKS_CMD:
{
stat = currentCamera->enablePreviewCallbacks();
}
break;
case EXIT_CMD:
{
currentCamera->stopPreview();
return -1;
}
break;
default:
{
}
break;
}
printf("Command status 0x%x \n", stat);
return NO_ERROR;
}
int main()
{
sp<ProcessState> proc(ProcessState::self());
Vector< sp<CameraContext> > availableCameras;
sp<CameraContext> camera;
int i = 0;
ProcessState::self()->startThreadPool();
do {
camera = new CameraContext(i);
if ( NULL == camera.get() ) {
return NO_INIT;
}
status_t stat = camera->openCamera();
if ( NO_ERROR != stat ) {
printf("Error encountered during camera open \n");
return stat;
}
availableCameras.add(camera);
i++;
} while ( i < camera->getNumberOfCameras() ) ;
while ( true ) {
if ( NO_ERROR != functionalTest(availableCameras) ) {
break;
}
};
for ( size_t j = 0 ; j < availableCameras.size() ; j++ ) {
camera = availableCameras.itemAt(j);
camera->closeCamera();
camera.clear();
}
availableCameras.clear();
return 0;
}