author | Lawrence Mok <lawrence.mok@amlogic.com> | 2011-11-24 03:57:12 (GMT) |
---|---|---|
committer | Lawrence Mok <lawrence.mok@amlogic.com> | 2011-11-24 03:57:12 (GMT) |
commit | 0f7a637e95233bfcb9fcdd443f645e70e9e31fe6 (patch) | |
tree | 698630fe535db20ea6d07916a4d9e9c8e44be9a6 | |
parent | 52be3fde258b4dfc94afbad65b827dc7c818566e (diff) | |
download | camera-0f7a637e95233bfcb9fcdd443f645e70e9e31fe6.zip camera-0f7a637e95233bfcb9fcdd443f645e70e9e31fe6.tar.gz camera-0f7a637e95233bfcb9fcdd443f645e70e9e31fe6.tar.bz2 |
fix image capture buffer allocation
-rw-r--r-- | ANativeWindowDisplayAdapter.cpp | 10 | ||||
-rw-r--r-- | Android.mk | 1 | ||||
-rw-r--r-- | BaseCameraAdapter.cpp | 8 | ||||
-rw-r--r-- | CameraHal.cpp | 5 | ||||
-rw-r--r-- | MemoryManager.cpp | 107 | ||||
-rw-r--r-- | V4LCameraAdapter/V4LCameraAdapter.cpp | 113 | ||||
-rw-r--r-- | inc/CameraHal.h | 9 | ||||
-rw-r--r-- | inc/V4LCameraAdapter/V4LCameraAdapter.h | 8 |
8 files changed, 160 insertions, 101 deletions
diff --git a/ANativeWindowDisplayAdapter.cpp b/ANativeWindowDisplayAdapter.cpp index a868407..1610fa2 100644 --- a/ANativeWindowDisplayAdapter.cpp +++ b/ANativeWindowDisplayAdapter.cpp @@ -15,9 +15,8 @@ */ - - -#define LOG_TAG "CameraHAL" +//#define LOG_NDEBUG 0 +#define LOG_TAG "ANativeW" #include "ANativeWindowDisplayAdapter.h" //#include <OMX_IVCommon.h> @@ -25,13 +24,12 @@ #include <ui/GraphicBufferMapper.h> //#include <hal_public.h> -#define LOG_NDEBUG 0 -#undef LOG_TAG -#define LOG_TAG "ANativeW" +#if 0 #undef LOG_FUNCTION_NAME #undef LOG_FUNCTION_NAME_EXIT #define LOG_FUNCTION_NAME LOGV("%d: %s() ENTER", __LINE__, __FUNCTION__); #define LOG_FUNCTION_NAME_EXIT LOGV("%d: %s() EXIT", __LINE__, __FUNCTION__); +#endif namespace android { @@ -67,7 +67,6 @@ LOCAL_SHARED_LIBRARIES:= \ #libion \ LOCAL_CFLAGS := -fno-short-enums -DCOPY_IMAGE_BUFFER -LOCAL_CFLAGS += -DLOG_NDEBUG=0 LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw LOCAL_MODULE:= camera.amlogic diff --git a/BaseCameraAdapter.cpp b/BaseCameraAdapter.cpp index 925a09c..bc342e6 100644 --- a/BaseCameraAdapter.cpp +++ b/BaseCameraAdapter.cpp @@ -304,14 +304,14 @@ void BaseCameraAdapter::returnFrame(void* frameBuf, CameraFrame::FrameType frame } } - CAMHAL_LOGVB("REFCOUNT 0x%x %d", frameBuf, refCount); + //CAMHAL_LOGVB("REFCOUNT 0x%x %d", frameBuf, refCount); if ( NO_ERROR == res ) { //check if someone is holding this buffer if ( 0 == refCount ) { -#ifdef DEBUG_LOG && 0 +#if 0 //#ifdef DEBUG_LOG //TODO figure out if this is a problem if(mBuffersWithDucati.indexOfKey((int)frameBuf)>=0) { @@ -1239,10 +1239,10 @@ status_t BaseCameraAdapter::__sendFrameToSubscribers(CameraFrame* frame, return -EINVAL; } - CAMHAL_LOGVB("Type of Frame: 0x%x address: 0x%x refCount start %d", + /*CAMHAL_LOGVB("Type of Frame: 0x%x address: 0x%x refCount start %d", frame->mFrameType, ( uint32_t ) frame->mBuffer, - refCount); + refCount);*/ for ( unsigned int i = 0 ; i < refCount; i++ ) { frame->mCookie = ( void * ) subscribers->keyAt(i); diff --git a/CameraHal.cpp b/CameraHal.cpp index 0a1d0fa..7f1df0b 100644 --- a/CameraHal.cpp +++ b/CameraHal.cpp @@ -111,6 +111,11 @@ void CameraHal::setCallbacks(camera_notify_callback notify_cb, user); } + if ( NULL != mMemoryManager.get() ) + { + mMemoryManager->setRequestMemoryCallback(get_memory); + } + LOG_FUNCTION_NAME_EXIT; } diff --git a/MemoryManager.cpp b/MemoryManager.cpp index 38bb7d9..0d5c182 100644 --- a/MemoryManager.cpp +++ b/MemoryManager.cpp @@ -1,4 +1,5 @@ /* + * Copyright (C) Amlogic * Copyright (C) Texas Instruments - http://www.ti.com/ * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,54 +15,33 @@ * limitations under the License. */ - - -#define LOG_TAG "CameraHAL" - +#define LOG_TAG "MemoryManager" #include "CameraHal.h" #include "TICameraParameters.h" -extern "C" { - -//#include <ion.h> - -//#include <timm_osal_interfaces.h> -//#include <timm_osal_trace.h> - - -}; - namespace android { - -///@todo Move these constants to a common header file, preferably in tiler.h -#define STRIDE_8BIT (4 * 1024) -#define STRIDE_16BIT (4 * 1024) - -#define ALLOCATION_2D 2 - -///Utility Macro Declarations - /*--------------------MemoryManager Class STARTS here-----------------------------*/ +int MemoryManager::setRequestMemoryCallback(camera_request_memory get_memory) +{ + mRequestMemory = get_memory; + return 0; +} + void* MemoryManager::allocateBuffer(int width, int height, const char* format, int &bytes, int numBufs) { LOG_FUNCTION_NAME; - return NULL; -#if 0 - if(mIonFd == 0) + ///We allocate numBufs+1 because the last entry will be marked NULL to indicate + ///end of array, which is used when freeing the buffers + const uint numArrayEntriesC = (uint)(numBufs+1); + + if (!mRequestMemory) { - mIonFd = ion_open(); - if(mIonFd == 0) - { - CAMHAL_LOGEA("ion_open failed!!!"); - return NULL; - } + CAMHAL_LOGEA("no req. mem cb"); + LOG_FUNCTION_NAME_EXIT; + return NULL; } - ///We allocate numBufs+1 because the last entry will be marked NULL to indicate end of array, which is used when freeing - ///the buffers - const uint numArrayEntriesC = (uint)(numBufs+1); - ///Allocate a buffer array uint32_t *bufsArr = new uint32_t [numArrayEntriesC]; if(!bufsArr) @@ -78,36 +58,23 @@ void* MemoryManager::allocateBuffer(int width, int height, const char* format, i //2D Allocations are not supported currently if(bytes != 0) { - struct ion_handle *handle; - int mmap_fd; + camera_memory_t* handle = NULL; ///1D buffers for (int i = 0; i < numBufs; i++) { - int ret = ion_alloc(mIonFd, bytes, 0, 1 << ION_HEAP_TYPE_CARVEOUT, &handle); - if(ret < 0) + handle = mRequestMemory(-1, bytes, 1, NULL); + if(!handle) { - CAMHAL_LOGEB("ion_alloc resulted in error %d", ret); + CAMHAL_LOGEA("req. mem failed"); goto error; } - CAMHAL_LOGDB("Before mapping, handle = %x, nSize = %d", handle, bytes); - if ((ret = ion_map(mIonFd, handle, bytes, PROT_READ | PROT_WRITE, MAP_SHARED, 0, - (unsigned char**)&bufsArr[i], &mmap_fd)) < 0) - { - CAMHAL_LOGEB("Userspace mapping of ION buffers returned error %d", ret); - ion_free(mIonFd, handle); - goto error; - } + CAMHAL_LOGDB("handle = %x, nSize = %d", handle, bytes); + bufsArr[i] = (uint32_t)handle; - mIonHandleMap.add(bufsArr[i], (unsigned int)handle); - mIonFdMap.add(bufsArr[i], (unsigned int) mmap_fd); - mIonBufLength.add(bufsArr[i], (unsigned int) bytes); + mMemoryHandleMap.add(bufsArr[i], (unsigned int)handle); } - - } - else // If bytes is not zero, then it is a 2-D tiler buffer request - { } LOG_FUNCTION_NAME_EXIT; @@ -125,33 +92,24 @@ error: LOG_FUNCTION_NAME_EXIT; return NULL; -#endif } -//TODO: Get needed data to map tiler buffers -//Return dummy data for now uint32_t * MemoryManager::getOffsets() { LOG_FUNCTION_NAME; - LOG_FUNCTION_NAME_EXIT; - return NULL; } int MemoryManager::getFd() { LOG_FUNCTION_NAME; - LOG_FUNCTION_NAME_EXIT; - return -1; } int MemoryManager::freeBuffer(void* buf) { - return -1; -#if 0 status_t ret = NO_ERROR; LOG_FUNCTION_NAME; @@ -167,14 +125,10 @@ int MemoryManager::freeBuffer(void* buf) while(*bufEntry) { unsigned int ptr = (unsigned int) *bufEntry++; - if(mIonBufLength.valueFor(ptr)) + camera_memory_t* handle = (camera_memory_t*)mMemoryHandleMap.valueFor(ptr); + if(handle) { - munmap((void *)ptr, mIonBufLength.valueFor(ptr)); - close(mIonFdMap.valueFor(ptr)); - ion_free(mIonFd, (ion_handle*)mIonHandleMap.valueFor(ptr)); - mIonHandleMap.removeItem(ptr); - mIonBufLength.removeItem(ptr); - mIonFdMap.removeItem(ptr); + handle->release(handle); } else { @@ -186,17 +140,8 @@ int MemoryManager::freeBuffer(void* buf) uint32_t * bufArr = (uint32_t*)buf; delete [] bufArr; - if(mIonBufLength.size() == 0) - { - if(mIonFd) - { - ion_close(mIonFd); - mIonFd = 0; - } - } LOG_FUNCTION_NAME_EXIT; return ret; -#endif } status_t MemoryManager::setErrorHandler(ErrorNotifier *errorNotifier) diff --git a/V4LCameraAdapter/V4LCameraAdapter.cpp b/V4LCameraAdapter/V4LCameraAdapter.cpp index 4882cad..82d0672 100644 --- a/V4LCameraAdapter/V4LCameraAdapter.cpp +++ b/V4LCameraAdapter/V4LCameraAdapter.cpp @@ -145,7 +145,7 @@ status_t V4LCameraAdapter::initialize(CameraProperties::Properties* caps) mRecording = false; // --------- - writefile(SYSFILE_CAMERA_SET_PARA, "1"); + writefile((char*)SYSFILE_CAMERA_SET_PARA, (char*)"1"); LOG_FUNCTION_NAME_EXIT; @@ -209,7 +209,9 @@ status_t V4LCameraAdapter::setParameters(const CameraParameters ¶ms) ret = ioctl(mCameraHandle, VIDIOC_S_FMT, &mVideoInfo->format); if (ret < 0) { CAMHAL_LOGEB("Open: VIDIOC_S_FMT Failed: %s", strerror(errno)); - return ret; + LOGD("ret=%d", ret); + ret = NO_ERROR; //TODO + //return ret; } // Udpate the current parameter set @@ -247,7 +249,9 @@ status_t V4LCameraAdapter::useBuffers(CameraMode mode, void* bufArr, int num, si ret = UseBuffersPreview(bufArr, num); break; - //@todo Insert Image capture case here + case CAMERA_IMAGE_CAPTURE: + ret = UseBuffersCapture(bufArr, num); + break; case CAMERA_VIDEO: //@warn Video capture is not fully supported yet @@ -323,6 +327,36 @@ status_t V4LCameraAdapter::UseBuffersPreview(void* bufArr, int num) return ret; } +status_t V4LCameraAdapter::UseBuffersCapture(void* bufArr, int num) +{ + int ret = NO_ERROR; + + if(NULL == bufArr) + { + return BAD_VALUE; + } + + if (num > 1) + { + LOGD("----------------- UseBuffersCapture num=%d", num); + } + + uint32_t *ptr = (uint32_t*) bufArr; + LOGV("UseBuffersCapture %#x", ptr[0]); + mCaptureBuf = (camera_memory_t*)ptr[0]; + + return ret; +} + +status_t V4LCameraAdapter::takePicture() +{ + LOG_FUNCTION_NAME; + if (createThread(beginPictureThread, this) == false) + return -1; + LOG_FUNCTION_NAME_EXIT; + return NO_ERROR; +} + status_t V4LCameraAdapter::startPreview() { status_t ret = NO_ERROR; @@ -462,7 +496,9 @@ status_t V4LCameraAdapter::getFrameDataSize(size_t &dataFrameSize, size_t buffer status_t V4LCameraAdapter::getPictureBufferSize(size_t &length, size_t bufferCount) { - // We don't support image capture yet, safely return from here without messing up + int width, height; + mParams.getPictureSize(&width, &height); + length = width * height * 2; //wild guess return NO_ERROR; } @@ -618,6 +654,75 @@ int V4LCameraAdapter::previewThread() return ret; } +/* Image Capture Thread */ +// --------------------------------------------------------------------------- +/*static*/ int V4LCameraAdapter::beginPictureThread(void *cookie) +{ + V4LCameraAdapter *c = (V4LCameraAdapter *)cookie; + return c->pictureThread(); +} + +int V4LCameraAdapter::pictureThread() +{ + status_t ret = NO_ERROR; + int width, height; + CameraFrame frame; + + if (true) + { + int index = 0; + char *fp = this->GetFrame(index); + if(!fp) + { + return 0; //BAD_VALUE; + } + + if (!mCaptureBuf || !mCaptureBuf->data) + { + return 0; //BAD_VALUE; + } + + int width, height; + uint16_t* dest = (uint16_t*)mCaptureBuf->data; + uint16_t* src = (uint16_t*) fp; + mParams.getPictureSize(&width, &height); + //LOGD("pictureThread mCaptureBuf=%#x dest=%#x fp=%#x width=%d height=%d", mCaptureBuf, dest, fp, width, height); + //frame size? + for(int i=0;i<height;i++) + { + for(int j=0;j<width;j++) + { + *dest = *src; + src++; + dest++; + } + //dest += 4096/2-width; + } + + frame.mFrameMask = CameraFrame::IMAGE_FRAME; + frame.mFrameType = CameraFrame::IMAGE_FRAME; + frame.mQuirks = CameraFrame::ENCODE_RAW_YUV422I_TO_JPEG; + frame.mBuffer = mCaptureBuf; + frame.mLength = width*height*2; + frame.mAlignment = width*2; + frame.mOffset = 0; + frame.mYuv[0] = NULL; + frame.mYuv[1] = NULL; + frame.mWidth = width; + frame.mHeight = height; + frame.mTimestamp = systemTime(SYSTEM_TIME_MONOTONIC);; + ret = setInitFrameRefCount(frame.mBuffer, frame.mFrameMask); + if (ret) + LOGE("setInitFrameRefCount err=%d", ret); + else + ret = sendFrameToSubscribers(&frame); + //LOGD("pictureThread /sendFrameToSubscribers ret=%d", ret); + + } + + return ret; +} + extern "C" CameraAdapter* CameraAdapter_Factory() { CameraAdapter *adapter = NULL; diff --git a/inc/CameraHal.h b/inc/CameraHal.h index a3fcf85..c157fd7 100644 --- a/inc/CameraHal.h +++ b/inc/CameraHal.h @@ -677,12 +677,13 @@ private: class MemoryManager : public BufferProvider, public virtual RefBase { public: - MemoryManager():mIonFd(0){ } + MemoryManager(){ } ///Initializes the memory manager creates any resources required status_t initialize() { return NO_ERROR; } int setErrorHandler(ErrorNotifier *errorNotifier); + int setRequestMemoryCallback(camera_request_memory get_memory); virtual void* allocateBuffer(int width, int height, const char* format, int &bytes, int numBufs); virtual uint32_t * getOffsets(); virtual int getFd() ; @@ -690,11 +691,9 @@ public: private: + camera_request_memory mRequestMemory; sp<ErrorNotifier> mErrorNotifier; - int mIonFd; - KeyedVector<unsigned int, unsigned int> mIonHandleMap; - KeyedVector<unsigned int, unsigned int> mIonFdMap; - KeyedVector<unsigned int, unsigned int> mIonBufLength; + KeyedVector<unsigned int, unsigned int> mMemoryHandleMap; }; diff --git a/inc/V4LCameraAdapter/V4LCameraAdapter.h b/inc/V4LCameraAdapter/V4LCameraAdapter.h index 5e06074..6b20171 100644 --- a/inc/V4LCameraAdapter/V4LCameraAdapter.h +++ b/inc/V4LCameraAdapter/V4LCameraAdapter.h @@ -79,6 +79,7 @@ public: // API virtual status_t UseBuffersPreview(void* bufArr, int num); + virtual status_t UseBuffersCapture(void* bufArr, int num); //API to flush the buffers for preview status_t flushBuffers(); @@ -86,6 +87,7 @@ public: protected: //----------Parent class method implementation------------------------------------ + virtual status_t takePicture(); virtual status_t startPreview(); virtual status_t stopPreview(); virtual status_t useBuffers(CameraMode mode, void* bufArr, int num, size_t length, unsigned int queueable); @@ -121,6 +123,9 @@ private: int previewThread(); + static int beginPictureThread(void *cookie); + int pictureThread(); + public: private: @@ -128,6 +133,9 @@ private: KeyedVector<int, int> mPreviewBufs; mutable Mutex mPreviewBufsLock; + //TODO use members from BaseCameraAdapter + camera_memory_t *mCaptureBuf; + CameraParameters mParams; bool mPreviewing; |