summaryrefslogtreecommitdiff
authorguosong.zhou <guosong.zhou@amlogic.com>2014-11-10 02:53:29 (GMT)
committer guosong.zhou <guosong.zhou@amlogic.com>2014-11-10 02:53:29 (GMT)
commite498bd27a04895f167b3fc80763c36f9fd7f44ce (patch)
tree9f44251a891c2d5563a41a3f5fe4cb416947ef76
parentf54095ffb86d6f7177ebde18a3cdf540e78f4eb0 (diff)
downloadcamera-e498bd27a04895f167b3fc80763c36f9fd7f44ce.zip
camera-e498bd27a04895f167b3fc80763c36f9fd7f44ce.tar.gz
camera-e498bd27a04895f167b3fc80763c36f9fd7f44ce.tar.bz2
resolve jpeg blob buffersize for cts crash
Diffstat
-rwxr-xr-xv3/EmulatedFakeCamera3.cpp70
-rwxr-xr-x[-rw-r--r--]v3/EmulatedFakeCamera3.h8
-rwxr-xr-xv3/fake-pipeline2/JpegCompressor.cpp23
-rwxr-xr-xv3/fake-pipeline2/JpegCompressor.h4
4 files changed, 84 insertions, 21 deletions
diff --git a/v3/EmulatedFakeCamera3.cpp b/v3/EmulatedFakeCamera3.cpp
index ebf2022..64dbe85 100755
--- a/v3/EmulatedFakeCamera3.cpp
+++ b/v3/EmulatedFakeCamera3.cpp
@@ -124,6 +124,41 @@ const float EmulatedFakeCamera3::kExposureWanderMax = 1;
/**
* Camera device lifecycle methods
*/
+static const ssize_t kMinJpegBufferSize = 256 * 1024 + sizeof(camera3_jpeg_blob);
+jpegsize EmulatedFakeCamera3::getMaxJpegResolution(int32_t picSizes[],int count) {
+ int32_t maxJpegWidth = 0, maxJpegHeight = 0;
+ jpegsize maxJpegResolution;
+ for (int i=0; i < count; i+= 4) {
+ int32_t width = picSizes[i+1];
+ int32_t height = picSizes[i+2];
+ if (picSizes[i+0] == HAL_PIXEL_FORMAT_BLOB &&
+ (width * height > maxJpegWidth * maxJpegHeight)) {
+ maxJpegWidth = width;
+ maxJpegHeight = height;
+ }
+ }
+ maxJpegResolution.width = maxJpegWidth;
+ maxJpegResolution.height = maxJpegHeight;
+ return maxJpegResolution;
+}
+ssize_t EmulatedFakeCamera3::getJpegBufferSize(int width, int height) {
+ if (maxJpegResolution.width == 0) {
+ return BAD_VALUE;
+ }
+ ssize_t maxJpegBufferSize = JpegCompressor::kMaxJpegSize;
+
+ // Calculate final jpeg buffer size for the given resolution.
+ float scaleFactor = ((float) (width * height)) /
+ (maxJpegResolution.width * maxJpegResolution.height);
+ ssize_t jpegBufferSize = scaleFactor * maxJpegBufferSize;
+ // Bound the buffer size to [MIN_JPEG_BUFFER_SIZE, maxJpegBufferSize].
+ if (jpegBufferSize > maxJpegBufferSize) {
+ jpegBufferSize = maxJpegBufferSize;
+ } else if (jpegBufferSize < kMinJpegBufferSize) {
+ jpegBufferSize = kMinJpegBufferSize;
+ }
+ return jpegBufferSize;
+}
EmulatedFakeCamera3::EmulatedFakeCamera3(int cameraId, bool facingBack,
struct hw_module_t* module) :
@@ -1074,6 +1109,7 @@ status_t EmulatedFakeCamera3::processCaptureRequest(
uint32_t sensitivity;
bool needJpeg = false;
struct ExifInfo info;
+ ssize_t jpegbuffersize;
exposureTime = settings.find(ANDROID_SENSOR_EXPOSURE_TIME).data.i64[0];
frameDuration = settings.find(ANDROID_SENSOR_FRAME_DURATION).data.i64[0];
@@ -1205,6 +1241,9 @@ status_t EmulatedFakeCamera3::processCaptureRequest(
} else {
info.has_focallen = false;
}
+ jpegbuffersize = getJpegBufferSize(info.mainwidth,info.mainheight);
+
+ mJpegCompressor->SetMaxJpegBufferSize(jpegbuffersize);
mJpegCompressor->SetExifInfo(info);
mSensor->setPictureRotate(info.orientation);
DBG_LOGB("%s::thumbnailSize_width=%d,thumbnailSize_height=%d,mainsize_width=%d,mainsize_height=%d,jpegOrientation=%d",__FUNCTION__,
@@ -1473,21 +1512,6 @@ status_t EmulatedFakeCamera3::constructStaticInfo() {
info.update(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
(int32_t*)Sensor::kResolution, 2);
- int32_t full_size[4];
- if (mFacingBack) {
- full_size[0] = 0;
- full_size[1] = 0;
- full_size[2] = 1600;
- full_size[3] = 1200;
- } else {
- full_size[0] = 0;
- full_size[1] = 0;
- full_size[2] = 800;
- full_size[3] = 600;
- }
- info.update(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
- (int32_t*)full_size,
- sizeof(full_size)/sizeof(full_size[0]));
//(int32_t*)Sensor::kResolution, 2);
info.update(ANDROID_SENSOR_INFO_WHITE_LEVEL,
@@ -1540,6 +1564,22 @@ status_t EmulatedFakeCamera3::constructStaticInfo() {
info.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
picSizes, count);
+ maxJpegResolution = getMaxJpegResolution(picSizes,count);
+ int32_t full_size[4];
+ if (mFacingBack) {
+ full_size[0] = 0;
+ full_size[1] = 0;
+ full_size[2] = maxJpegResolution.width;
+ full_size[3] = maxJpegResolution.height;
+ } else {
+ full_size[0] = 0;
+ full_size[1] = 0;
+ full_size[2] = maxJpegResolution.width;
+ full_size[3] = maxJpegResolution.height;
+ }
+ info.update(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
+ (int32_t*)full_size,
+ sizeof(full_size)/sizeof(full_size[0]));
duration_count = sizeof(duration)/sizeof(duration[0]);
if (count < duration_count) {
duration_count = count;
diff --git a/v3/EmulatedFakeCamera3.h b/v3/EmulatedFakeCamera3.h
index 4d1edd2..2a1e5bb 100644..100755
--- a/v3/EmulatedFakeCamera3.h
+++ b/v3/EmulatedFakeCamera3.h
@@ -42,6 +42,10 @@ namespace android {
* connectDevice(), and closeCamera() methods of this class that are invoked in
* response to hw_module_methods_t::open, and camera_device::close callbacks.
*/
+struct jpegsize {
+ int width;
+ int height;
+};
class EmulatedFakeCamera3 : public EmulatedCamera3,
private Sensor::SensorListener {
public:
@@ -120,7 +124,9 @@ private:
static const struct KeyInfo_s sKeyInfo[];
static const struct KeyInfo_s sKeyBackwardCompat[];
-
+ jpegsize maxJpegResolution;
+ jpegsize getMaxJpegResolution(int32_t picSizes[],int count);
+ ssize_t getJpegBufferSize(int width, int height);
/**
* Run the fake 3A algorithms as needed. May override/modify settings
* values.
diff --git a/v3/fake-pipeline2/JpegCompressor.cpp b/v3/fake-pipeline2/JpegCompressor.cpp
index 4e01be7..488bb5f 100755
--- a/v3/fake-pipeline2/JpegCompressor.cpp
+++ b/v3/fake-pipeline2/JpegCompressor.cpp
@@ -28,6 +28,7 @@
#include <sys/time.h>
#define ARRAY_SIZE(array) (sizeof((array)) / sizeof((array)[0]))
+const size_t MARKER_LENGTH = 2; // length of a marker
const uint8_t MARK = 0xFF;
const uint8_t EOI = 0xD9;
bool checkJpegEnd(uint8_t *buf) {
@@ -169,6 +170,7 @@ bool JpegCompressor::threadLoop() {
}
if ((exiftable)&&(mDstThumbBuffer != NULL)) {
+ uint32_t realjpegsize = 0;
Section_t* exif_section = NULL;
ExifElementsTable* exif = exiftable;
exif->insertExifToJpeg((unsigned char*)mJpegBuffer.img,mMainJpegSize);
@@ -177,10 +179,15 @@ bool JpegCompressor::threadLoop() {
if (exif_section) {
exif->saveJpeg((unsigned char*) mJpegBuffer.img, mMainJpegSize + exif_section->Size);
}
-
- int offset = kMaxJpegSize-sizeof(struct camera2_jpeg_blob);
+ for (uint32_t size = (mMainJpegSize + exif_section->Size - 2); size > 0; size--) {
+ if (checkJpegEnd(mJpegBuffer.img + size)) {
+ realjpegsize = (size + MARKER_LENGTH);
+ break;
+ }
+ }
+ int offset = mMaxbufsize-sizeof(struct camera2_jpeg_blob);
blob.jpeg_blob_id = 0x00FF;
- blob.jpeg_size = mMainJpegSize + exif_section->Size;
+ blob.jpeg_size = realjpegsize;
memcpy(mJpegBuffer.img+offset, &blob, sizeof(struct camera2_jpeg_blob));
}
mListener->onJpegDone(mJpegBuffer, res == OK);
@@ -346,7 +353,7 @@ status_t JpegCompressor::thumbcompress() {
jpeg_finish_compress(&mCInfo);
if (checkError("Error while finishing compression")) return NO_INIT;
mThumbJpegSize = kMaxJpegSize - mCInfo.dest->free_in_buffer;
-
+ ALOGD("mThumbJpegSize = %d",mThumbJpegSize);
return OK;
}
bool JpegCompressor::isBusy() {
@@ -465,6 +472,14 @@ void JpegCompressor::ThumbJpegTermDestination(j_compress_ptr cinfo) {
JpegCompressor::JpegListener::~JpegListener() {
}
+void JpegCompressor::SetMaxJpegBufferSize(ssize_t size)
+{
+ mMaxbufsize = size;
+}
+ssize_t JpegCompressor::GetMaxJpegBufferSize()
+{
+ return mMaxbufsize;
+}
void JpegCompressor::SetExifInfo(struct ExifInfo info)
{
mInfo.mainwidth = info.mainwidth;
diff --git a/v3/fake-pipeline2/JpegCompressor.h b/v3/fake-pipeline2/JpegCompressor.h
index 019b165..8b19fec 100755
--- a/v3/fake-pipeline2/JpegCompressor.h
+++ b/v3/fake-pipeline2/JpegCompressor.h
@@ -119,12 +119,14 @@ class JpegCompressor: private Thread, public virtual RefBase {
bool isStreamInUse(uint32_t id);
bool waitForDone(nsecs_t timeout);
-
+ ssize_t GetMaxJpegBufferSize();
+ void SetMaxJpegBufferSize(ssize_t size);
void SetExifInfo(struct ExifInfo info);
int GenExif(ExifElementsTable* exiftable);
// TODO: Measure this
static const size_t kMaxJpegSize = 300000;
+ ssize_t mMaxbufsize;
private:
Mutex mBusyMutex;