diff options
author | Daniel Levin <dendy@ti.com> | 2012-11-27 21:34:12 +0200 |
---|---|---|
committer | Daniel Levin <dendy@ti.com> | 2012-12-04 15:38:30 +0200 |
commit | cf614ea4fd9ebc303d6314016d7e226fa7cd1966 (patch) | |
tree | 7f09a3067b666a09dd8faadcac8d33b89166e219 /camera/BufferSourceAdapter.cpp | |
parent | 92c40268fb2cdf196b7bd97fa5e569d8267a9ac7 (diff) | |
parent | 005d358cbcf413658d3e5204b699d9bf7367c256 (diff) | |
download | hardware_ti_omap4-cf614ea4fd9ebc303d6314016d7e226fa7cd1966.zip hardware_ti_omap4-cf614ea4fd9ebc303d6314016d7e226fa7cd1966.tar.gz hardware_ti_omap4-cf614ea4fd9ebc303d6314016d7e226fa7cd1966.tar.bz2 |
Merge branch 'd-jb-mr0-release-camera' into p-jb-mr1-release
Conflicts:
camera/OMXCameraAdapter/OMXCameraAdapter.cpp
test/CameraHal/camera_test_bufferqueue.h
test/CameraHal/camera_test_surfacetexture.cpp
Change-Id: I1f13c6a5b6369e943773d04a650406a79eb95750
Signed-off-by: Daniel Levin <dendy@ti.com>
Diffstat (limited to 'camera/BufferSourceAdapter.cpp')
-rw-r--r-- | camera/BufferSourceAdapter.cpp | 249 |
1 files changed, 220 insertions, 29 deletions
diff --git a/camera/BufferSourceAdapter.cpp b/camera/BufferSourceAdapter.cpp index d63b117..3c4e698 100644 --- a/camera/BufferSourceAdapter.cpp +++ b/camera/BufferSourceAdapter.cpp @@ -31,8 +31,7 @@ static int getANWFormat(const char* parameters_format) if (parameters_format != NULL) { if (strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_YUV422I) == 0) { CAMHAL_LOGDA("CbYCrY format selected"); - // TODO(XXX): not defined yet - format = -1; + format = HAL_PIXEL_FORMAT_TI_UYVY; } else if (strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) { CAMHAL_LOGDA("YUV420SP format selected"); format = HAL_PIXEL_FORMAT_TI_NV12; @@ -58,11 +57,12 @@ static int getUsageFromANW(int format) switch (format) { case HAL_PIXEL_FORMAT_TI_NV12: + case HAL_PIXEL_FORMAT_TI_Y16: + case HAL_PIXEL_FORMAT_TI_UYVY: // This usage flag indicates to gralloc we want the // buffers to come from system heap usage |= GRALLOC_USAGE_PRIVATE_0; break; - case HAL_PIXEL_FORMAT_TI_Y16: default: // No special flags needed break; @@ -78,6 +78,8 @@ static const char* getFormatFromANW(int format) return android::CameraParameters::PIXEL_FORMAT_YUV420SP; case HAL_PIXEL_FORMAT_TI_Y16: return android::CameraParameters::PIXEL_FORMAT_BAYER_RGGB; + case HAL_PIXEL_FORMAT_TI_UYVY: + return android::CameraParameters::PIXEL_FORMAT_YUV422I; default: break; } @@ -88,6 +90,7 @@ static CameraFrame::FrameType formatToOutputFrameType(const char* format) { switch (getANWFormat(format)) { case HAL_PIXEL_FORMAT_TI_NV12: case HAL_PIXEL_FORMAT_TI_Y16: + case HAL_PIXEL_FORMAT_TI_UYVY: // Assuming NV12 1D is RAW or Image frame return CameraFrame::RAW_FRAME; default: @@ -102,6 +105,7 @@ static int getHeightFromFormat(const char* format, int stride, int size) { case HAL_PIXEL_FORMAT_TI_NV12: return (size / (3 * stride)) * 2; case HAL_PIXEL_FORMAT_TI_Y16: + case HAL_PIXEL_FORMAT_TI_UYVY: return (size / stride) / 2; default: break; @@ -112,6 +116,11 @@ static int getHeightFromFormat(const char* format, int stride, int size) { /*--------------------BufferSourceAdapter Class STARTS here-----------------------------*/ +///Constant definitions +// TODO(XXX): Temporarily increase number of buffers we can allocate from ANW +// until faux-NPA mode is implemented +const int BufferSourceAdapter::NO_BUFFERS_IMAGE_CAPTURE_SYSTEM_HEAP = 15; + /** * Display Adapter class STARTS here.. */ @@ -136,6 +145,10 @@ BufferSourceAdapter::~BufferSourceAdapter() { LOG_FUNCTION_NAME; + freeBufferList(mBuffers); + + android::AutoMutex lock(mLock); + destroy(); if (mFrameProvider) { @@ -155,12 +168,6 @@ BufferSourceAdapter::~BufferSourceAdapter() mReturnFrame.clear(); } - if( mBuffers != NULL) - { - delete [] mBuffers; - mBuffers = NULL; - } - LOG_FUNCTION_NAME_EXIT; } @@ -193,12 +200,33 @@ int BufferSourceAdapter::setPreviewWindow(preview_stream_ops_t *source) return BAD_VALUE; } - if ( source == mBufferSource ) { - return ALREADY_EXISTS; - } + if (mBufferSource) { + char id1[OP_STR_SIZE], id2[OP_STR_SIZE]; + status_t ret; - // Destroy the existing source, if it exists - destroy(); + ret = extendedOps()->get_id(mBufferSource, id1, sizeof(id1)); + if (ret != 0) { + CAMHAL_LOGE("Surface::getId returned error %d", ret); + return ret; + } + + ret = extendedOps()->get_id(source, id2, sizeof(id2)); + if (ret != 0) { + CAMHAL_LOGE("Surface::getId returned error %d", ret); + return ret; + } + if ((0 >= strlen(id1)) || (0 >= strlen(id2))) { + CAMHAL_LOGE("Cannot set ST without name: id1:\"%s\" id2:\"%s\"", + id1, id2); + return NOT_ENOUGH_DATA; + } + if (0 == strcmp(id1, id2)) { + return ALREADY_EXISTS; + } + + // client has to unset mBufferSource before being able to set a new one + return BAD_VALUE; + } // Move to new source obj mBufferSource = source; @@ -208,6 +236,19 @@ int BufferSourceAdapter::setPreviewWindow(preview_stream_ops_t *source) return NO_ERROR; } +bool BufferSourceAdapter::match(const char * str) { + char id1[OP_STR_SIZE]; + status_t ret; + + ret = extendedOps()->get_id(mBufferSource, id1, sizeof(id1)); + + if (ret != 0) { + CAMHAL_LOGE("Surface::getId returned error %d", ret); + } + + return strcmp(id1, str) == 0; +} + int BufferSourceAdapter::setFrameProvider(FrameNotifier *frameProvider) { LOG_FUNCTION_NAME; @@ -324,6 +365,7 @@ CameraBuffer* BufferSourceAdapter::allocateBufferList(int width, int dummyHeight int pixFormat = getANWFormat(format); int usage = getUsageFromANW(pixFormat); + mPixelFormat = CameraHal::getPixelFormatConstant(format); // Set gralloc usage bits for window. err = mBufferSource->set_usage(mBufferSource, usage); @@ -338,7 +380,7 @@ CameraBuffer* BufferSourceAdapter::allocateBufferList(int width, int dummyHeight return NULL; } - CAMHAL_LOGDB("Number of buffers set to ANativeWindow %d", numBufs); + CAMHAL_LOGDB("Number of buffers set to BufferSourceAdapter %d", numBufs); // Set the number of buffers needed for this buffer source err = mBufferSource->set_buffer_count(mBufferSource, numBufs); if (err != 0) { @@ -399,9 +441,10 @@ CameraBuffer* BufferSourceAdapter::allocateBufferList(int width, int dummyHeight CAMHAL_LOGDB("got handle %p", handle); mBuffers[i].opaque = (void *)handle; mBuffers[i].type = CAMERA_BUFFER_ANW; + mBuffers[i].format = mPixelFormat; mFramesWithCameraAdapterMap.add(handle, i); - bytes = getBufSize(format, width, height); + bytes = CameraHal::calculateBufferSize(format, width, height); } for( i = 0; i < mBufferCount-undequeued; i++ ) { @@ -436,7 +479,6 @@ CameraBuffer* BufferSourceAdapter::allocateBufferList(int width, int dummyHeight mFramesWithCameraAdapterMap.removeItem((buffer_handle_t *) mBuffers[i].opaque); } - mPixelFormat = getPixFormatConstant(format); mFrameWidth = width; mFrameHeight = height; mBufferSourceDirection = BUFFER_SOURCE_TAP_OUT; @@ -468,6 +510,118 @@ CameraBuffer* BufferSourceAdapter::allocateBufferList(int width, int dummyHeight } +CameraBuffer *BufferSourceAdapter::getBuffers(bool reset) { + int undequeued = 0; + status_t err; + android::Mutex::Autolock lock(mLock); + + if (!mBufferSource || !mBuffers) { + CAMHAL_LOGE("Adapter is not set up properly: " + "mBufferSource:%p mBuffers:%p", + mBufferSource, mBuffers); + goto fail; + } + + // CameraHal is indicating to us that the state of the mBuffer + // might have changed. We might need to check the state of the + // buffer list and pass a new one depending on the state of our + // surface + if (reset) { + const int lnumBufs = mBufferCount; + android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get(); + android::Rect bounds(mFrameWidth, mFrameHeight); + void *y_uv[2]; + CameraBuffer * newBuffers = NULL; + unsigned int index = 0; + android::KeyedVector<void*, int> missingIndices; + + newBuffers = new CameraBuffer [lnumBufs]; + memset (newBuffers, 0, sizeof(CameraBuffer) * lnumBufs); + + // Use this vector to figure out missing indices + for (int i = 0; i < mBufferCount; i++) { + missingIndices.add(mBuffers[i].opaque, i); + } + + // assign buffers that we have already dequeued + for (index = 0; index < mFramesWithCameraAdapterMap.size(); index++) { + int value = mFramesWithCameraAdapterMap.valueAt(index); + newBuffers[index].opaque = mBuffers[value].opaque; + newBuffers[index].type = mBuffers[value].type; + newBuffers[index].format = mBuffers[value].format; + newBuffers[index].mapped = mBuffers[value].mapped; + mFramesWithCameraAdapterMap.replaceValueAt(index, index); + missingIndices.removeItem(newBuffers[index].opaque); + } + + mBufferSource->get_min_undequeued_buffer_count(mBufferSource, &undequeued); + + // dequeue the rest of the buffers + for (index; index < (unsigned int)(mBufferCount-undequeued); index++) { + buffer_handle_t *handle; + int stride; // dummy variable to get stride + + err = mBufferSource->dequeue_buffer(mBufferSource, &handle, &stride); + if (err != 0) { + CAMHAL_LOGEB("dequeueBuffer failed: %s (%d)", strerror(-err), -err); + if ( ENODEV == err ) { + CAMHAL_LOGEA("Preview surface abandoned!"); + mBufferSource = NULL; + } + goto fail; + } + newBuffers[index].opaque = (void *)handle; + newBuffers[index].type = CAMERA_BUFFER_ANW; + newBuffers[index].format = mPixelFormat; + mFramesWithCameraAdapterMap.add(handle, index); + + mBufferSource->lock_buffer(mBufferSource, handle); + mapper.lock(*handle, CAMHAL_GRALLOC_USAGE, bounds, y_uv); + newBuffers[index].mapped = y_uv[0]; + CAMHAL_LOGDB("got handle %p", handle); + + missingIndices.removeItem(newBuffers[index].opaque); + } + + // now we need to figure out which buffers aren't dequeued + // which are in mBuffers but not newBuffers yet + if ((mBufferCount - index) != missingIndices.size()) { + CAMHAL_LOGD("Hrmm somethings gone awry. We are missing a different number" + " of buffers than we can fill"); + } + for (unsigned int i = 0; i < missingIndices.size(); i++) { + int j = missingIndices.valueAt(i); + + CAMHAL_LOGD("Filling at %d", j); + newBuffers[index].opaque = mBuffers[j].opaque; + newBuffers[index].type = mBuffers[j].type; + newBuffers[index].format = mBuffers[j].format; + newBuffers[index].mapped = mBuffers[j].mapped; + } + + delete [] mBuffers; + mBuffers = newBuffers; + } + + return mBuffers; + + fail: + return NULL; +} + +unsigned int BufferSourceAdapter::getSize() { + android::Mutex::Autolock lock(mLock); + return CameraHal::calculateBufferSize(mPixelFormat, mFrameWidth, mFrameHeight); +} + +int BufferSourceAdapter::getBufferCount() { + int count = -1; + + android::Mutex::Autolock lock(mLock); + if (mBufferSource) extendedOps()->get_buffer_count(mBufferSource, &count); + return count; +} + CameraBuffer* BufferSourceAdapter::getBufferList(int *num) { LOG_FUNCTION_NAME; status_t err; @@ -478,6 +632,7 @@ CameraBuffer* BufferSourceAdapter::getBufferList(int *num) { // TODO(XXX): Only supporting one input buffer at a time right now *num = 1; + mBufferCount = *num; mBuffers = new CameraBuffer [lnumBufs]; memset (mBuffers, 0, sizeof(CameraBuffer) * lnumBufs); @@ -485,7 +640,10 @@ CameraBuffer* BufferSourceAdapter::getBufferList(int *num) { return NULL; } - err = extendedOps()->update_and_get_buffer(mBufferSource, &handle, &mBuffers[0].stride); + err = extendedOps()->update_and_get_buffer(mBufferSource, + &handle, + &mBuffers[0].stride, + &mBuffers[0].privateData); if (err != 0) { CAMHAL_LOGEB("update and get buffer failed: %s (%d)", strerror(-err), -err); if ( ENODEV == err ) { @@ -503,6 +661,10 @@ CameraBuffer* BufferSourceAdapter::getBufferList(int *num) { err = extendedOps()->get_buffer_dimension(mBufferSource, &mBuffers[0].width, &mBuffers[0].height); err = extendedOps()->get_buffer_format(mBufferSource, &formatSource); + int t, l, r, b, w, h; + err = extendedOps()->get_crop(mBufferSource, &l, &t, &r, &b); + err = extendedOps()->get_current_size(mBufferSource, &w, &h); + // lock buffer { void *y_uv[2]; @@ -516,6 +678,8 @@ CameraBuffer* BufferSourceAdapter::getBufferList(int *num) { mPixelFormat = getFormatFromANW(formatSource); mBuffers[0].format = mPixelFormat; + mBuffers[0].actual_size = CameraHal::calculateBufferSize(mPixelFormat, w, h); + mBuffers[0].offset = t * w + l * CameraHal::getBPP(mPixelFormat); mBufferSourceDirection = BUFFER_SOURCE_TAP_IN; return mBuffers; @@ -649,16 +813,14 @@ int BufferSourceAdapter::freeBufferList(CameraBuffer * buflist) status_t ret = NO_ERROR; + if ( mBuffers != buflist ) { + return BAD_VALUE; + } + android::AutoMutex lock(mLock); if (mBufferSourceDirection == BUFFER_SOURCE_TAP_OUT) returnBuffersToWindow(); - if ( NULL != buflist ) - { - delete [] buflist; - mBuffers = NULL; - } - if( mBuffers != NULL) { delete [] mBuffers; @@ -686,21 +848,31 @@ void BufferSourceAdapter::handleFrameCallback(CameraFrame* frame) status_t ret = NO_ERROR; buffer_handle_t *handle = NULL; int i; + uint32_t x, y; android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get(); + android::AutoMutex lock(mLock); + if (!mBuffers || !frame->mBuffer) { CAMHAL_LOGEA("Adapter sent BufferSourceAdapter a NULL frame?"); return; } - android::AutoMutex lock(mLock); - for ( i = 0; i < mBufferCount; i++ ) { if (frame->mBuffer == &mBuffers[i]) { break; } } + if (i >= mBufferCount) { + CAMHAL_LOGD("Can't find frame in buffer list"); + if (frame->mFrameType != CameraFrame::REPROCESS_INPUT_FRAME) { + mFrameProvider->returnFrame(frame->mBuffer, + static_cast<CameraFrame::FrameType>(frame->mFrameType)); + } + return; + } + handle = (buffer_handle_t *) mBuffers[i].opaque; // Handle input buffers @@ -709,9 +881,19 @@ void BufferSourceAdapter::handleFrameCallback(CameraFrame* frame) if (frame->mFrameType == CameraFrame::REPROCESS_INPUT_FRAME) { CAMHAL_LOGD("Unlock %p (buffer #%d)", handle, i); mapper.unlock(*handle); + extendedOps()->release_buffer(mBufferSource, mBuffers[i].privateData); return; } + CameraHal::getXYFromOffset(&x, &y, frame->mOffset, frame->mAlignment, mPixelFormat); + CAMHAL_LOGVB("offset = %u left = %d top = %d right = %d bottom = %d", + frame->mOffset, x, y, x + frame->mWidth, y + frame->mHeight); + ret = mBufferSource->set_crop(mBufferSource, x, y, x + frame->mWidth, y + frame->mHeight); + if (NO_ERROR != ret) { + CAMHAL_LOGE("mBufferSource->set_crop returned error %d", ret); + goto fail; + } + if ( NULL != frame->mMetaData.get() ) { camera_memory_t *extMeta = frame->mMetaData->getExtendedMetadata(); if ( NULL != extMeta ) { @@ -720,6 +902,7 @@ void BufferSourceAdapter::handleFrameCallback(CameraFrame* frame) ret = extendedOps()->set_metadata(mBufferSource, extMeta); if (ret != 0) { CAMHAL_LOGE("Surface::set_metadata returned error %d", ret); + goto fail; } } } @@ -730,12 +913,18 @@ void BufferSourceAdapter::handleFrameCallback(CameraFrame* frame) ret = mBufferSource->enqueue_buffer(mBufferSource, handle); if (ret != 0) { CAMHAL_LOGE("Surface::queueBuffer returned error %d", ret); + goto fail; } mFramesWithCameraAdapterMap.removeItem((buffer_handle_t *) frame->mBuffer->opaque); - // signal return frame thread that it can dequeue a buffer now - mReturnFrame->signal(); + return; + +fail: + mFramesWithCameraAdapterMap.clear(); + mBufferSource = NULL; + mReturnFrame->requestExit(); + mQueueFrame->requestExit(); } @@ -750,7 +939,9 @@ bool BufferSourceAdapter::handleFrameReturn() void *y_uv[2]; android::Rect bounds(mFrameWidth, mFrameHeight); - if ( NULL == mBufferSource ) { + android::AutoMutex lock(mLock); + + if ( (NULL == mBufferSource) || (NULL == mBuffers) ) { return false; } |