summaryrefslogtreecommitdiffstats
path: root/camera/CameraHal.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'camera/CameraHal.cpp')
-rw-r--r--camera/CameraHal.cpp260
1 files changed, 211 insertions, 49 deletions
diff --git a/camera/CameraHal.cpp b/camera/CameraHal.cpp
index 722f553..840dc04 100644
--- a/camera/CameraHal.cpp
+++ b/camera/CameraHal.cpp
@@ -23,6 +23,7 @@
#include "CameraHal.h"
#include "ANativeWindowDisplayAdapter.h"
+#include "BufferSourceAdapter.h"
#include "TICameraParameters.h"
#include "CameraProperties.h"
#include <cutils/properties.h>
@@ -46,8 +47,13 @@ const int CameraHal::NO_BUFFERS_IMAGE_CAPTURE = 9;
const int CameraHal::SW_SCALING_FPS_LIMIT = 15;
const uint32_t MessageNotifier::EVENT_BIT_FIELD_POSITION = 16;
+
const uint32_t MessageNotifier::FRAME_BIT_FIELD_POSITION = 0;
+// TODO(XXX): Temporarily increase number of buffers we can allocate from ANW
+// until faux-NPA mode is implemented
+const int CameraHal::NO_BUFFERS_IMAGE_CAPTURE_SYSTEM_HEAP = 15;
+
#ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING
// HACK: Default path to directory where RAW images coming from video port will be saved to.
// If directory not exists the saving is skipped and video port frame is ignored.
@@ -1277,7 +1283,9 @@ status_t CameraHal::freePreviewDataBufs()
return ret;
}
-status_t CameraHal::allocImageBufs(unsigned int width, unsigned int height, size_t size, const char* previewFormat, unsigned int bufferCount)
+status_t CameraHal::allocImageBufs(unsigned int width, unsigned int height, size_t size,
+ const char* previewFormat, unsigned int bufferCount,
+ unsigned int *max_queueable)
{
status_t ret = NO_ERROR;
int bytes;
@@ -1288,38 +1296,41 @@ status_t CameraHal::allocImageBufs(unsigned int width, unsigned int height, size
// allocate image buffers only if not already allocated
if(NULL != mImageBuffers) {
+ if (mBufferSourceAdapter_Out.get()) {
+ mBufferSourceAdapter_Out->maxQueueableBuffers(*max_queueable);
+ } else {
+ *max_queueable = bufferCount;
+ }
return NO_ERROR;
}
- if ( NO_ERROR == ret )
- {
- bytes = ((bytes+4095)/4096)*4096;
+ if (mBufferSourceAdapter_Out.get()) {
+ mImageBuffers = mBufferSourceAdapter_Out->allocateBufferList(width, height, previewFormat,
+ bytes, bufferCount);
+ mBufferSourceAdapter_Out->maxQueueableBuffers(*max_queueable);
+ } else {
+ bytes = ((bytes + 4095) / 4096) * 4096;
mImageBuffers = mMemoryManager->allocateBufferList(0, 0, previewFormat, bytes, bufferCount);
+ *max_queueable = bufferCount;
+ }
- CAMHAL_LOGDB("Size of Image cap buffer = %d", bytes);
- if( NULL == mImageBuffers )
- {
- CAMHAL_LOGEA("Couldn't allocate image buffers using memory manager");
- ret = -NO_MEMORY;
- }
- else
- {
- bytes = size;
- }
- }
+ CAMHAL_LOGDB("Size of Image cap buffer = %d", bytes);
+ if ( NULL == mImageBuffers ) {
+ CAMHAL_LOGEA("Couldn't allocate image buffers using memory manager");
+ ret = -NO_MEMORY;
+ } else {
+ bytes = size;
+ }
- if ( NO_ERROR == ret )
- {
+ if ( NO_ERROR == ret ) {
mImageFd = mMemoryManager->getFd();
mImageLength = bytes;
mImageOffsets = mMemoryManager->getOffsets();
- }
- else
- {
+ } else {
mImageFd = -1;
mImageLength = 0;
mImageOffsets = NULL;
- }
+ }
LOG_FUNCTION_NAME_EXIT;
@@ -1451,6 +1462,14 @@ status_t CameraHal::signalEndImageCapture()
LOG_FUNCTION_NAME;
+ if (mBufferSourceAdapter_Out.get()) {
+ mBufferSourceAdapter_Out->disableDisplay();
+ }
+
+ if (mBufferSourceAdapter_In.get()) {
+ mBufferSourceAdapter_In->disableDisplay();
+ }
+
if ( mBracketingRunning ) {
stopImageBracketing();
} else {
@@ -1468,22 +1487,19 @@ status_t CameraHal::freeImageBufs()
LOG_FUNCTION_NAME;
- if ( NO_ERROR == ret )
- {
-
- if( NULL != mImageBuffers )
- {
-
- ret = mMemoryManager->freeBufferList(mImageBuffers);
- mImageBuffers = NULL;
+ if (NULL == mImageBuffers) {
+ return -EINVAL;
+ }
- }
- else
- {
- ret = -EINVAL;
- }
+ if (mBufferSourceAdapter_Out.get()) {
+ ret = mBufferSourceAdapter_Out->freeBufferList(mImageBuffers);
+ } else {
+ ret = mMemoryManager->freeBufferList(mImageBuffers);
+ }
- }
+ if (ret == NO_ERROR) {
+ mImageBuffers = NULL;
+ }
LOG_FUNCTION_NAME_EXIT;
@@ -1620,9 +1636,7 @@ status_t CameraHal::startPreview()
mAppCallbackNotifier->enableMsgType (CAMERA_MSG_PREVIEW_FRAME);
}
- if (mCameraAdapter->getState() == CameraAdapter::CAPTURE_STATE) {
- mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_IMAGE_CAPTURE);
- }
+ signalEndImageCapture();
return ret;
}
@@ -1872,6 +1886,137 @@ status_t CameraHal::setPreviewWindow(struct preview_stream_ops *window)
return ret;
}
+/**
+ @brief Sets ANativeWindow object.
+
+ Buffers provided to CameraHal via this object for tap-in/tap-out
+ functionality.
+
+ TODO(XXX): this is just going to use preview_stream_ops for now, but we
+ most likely need to extend it when we want more functionality
+
+ @param[in] window The ANativeWindow object created by Surface flinger
+ @return NO_ERROR If the ANativeWindow object passes validation criteria
+ @todo Define validation criteria for ANativeWindow object. Define error codes for scenarios
+
+ */
+status_t CameraHal::setBufferSource(struct preview_stream_ops *tapin, struct preview_stream_ops *tapout)
+{
+ status_t ret = NO_ERROR;
+
+ LOG_FUNCTION_NAME;
+
+ // If either a tapin or tapout was previously set
+ // we need to clean up and clear capturing
+ if ((!tapout && mBufferSourceAdapter_Out.get()) ||
+ (!tapin && mBufferSourceAdapter_In.get())) {
+ signalEndImageCapture();
+ }
+
+ // Set tapout point
+ // destroy current buffer tapout if NULL tapout is passed
+ if (!tapout) {
+ if (mBufferSourceAdapter_Out.get() != NULL) {
+ CAMHAL_LOGD("NULL tapout passed, destroying buffer tapout adapter");
+ mBufferSourceAdapter_Out.clear();
+ mBufferSourceAdapter_Out = 0;
+ }
+ ret = NO_ERROR;
+ } else if (mBufferSourceAdapter_Out.get() == NULL) {
+ mBufferSourceAdapter_Out = new BufferSourceAdapter();
+ if(!mBufferSourceAdapter_Out.get()) {
+ CAMHAL_LOGEA("Couldn't create DisplayAdapter");
+ ret = NO_MEMORY;
+ goto exit;
+ }
+
+ ret = mBufferSourceAdapter_Out->initialize();
+ if (ret != NO_ERROR)
+ {
+ mBufferSourceAdapter_Out.clear();
+ mBufferSourceAdapter_Out = 0;
+ CAMHAL_LOGEA("DisplayAdapter initialize failed");
+ goto exit;
+ }
+
+ // CameraAdapter will be the frame provider for BufferSourceAdapter
+ mBufferSourceAdapter_Out->setFrameProvider(mCameraAdapter);
+
+ // BufferSourceAdapter will use ErrorHandler to send errors back to
+ // the application
+ mBufferSourceAdapter_Out->setErrorHandler(mAppCallbackNotifier.get());
+
+ // Update the display adapter with the new window that is passed from CameraService
+ ret = mBufferSourceAdapter_Out->setPreviewWindow(tapout);
+ if(ret != NO_ERROR) {
+ CAMHAL_LOGEB("DisplayAdapter setPreviewWindow returned error %d", ret);
+ goto exit;
+ }
+ } else {
+ // Update the display adapter with the new window that is passed from CameraService
+ freeImageBufs();
+ ret = mBufferSourceAdapter_Out->setPreviewWindow(tapout);
+ if (ret == ALREADY_EXISTS) {
+ // ALREADY_EXISTS should be treated as a noop in this case
+ ret = NO_ERROR;
+ }
+ }
+
+ if (ret != NO_ERROR) {
+ CAMHAL_LOGE("Error while trying to set tapout point");
+ goto exit;
+ }
+
+ // 1. Set tapin point
+ if (!tapin) {
+ if (mBufferSourceAdapter_In.get() != NULL) {
+ CAMHAL_LOGD("NULL tapin passed, destroying buffer tapin adapter");
+ mBufferSourceAdapter_In.clear();
+ mBufferSourceAdapter_In = 0;
+ }
+ ret = NO_ERROR;
+ } else if (mBufferSourceAdapter_In.get() == NULL) {
+ mBufferSourceAdapter_In = new BufferSourceAdapter();
+ if(!mBufferSourceAdapter_In.get()) {
+ CAMHAL_LOGEA("Couldn't create DisplayAdapter");
+ ret = NO_MEMORY;
+ goto exit;
+ }
+
+ ret = mBufferSourceAdapter_In->initialize();
+ if (ret != NO_ERROR)
+ {
+ mBufferSourceAdapter_In.clear();
+ mBufferSourceAdapter_In = 0;
+ CAMHAL_LOGEA("DisplayAdapter initialize failed");
+ goto exit;
+ }
+
+ // We need to set a frame provider so camera adapter can return the frame back to us
+ mBufferSourceAdapter_In->setFrameProvider(mCameraAdapter);
+
+ // BufferSourceAdapter will use ErrorHandler to send errors back to
+ // the application
+ mBufferSourceAdapter_In->setErrorHandler(mAppCallbackNotifier.get());
+
+ // Update the display adapter with the new window that is passed from CameraService
+ ret = mBufferSourceAdapter_In->setPreviewWindow(tapin);
+ if(ret != NO_ERROR) {
+ CAMHAL_LOGEB("DisplayAdapter setPreviewWindow returned error %d", ret);
+ goto exit;
+ }
+ } else {
+ // Update the display adapter with the new window that is passed from CameraService
+ ret = mBufferSourceAdapter_In->setPreviewWindow(tapin);
+ if (ret == ALREADY_EXISTS) {
+ // ALREADY_EXISTS should be treated as a noop in this case
+ ret = NO_ERROR;
+ }
+ }
+
+ exit:
+ return ret;
+}
/**
@@ -2414,9 +2559,12 @@ void CameraHal::eventCallback(CameraHalEvent* event)
status_t CameraHal::startImageBracketing()
{
- status_t ret = NO_ERROR;
- CameraFrame frame;
- CameraAdapter::BuffersDescriptor desc;
+ status_t ret = NO_ERROR;
+ CameraFrame frame;
+ CameraAdapter::BuffersDescriptor desc;
+ unsigned int max_queueable = 0;
+
+
#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
@@ -2464,6 +2612,7 @@ status_t CameraHal::startImageBracketing()
if ( NO_ERROR == ret )
{
+ unsigned int bufferCount = mBracketRangeNegative + 1;
mParameters.getPictureSize(( int * ) &frame.mWidth,
( int * ) &frame.mHeight);
@@ -2471,7 +2620,9 @@ status_t CameraHal::startImageBracketing()
frame.mHeight,
frame.mLength,
mParameters.getPictureFormat(),
- ( mBracketRangeNegative + 1 ));
+ bufferCount,
+ &max_queueable);
+ mBracketRangeNegative = bufferCount - 1;
if ( NO_ERROR != ret )
{
CAMHAL_LOGEB("allocImageBufs returned error 0x%x", ret);
@@ -2486,7 +2637,7 @@ status_t CameraHal::startImageBracketing()
desc.mFd = mImageFd;
desc.mLength = mImageLength;
desc.mCount = ( size_t ) ( mBracketRangeNegative + 1 );
- desc.mMaxQueueable = ( size_t ) ( mBracketRangeNegative + 1 );
+ desc.mMaxQueueable = ( size_t) max_queueable;
ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_USE_BUFFERS_IMAGE_CAPTURE,
( int ) &desc);
@@ -2547,6 +2698,7 @@ status_t CameraHal::takePicture(const char *params)
int burst = -1;
const char *valstr = NULL;
unsigned int bufferCount = 1;
+ unsigned int max_queueable = 0;
unsigned int rawBufferCount = 1;
bool isCPCamMode = false;
@@ -2648,6 +2800,13 @@ status_t CameraHal::takePicture(const char *params)
// For CPCam mode...allocate for worst case burst
bufferCount = isCPCamMode || (burst > CameraHal::NO_BUFFERS_IMAGE_CAPTURE) ?
CameraHal::NO_BUFFERS_IMAGE_CAPTURE : burst;
+
+ if (mBufferSourceAdapter_Out.get()) {
+ // TODO(XXX): Temporarily increase number of buffers we can allocate from ANW
+ // until faux-NPA mode is implemented
+ bufferCount = NO_BUFFERS_IMAGE_CAPTURE_SYSTEM_HEAP;
+ }
+
if ( NULL != mAppCallbackNotifier.get() ) {
mAppCallbackNotifier->setBurst(true);
}
@@ -2713,7 +2872,8 @@ status_t CameraHal::takePicture(const char *params)
frame.mHeight,
frame.mLength,
mParameters.getPictureFormat(),
- bufferCount);
+ bufferCount,
+ &max_queueable);
if ( NO_ERROR != ret )
{
CAMHAL_LOGEB("allocImageBufs returned error 0x%x", ret);
@@ -2727,7 +2887,7 @@ status_t CameraHal::takePicture(const char *params)
desc.mFd = mImageFd;
desc.mLength = mImageLength;
desc.mCount = ( size_t ) bufferCount;
- desc.mMaxQueueable = ( size_t ) bufferCount;
+ desc.mMaxQueueable = ( size_t ) max_queueable;
ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_USE_BUFFERS_IMAGE_CAPTURE,
( int ) &desc);
@@ -2759,6 +2919,10 @@ status_t CameraHal::takePicture(const char *params)
}
}
+ if ((ret == NO_ERROR) && mBufferSourceAdapter_Out.get()) {
+ mBufferSourceAdapter_Out->enableDisplay(0, 0, NULL);
+ }
+
if ((NO_ERROR == ret) && (NULL != mCameraAdapter)) {
#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
@@ -2790,11 +2954,9 @@ status_t CameraHal::takePicture(const char *params)
status_t CameraHal::cancelPicture( )
{
LOG_FUNCTION_NAME;
+ status_t ret = NO_ERROR;
- Mutex::Autolock lock(mLock);
-
- mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_IMAGE_CAPTURE);
-
+ ret = signalEndImageCapture();
return NO_ERROR;
}