diff options
Diffstat (limited to 'camera/AppCallbackNotifier.cpp')
-rw-r--r-- | camera/AppCallbackNotifier.cpp | 171 |
1 files changed, 114 insertions, 57 deletions
diff --git a/camera/AppCallbackNotifier.cpp b/camera/AppCallbackNotifier.cpp index 44d6a39..dcb7918 100644 --- a/camera/AppCallbackNotifier.cpp +++ b/camera/AppCallbackNotifier.cpp @@ -201,6 +201,7 @@ status_t AppCallbackNotifier::initialize() mRecording = false; mPreviewing = false; + mExternalLocking = false; LOG_FUNCTION_NAME_EXIT; @@ -699,6 +700,44 @@ static void copy2Dto1D(void *dst, } } +static void copyCroppedNV12(CameraFrame* frame, unsigned char *dst) +{ + unsigned int stride, width, height; + uint32_t offset, uvoffset; + size_t size; + + CAMHAL_ASSERT(frame && dst); + + offset = frame->mOffset; + stride = frame->mAlignment; + width = frame->mWidth; + height = frame->mHeight; + size = frame->mLength; + unsigned const char *src = (unsigned char *) frame->mBuffer->mapped; + + // offset to beginning of uv plane + uvoffset = (offset + size) * 2 / 3; + // offset to beginning of valid region of uv plane + uvoffset += (offset - (offset % stride)) / 2 + (offset % stride); + + // start of valid luma region + unsigned const char *luma = src + offset; + // start of valid chroma region + unsigned const char *chroma = src + uvoffset; + + // copy luma and chroma line x line + for (unsigned int i = 0; i < height; i++) { + memcpy(dst, luma, width); + luma += stride; + dst += width; + } + for (unsigned int i = 0; i < height / 2; i++) { + memcpy(dst, chroma, width); + chroma += stride; + dst += width; + } +} + void AppCallbackNotifier::copyAndSendPictureFrame(CameraFrame* frame, int32_t msgType) { camera_memory_t* picture = NULL; @@ -712,13 +751,26 @@ void AppCallbackNotifier::copyAndSendPictureFrame(CameraFrame* frame, int32_t ms goto exit; } - picture = mRequestMemory(-1, frame->mLength, 1, NULL); + if (frame->mBuffer->format && + (strcmp(frame->mBuffer->format, android::CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) && + (frame->mAlignment != frame->mWidth) && + ( msgType == CAMERA_MSG_RAW_IMAGE )) { + size_t size; - if (NULL != picture) { - dest = picture->data; - if (NULL != dest) { - src = (void *) ((unsigned int) frame->mBuffer->mapped + frame->mOffset); - memcpy(dest, src, frame->mLength); + size = CameraHal::calculateBufferSize(frame->mBuffer->format, frame->mWidth, frame->mHeight); + picture = mRequestMemory(-1, size, 1, NULL); + if (picture && picture->data) { + copyCroppedNV12(frame, (unsigned char*) picture->data); + } + } else { + picture = mRequestMemory(-1, frame->mLength, 1, NULL); + + if (NULL != picture) { + dest = picture->data; + if (NULL != dest) { + src = (void *) ((unsigned int) frame->mBuffer->mapped + frame->mOffset); + memcpy(dest, src, frame->mLength); + } } } } @@ -735,6 +787,38 @@ void AppCallbackNotifier::copyAndSendPictureFrame(CameraFrame* frame, int32_t ms } } +void AppCallbackNotifier::lockBufferAndUpdatePtrs(CameraFrame* frame) +{ + android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get(); + android::Rect bounds; + + bounds.left = 0; + bounds.top = 0; + bounds.right = frame->mWidth; + bounds.bottom = frame->mHeight; + void *y_uv[2]; + buffer_handle_t *handle = reinterpret_cast<buffer_handle_t *>(frame->mBuffer->opaque); + mapper.lock(*handle, CAMHAL_GRALLOC_USAGE, bounds, y_uv); + frame->mBuffer->mapped = y_uv[0]; + frame->mYuv[0] = reinterpret_cast<int>(frame->mBuffer->mapped); + frame->mYuv[1] = frame->mYuv[0] + (frame->mLength + frame->mOffset)*2/3; +} + +void AppCallbackNotifier::unlockBufferAndUpdatePtrs(CameraFrame* frame) +{ + android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get(); + buffer_handle_t *handle = reinterpret_cast<buffer_handle_t *>(frame->mBuffer->opaque); + mapper.unlock(*handle); + frame->mBuffer->mapped = NULL; + frame->mYuv[0] = NULL; + frame->mYuv[1] = NULL; +} + +void AppCallbackNotifier::setExternalLocking(bool extBuffLocking) +{ + mExternalLocking = extBuffLocking; +} + void AppCallbackNotifier::copyAndSendPreviewFrame(CameraFrame* frame, int32_t msgType) { camera_memory_t* picture = NULL; @@ -754,7 +838,9 @@ void AppCallbackNotifier::copyAndSendPreviewFrame(CameraFrame* frame, int32_t ms } dest = &mPreviewBuffers[mPreviewBufCount]; - + if (mExternalLocking) { + lockBufferAndUpdatePtrs(frame); + } CAMHAL_LOGVB("%d:copy2Dto1D(%p, %p, %d, %d, %d, %d, %d,%s)", __LINE__, dest, @@ -806,6 +892,10 @@ void AppCallbackNotifier::copyAndSendPreviewFrame(CameraFrame* frame, int32_t ms mDataCb(msgType, mPreviewMemory, mPreviewBufCount, NULL, mCallbackCookie); } + if (mExternalLocking) { + unlockBufferAndUpdatePtrs(frame); + } + // increment for next buffer mPreviewBufCount = (mPreviewBufCount + 1) % AppCallbackNotifier::MAX_BUFFERS; } @@ -989,9 +1079,9 @@ void AppCallbackNotifier::notifyFrame() current_snapshot = (mPreviewBufCount + MAX_BUFFERS - 1) % MAX_BUFFERS; tn_jpeg->src = (uint8_t *)mPreviewBuffers[current_snapshot].mapped; tn_jpeg->src_size = mPreviewMemory->size / MAX_BUFFERS; - tn_jpeg->dst_size = calculateBufferSize(tn_width, - tn_height, - previewFormat); + tn_jpeg->dst_size = CameraHal::calculateBufferSize(previewFormat, + tn_width, + tn_height); tn_jpeg->dst = (uint8_t*) malloc(tn_jpeg->dst_size); tn_jpeg->quality = tn_quality; tn_jpeg->in_width = width; @@ -1080,7 +1170,9 @@ void AppCallbackNotifier::notifyFrame() bounds.top = 0; bounds.right = mVideoWidth; bounds.bottom = mVideoHeight; - + if (mExternalLocking) { + lockBufferAndUpdatePtrs(frame); + } void *y_uv[2]; mapper.lock((buffer_handle_t)vBuf, CAMHAL_GRALLOC_USAGE, bounds, y_uv); y_uv[1] = y_uv[0] + mVideoHeight*4096; @@ -1103,6 +1195,9 @@ void AppCallbackNotifier::notifyFrame() VT_resizeFrame_Video_opt2_lp(&input, &output, NULL, 0); mapper.unlock((buffer_handle_t)vBuf->opaque); + if (mExternalLocking) { + unlockBufferAndUpdatePtrs(frame); + } videoMetadataBuffer->metadataBufferType = (int) android::kMetadataBufferTypeCameraSource; /* FIXME remove cast */ videoMetadataBuffer->handle = (void *)vBuf->opaque; @@ -1130,10 +1225,15 @@ void AppCallbackNotifier::notifyFrame() CAMHAL_LOGEA("Error! One of the video buffers is NULL"); break; } - + if (mExternalLocking) { + lockBufferAndUpdatePtrs(frame); + } *reinterpret_cast<buffer_handle_t*>(fakebuf->data) = reinterpret_cast<buffer_handle_t>(frame->mBuffer->mapped); mDataCbTimestamp(frame->mTimestamp, CAMERA_MSG_VIDEO_FRAME, fakebuf, 0, mCallbackCookie); fakebuf->release(fakebuf); + if (mExternalLocking) { + unlockBufferAndUpdatePtrs(frame); + } } } } @@ -1459,49 +1559,6 @@ void AppCallbackNotifier::setFrameProvider(FrameNotifier *frameNotifier) LOG_FUNCTION_NAME_EXIT; } -size_t AppCallbackNotifier::calculateBufferSize(size_t width, size_t height, const char *pixelFormat) -{ - size_t res = 0; - - LOG_FUNCTION_NAME - - if(strcmp(pixelFormat, android::CameraParameters::PIXEL_FORMAT_YUV422I) == 0) { - res = width*height*2; - } else if(strcmp(pixelFormat, android::CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) { - res = (width*height*3)/2; - } else if(strcmp(pixelFormat, android::CameraParameters::PIXEL_FORMAT_RGB565) == 0) { - res = width*height*2; - } else if (strcmp(pixelFormat, android::CameraParameters::PIXEL_FORMAT_YUV420P) == 0) { - size_t yStride, uvStride, ySize, uvSize; - alignYV12(width, height, yStride, uvStride, ySize, uvSize, res); - mPreviewPixelFormat = android::CameraParameters::PIXEL_FORMAT_YUV420P; - } - - LOG_FUNCTION_NAME_EXIT; - - return res; -} - -const char* AppCallbackNotifier::getContstantForPixelFormat(const char *pixelFormat) { - if (!pixelFormat) { - // returning NV12 as default - return android::CameraParameters::PIXEL_FORMAT_YUV420SP; - } - - if(strcmp(pixelFormat, android::CameraParameters::PIXEL_FORMAT_YUV422I) == 0) { - return android::CameraParameters::PIXEL_FORMAT_YUV422I; - } else if(strcmp(pixelFormat, android::CameraParameters::PIXEL_FORMAT_YUV420SP) == 0 ) { - return android::CameraParameters::PIXEL_FORMAT_YUV420SP; - } else if(strcmp(pixelFormat, android::CameraParameters::PIXEL_FORMAT_RGB565) == 0) { - return android::CameraParameters::PIXEL_FORMAT_RGB565; - } else if(strcmp(pixelFormat, android::CameraParameters::PIXEL_FORMAT_YUV420P) == 0) { - return android::CameraParameters::PIXEL_FORMAT_YUV420P; - } else { - // returning NV12 as default - return android::CameraParameters::PIXEL_FORMAT_YUV420SP; - } -} - status_t AppCallbackNotifier::startPreviewCallbacks(android::CameraParameters ¶ms, CameraBuffer *buffers, uint32_t *offsets, int fd, size_t length, size_t count) { unsigned int *bufArr; @@ -1531,8 +1588,8 @@ status_t AppCallbackNotifier::startPreviewCallbacks(android::CameraParameters &p mPreviewWidth = w; mPreviewHeight = h; mPreviewStride = 4096; - mPreviewPixelFormat = getContstantForPixelFormat(params.getPreviewFormat()); - size = calculateBufferSize(w, h, mPreviewPixelFormat); + mPreviewPixelFormat = CameraHal::getPixelFormatConstant(params.getPreviewFormat()); + size = CameraHal::calculateBufferSize(mPreviewPixelFormat, w, h); mPreviewMemory = mRequestMemory(-1, size, AppCallbackNotifier::MAX_BUFFERS, NULL); if (!mPreviewMemory) { |