summaryrefslogtreecommitdiffstats
path: root/camera/AppCallbackNotifier.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'camera/AppCallbackNotifier.cpp')
-rw-r--r--camera/AppCallbackNotifier.cpp171
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 &params, 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) {