blob: fb90a7943a6e78e47ee6f7fba31ecb579b19c4ba [file] [log] [blame]
/*
* Copyright (C) Texas Instruments - http://www.ti.com/
*
* 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 "CameraHAL"
#include "BaseCameraAdapter.h"
namespace android {
/*--------------------Camera Adapter Class STARTS here-----------------------------*/
BaseCameraAdapter::BaseCameraAdapter()
{
mReleaseImageBuffersCallback = NULL;
mEndImageCaptureCallback = NULL;
mErrorNotifier = NULL;
mEndCaptureData = NULL;
mReleaseData = NULL;
mRecording = false;
mPreviewBuffers = NULL;
mPreviewBufferCount = 0;
mPreviewBuffersLength = 0;
mVideoBuffers = NULL;
mVideoBuffersCount = 0;
mVideoBuffersLength = 0;
mCaptureBuffers = NULL;
mCaptureBuffersCount = 0;
mCaptureBuffersLength = 0;
mPreviewDataBuffers = NULL;
mPreviewDataBuffersCount = 0;
mPreviewDataBuffersLength = 0;
mAdapterState = INTIALIZED_STATE;
#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
mStartFocus.tv_sec = 0;
mStartFocus.tv_usec = 0;
mStartCapture.tv_sec = 0;
mStartCapture.tv_usec = 0;
#endif
}
BaseCameraAdapter::~BaseCameraAdapter()
{
LOG_FUNCTION_NAME;
Mutex::Autolock lock(mSubscriberLock);
mFrameSubscribers.clear();
mImageSubscribers.clear();
mRawSubscribers.clear();
mVideoSubscribers.clear();
mFocusSubscribers.clear();
mShutterSubscribers.clear();
mZoomSubscribers.clear();
mFaceSubscribers.clear();
LOG_FUNCTION_NAME_EXIT;
}
status_t BaseCameraAdapter::registerImageReleaseCallback(release_image_buffers_callback callback, void *user_data)
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
mReleaseImageBuffersCallback = callback;
mReleaseData = user_data;
LOG_FUNCTION_NAME_EXIT;
return ret;
}
status_t BaseCameraAdapter::registerEndCaptureCallback(end_image_capture_callback callback, void *user_data)
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
mEndImageCaptureCallback= callback;
mEndCaptureData = user_data;
LOG_FUNCTION_NAME_EXIT;
return ret;
}
status_t BaseCameraAdapter::setErrorHandler(ErrorNotifier *errorNotifier)
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
if ( NULL == errorNotifier )
{
CAMHAL_LOGEA("Invalid Error Notifier reference");
ret = -EINVAL;
}
if ( NO_ERROR == ret )
{
mErrorNotifier = errorNotifier;
}
LOG_FUNCTION_NAME_EXIT;
return ret;
}
void BaseCameraAdapter::enableMsgType(int32_t msgs, frame_callback callback, event_callback eventCb, void* cookie)
{
Mutex::Autolock lock(mSubscriberLock);
LOG_FUNCTION_NAME;
if ( CameraFrame::PREVIEW_FRAME_SYNC == msgs )
{
mFrameSubscribers.add((int) cookie, callback);
}
else if ( CameraFrame::FRAME_DATA_SYNC == msgs )
{
mFrameDataSubscribers.add((int) cookie, callback);
}
else if ( CameraFrame::IMAGE_FRAME == msgs)
{
mImageSubscribers.add((int) cookie, callback);
}
else if ( CameraFrame::RAW_FRAME == msgs)
{
mRawSubscribers.add((int) cookie, callback);
}
else if ( CameraFrame::VIDEO_FRAME_SYNC == msgs)
{
mVideoSubscribers.add((int) cookie, callback);
}
else if ( CameraHalEvent::ALL_EVENTS == msgs)
{
mFocusSubscribers.add((int) cookie, eventCb);
mShutterSubscribers.add((int) cookie, eventCb);
mZoomSubscribers.add((int) cookie, eventCb);
mFaceSubscribers.add((int) cookie, eventCb);
}
else
{
CAMHAL_LOGEA("Message type subscription no supported yet!");
}
LOG_FUNCTION_NAME_EXIT;
}
void BaseCameraAdapter::disableMsgType(int32_t msgs, void* cookie)
{
Mutex::Autolock lock(mSubscriberLock);
LOG_FUNCTION_NAME;
if ( CameraFrame::PREVIEW_FRAME_SYNC == msgs )
{
mFrameSubscribers.removeItem((int) cookie);
}
else if ( CameraFrame::FRAME_DATA_SYNC == msgs )
{
mFrameDataSubscribers.removeItem((int) cookie);
}
else if ( CameraFrame::IMAGE_FRAME == msgs)
{
mImageSubscribers.removeItem((int) cookie);
}
else if ( CameraFrame::RAW_FRAME == msgs)
{
mRawSubscribers.removeItem((int) cookie);
}
else if ( CameraFrame::VIDEO_FRAME_SYNC == msgs)
{
mVideoSubscribers.removeItem((int) cookie);
}
else if ( CameraFrame::ALL_FRAMES == msgs )
{
mFrameSubscribers.removeItem((int) cookie);
mFrameDataSubscribers.removeItem((int) cookie);
mImageSubscribers.removeItem((int) cookie);
mRawSubscribers.removeItem((int) cookie);
mVideoSubscribers.removeItem((int) cookie);
}
else if ( CameraHalEvent::ALL_EVENTS == msgs)
{
//Subscribe only for focus
//TODO: Process case by case
mFocusSubscribers.removeItem((int) cookie);
mShutterSubscribers.removeItem((int) cookie);
mZoomSubscribers.removeItem((int) cookie);
mFaceSubscribers.removeItem((int) cookie);
}
else
{
CAMHAL_LOGEB("Message type 0x%x subscription no supported yet!", msgs);
}
LOG_FUNCTION_NAME_EXIT;
}
void BaseCameraAdapter::returnFrame(void* frameBuf, CameraFrame::FrameType frameType)
{
status_t res = NO_ERROR;
size_t subscriberCount = 0;
int refCount = -1;
Mutex::Autolock lock(mReturnFrameLock);
if ( NULL == frameBuf )
{
CAMHAL_LOGEA("Invalid frameBuf");
return;
}
if ( NO_ERROR == res)
{
refCount = getFrameRefCount(frameBuf, frameType);
if ( 0 < refCount )
{
refCount--;
setFrameRefCount(frameBuf, frameType, refCount);
if ( ( mRecording ) && ( CameraFrame::VIDEO_FRAME_SYNC == frameType ) )
{
refCount += getFrameRefCount(frameBuf, CameraFrame::PREVIEW_FRAME_SYNC);
}
else if ( ( mRecording ) && ( CameraFrame::PREVIEW_FRAME_SYNC == frameType ) )
{
refCount += getFrameRefCount(frameBuf, CameraFrame::VIDEO_FRAME_SYNC);
}
}
else
{
return;
}
}
if ( NO_ERROR == res )
{
//check if someone is holding this buffer
if ( 0 == refCount )
{
res = fillThisBuffer(frameBuf, frameType);
}
}
}
status_t BaseCameraAdapter::sendCommand(CameraCommands operation, int value1, int value2, int value3)
{
status_t ret = NO_ERROR;
struct timeval *refTimestamp;
BuffersDescriptor *desc = NULL;
CameraFrame *frame = NULL;
LOG_FUNCTION_NAME;
switch ( operation ) {
case CameraAdapter::CAMERA_USE_BUFFERS_PREVIEW:
CAMHAL_LOGDA("Use buffers for preview");
desc = ( BuffersDescriptor * ) value1;
if ( NULL == desc )
{
CAMHAL_LOGEA("Invalid preview buffers!");
return -EINVAL;
}
if ( ret == NO_ERROR )
{
ret = setState(operation);
}
if ( ret == NO_ERROR )
{
Mutex::Autolock lock(mPreviewBufferLock);
mPreviewBuffers = (int *) desc->mBuffers;
mPreviewBuffersLength = desc->mLength;
mPreviewBuffersAvailable.clear();
for ( uint32_t i = 0 ; i < desc->mMaxQueueable ; i++ )
{
mPreviewBuffersAvailable.add(mPreviewBuffers[i], 0);
}
// initial ref count for undeqeueued buffers is 1 since buffer provider
// is still holding on to it
for ( uint32_t i = desc->mMaxQueueable ; i < desc->mCount ; i++ )
{
mPreviewBuffersAvailable.add(mPreviewBuffers[i], 1);
}
}
if ( NULL != desc )
{
ret = useBuffers(CameraAdapter::CAMERA_PREVIEW,
desc->mBuffers,
desc->mCount,
desc->mLength,
desc->mMaxQueueable);
}
if ( ret == NO_ERROR )
{
ret = commitState();
}
else
{
ret |= rollbackState();
}
break;
case CameraAdapter::CAMERA_USE_BUFFERS_PREVIEW_DATA:
CAMHAL_LOGDA("Use buffers for preview data");
desc = ( BuffersDescriptor * ) value1;
if ( NULL == desc )
{
CAMHAL_LOGEA("Invalid preview data buffers!");
return -EINVAL;
}
if ( ret == NO_ERROR )
{
ret = setState(operation);
}
if ( ret == NO_ERROR )
{
Mutex::Autolock lock(mPreviewDataBufferLock);
mPreviewDataBuffers = (int *) desc->mBuffers;
mPreviewDataBuffersLength = desc->mLength;
mPreviewDataBuffersAvailable.clear();
for ( uint32_t i = 0 ; i < desc->mMaxQueueable ; i++ )
{
mPreviewDataBuffersAvailable.add(mPreviewDataBuffers[i], true);
}
// initial ref count for undeqeueued buffers is 1 since buffer provider
// is still holding on to it
for ( uint32_t i = desc->mMaxQueueable ; i < desc->mCount ; i++ )
{
mPreviewDataBuffersAvailable.add(mPreviewBuffers[i], 1);
}
}
if ( NULL != desc )
{
ret = useBuffers(CameraAdapter::CAMERA_MEASUREMENT,
desc->mBuffers,
desc->mCount,
desc->mLength,
desc->mMaxQueueable);
}
if ( ret == NO_ERROR )
{
ret = commitState();
}
else
{
ret |= rollbackState();
}
break;
case CameraAdapter::CAMERA_USE_BUFFERS_IMAGE_CAPTURE:
CAMHAL_LOGDA("Use buffers for image capture");
desc = ( BuffersDescriptor * ) value1;
if ( NULL == desc )
{
CAMHAL_LOGEA("Invalid capture buffers!");
return -EINVAL;
}
if ( ret == NO_ERROR )
{
ret = setState(operation);
}
if ( ret == NO_ERROR )
{
Mutex::Autolock lock(mCaptureBufferLock);
mCaptureBuffers = (int *) desc->mBuffers;
mCaptureBuffersLength = desc->mLength;
mCaptureBuffersAvailable.clear();
for ( uint32_t i = 0 ; i < desc->mMaxQueueable ; i++ )
{
mCaptureBuffersAvailable.add(mCaptureBuffers[i], true);
}
// initial ref count for undeqeueued buffers is 1 since buffer provider
// is still holding on to it
for ( uint32_t i = desc->mMaxQueueable ; i < desc->mCount ; i++ )
{
mCaptureBuffersAvailable.add(mPreviewBuffers[i], 1);
}
}
if ( NULL != desc )
{
ret = useBuffers(CameraAdapter::CAMERA_IMAGE_CAPTURE,
desc->mBuffers,
desc->mCount,
desc->mLength,
desc->mMaxQueueable);
}
if ( ret == NO_ERROR )
{
ret = commitState();
}
else
{
ret |= rollbackState();
}
break;
case CameraAdapter::CAMERA_START_SMOOTH_ZOOM:
{
if ( ret == NO_ERROR )
{
ret = setState(operation);
}
if ( ret == NO_ERROR )
{
ret = startSmoothZoom(value1);
}
if ( ret == NO_ERROR )
{
ret = commitState();
}
else
{
ret |= rollbackState();
}
break;
}
case CameraAdapter::CAMERA_STOP_SMOOTH_ZOOM:
{
if ( ret == NO_ERROR )
{
ret = setState(operation);
}
if ( ret == NO_ERROR )
{
ret = stopSmoothZoom();
}
if ( ret == NO_ERROR )
{
ret = commitState();
}
else
{
ret |= rollbackState();
}
break;
}
case CameraAdapter::CAMERA_START_PREVIEW:
{
CAMHAL_LOGDA("Start Preview");
if ( ret == NO_ERROR )
{
ret = setState(operation);
}
if ( ret == NO_ERROR )
{
ret = startPreview();
}
if ( ret == NO_ERROR )
{
ret = commitState();
}
else
{
ret |= rollbackState();
}
break;
}
case CameraAdapter::CAMERA_STOP_PREVIEW:
{
CAMHAL_LOGDA("Stop Preview");
if ( ret == NO_ERROR )
{
ret = setState(operation);
}
if ( ret == NO_ERROR )
{
ret = stopPreview();
}
if ( ret == NO_ERROR )
{
ret = commitState();
}
else
{
ret |= rollbackState();
}
break;
}
case CameraAdapter::CAMERA_START_VIDEO:
{
CAMHAL_LOGDA("Start video recording");
if ( ret == NO_ERROR )
{
ret = setState(operation);
}
if ( ret == NO_ERROR )
{
ret = startVideoCapture();
}
if ( ret == NO_ERROR )
{
ret = commitState();
}
else
{
ret |= rollbackState();
}
break;
}
case CameraAdapter::CAMERA_STOP_VIDEO:
{
CAMHAL_LOGDA("Stop video recording");
if ( ret == NO_ERROR )
{
ret = setState(operation);
}
if ( ret == NO_ERROR )
{
ret = stopVideoCapture();
}
if ( ret == NO_ERROR )
{
ret = commitState();
}
else
{
ret |= rollbackState();
}
break;
}
case CameraAdapter::CAMERA_PREVIEW_FLUSH_BUFFERS:
{
if ( ret == NO_ERROR )
{
ret = setState(operation);
}
if ( ret == NO_ERROR )
{
ret = flushBuffers();
}
if ( ret == NO_ERROR )
{
ret = commitState();
}
else
{
ret |= rollbackState();
}
break;
}
case CameraAdapter::CAMERA_START_IMAGE_CAPTURE:
{
#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
refTimestamp = ( struct timeval * ) value1;
if ( NULL != refTimestamp )
{
memcpy( &mStartCapture, refTimestamp, sizeof( struct timeval ));
}
#endif
if ( ret == NO_ERROR )
{
ret = setState(operation);
}
if ( ret == NO_ERROR )
{
ret = takePicture();
}
if ( ret == NO_ERROR )
{
ret = commitState();
}
else
{
ret |= rollbackState();
}
break;
}
case CameraAdapter::CAMERA_STOP_IMAGE_CAPTURE:
{
if ( ret == NO_ERROR )
{
ret = setState(operation);
}
if ( ret == NO_ERROR )
{
ret = stopImageCapture();
}
if ( ret == NO_ERROR )
{
ret = commitState();
}
else
{
ret |= rollbackState();
}
break;
}
case CameraAdapter::CAMERA_START_BRACKET_CAPTURE:
{
#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
refTimestamp = ( struct timeval * ) value2;
if ( NULL != refTimestamp )
{
memcpy( &mStartCapture, refTimestamp, sizeof( struct timeval ));
}
#endif
if ( ret == NO_ERROR )
{
ret = setState(operation);
}
if ( ret == NO_ERROR )
{
ret = startBracketing(value1);
}
if ( ret == NO_ERROR )
{
ret = commitState();
}
else
{
ret |= rollbackState();
}
break;
}
case CameraAdapter::CAMERA_STOP_BRACKET_CAPTURE:
{
if ( ret == NO_ERROR )
{
ret = setState(operation);
}
if ( ret == NO_ERROR )
{
ret = stopBracketing();
}
if ( ret == NO_ERROR )
{
ret = commitState();
}
else
{
ret |= rollbackState();
}
break;
}
case CameraAdapter::CAMERA_PERFORM_AUTOFOCUS:
#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
refTimestamp = ( struct timeval * ) value1;
if ( NULL != refTimestamp )
{
memcpy( &mStartFocus, refTimestamp, sizeof( struct timeval ));
}
#endif
if ( ret == NO_ERROR )
{
ret = setState(operation);
}
if ( ret == NO_ERROR )
{
ret = autoFocus();
}
if ( ret == NO_ERROR )
{
ret = commitState();
}
else
{
ret |= rollbackState();
}
break;
case CameraAdapter::CAMERA_CANCEL_AUTOFOCUS:
if ( ret == NO_ERROR )
{
ret = setState(operation);
}
if ( ret == NO_ERROR )
{
ret = cancelAutoFocus();
}
if ( ret == NO_ERROR )
{
ret = commitState();
}
else
{
ret |= rollbackState();
}
break;
case CameraAdapter::CAMERA_QUERY_RESOLUTION_PREVIEW:
if ( ret == NO_ERROR )
{
ret = setState(operation);
}
if ( ret == NO_ERROR )
{
frame = ( CameraFrame * ) value1;
if ( NULL != frame )
{
ret = getFrameSize(frame->mWidth, frame->mHeight);
}
else
{
ret = -EINVAL;
}
}
if ( ret == NO_ERROR )
{
ret = commitState();
}
else
{
ret |= rollbackState();
}
break;
case CameraAdapter::CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE:
if ( ret == NO_ERROR )
{
ret = setState(operation);
}
if ( ret == NO_ERROR )
{
frame = ( CameraFrame * ) value1;
if ( NULL != frame )
{
ret = getPictureBufferSize(frame->mLength, value2);
}
else
{
ret = -EINVAL;
}
}
if ( ret == NO_ERROR )
{
ret = commitState();
}
else
{
ret |= rollbackState();
}
break;
case CameraAdapter::CAMERA_QUERY_BUFFER_SIZE_PREVIEW_DATA:
if ( ret == NO_ERROR )
{
ret = setState(operation);
}
if ( ret == NO_ERROR )
{
frame = ( CameraFrame * ) value1;
if ( NULL != frame )
{
ret = getFrameDataSize(frame->mLength, value2);
}
else
{
ret = -EINVAL;
}
}
if ( ret == NO_ERROR )
{
ret = commitState();
}
else
{
ret |= rollbackState();
}
break;
case CameraAdapter::CAMERA_START_FD:
ret = startFaceDetection();
break;
case CameraAdapter::CAMERA_STOP_FD:
ret = stopFaceDetection();
break;
default:
CAMHAL_LOGEB("Command 0x%x unsupported!", operation);
break;
};
LOG_FUNCTION_NAME_EXIT;
return ret;
}
status_t BaseCameraAdapter::notifyFocusSubscribers(bool status)
{
event_callback eventCb;
CameraHalEvent focusEvent;
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
if ( mFocusSubscribers.size() == 0 ) {
CAMHAL_LOGDA("No Focus Subscribers!");
return NO_INIT;
}
#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
//dump the AF latency
CameraHal::PPM("Focus finished in: ", &mStartFocus);
#endif
focusEvent.mEventData = new CameraHalEvent::CameraHalEventData();
if ( NULL == focusEvent.mEventData.get() ) {
return -ENOMEM;
}
focusEvent.mEventType = CameraHalEvent::EVENT_FOCUS_LOCKED;
focusEvent.mEventData->focusEvent.focusLocked = status;
focusEvent.mEventData->focusEvent.focusError = !status;
for (unsigned int i = 0 ; i < mFocusSubscribers.size(); i++ )
{
focusEvent.mCookie = (void *) mFocusSubscribers.keyAt(i);
eventCb = (event_callback) mFocusSubscribers.valueAt(i);
eventCb ( &focusEvent );
}
focusEvent.mEventData.clear();
LOG_FUNCTION_NAME_EXIT;
return ret;
}
status_t BaseCameraAdapter::notifyShutterSubscribers()
{
CameraHalEvent shutterEvent;
event_callback eventCb;
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
if ( mShutterSubscribers.size() == 0 )
{
CAMHAL_LOGEA("No shutter Subscribers!");
return NO_INIT;
}
shutterEvent.mEventData = new CameraHalEvent::CameraHalEventData();
if ( NULL == shutterEvent.mEventData.get() ) {
return -ENOMEM;
}
shutterEvent.mEventType = CameraHalEvent::EVENT_SHUTTER;
shutterEvent.mEventData->shutterEvent.shutterClosed = true;
for (unsigned int i = 0 ; i < mShutterSubscribers.size() ; i++ ) {
shutterEvent.mCookie = ( void * ) mShutterSubscribers.keyAt(i);
eventCb = ( event_callback ) mShutterSubscribers.valueAt(i);
CAMHAL_LOGEA("Sending shutter callback");
eventCb ( &shutterEvent );
}
shutterEvent.mEventData.clear();
LOG_FUNCTION_NAME;
return ret;
}
status_t BaseCameraAdapter::notifyZoomSubscribers(int zoomIdx, bool targetReached)
{
event_callback eventCb;
CameraHalEvent zoomEvent;
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
if ( mZoomSubscribers.size() == 0 ) {
CAMHAL_LOGDA("No zoom Subscribers!");
return NO_INIT;
}
zoomEvent.mEventData = new CameraHalEvent::CameraHalEventData();
if ( NULL == zoomEvent.mEventData.get() ) {
return -ENOMEM;
}
zoomEvent.mEventType = CameraHalEvent::EVENT_ZOOM_INDEX_REACHED;
zoomEvent.mEventData->zoomEvent.currentZoomIndex = zoomIdx;
zoomEvent.mEventData->zoomEvent.targetZoomIndexReached = targetReached;
for (unsigned int i = 0 ; i < mZoomSubscribers.size(); i++ ) {
zoomEvent.mCookie = (void *) mZoomSubscribers.keyAt(i);
eventCb = (event_callback) mZoomSubscribers.valueAt(i);
eventCb ( &zoomEvent );
}
zoomEvent.mEventData.clear();
LOG_FUNCTION_NAME_EXIT;
return ret;
}
status_t BaseCameraAdapter::notifyFaceSubscribers(sp<CameraFDResult> &faces)
{
event_callback eventCb;
CameraHalEvent faceEvent;
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
if ( mFaceSubscribers.size() == 0 ) {
CAMHAL_LOGDA("No face detection subscribers!");
return NO_INIT;
}
faceEvent.mEventData = new CameraHalEvent::CameraHalEventData();
if ( NULL == faceEvent.mEventData.get() ) {
return -ENOMEM;
}
faceEvent.mEventType = CameraHalEvent::EVENT_FACE;
faceEvent.mEventData->faceEvent = faces;
for (unsigned int i = 0 ; i < mFaceSubscribers.size(); i++ ) {
faceEvent.mCookie = (void *) mFaceSubscribers.keyAt(i);
eventCb = (event_callback) mFaceSubscribers.valueAt(i);
eventCb ( &faceEvent );
}
faceEvent.mEventData.clear();
LOG_FUNCTION_NAME_EXIT;
return ret;
}
status_t BaseCameraAdapter::sendFrameToSubscribers(CameraFrame *frame)
{
status_t ret = NO_ERROR;
frame_callback callback;
uint32_t i = 0;
KeyedVector<int, frame_callback> *subscribers = NULL;
size_t refCount = 0;
if ( NULL == frame )
{
CAMHAL_LOGEA("Invalid CameraFrame");
ret = -EINVAL;
}
if ( NO_ERROR == ret )
{
switch(frame->mFrameType)
{
case CameraFrame::IMAGE_FRAME:
{
#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
CameraHal::PPM("Shot to Jpeg: ", &mStartCapture);
#endif
subscribers = &mImageSubscribers;
break;
}
case CameraFrame::RAW_FRAME:
{
subscribers = &mRawSubscribers;
break;
}
case CameraFrame::VIDEO_FRAME_SYNC:
{
subscribers = &mVideoSubscribers;
break;
}
case CameraFrame::FRAME_DATA_SYNC:
{
subscribers = &mFrameDataSubscribers;
break;
}
case CameraFrame::PREVIEW_FRAME_SYNC:
case CameraFrame::SNAPSHOT_FRAME:
{
subscribers = &mFrameSubscribers;
break;
}
default:
{
ret = -EINVAL;
break;
}
};
}
if ( ( NO_ERROR == ret ) &&
( NULL != subscribers ) )
{
Mutex::Autolock lock(mSubscriberLock);
refCount = subscribers->size();
CAMHAL_LOGVB("Type of Frame: 0x%x address: 0x%x refCount start %d",
frame->mFrameType,
( uint32_t ) frame->mBuffer,
refCount);
setFrameRefCount(frame->mBuffer,
( CameraFrame::FrameType ) frame->mFrameType,
refCount);
for ( i = 0 ; i < subscribers->size(); i++ )
{
frame->mCookie = ( void * ) subscribers->keyAt(i);
callback = (frame_callback) subscribers->valueAt(i);
callback(frame);
}
}
if ( 0 == i )
{
//No subscribers for this frame
ret = -1;
}
return ret;
}
int BaseCameraAdapter::getFrameRefCount(void* frameBuf, CameraFrame::FrameType frameType)
{
int res = -1;
LOG_FUNCTION_NAME;
switch ( frameType )
{
case CameraFrame::IMAGE_FRAME:
case CameraFrame::RAW_FRAME:
{
Mutex::Autolock lock(mCaptureBufferLock);
res = mCaptureBuffersAvailable.valueFor( ( unsigned int ) frameBuf );
}
break;
case CameraFrame::PREVIEW_FRAME_SYNC:
case CameraFrame::SNAPSHOT_FRAME:
{
Mutex::Autolock lock(mPreviewBufferLock);
res = mPreviewBuffersAvailable.valueFor( ( unsigned int ) frameBuf );
}
break;
case CameraFrame::FRAME_DATA_SYNC:
{
Mutex::Autolock lock(mPreviewDataBufferLock);
res = mPreviewDataBuffersAvailable.valueFor( ( unsigned int ) frameBuf );
}
break;
case CameraFrame::VIDEO_FRAME_SYNC:
{
Mutex::Autolock lock(mVideoBufferLock);
res = mVideoBuffersAvailable.valueFor( ( unsigned int ) frameBuf );
}
break;
default:
break;
};
LOG_FUNCTION_NAME_EXIT;
return res;
}
void BaseCameraAdapter::setFrameRefCount(void* frameBuf, CameraFrame::FrameType frameType, int refCount)
{
LOG_FUNCTION_NAME;
switch ( frameType )
{
case CameraFrame::IMAGE_FRAME:
case CameraFrame::RAW_FRAME:
{
Mutex::Autolock lock(mCaptureBufferLock);
mCaptureBuffersAvailable.replaceValueFor( ( unsigned int ) frameBuf, refCount);
}
break;
case CameraFrame::PREVIEW_FRAME_SYNC:
case CameraFrame::SNAPSHOT_FRAME:
{
Mutex::Autolock lock(mPreviewBufferLock);
mPreviewBuffersAvailable.replaceValueFor( ( unsigned int ) frameBuf, refCount);
}
break;
case CameraFrame::FRAME_DATA_SYNC:
{
Mutex::Autolock lock(mPreviewDataBufferLock);
mPreviewDataBuffersAvailable.replaceValueFor( ( unsigned int ) frameBuf, refCount);
}
break;
case CameraFrame::VIDEO_FRAME_SYNC:
{
Mutex::Autolock lock(mVideoBufferLock);
mVideoBuffersAvailable.replaceValueFor( ( unsigned int ) frameBuf, refCount);
}
break;
default:
break;
};
LOG_FUNCTION_NAME_EXIT;
}
status_t BaseCameraAdapter::startVideoCapture()
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
Mutex::Autolock lock(mVideoBufferLock);
//If the capture is already ongoing, return from here.
if ( mRecording )
{
ret = NO_INIT;
}
if ( NO_ERROR == ret )
{
for ( unsigned int i = 0 ; i < mPreviewBuffersAvailable.size() ; i++ )
{
mVideoBuffersAvailable.add(mPreviewBuffersAvailable.keyAt(i), 0);
}
mRecording = true;
}
LOG_FUNCTION_NAME_EXIT;
return ret;
}
status_t BaseCameraAdapter::stopVideoCapture()
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
if ( !mRecording )
{
ret = NO_INIT;
}
if ( NO_ERROR == ret )
{
for ( unsigned int i = 0 ; i < mVideoBuffersAvailable.size() ; i++ )
{
void *frameBuf = ( void * ) mVideoBuffersAvailable.keyAt(i);
if( getFrameRefCount(frameBuf, CameraFrame::VIDEO_FRAME_SYNC) > 0)
{
returnFrame(frameBuf, CameraFrame::VIDEO_FRAME_SYNC);
}
}
mVideoBuffersAvailable.clear();
mRecording = false;
}
LOG_FUNCTION_NAME_EXIT;
return ret;
}
//-----------------Stub implementation of the interface ------------------------------
status_t BaseCameraAdapter::takePicture()
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
LOG_FUNCTION_NAME_EXIT;
return ret;
}
status_t BaseCameraAdapter::stopImageCapture()
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
LOG_FUNCTION_NAME_EXIT;
return ret;
}
status_t BaseCameraAdapter::startBracketing(int range)
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
LOG_FUNCTION_NAME_EXIT;
return ret;
}
status_t BaseCameraAdapter::stopBracketing()
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
LOG_FUNCTION_NAME_EXIT;
return ret;
}
status_t BaseCameraAdapter::autoFocus()
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
notifyFocusSubscribers(false);
LOG_FUNCTION_NAME_EXIT;
return ret;
}
status_t BaseCameraAdapter::cancelAutoFocus()
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
LOG_FUNCTION_NAME_EXIT;
return ret;
}
status_t BaseCameraAdapter::startSmoothZoom(int targetIdx)
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
LOG_FUNCTION_NAME_EXIT;
return ret;
}
status_t BaseCameraAdapter::stopSmoothZoom()
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
LOG_FUNCTION_NAME_EXIT;
return ret;
}
status_t BaseCameraAdapter::startPreview()
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
LOG_FUNCTION_NAME_EXIT;
return ret;
}
status_t BaseCameraAdapter::stopPreview()
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
LOG_FUNCTION_NAME_EXIT;
return ret;
}
status_t BaseCameraAdapter::useBuffers(CameraMode mode, void* bufArr, int num, size_t length, unsigned int queueable)
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
LOG_FUNCTION_NAME_EXIT;
return ret;
}
status_t BaseCameraAdapter::fillThisBuffer(void* frameBuf, CameraFrame::FrameType frameType)
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
LOG_FUNCTION_NAME_EXIT;
return ret;
}
status_t BaseCameraAdapter::getFrameSize(size_t &width, size_t &height)
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
LOG_FUNCTION_NAME_EXIT;
return ret;
}
status_t BaseCameraAdapter::getFrameDataSize(size_t &dataFrameSize, size_t bufferCount)
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
LOG_FUNCTION_NAME_EXIT;
return ret;
}
status_t BaseCameraAdapter::getPictureBufferSize(size_t &length, size_t bufferCount)
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
LOG_FUNCTION_NAME_EXIT;
return ret;
}
status_t BaseCameraAdapter::startFaceDetection()
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
LOG_FUNCTION_NAME_EXIT;
return ret;
}
status_t BaseCameraAdapter::stopFaceDetection()
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
LOG_FUNCTION_NAME_EXIT;
return ret;
}
status_t BaseCameraAdapter::setState(CameraCommands operation)
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
mLock.lock();
switch ( mAdapterState )
{
case INTIALIZED_STATE:
switch ( operation )
{
case CAMERA_USE_BUFFERS_PREVIEW:
CAMHAL_LOGDB("Adapter state switch INTIALIZED_STATE->LOADED_PREVIEW_STATE event = 0x%x",
operation);
mNextState = LOADED_PREVIEW_STATE;
break;
//These events don't change the current state
case CAMERA_QUERY_RESOLUTION_PREVIEW:
case CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE:
case CAMERA_QUERY_BUFFER_SIZE_PREVIEW_DATA:
CAMHAL_LOGDB("Adapter state switch INTIALIZED_STATE->INTIALIZED_STATE event = 0x%x",
operation);
mNextState = INTIALIZED_STATE;
break;
default:
CAMHAL_LOGEB("Adapter state switch INTIALIZED_STATE Invalid Op! event = 0x%x",
operation);
ret = INVALID_OPERATION;
break;
}
break;
case LOADED_PREVIEW_STATE:
switch ( operation )
{
case CAMERA_START_PREVIEW:
CAMHAL_LOGDB("Adapter state switch LOADED_PREVIEW_STATE->PREVIEW_STATE event = 0x%x",
operation);
mNextState = PREVIEW_STATE;
break;
//These events don't change the current state
case CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE:
case CAMERA_QUERY_BUFFER_SIZE_PREVIEW_DATA:
case CAMERA_USE_BUFFERS_PREVIEW_DATA:
CAMHAL_LOGDB("Adapter state switch LOADED_PREVIEW_STATE->LOADED_PREVIEW_STATE event = 0x%x",
operation);
mNextState = LOADED_PREVIEW_STATE;
break;
default:
CAMHAL_LOGDB("Adapter state switch LOADED_PREVIEW Invalid Op! event = 0x%x",
operation);
ret = INVALID_OPERATION;
break;
}
break;
case PREVIEW_STATE:
switch ( operation )
{
case CAMERA_STOP_PREVIEW:
CAMHAL_LOGDB("Adapter state switch PREVIEW_STATE->INTIALIZED_STATE event = 0x%x",
operation);
mNextState = INTIALIZED_STATE;
break;
case CAMERA_PERFORM_AUTOFOCUS:
CAMHAL_LOGDB("Adapter state switch PREVIEW_STATE->AF_STATE event = 0x%x",
operation);
mNextState = AF_STATE;
break;
case CAMERA_START_SMOOTH_ZOOM:
CAMHAL_LOGDB("Adapter state switch PREVIEW_STATE->ZOOM_STATE event = 0x%x",
operation);
mNextState = ZOOM_STATE;
break;
case CAMERA_USE_BUFFERS_IMAGE_CAPTURE:
CAMHAL_LOGDB("Adapter state switch PREVIEW_STATE->LOADED_CAPTURE_STATE event = 0x%x",
operation);
mNextState = LOADED_CAPTURE_STATE;
break;
case CAMERA_START_VIDEO:
CAMHAL_LOGDB("Adapter state switch PREVIEW_STATE->VIDEO_STATE event = 0x%x",
operation);
mNextState = VIDEO_STATE;
break;
case CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE:
case CAMERA_STOP_SMOOTH_ZOOM:
CAMHAL_LOGDB("Adapter state switch PREVIEW_ACTIVE->PREVIEW_ACTIVE event = 0x%x",
operation);
mNextState = PREVIEW_STATE;
break;
default:
CAMHAL_LOGEB("Adapter state switch PREVIEW_ACTIVE Invalid Op! event = 0x%x",
operation);
ret = INVALID_OPERATION;
break;
}
break;
case LOADED_CAPTURE_STATE:
switch ( operation )
{
case CAMERA_START_IMAGE_CAPTURE:
CAMHAL_LOGDB("Adapter state switch LOADED_CAPTURE_STATE->CAPTURE_STATE event = 0x%x",
operation);
mNextState = CAPTURE_STATE;
break;
case CAMERA_START_BRACKET_CAPTURE:
CAMHAL_LOGDB("Adapter state switch LOADED_CAPTURE_STATE->BRACKETING_STATE event = 0x%x",
operation);
mNextState = BRACKETING_STATE;
break;
default:
CAMHAL_LOGEB("Adapter state switch LOADED_CAPTURE_STATE Invalid Op! event = 0x%x",
operation);
ret = INVALID_OPERATION;
break;
}
break;
case CAPTURE_STATE:
switch ( operation )
{
case CAMERA_STOP_IMAGE_CAPTURE:
CAMHAL_LOGDB("Adapter state switch CAPTURE_STATE->PREVIEW_STATE event = 0x%x",
operation);
mNextState = PREVIEW_STATE;
break;
default:
CAMHAL_LOGEB("Adapter state switch CAPTURE_STATE Invalid Op! event = 0x%x",
operation);
ret = INVALID_OPERATION;
break;
}
break;
case BRACKETING_STATE:
switch ( operation )
{
case CAMERA_STOP_BRACKET_CAPTURE:
CAMHAL_LOGDB("Adapter state switch BRACKETING_STATE->PREVIEW_STATE event = 0x%x",
operation);
mNextState = PREVIEW_STATE;
break;
case CAMERA_START_IMAGE_CAPTURE:
CAMHAL_LOGDB("Adapter state switch BRACKETING_STATE->CAPTURE_STATE event = 0x%x",
operation);
mNextState = CAPTURE_STATE;
break;
default:
CAMHAL_LOGEB("Adapter state switch BRACKETING_STATE Invalid Op! event = 0x%x",
operation);
ret = INVALID_OPERATION;
break;
}
break;
case AF_STATE:
switch ( operation )
{
case CAMERA_CANCEL_AUTOFOCUS:
CAMHAL_LOGDB("Adapter state switch AF_STATE->PREVIEW_STATE event = 0x%x",
operation);
mNextState = PREVIEW_STATE;
break;
case CAMERA_START_SMOOTH_ZOOM:
CAMHAL_LOGDB("Adapter state switch AF_STATE->AF_ZOOM_STATE event = 0x%x",
operation);
mNextState = AF_ZOOM_STATE;
break;
default:
CAMHAL_LOGEB("Adapter state switch AF_STATE Invalid Op! event = 0x%x",
operation);
ret = INVALID_OPERATION;
break;
}
break;
case ZOOM_STATE:
switch ( operation )
{
case CAMERA_STOP_SMOOTH_ZOOM:
CAMHAL_LOGDB("Adapter state switch ZOOM_STATE->PREVIEW_STATE event = 0x%x",
operation);
mNextState = PREVIEW_STATE;
break;
case CAMERA_PERFORM_AUTOFOCUS:
CAMHAL_LOGDB("Adapter state switch ZOOM_STATE->AF_ZOOM_STATE event = 0x%x",
operation);
mNextState = AF_ZOOM_STATE;
break;
default:
CAMHAL_LOGEB("Adapter state switch ZOOM_STATE Invalid Op! event = 0x%x",
operation);
ret = INVALID_OPERATION;
break;
}
break;
case VIDEO_STATE:
switch ( operation )
{
case CAMERA_STOP_VIDEO:
CAMHAL_LOGDB("Adapter state switch VIDEO_STATE->PREVIEW_STATE event = 0x%x",
operation);
mNextState = PREVIEW_STATE;
break;
default:
CAMHAL_LOGEB("Adapter state switch VIDEO_STATE Invalid Op! event = 0x%x",
operation);
ret = INVALID_OPERATION;
break;
}
break;
case AF_ZOOM_STATE:
switch ( operation )
{
case CAMERA_STOP_SMOOTH_ZOOM:
CAMHAL_LOGDB("Adapter state switch AF_ZOOM_STATE->AF_STATE event = 0x%x",
operation);
mNextState = AF_STATE;
break;
case CAMERA_CANCEL_AUTOFOCUS:
CAMHAL_LOGDB("Adapter state switch AF_ZOOM_STATE->ZOOM_STATE event = 0x%x",
operation);
mNextState = ZOOM_STATE;
break;
default:
CAMHAL_LOGEB("Adapter state switch AF_ZOOM_STATE Invalid Op! event = 0x%x",
operation);
ret = INVALID_OPERATION;
break;
}
break;
case VIDEO_ZOOM_STATE:
switch ( operation )
{
case CAMERA_STOP_SMOOTH_ZOOM:
CAMHAL_LOGDB("Adapter state switch VIDEO_ZOOM_STATE->VIDEO_STATE event = 0x%x",
operation);
mNextState = VIDEO_STATE;
break;
default:
CAMHAL_LOGEB("Adapter state switch VIDEO_ZOOM_STATE Invalid Op! event = 0x%x",
operation);
ret = INVALID_OPERATION;
break;
}
break;
case BRACKETING_ZOOM_STATE:
switch ( operation )
{
case CAMERA_STOP_SMOOTH_ZOOM:
CAMHAL_LOGDB("Adapter state switch BRACKETING_ZOOM_STATE->BRACKETING_STATE event = 0x%x",
operation);
mNextState = BRACKETING_STATE;
break;
default:
CAMHAL_LOGEB("Adapter state switch BRACKETING_ZOOM_STATE Invalid Op! event = 0x%x",
operation);
ret = INVALID_OPERATION;
break;
}
break;
default:
CAMHAL_LOGEA("Invalid Adapter state!");
ret = INVALID_OPERATION;
}
LOG_FUNCTION_NAME_EXIT;
return ret;
}
//State transition finished successfully.
//Commit the state and unlock the adapter state.
status_t BaseCameraAdapter::commitState()
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
mAdapterState = mNextState;
mLock.unlock();
LOG_FUNCTION_NAME_EXIT;
return ret;
}
status_t BaseCameraAdapter::rollbackState()
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
mNextState = mAdapterState;
mLock.unlock();
LOG_FUNCTION_NAME_EXIT;
return ret;
}
// getNextState() and getState()
// publicly exposed functions to retrieve the adapter states
// please notice that these functions are locked
CameraAdapter::AdapterState BaseCameraAdapter::getState()
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
Mutex::Autolock lock(mLock);
LOG_FUNCTION_NAME_EXIT;
return mAdapterState;
}
CameraAdapter::AdapterState BaseCameraAdapter::getNextState()
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
Mutex::Autolock lock(mLock);
LOG_FUNCTION_NAME_EXIT;
return mNextState;
}
// getNextState() and getState()
// internal protected functions to retrieve the adapter states
// please notice that these functions are NOT locked to help
// internal functions query state in the middle of state
// transition
status_t BaseCameraAdapter::getState(AdapterState &state)
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
state = mAdapterState;
LOG_FUNCTION_NAME_EXIT;
return ret;
}
status_t BaseCameraAdapter::getNextState(AdapterState &state)
{
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
state = mNextState;
LOG_FUNCTION_NAME_EXIT;
return ret;
}
void BaseCameraAdapter::onOrientationEvent(uint32_t orientation, uint32_t tilt)
{
LOG_FUNCTION_NAME;
LOG_FUNCTION_NAME_EXIT;
}
//-----------------------------------------------------------------------------
};
/*--------------------Camera Adapter Class ENDS here-----------------------------*/