From 05609e061fa59b8cda3e6cad530615952502b5c5 Mon Sep 17 00:00:00 2001
From: Pawit Pornkitprasan
Date: Sat, 17 Dec 2011 23:12:12 +0700
Subject: Fix image capture logic
---
libcamera/SecCameraHWInterface.cpp | 251 +++++--------------------------------
1 file changed, 30 insertions(+), 221 deletions(-)
diff --git a/libcamera/SecCameraHWInterface.cpp b/libcamera/SecCameraHWInterface.cpp
index ca82669..fd25127 100755
--- a/libcamera/SecCameraHWInterface.cpp
+++ b/libcamera/SecCameraHWInterface.cpp
@@ -2,6 +2,7 @@
**
** Copyright 2008, The Android Open Source Project
** Copyright 2010, Samsung Electronics Co. LTD
+** Copyright 2011, The CyanogenMod Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -1054,7 +1055,6 @@ int CameraHardwareSec::pictureThread()
int mThumbWidth, mThumbHeight, mThumbSize;
int cap_width, cap_height, cap_frame_size;
int JpegImageSize, JpegExifSize;
- bool isLSISensor = false;
unsigned int output_size = 0;
@@ -1118,25 +1118,9 @@ int CameraHardwareSec::pictureThread()
LOG_CAMERA("getSnapshotAndJpeg interval: %lu us", LOG_TIME(1));
if (mSecCamera->getCameraId() == SecCamera::CAMERA_ID_BACK) {
- isLSISensor = !strncmp((const char*)mCameraSensorName, "S5K4ECGX", 8);
- if(isLSISensor) {
- LOGI("== Camera Sensor Detect %s - Samsung LSI SOC 5M ==\n", mCameraSensorName);
- // LSI 5M SOC
- if (!SplitFrame(jpeg_data, SecCamera::getInterleaveDataSize(),
- SecCamera::getJpegLineLength(),
- mPostViewWidth * 2, mPostViewWidth,
- JpegHeap->data, &JpegImageSize,
- PostviewHeap->base(), &mPostViewSize)) {
- ret = UNKNOWN_ERROR;
- goto out;
- }
- } else {
- LOGI("== Camera Sensor Detect %s Sony SOC 5M ==\n", mCameraSensorName);
- decodeInterleaveData(jpeg_data,
- SecCamera::getInterleaveDataSize(),
- mPostViewWidth, mPostViewHeight,
- &JpegImageSize, JpegHeap->data, PostviewHeap->base());
- }
+ // TODO: copy postview to PostviewHeap->base()
+ memcpy(JpegHeap->data, jpeg_data, jpeg_size);
+ JpegImageSize = jpeg_size;
} else {
JpegImageSize = static_cast(output_size);
}
@@ -1152,27 +1136,35 @@ int CameraHardwareSec::pictureThread()
}
if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) {
- camera_memory_t *ExifHeap =
- mGetMemoryCb(-1, EXIF_FILE_SIZE + JPG_STREAM_BUF_SIZE, 1, 0);
- JpegExifSize = mSecCamera->getExif((unsigned char *)ExifHeap->data,
- (unsigned char *)ThumbnailHeap->base());
+ if (mSecCamera->getCameraId() == SecCamera::CAMERA_ID_BACK) {
+ // Aries' back camera already has EXIF data
+ camera_memory_t *mem = mGetMemoryCb(-1, JpegImageSize, 1, 0);
+ memcpy(mem->data, JpegHeap->data, JpegImageSize);
+ mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, mem, 0, NULL, mCallbackCookie);
+ mem->release(mem);
+ } else {
+ camera_memory_t *ExifHeap =
+ mGetMemoryCb(-1, EXIF_FILE_SIZE + JPG_STREAM_BUF_SIZE, 1, 0);
+ JpegExifSize = mSecCamera->getExif((unsigned char *)ExifHeap->data,
+ (unsigned char *)ThumbnailHeap->base());
- LOGV("JpegExifSize=%d", JpegExifSize);
+ LOGV("JpegExifSize=%d", JpegExifSize);
- if (JpegExifSize < 0) {
- ret = UNKNOWN_ERROR;
+ if (JpegExifSize < 0) {
+ ret = UNKNOWN_ERROR;
+ ExifHeap->release(ExifHeap);
+ goto out;
+ }
+
+ camera_memory_t *mem = mGetMemoryCb(-1, JpegImageSize + JpegExifSize, 1, 0);
+ uint8_t *ptr = (uint8_t *) mem->data;
+ memcpy(ptr, JpegHeap->data, 2); ptr += 2;
+ memcpy(ptr, ExifHeap->data, JpegExifSize); ptr += JpegExifSize;
+ memcpy(ptr, (uint8_t *) JpegHeap->data + 2, JpegImageSize - 2);
+ mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, mem, 0, NULL, mCallbackCookie);
+ mem->release(mem);
ExifHeap->release(ExifHeap);
- goto out;
}
-
- camera_memory_t *mem = mGetMemoryCb(-1, JpegImageSize + JpegExifSize, 1, 0);
- uint8_t *ptr = (uint8_t *) mem->data;
- memcpy(ptr, JpegHeap->data, 2); ptr += 2;
- memcpy(ptr, ExifHeap->data, JpegExifSize); ptr += JpegExifSize;
- memcpy(ptr, (uint8_t *) JpegHeap->data + 2, JpegImageSize - 2);
- mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, mem, 0, NULL, mCallbackCookie);
- mem->release(mem);
- ExifHeap->release(ExifHeap);
}
LOG_TIME_END(0)
@@ -1297,189 +1289,6 @@ bool CameraHardwareSec::FindEOIMarkerInJPEG(unsigned char *pBuf, int dwBufSize,
return false;
}
-bool CameraHardwareSec::SplitFrame(unsigned char *pFrame, int dwSize,
- int dwJPEGLineLength, int dwVideoLineLength, int dwVideoHeight,
- void *pJPEG, int *pdwJPEGSize,
- void *pVideo, int *pdwVideoSize)
-{
- LOGV("===========SplitFrame Start==============");
-
- if (NULL == pFrame || 0 >= dwSize) {
- LOGE("There is no contents (pFrame=%p, dwSize=%d", pFrame, dwSize);
- return false;
- }
-
- if (0 == dwJPEGLineLength || 0 == dwVideoLineLength) {
- LOGE("There in no input information for decoding interleaved jpeg");
- return false;
- }
-
- unsigned char *pSrc = pFrame;
- unsigned char *pSrcEnd = pFrame + dwSize;
-
- unsigned char *pJ = (unsigned char *)pJPEG;
- int dwJSize = 0;
- unsigned char *pV = (unsigned char *)pVideo;
- int dwVSize = 0;
-
- bool bRet = false;
- bool isFinishJpeg = false;
-
- while (pSrc < pSrcEnd) {
- // Check video start marker
- if (CheckVideoStartMarker(pSrc)) {
- int copyLength;
-
- if (pSrc + dwVideoLineLength <= pSrcEnd)
- copyLength = dwVideoLineLength;
- else
- copyLength = pSrcEnd - pSrc - VIDEO_COMMENT_MARKER_LENGTH;
-
- // Copy video data
- if (pV) {
- memcpy(pV, pSrc + VIDEO_COMMENT_MARKER_LENGTH, copyLength);
- pV += copyLength;
- dwVSize += copyLength;
- }
-
- pSrc += copyLength + VIDEO_COMMENT_MARKER_LENGTH;
- } else {
- // Copy pure JPEG data
- int size = 0;
- int dwCopyBufLen = dwJPEGLineLength <= pSrcEnd-pSrc ? dwJPEGLineLength : pSrcEnd - pSrc;
-
- if (FindEOIMarkerInJPEG((unsigned char *)pSrc, dwCopyBufLen, &size)) {
- isFinishJpeg = true;
- size += 2; // to count EOF marker size
- } else {
- if ((dwCopyBufLen == 1) && (pJPEG < pJ)) {
- unsigned char checkBuf[2] = { *(pJ - 1), *pSrc };
-
- if (CheckEOIMarker(checkBuf))
- isFinishJpeg = true;
- }
- size = dwCopyBufLen;
- }
-
- memcpy(pJ, pSrc, size);
-
- dwJSize += size;
-
- pJ += dwCopyBufLen;
- pSrc += dwCopyBufLen;
- }
- if (isFinishJpeg)
- break;
- }
-
- if (isFinishJpeg) {
- bRet = true;
- if(pdwJPEGSize)
- *pdwJPEGSize = dwJSize;
- if(pdwVideoSize)
- *pdwVideoSize = dwVSize;
- } else {
- LOGE("DecodeInterleaveJPEG_WithOutDT() => Can not find EOI");
- bRet = false;
- if(pdwJPEGSize)
- *pdwJPEGSize = 0;
- if(pdwVideoSize)
- *pdwVideoSize = 0;
- }
- LOGV("===========SplitFrame end==============");
-
- return bRet;
-}
-
-int CameraHardwareSec::decodeInterleaveData(unsigned char *pInterleaveData,
- int interleaveDataSize,
- int yuvWidth,
- int yuvHeight,
- int *pJpegSize,
- void *pJpegData,
- void *pYuvData)
-{
- if (pInterleaveData == NULL)
- return false;
-
- bool ret = true;
- unsigned int *interleave_ptr = (unsigned int *)pInterleaveData;
- unsigned char *jpeg_ptr = (unsigned char *)pJpegData;
- unsigned char *yuv_ptr = (unsigned char *)pYuvData;
- unsigned char *p;
- int jpeg_size = 0;
- int yuv_size = 0;
-
- int i = 0;
-
- LOGV("decodeInterleaveData Start~~~");
- while (i < interleaveDataSize) {
- if ((*interleave_ptr == 0xFFFFFFFF) || (*interleave_ptr == 0x02FFFFFF) ||
- (*interleave_ptr == 0xFF02FFFF)) {
- // Padding Data
-// LOGE("%d(%x) padding data\n", i, *interleave_ptr);
- interleave_ptr++;
- i += 4;
- }
- else if ((*interleave_ptr & 0xFFFF) == 0x05FF) {
- // Start-code of YUV Data
-// LOGE("%d(%x) yuv data\n", i, *interleave_ptr);
- p = (unsigned char *)interleave_ptr;
- p += 2;
- i += 2;
-
- // Extract YUV Data
- if (pYuvData != NULL) {
- memcpy(yuv_ptr, p, yuvWidth * 2);
- yuv_ptr += yuvWidth * 2;
- yuv_size += yuvWidth * 2;
- }
- p += yuvWidth * 2;
- i += yuvWidth * 2;
-
- // Check End-code of YUV Data
- if ((*p == 0xFF) && (*(p + 1) == 0x06)) {
- interleave_ptr = (unsigned int *)(p + 2);
- i += 2;
- } else {
- ret = false;
- break;
- }
- } else {
- // Extract JPEG Data
-// LOGE("%d(%x) jpg data, jpeg_size = %d bytes\n", i, *interleave_ptr, jpeg_size);
- if (pJpegData != NULL) {
- memcpy(jpeg_ptr, interleave_ptr, 4);
- jpeg_ptr += 4;
- jpeg_size += 4;
- }
- interleave_ptr++;
- i += 4;
- }
- }
- if (ret) {
- if (pJpegData != NULL) {
- // Remove Padding after EOI
- for (i = 0; i < 3; i++) {
- if (*(--jpeg_ptr) != 0xFF) {
- break;
- }
- jpeg_size--;
- }
- *pJpegSize = jpeg_size;
-
- }
- // Check YUV Data Size
- if (pYuvData != NULL) {
- if (yuv_size != (yuvWidth * yuvHeight * 2)) {
- ret = false;
- }
- }
- }
- LOGV("decodeInterleaveData End~~~");
- return ret;
-}
-
status_t CameraHardwareSec::dump(int fd) const
{
const size_t SIZE = 256;
@@ -2705,7 +2514,7 @@ extern "C" {
version_major : 1,
version_minor : 0,
id : CAMERA_HARDWARE_MODULE_ID,
- name : "Crespo camera HAL",
+ name : "Aries camera HAL",
author : "Samsung Corporation",
methods : &camera_module_methods,
},
--
cgit v1.1