/* * 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 &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 *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-----------------------------*/