diff options
Diffstat (limited to 'camera/ANativeWindowDisplayAdapter.cpp')
-rw-r--r-- | camera/ANativeWindowDisplayAdapter.cpp | 1345 |
1 files changed, 0 insertions, 1345 deletions
diff --git a/camera/ANativeWindowDisplayAdapter.cpp b/camera/ANativeWindowDisplayAdapter.cpp deleted file mode 100644 index f144327..0000000 --- a/camera/ANativeWindowDisplayAdapter.cpp +++ /dev/null @@ -1,1345 +0,0 @@ -/* - * 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. - */ - -#include "ANativeWindowDisplayAdapter.h" -#include <OMX_IVCommon.h> -#include <ui/GraphicBuffer.h> -#include <ui/GraphicBufferMapper.h> -#include <hal_public.h> - -namespace Ti { -namespace Camera { - -///Constant declarations -///@todo Check the time units -const int ANativeWindowDisplayAdapter::DISPLAY_TIMEOUT = 1000; // seconds - -//Suspends buffers after given amount of failed dq's -const int ANativeWindowDisplayAdapter::FAILED_DQS_TO_SUSPEND = 3; - - -OMX_COLOR_FORMATTYPE toOMXPixFormat(const char* parameters_format) -{ - OMX_COLOR_FORMATTYPE pixFormat; - - if ( parameters_format != NULL ) - { - if (strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_YUV422I) == 0) - { - CAMHAL_LOGDA("CbYCrY format selected"); - pixFormat = OMX_COLOR_FormatCbYCrY; - } - else if(strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) - { - CAMHAL_LOGDA("YUV420SP format selected"); - pixFormat = OMX_COLOR_FormatYUV420SemiPlanar; - } - else if(strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_RGB565) == 0) - { - CAMHAL_LOGDA("RGB565 format selected"); - pixFormat = OMX_COLOR_Format16bitRGB565; - } - else - { - CAMHAL_LOGDA("Invalid format, NV12 format selected as default"); - pixFormat = OMX_COLOR_FormatYUV420SemiPlanar; - } - } - else { - CAMHAL_LOGEA("Preview format is NULL, defaulting to NV12"); - pixFormat = OMX_COLOR_FormatYUV420SemiPlanar; - } - - return pixFormat; -} - -const char* DisplayAdapter::getPixFormatConstant(const char* parameters_format) const -{ - const char* pixFormat; - - if ( parameters_format != NULL ) - { - if (strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_YUV422I) == 0) - { - CAMHAL_LOGVA("CbYCrY format selected"); - pixFormat = android::CameraParameters::PIXEL_FORMAT_YUV422I; - } - else if(strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_YUV420SP) == 0 || - strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_YUV420P) == 0) - { - // TODO(XXX): We are treating YV12 the same as YUV420SP - CAMHAL_LOGVA("YUV420SP format selected"); - pixFormat = android::CameraParameters::PIXEL_FORMAT_YUV420SP; - } - else if(strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_RGB565) == 0) - { - CAMHAL_LOGVA("RGB565 format selected"); - pixFormat = android::CameraParameters::PIXEL_FORMAT_RGB565; - } - else if(strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_BAYER_RGGB) == 0) - { - CAMHAL_LOGVA("BAYER format selected"); - pixFormat = android::CameraParameters::PIXEL_FORMAT_BAYER_RGGB; - } - else - { - CAMHAL_LOGEA("Invalid format, NV12 format selected as default"); - pixFormat = android::CameraParameters::PIXEL_FORMAT_YUV420SP; - } - } - else - { - CAMHAL_LOGEA("Preview format is NULL, defaulting to NV12"); - pixFormat = android::CameraParameters::PIXEL_FORMAT_YUV420SP; - } - - return pixFormat; -} - -size_t DisplayAdapter::getBufSize(const char* parameters_format, int width, int height) const -{ - int buf_size; - - if ( parameters_format != NULL ) { - if (strcmp(parameters_format, - android::CameraParameters::PIXEL_FORMAT_YUV422I) == 0) { - buf_size = width * height * 2; - } - else if((strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) || - (strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_YUV420P) == 0)) { - buf_size = width * height * 3 / 2; - } - else if(strcmp(parameters_format, - android::CameraParameters::PIXEL_FORMAT_RGB565) == 0) { - buf_size = width * height * 2; - } - else if (strcmp(parameters_format, - android::CameraParameters::PIXEL_FORMAT_BAYER_RGGB) == 0) { - buf_size = width * height * 2; - } else { - CAMHAL_LOGEA("Invalid format"); - buf_size = 0; - } - } else { - CAMHAL_LOGEA("Preview format is NULL"); - buf_size = 0; - } - - return buf_size; -} -/*--------------------ANativeWindowDisplayAdapter Class STARTS here-----------------------------*/ - - -/** - * Display Adapter class STARTS here.. - */ -ANativeWindowDisplayAdapter::ANativeWindowDisplayAdapter():mDisplayThread(NULL), - mDisplayState(ANativeWindowDisplayAdapter::DISPLAY_INIT), - mDisplayEnabled(false), - mBufferCount(0) - - - -{ - LOG_FUNCTION_NAME; - -#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS - - mShotToShot = false; - mStartCapture.tv_sec = 0; - mStartCapture.tv_usec = 0; - mStandbyToShot.tv_sec = 0; - mStandbyToShot.tv_usec = 0; - mMeasureStandby = false; -#endif - - mPixelFormat = NULL; - mBuffers = NULL; - mOffsetsMap = NULL; - mFrameProvider = NULL; - mANativeWindow = NULL; - - mFrameWidth = 0; - mFrameHeight = 0; - mPreviewWidth = 0; - mPreviewHeight = 0; - - mSuspend = false; - mFailedDQs = 0; - - mPaused = false; - mXOff = -1; - mYOff = -1; - mFirstInit = false; - - mFD = -1; - - LOG_FUNCTION_NAME_EXIT; -} - -ANativeWindowDisplayAdapter::~ANativeWindowDisplayAdapter() -{ - Utils::Semaphore sem; - Utils::Message msg; - - LOG_FUNCTION_NAME; - - ///If Frame provider exists - if (mFrameProvider) { - // Unregister with the frame provider - mFrameProvider->disableFrameNotification(CameraFrame::ALL_FRAMES); - delete mFrameProvider; - mFrameProvider = NULL; - } - - ///The ANativeWindow object will get destroyed here - destroy(); - - ///If Display thread exists - if(mDisplayThread.get()) - { - ///Kill the display thread - sem.Create(); - msg.command = DisplayThread::DISPLAY_EXIT; - - // Send the semaphore to signal once the command is completed - msg.arg1 = &sem; - - ///Post the message to display thread - mDisplayThread->msgQ().put(&msg); - - ///Wait for the ACK - implies that the thread is now started and waiting for frames - sem.Wait(); - - // Exit and cleanup the thread - mDisplayThread->requestExitAndWait(); - - // Delete the display thread - mDisplayThread.clear(); - } - - LOG_FUNCTION_NAME_EXIT; - -} - -status_t ANativeWindowDisplayAdapter::initialize() -{ - LOG_FUNCTION_NAME; - - ///Create the display thread - mDisplayThread = new DisplayThread(this); - if ( !mDisplayThread.get() ) - { - CAMHAL_LOGEA("Couldn't create display thread"); - LOG_FUNCTION_NAME_EXIT; - return NO_MEMORY; - } - - ///Start the display thread - status_t ret = mDisplayThread->run("DisplayThread", android::PRIORITY_URGENT_DISPLAY); - if ( ret != NO_ERROR ) - { - CAMHAL_LOGEA("Couldn't run display thread"); - LOG_FUNCTION_NAME_EXIT; - return ret; - } - - LOG_FUNCTION_NAME_EXIT; - - return ret; -} - -int ANativeWindowDisplayAdapter::setPreviewWindow(preview_stream_ops_t* window) -{ - LOG_FUNCTION_NAME; - ///Note that Display Adapter cannot work without a valid window object - if ( !window) - { - CAMHAL_LOGEA("NULL window object passed to DisplayAdapter"); - LOG_FUNCTION_NAME_EXIT; - return BAD_VALUE; - } - - if ( window == mANativeWindow ) { - return ALREADY_EXISTS; - } - - ///Destroy the existing window object, if it exists - destroy(); - - ///Move to new window obj - mANativeWindow = window; - - LOG_FUNCTION_NAME_EXIT; - - return NO_ERROR; -} - -int ANativeWindowDisplayAdapter::setFrameProvider(FrameNotifier *frameProvider) -{ - LOG_FUNCTION_NAME; - - // Check for NULL pointer - if ( !frameProvider ) { - CAMHAL_LOGEA("NULL passed for frame provider"); - LOG_FUNCTION_NAME_EXIT; - return BAD_VALUE; - } - - //Release any previous frame providers - if ( NULL != mFrameProvider ) { - delete mFrameProvider; - } - - /** Dont do anything here, Just save the pointer for use when display is - actually enabled or disabled - */ - mFrameProvider = new FrameProvider(frameProvider, this, frameCallbackRelay); - - LOG_FUNCTION_NAME_EXIT; - - return NO_ERROR; -} - -int ANativeWindowDisplayAdapter::setErrorHandler(ErrorNotifier *errorNotifier) -{ - status_t ret = NO_ERROR; - - LOG_FUNCTION_NAME; - - if ( NULL == errorNotifier ) { - CAMHAL_LOGEA("Invalid Error Notifier reference"); - ret = BAD_VALUE; - } - - if ( NO_ERROR == ret ) - { - mErrorNotifier = errorNotifier; - } - - LOG_FUNCTION_NAME_EXIT; - - return ret; -} - -#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS - -status_t ANativeWindowDisplayAdapter::setSnapshotTimeRef(struct timeval *refTime) -{ - status_t ret = NO_ERROR; - - LOG_FUNCTION_NAME; - - if ( NULL != refTime ) - { - android::AutoMutex lock(mLock); - memcpy(&mStartCapture, refTime, sizeof(struct timeval)); - } - - LOG_FUNCTION_NAME_EXIT; - - return ret; -} - -#endif - - -int ANativeWindowDisplayAdapter::enableDisplay(int width, int height, struct timeval *refTime) -{ - Utils::Semaphore sem; - Utils::Message msg; - - LOG_FUNCTION_NAME; - - if ( mDisplayEnabled ) - { - CAMHAL_LOGDA("Display is already enabled"); - LOG_FUNCTION_NAME_EXIT; - - return NO_ERROR; - } - -#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS - - if ( NULL != refTime ) - { - android::AutoMutex lock(mLock); - memcpy(&mStandbyToShot, refTime, sizeof(struct timeval)); - mMeasureStandby = true; - } - -#endif - - //Send START_DISPLAY COMMAND to display thread. Display thread will start and then wait for a message - sem.Create(); - msg.command = DisplayThread::DISPLAY_START; - - // Send the semaphore to signal once the command is completed - msg.arg1 = &sem; - - ///Post the message to display thread - mDisplayThread->msgQ().put(&msg); - - ///Wait for the ACK - implies that the thread is now started and waiting for frames - sem.Wait(); - - // Register with the frame provider for frames - mFrameProvider->enableFrameNotification(CameraFrame::PREVIEW_FRAME_SYNC); - mFrameProvider->enableFrameNotification(CameraFrame::SNAPSHOT_FRAME); - - mDisplayEnabled = true; - mPreviewWidth = width; - mPreviewHeight = height; - - CAMHAL_LOGVB("mPreviewWidth = %d mPreviewHeight = %d", mPreviewWidth, mPreviewHeight); - - LOG_FUNCTION_NAME_EXIT; - - return NO_ERROR; -} - -int ANativeWindowDisplayAdapter::disableDisplay(bool cancel_buffer) -{ - status_t ret = NO_ERROR; - android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get(); - - LOG_FUNCTION_NAME; - - if(!mDisplayEnabled) - { - CAMHAL_LOGDA("Display is already disabled"); - LOG_FUNCTION_NAME_EXIT; - return ALREADY_EXISTS; - } - - // Unregister with the frame provider here - mFrameProvider->disableFrameNotification(CameraFrame::PREVIEW_FRAME_SYNC); - mFrameProvider->disableFrameNotification(CameraFrame::SNAPSHOT_FRAME); - mFrameProvider->removeFramePointers(); - - if ( NULL != mDisplayThread.get() ) - { - //Send STOP_DISPLAY COMMAND to display thread. Display thread will stop and dequeue all messages - // and then wait for message - Utils::Semaphore sem; - sem.Create(); - Utils::Message msg; - msg.command = DisplayThread::DISPLAY_STOP; - - // Send the semaphore to signal once the command is completed - msg.arg1 = &sem; - - ///Post the message to display thread - mDisplayThread->msgQ().put(&msg); - - ///Wait for the ACK for display to be disabled - - sem.Wait(); - - } - - android::AutoMutex lock(mLock); - { - ///Reset the display enabled flag - mDisplayEnabled = false; - - // Reset pause flag since display is being disabled - mPaused = false; - - ///Reset the offset values - mXOff = -1; - mYOff = -1; - - ///Reset the frame width and height values - mFrameWidth =0; - mFrameHeight = 0; - mPreviewWidth = 0; - mPreviewHeight = 0; - - if(cancel_buffer) - { - // Return the buffers to ANativeWindow here, the mFramesWithCameraAdapterMap is also cleared inside - returnBuffersToWindow(); - } - else - { - mANativeWindow = NULL; - // Clear the frames with camera adapter map - mFramesWithCameraAdapterMap.clear(); - } - - - } - LOG_FUNCTION_NAME_EXIT; - - return NO_ERROR; -} - -status_t ANativeWindowDisplayAdapter::pauseDisplay(bool pause) -{ - status_t ret = NO_ERROR; - - LOG_FUNCTION_NAME; - - { - android::AutoMutex lock(mLock); - mPaused = pause; - } - - LOG_FUNCTION_NAME_EXIT; - - return ret; -} - - -void ANativeWindowDisplayAdapter::destroy() -{ - LOG_FUNCTION_NAME; - - ///Check if the display is disabled, if not disable it - if ( mDisplayEnabled ) - { - CAMHAL_LOGDA("WARNING: Calling destroy of Display adapter when display enabled. Disabling display.."); - disableDisplay(false); - } - - mBufferCount = 0; - - LOG_FUNCTION_NAME_EXIT; -} - -// Implementation of inherited interfaces -CameraBuffer* ANativeWindowDisplayAdapter::allocateBufferList(int width, int height, const char* format, int &bytes, int numBufs) -{ - LOG_FUNCTION_NAME; - status_t err; - int i = -1; - const int lnumBufs = numBufs; - int undequeued = 0; - android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get(); - android::Rect bounds; - - mBuffers = new CameraBuffer [lnumBufs]; - memset (mBuffers, 0, sizeof(CameraBuffer) * lnumBufs); - - mFramesType.clear(); - - if ( NULL == mANativeWindow ) { - return NULL; - } - - // Set gralloc usage bits for window. - err = mANativeWindow->set_usage(mANativeWindow, CAMHAL_GRALLOC_USAGE); - if ( NO_ERROR != err ) { - CAMHAL_LOGE("Surface::setUsage failed: %s (%d)", strerror(-err), -err); - - if ( NO_INIT == err ) { - CAMHAL_LOGEA("Preview surface abandoned!"); - mANativeWindow = NULL; - } - - return NULL; - } - - CAMHAL_LOGDB("Number of buffers set to ANativeWindow %d", numBufs); - ///Set the number of buffers needed for camera preview - err = mANativeWindow->set_buffer_count(mANativeWindow, numBufs); - if ( NO_ERROR != err ) { - CAMHAL_LOGE("Surface::setBufferCount failed: %s (%d)", strerror(-err), -err); - - if ( NO_INIT == err ) { - CAMHAL_LOGEA("Preview surface abandoned!"); - mANativeWindow = NULL; - } - - return NULL; - } - CAMHAL_LOGDB("Configuring %d buffers for ANativeWindow", numBufs); - mBufferCount = numBufs; - - - // Set window geometry - err = mANativeWindow->set_buffers_geometry( - mANativeWindow, - width, - height, - /*toOMXPixFormat(format)*/HAL_PIXEL_FORMAT_TI_NV12); // Gralloc only supports NV12 alloc! - - if ( NO_ERROR != err ) { - CAMHAL_LOGE("native_window_set_buffers_geometry failed: %s (%d)", strerror(-err), -err); - - if ( NO_INIT == err ) { - CAMHAL_LOGEA("Preview surface abandoned!"); - mANativeWindow = NULL; - } - - return NULL; - } - - ///We just return the buffers from ANativeWindow, if the width and height are same, else (vstab, vnf case) - ///re-allocate buffers using ANativeWindow and then get them - ///@todo - Re-allocate buffers for vnf and vstab using the width, height, format, numBufs etc - if ( mBuffers == NULL ) - { - CAMHAL_LOGEA("Couldn't create array for ANativeWindow buffers"); - LOG_FUNCTION_NAME_EXIT; - return NULL; - } - - mANativeWindow->get_min_undequeued_buffer_count(mANativeWindow, &undequeued); - - for ( i=0; i < mBufferCount; i++ ) - { - buffer_handle_t *handle; - int stride; // dummy variable to get stride - // TODO(XXX): Do we need to keep stride information in camera hal? - - err = mANativeWindow->dequeue_buffer(mANativeWindow, &handle, &stride); - - if ( NO_ERROR != err ) { - CAMHAL_LOGE("Surface::dequeueBuffer failed: %s (%d)", strerror(-err), -err); - - if ( NO_INIT == err ) { - CAMHAL_LOGEA("Preview surface abandoned!"); - mANativeWindow = NULL; - } - - goto fail; - } - - CAMHAL_LOGDB("got handle %p", handle); - mBuffers[i].opaque = (void *)handle; - mBuffers[i].type = CAMERA_BUFFER_ANW; - mFramesWithCameraAdapterMap.add(handle, i); - - // Tag remaining preview buffers as preview frames - if ( i >= ( mBufferCount - undequeued ) ) { - mFramesType.add( (int) mBuffers[i].opaque, - CameraFrame::PREVIEW_FRAME_SYNC); - } - - bytes = getBufSize(format, width, height); - - } - - // lock the initial queueable buffers - bounds.left = 0; - bounds.top = 0; - bounds.right = width; - bounds.bottom = height; - - for( i = 0; i < mBufferCount-undequeued; i++ ) - { - void *y_uv[2]; - buffer_handle_t *handle = (buffer_handle_t *) mBuffers[i].opaque; - - mANativeWindow->lock_buffer(mANativeWindow, handle); - - mapper.lock(*handle, CAMHAL_GRALLOC_USAGE, bounds, y_uv); - mBuffers[i].mapped = y_uv[0]; - mFrameProvider->addFramePointers(&mBuffers[i], y_uv); - } - - // return the rest of the buffers back to ANativeWindow - for(i = (mBufferCount-undequeued); i >= 0 && i < mBufferCount; i++) - { - buffer_handle_t *handle = (buffer_handle_t *) mBuffers[i].opaque; - err = mANativeWindow->cancel_buffer(mANativeWindow, handle); - if ( NO_ERROR != err ) { - CAMHAL_LOGE("Surface::cancelBuffer failed: %s (%d)", strerror(-err), -err); - - if ( NO_INIT == err ) { - CAMHAL_LOGEA("Preview surface abandoned!"); - mANativeWindow = NULL; - } - - goto fail; - } - mFramesWithCameraAdapterMap.removeItem((buffer_handle_t *) mBuffers[i].opaque); - //LOCK UNLOCK TO GET YUV POINTERS - void *y_uv[2]; - mapper.lock(*(buffer_handle_t *) mBuffers[i].opaque, CAMHAL_GRALLOC_USAGE, bounds, y_uv); - mBuffers[i].mapped = y_uv[0]; - mFrameProvider->addFramePointers(&mBuffers[i], y_uv); - mapper.unlock(*(buffer_handle_t *) mBuffers[i].opaque); - } - - mFirstInit = true; - mPixelFormat = getPixFormatConstant(format); - mFrameWidth = width; - mFrameHeight = height; - - return mBuffers; - - fail: - // need to cancel buffers if any were dequeued - for (int start = 0; start < i && i > 0; start++) { - status_t err = mANativeWindow->cancel_buffer(mANativeWindow, - (buffer_handle_t *) mBuffers[start].opaque); - if ( NO_ERROR != err ) { - CAMHAL_LOGE("Surface::cancelBuffer failed w/ error 0x%08x", err); - break; - } - mFramesWithCameraAdapterMap.removeItem((buffer_handle_t *) mBuffers[start].opaque); - } - - freeBufferList(mBuffers); - - CAMHAL_LOGEA("Error occurred, performing cleanup"); - - if ( NULL != mErrorNotifier.get() ) { - mErrorNotifier->errorNotify(NO_MEMORY); - } - - LOG_FUNCTION_NAME_EXIT; - return NULL; - -} - -CameraBuffer* ANativeWindowDisplayAdapter::getBufferList(int *numBufs) { - LOG_FUNCTION_NAME; - if (numBufs) *numBufs = -1; - - return NULL; -} - -uint32_t * ANativeWindowDisplayAdapter::getOffsets() -{ - const int lnumBufs = mBufferCount; - - LOG_FUNCTION_NAME; - - // TODO(XXX): Need to remove getOffsets from the API. No longer needed - - if ( NULL == mANativeWindow ) - { - CAMHAL_LOGEA("mANativeWindow reference is missing"); - goto fail; - } - - if( mBuffers == NULL) - { - CAMHAL_LOGEA("Buffers not allocated yet!!"); - goto fail; - } - - if(mOffsetsMap == NULL) - { - mOffsetsMap = new uint32_t[lnumBufs]; - for(int i = 0; i < mBufferCount; i++) - { - mOffsetsMap[i] = 0; - } - } - - LOG_FUNCTION_NAME_EXIT; - - return mOffsetsMap; - - fail: - - if ( NULL != mOffsetsMap ) - { - delete [] mOffsetsMap; - mOffsetsMap = NULL; - } - - if ( NULL != mErrorNotifier.get() ) { - mErrorNotifier->errorNotify(INVALID_OPERATION); - } - - LOG_FUNCTION_NAME_EXIT; - - return NULL; -} - -status_t ANativeWindowDisplayAdapter::minUndequeueableBuffers(int& undequeueable) { - LOG_FUNCTION_NAME; - status_t ret = NO_ERROR; - - if(!mANativeWindow) { - ret = INVALID_OPERATION; - goto end; - } - - ret = mANativeWindow->get_min_undequeued_buffer_count(mANativeWindow, &undequeueable); - if ( NO_ERROR != ret ) { - CAMHAL_LOGEB("get_min_undequeued_buffer_count failed: %s (%d)", strerror(-ret), -ret); - - if ( NO_INIT == ret ) { - CAMHAL_LOGEA("Preview surface abandoned!"); - mANativeWindow = NULL; - } - - return ret; - } - - end: - return ret; - LOG_FUNCTION_NAME_EXIT; - -} - -status_t ANativeWindowDisplayAdapter::maxQueueableBuffers(unsigned int& queueable) -{ - LOG_FUNCTION_NAME; - status_t ret = NO_ERROR; - int undequeued = 0; - - if(mBufferCount == 0) - { - ret = INVALID_OPERATION; - goto end; - } - - ret = minUndequeueableBuffers(undequeued); - if (ret != NO_ERROR) { - goto end; - } - - queueable = mBufferCount - undequeued; - - end: - return ret; - LOG_FUNCTION_NAME_EXIT; -} - -int ANativeWindowDisplayAdapter::getFd() -{ - LOG_FUNCTION_NAME; - - if(mFD == -1) - { - buffer_handle_t *handle = (buffer_handle_t *)mBuffers[0].opaque; - IMG_native_handle_t *img = (IMG_native_handle_t *)handle; - // TODO: should we dup the fd? not really necessary and another thing for ANativeWindow - // to manage and close... - - mFD = dup(img->fd[0]); - } - - LOG_FUNCTION_NAME_EXIT; - - return mFD; - -} - -status_t ANativeWindowDisplayAdapter::returnBuffersToWindow() -{ - status_t ret = NO_ERROR; - - android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get(); - //Give the buffers back to display here - sort of free it - if (mANativeWindow) - for(unsigned int i = 0; i < mFramesWithCameraAdapterMap.size(); i++) { - int value = mFramesWithCameraAdapterMap.valueAt(i); - buffer_handle_t *handle = (buffer_handle_t *) mBuffers[value].opaque; - - // if buffer index is out of bounds skip - if ((value < 0) || (value >= mBufferCount)) { - CAMHAL_LOGEA("Potential out bounds access to handle...skipping"); - continue; - } - - // unlock buffer before giving it up - mapper.unlock(*handle); - - ret = mANativeWindow->cancel_buffer(mANativeWindow, handle); - if ( NO_INIT == ret ) { - CAMHAL_LOGEA("Preview surface abandoned!"); - mANativeWindow = NULL; - return ret; - } else if ( NO_ERROR != ret ) { - CAMHAL_LOGE("Surface::cancelBuffer() failed: %s (%d)", - strerror(-ret), - -ret); - return ret; - } - } - else - CAMHAL_LOGE("mANativeWindow is NULL"); - - ///Clear the frames with camera adapter map - mFramesWithCameraAdapterMap.clear(); - - return ret; - -} - -int ANativeWindowDisplayAdapter::freeBufferList(CameraBuffer * buflist) -{ - LOG_FUNCTION_NAME; - - status_t ret = NO_ERROR; - - android::AutoMutex lock(mLock); - - if(mBuffers != buflist) - { - CAMHAL_LOGEA("CameraHal passed wrong set of buffers to free!!!"); - if (mBuffers != NULL) - delete []mBuffers; - mBuffers = NULL; - } - - /* FIXME this will probably want the list that was just deleted */ - returnBuffersToWindow(); - - if ( NULL != buflist ) - { - delete [] buflist; - mBuffers = NULL; - } - - if( mBuffers != NULL) - { - delete [] mBuffers; - mBuffers = NULL; - } - - if ( NULL != mOffsetsMap ) - { - delete [] mOffsetsMap; - mOffsetsMap = NULL; - } - - if( mFD != -1) - { - close(mFD); // close duped handle - mFD = -1; - } - - mFramesType.clear(); - - return NO_ERROR; -} - - -bool ANativeWindowDisplayAdapter::supportsExternalBuffering() -{ - return false; -} - -void ANativeWindowDisplayAdapter::displayThread() -{ - bool shouldLive = true; - int timeout = 0; - status_t ret; - - LOG_FUNCTION_NAME; - - while(shouldLive) - { - ret = Utils::MessageQueue::waitForMsg(&mDisplayThread->msgQ() - , &mDisplayQ - , NULL - , ANativeWindowDisplayAdapter::DISPLAY_TIMEOUT); - - if ( !mDisplayThread->msgQ().isEmpty() ) - { - ///Received a message from CameraHal, process it - shouldLive = processHalMsg(); - - } - else if( !mDisplayQ.isEmpty()) - { - if ( mDisplayState== ANativeWindowDisplayAdapter::DISPLAY_INIT ) - { - - ///If display adapter is not started, continue - continue; - - } - else - { - Utils::Message msg; - ///Get the dummy msg from the displayQ - if(mDisplayQ.get(&msg)!=NO_ERROR) - { - CAMHAL_LOGEA("Error in getting message from display Q"); - continue; - } - - // There is a frame from ANativeWindow for us to dequeue - // We dequeue and return the frame back to Camera adapter - if(mDisplayState == ANativeWindowDisplayAdapter::DISPLAY_STARTED) - { - handleFrameReturn(); - } - - if (mDisplayState == ANativeWindowDisplayAdapter::DISPLAY_EXITED) - { - ///we exit the thread even though there are frames still to dequeue. They will be dequeued - ///in disableDisplay - shouldLive = false; - } - } - } - } - - LOG_FUNCTION_NAME_EXIT; -} - - -bool ANativeWindowDisplayAdapter::processHalMsg() -{ - Utils::Message msg; - - LOG_FUNCTION_NAME; - - - mDisplayThread->msgQ().get(&msg); - bool ret = true, invalidCommand = false; - - switch ( msg.command ) - { - - case DisplayThread::DISPLAY_START: - - CAMHAL_LOGDA("Display thread received DISPLAY_START command from Camera HAL"); - mDisplayState = ANativeWindowDisplayAdapter::DISPLAY_STARTED; - - break; - - case DisplayThread::DISPLAY_STOP: - - ///@bug There is no API to disable SF without destroying it - ///@bug Buffers might still be w/ display and will get displayed - ///@remarks Ideal seqyence should be something like this - ///mOverlay->setParameter("enabled", false); - CAMHAL_LOGDA("Display thread received DISPLAY_STOP command from Camera HAL"); - mDisplayState = ANativeWindowDisplayAdapter::DISPLAY_STOPPED; - - // flush frame message queue - while ( !mDisplayQ.isEmpty() ) { - Utils::Message message; - mDisplayQ.get(&message); - } - - break; - - case DisplayThread::DISPLAY_EXIT: - - CAMHAL_LOGDA("Display thread received DISPLAY_EXIT command from Camera HAL."); - CAMHAL_LOGDA("Stopping display thread..."); - mDisplayState = ANativeWindowDisplayAdapter::DISPLAY_EXITED; - ///Note that the SF can have pending buffers when we disable the display - ///This is normal and the expectation is that they may not be displayed. - ///This is to ensure that the user experience is not impacted - ret = false; - break; - - default: - - CAMHAL_LOGEB("Invalid Display Thread Command 0x%x.", msg.command); - invalidCommand = true; - - break; - } - - ///Signal the semaphore if it is sent as part of the message - if ( ( msg.arg1 ) && ( !invalidCommand ) ) - { - - CAMHAL_LOGDA("+Signalling display semaphore"); - Utils::Semaphore &sem = *((Utils::Semaphore*)msg.arg1); - - sem.Signal(); - - CAMHAL_LOGDA("-Signalling display semaphore"); - } - - - LOG_FUNCTION_NAME_EXIT; - return ret; -} - - -status_t ANativeWindowDisplayAdapter::PostFrame(ANativeWindowDisplayAdapter::DisplayFrame &dispFrame) -{ - status_t ret = NO_ERROR; - uint32_t actualFramesWithDisplay = 0; - android_native_buffer_t *buffer = NULL; - android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get(); - int i; - - ///@todo Do cropping based on the stabilized frame coordinates - ///@todo Insert logic to drop frames here based on refresh rate of - ///display or rendering rate whichever is lower - ///Queue the buffer to overlay - - if ( NULL == mANativeWindow ) { - return NO_INIT; - } - - if (!mBuffers || !dispFrame.mBuffer) { - CAMHAL_LOGEA("NULL sent to PostFrame"); - return BAD_VALUE; - } - - for ( i = 0; i < mBufferCount; i++ ) - { - if ( dispFrame.mBuffer == &mBuffers[i] ) - { - break; - } - } - - - android::AutoMutex lock(mLock); - - mFramesType.add( (int)mBuffers[i].opaque, dispFrame.mType); - - if ( mDisplayState == ANativeWindowDisplayAdapter::DISPLAY_STARTED && - (!mPaused || CameraFrame::CameraFrame::SNAPSHOT_FRAME == dispFrame.mType) && - !mSuspend) - { - uint32_t xOff = (dispFrame.mOffset% PAGE_SIZE); - uint32_t yOff = (dispFrame.mOffset / PAGE_SIZE); - - // Set crop only if current x and y offsets do not match with frame offsets - if((mXOff!=xOff) || (mYOff!=yOff)) - { - CAMHAL_LOGDB("Offset %d xOff = %d, yOff = %d", dispFrame.mOffset, xOff, yOff); - uint8_t bytesPerPixel; - ///Calculate bytes per pixel based on the pixel format - if(strcmp(mPixelFormat, android::CameraParameters::PIXEL_FORMAT_YUV422I) == 0) - { - bytesPerPixel = 2; - } - else if(strcmp(mPixelFormat, android::CameraParameters::PIXEL_FORMAT_RGB565) == 0) - { - bytesPerPixel = 2; - } - else if(strcmp(mPixelFormat, android::CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) - { - bytesPerPixel = 1; - } - else - { - bytesPerPixel = 1; - } - - CAMHAL_LOGVB(" crop.left = %d crop.top = %d crop.right = %d crop.bottom = %d", - xOff/bytesPerPixel, yOff , (xOff/bytesPerPixel)+mPreviewWidth, yOff+mPreviewHeight); - // We'll ignore any errors here, if the surface is - // already invalid, we'll know soon enough. - mANativeWindow->set_crop(mANativeWindow, xOff/bytesPerPixel, yOff, - (xOff/bytesPerPixel)+mPreviewWidth, yOff+mPreviewHeight); - - ///Update the current x and y offsets - mXOff = xOff; - mYOff = yOff; - } - - { - buffer_handle_t *handle = (buffer_handle_t *) mBuffers[i].opaque; - // unlock buffer before sending to display - mapper.unlock(*handle); - ret = mANativeWindow->enqueue_buffer(mANativeWindow, handle); - } - if ( NO_ERROR != ret ) { - CAMHAL_LOGE("Surface::queueBuffer returned error %d", ret); - } - - mFramesWithCameraAdapterMap.removeItem((buffer_handle_t *) dispFrame.mBuffer->opaque); - - - // HWComposer has not minimum buffer requirement. We should be able to dequeue - // the buffer immediately - Utils::Message msg; - mDisplayQ.put(&msg); - - -#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS - - if ( mMeasureStandby ) - { - CameraHal::PPM("Standby to first shot: Sensor Change completed - ", &mStandbyToShot); - mMeasureStandby = false; - } - else if (CameraFrame::CameraFrame::SNAPSHOT_FRAME == dispFrame.mType) - { - CameraHal::PPM("Shot to snapshot: ", &mStartCapture); - mShotToShot = true; - } - else if ( mShotToShot ) - { - CameraHal::PPM("Shot to shot: ", &mStartCapture); - mShotToShot = false; - } -#endif - - } - else - { - buffer_handle_t *handle = (buffer_handle_t *) mBuffers[i].opaque; - - // unlock buffer before giving it up - mapper.unlock(*handle); - - // cancel buffer and dequeue another one - ret = mANativeWindow->cancel_buffer(mANativeWindow, handle); - if ( NO_ERROR != ret ) { - CAMHAL_LOGE("Surface::cancelBuffer returned error %d", ret); - } - - mFramesWithCameraAdapterMap.removeItem((buffer_handle_t *) dispFrame.mBuffer->opaque); - - Utils::Message msg; - mDisplayQ.put(&msg); - ret = NO_ERROR; - } - - return ret; -} - - -bool ANativeWindowDisplayAdapter::handleFrameReturn() -{ - status_t err; - buffer_handle_t *buf; - int i = 0; - unsigned int k; - int stride; // dummy variable to get stride - android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get(); - android::Rect bounds; - CameraFrame::FrameType frameType = CameraFrame::PREVIEW_FRAME_SYNC; - - void *y_uv[2]; - - // TODO(XXX): Do we need to keep stride information in camera hal? - - if ( NULL == mANativeWindow ) { - return false; - } - - err = mANativeWindow->dequeue_buffer(mANativeWindow, &buf, &stride); - if (err != 0) { - CAMHAL_LOGE("Surface::dequeueBuffer failed: %s (%d)", strerror(-err), -err); - - if ( NO_INIT == err ) { - CAMHAL_LOGEA("Preview surface abandoned!"); - mANativeWindow = NULL; - } - - return false; - } - - err = mANativeWindow->lock_buffer(mANativeWindow, buf); - if ( NO_ERROR != err ) { - CAMHAL_LOGE("Surface::lockBuffer failed: %s (%d)", strerror(-err), -err); - - if ( NO_INIT == err ) { - CAMHAL_LOGEA("Preview surface abandoned!"); - mANativeWindow = NULL; - } - - return false; - } - - for(i = 0; i < mBufferCount; i++) - { - if (mBuffers[i].opaque == buf) - break; - } - if (i == mBufferCount) { - CAMHAL_LOGEB("Failed to find handle %p", buf); - } - - // lock buffer before sending to FrameProvider for filling - bounds.left = 0; - bounds.top = 0; - bounds.right = mFrameWidth; - bounds.bottom = mFrameHeight; - - int lock_try_count = 0; - while (mapper.lock(*(buffer_handle_t *) mBuffers[i].opaque, CAMHAL_GRALLOC_USAGE, bounds, y_uv) < 0){ - if (++lock_try_count > LOCK_BUFFER_TRIES){ - if ( NULL != mErrorNotifier.get() ){ - mErrorNotifier->errorNotify(CAMERA_ERROR_UNKNOWN); - } - return false; - } - CAMHAL_LOGEA("Gralloc Lock FrameReturn Error: Sleeping 15ms"); - usleep(15000); - } - - { - android::AutoMutex lock(mLock); - mFramesWithCameraAdapterMap.add((buffer_handle_t *) mBuffers[i].opaque, i); - - for( k = 0; k < mFramesType.size() ; k++) { - if(mFramesType.keyAt(k) == (int)mBuffers[i].opaque) - break; - } - - if ( k == mFramesType.size() ) { - CAMHAL_LOGE("Frame type for preview buffer 0%x not found!!", mBuffers[i].opaque); - return false; - } - - frameType = (CameraFrame::FrameType) mFramesType.valueAt(k); - mFramesType.removeItem((int) mBuffers[i].opaque); - } - - CAMHAL_LOGSVB("handleFrameReturn: found graphic buffer %d of %d", i, mBufferCount-1); - mFrameProvider->returnFrame(&mBuffers[i], frameType); - - return true; -} - -void ANativeWindowDisplayAdapter::frameCallbackRelay(CameraFrame* caFrame) -{ - - if ( NULL != caFrame ) - { - if ( NULL != caFrame->mCookie ) - { - ANativeWindowDisplayAdapter *da = (ANativeWindowDisplayAdapter*) caFrame->mCookie; - da->frameCallback(caFrame); - } - else - { - CAMHAL_LOGEB("Invalid Cookie in Camera Frame = %p, Cookie = %p", caFrame, caFrame->mCookie); - } - } - else - { - CAMHAL_LOGEB("Invalid Camera Frame = %p", caFrame); - } - -} - -void ANativeWindowDisplayAdapter::frameCallback(CameraFrame* caFrame) -{ - ///Call queueBuffer of overlay in the context of the callback thread - DisplayFrame df; - df.mBuffer = caFrame->mBuffer; - df.mType = (CameraFrame::FrameType) caFrame->mFrameType; - df.mOffset = caFrame->mOffset; - df.mWidthStride = caFrame->mAlignment; - df.mLength = caFrame->mLength; - df.mWidth = caFrame->mWidth; - df.mHeight = caFrame->mHeight; - PostFrame(df); -} - - -/*--------------------ANativeWindowDisplayAdapter Class ENDS here-----------------------------*/ - -} // namespace Camera -} // namespace Ti |