author | guosong.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) |
commit | e498bd27a04895f167b3fc80763c36f9fd7f44ce (patch) | |
tree | 9f44251a891c2d5563a41a3f5fe4cb416947ef76 | |
parent | f54095ffb86d6f7177ebde18a3cdf540e78f4eb0 (diff) | |
download | camera-e498bd27a04895f167b3fc80763c36f9fd7f44ce.zip camera-e498bd27a04895f167b3fc80763c36f9fd7f44ce.tar.gz camera-e498bd27a04895f167b3fc80763c36f9fd7f44ce.tar.bz2 |
resolve jpeg blob buffersize for cts crash
-rwxr-xr-x | v3/EmulatedFakeCamera3.cpp | 70 | ||||
-rwxr-xr-x[-rw-r--r--] | v3/EmulatedFakeCamera3.h | 8 | ||||
-rwxr-xr-x | v3/fake-pipeline2/JpegCompressor.cpp | 23 | ||||
-rwxr-xr-x | v3/fake-pipeline2/JpegCompressor.h | 4 |
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; |