summaryrefslogtreecommitdiffstats
path: root/camera/ANativeWindowDisplayAdapter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'camera/ANativeWindowDisplayAdapter.cpp')
-rw-r--r--camera/ANativeWindowDisplayAdapter.cpp1345
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