From 94c98021b7e0ea614d92a1d1ea8bf163de9136bd Mon Sep 17 00:00:00 2001 From: Emilian Peev Date: Wed, 19 Jun 2019 09:11:51 -0700 Subject: [PATCH] Camera: Destroy jpeg handle in 'encodeGrayscaleJpeg' Make sure 'jpeg_destroy_compress()' is always called before leaving 'encodeGrayscaleJpeg()'. Additionally fix misspelling of 'intrinsic'. Bug: 135622974 Test: atest cts/tests/camera/src/android/hardware/camera2/cts/StillCaptureTest.java#testDynamicDepth --generate-baseline=12 Change-Id: I55c1f86881ba05aac6aac6981df5fcb276c9d4da --- .../api2/DepthCompositeStream.cpp | 14 ++-- .../api2/DepthCompositeStream.h | 2 +- .../common/DepthPhotoProcessor.cpp | 75 ++++++++++--------- .../common/DepthPhotoProcessor.h | 8 +- 4 files changed, 53 insertions(+), 46 deletions(-) diff --git a/services/camera/libcameraservice/api2/DepthCompositeStream.cpp b/services/camera/libcameraservice/api2/DepthCompositeStream.cpp index 9525ad2635..8ebaa2b2c7 100644 --- a/services/camera/libcameraservice/api2/DepthCompositeStream.cpp +++ b/services/camera/libcameraservice/api2/DepthCompositeStream.cpp @@ -58,8 +58,8 @@ DepthCompositeStream::DepthCompositeStream(wp device, entry = staticInfo.find(ANDROID_LENS_INTRINSIC_CALIBRATION); if (entry.count == 5) { - mInstrinsicCalibration.reserve(5); - mInstrinsicCalibration.insert(mInstrinsicCalibration.end(), entry.data.f, + mIntrinsicCalibration.reserve(5); + mIntrinsicCalibration.insert(mIntrinsicCalibration.end(), entry.data.f, entry.data.f + 5); } else { ALOGW("%s: Intrinsic calibration absent from camera characteristics!", __FUNCTION__); @@ -323,12 +323,12 @@ status_t DepthCompositeStream::processInputFrame(const InputFrame &inputFrame) { depthPhoto.mMaxJpegSize = maxDepthJpegSize; // The camera intrinsic calibration layout is as follows: // [focalLengthX, focalLengthY, opticalCenterX, opticalCenterY, skew] - if (mInstrinsicCalibration.size() == 5) { - memcpy(depthPhoto.mInstrinsicCalibration, mInstrinsicCalibration.data(), - sizeof(depthPhoto.mInstrinsicCalibration)); - depthPhoto.mIsInstrinsicCalibrationValid = 1; + if (mIntrinsicCalibration.size() == 5) { + memcpy(depthPhoto.mIntrinsicCalibration, mIntrinsicCalibration.data(), + sizeof(depthPhoto.mIntrinsicCalibration)); + depthPhoto.mIsIntrinsicCalibrationValid = 1; } else { - depthPhoto.mIsInstrinsicCalibrationValid = 0; + depthPhoto.mIsIntrinsicCalibrationValid = 0; } // The camera lens distortion contains the following lens correction coefficients. // [kappa_1, kappa_2, kappa_3 kappa_4, kappa_5] diff --git a/services/camera/libcameraservice/api2/DepthCompositeStream.h b/services/camera/libcameraservice/api2/DepthCompositeStream.h index 1bf31f47b3..975c59bc5c 100644 --- a/services/camera/libcameraservice/api2/DepthCompositeStream.h +++ b/services/camera/libcameraservice/api2/DepthCompositeStream.h @@ -124,7 +124,7 @@ private: ssize_t mMaxJpegSize; std::vector> mSupportedDepthSizes; - std::vector mInstrinsicCalibration, mLensDistortion; + std::vector mIntrinsicCalibration, mLensDistortion; bool mIsLogicalCamera; void* mDepthPhotoLibHandle; process_depth_photo_frame mDepthPhotoProcess; diff --git a/services/camera/libcameraservice/common/DepthPhotoProcessor.cpp b/services/camera/libcameraservice/common/DepthPhotoProcessor.cpp index fc79150351..3c90de0d6e 100644 --- a/services/camera/libcameraservice/common/DepthPhotoProcessor.cpp +++ b/services/camera/libcameraservice/common/DepthPhotoProcessor.cpp @@ -61,6 +61,13 @@ using dynamic_depth::Pose; using dynamic_depth::Profile; using dynamic_depth::Profiles; +template<> +struct std::default_delete { + inline void operator()(jpeg_compress_struct* cinfo) const { + jpeg_destroy_compress(cinfo); + } +}; + namespace android { namespace camera3 { @@ -118,16 +125,16 @@ status_t encodeGrayscaleJpeg(size_t width, size_t height, uint8_t *in, void *out bool mSuccess; } dmgr; - jpeg_compress_struct cinfo = {}; + std::unique_ptr cinfo = std::make_unique(); jpeg_error_mgr jerr; // Initialize error handling with standard callbacks, but // then override output_message (to print to ALOG) and // error_exit to set a flag and print a message instead // of killing the whole process. - cinfo.err = jpeg_std_error(&jerr); + cinfo->err = jpeg_std_error(&jerr); - cinfo.err->output_message = [](j_common_ptr cinfo) { + cinfo->err->output_message = [](j_common_ptr cinfo) { char buffer[JMSG_LENGTH_MAX]; /* Create the message */ @@ -135,7 +142,7 @@ status_t encodeGrayscaleJpeg(size_t width, size_t height, uint8_t *in, void *out ALOGE("libjpeg error: %s", buffer); }; - cinfo.err->error_exit = [](j_common_ptr cinfo) { + cinfo->err->error_exit = [](j_common_ptr cinfo) { (*cinfo->err->output_message)(cinfo); if(cinfo->client_data) { auto & dmgr = *static_cast(cinfo->client_data); @@ -144,12 +151,12 @@ status_t encodeGrayscaleJpeg(size_t width, size_t height, uint8_t *in, void *out }; // Now that we initialized some callbacks, let's create our compressor - jpeg_create_compress(&cinfo); + jpeg_create_compress(cinfo.get()); dmgr.mBuffer = static_cast(out); dmgr.mBufferSize = maxOutSize; dmgr.mEncodedSize = 0; dmgr.mSuccess = true; - cinfo.client_data = static_cast(&dmgr); + cinfo->client_data = static_cast(&dmgr); // These lambdas become C-style function pointers and as per C++11 spec // may not capture anything. @@ -171,28 +178,28 @@ status_t encodeGrayscaleJpeg(size_t width, size_t height, uint8_t *in, void *out dmgr.mEncodedSize = dmgr.mBufferSize - dmgr.free_in_buffer; ALOGV("%s:%d Done with jpeg: %zu", __FUNCTION__, __LINE__, dmgr.mEncodedSize); }; - cinfo.dest = reinterpret_cast(&dmgr); - cinfo.image_width = width; - cinfo.image_height = height; - cinfo.input_components = 1; - cinfo.in_color_space = JCS_GRAYSCALE; + cinfo->dest = static_cast(&dmgr); + cinfo->image_width = width; + cinfo->image_height = height; + cinfo->input_components = 1; + cinfo->in_color_space = JCS_GRAYSCALE; // Initialize defaults and then override what we want - jpeg_set_defaults(&cinfo); + jpeg_set_defaults(cinfo.get()); - jpeg_set_quality(&cinfo, jpegQuality, 1); - jpeg_set_colorspace(&cinfo, JCS_GRAYSCALE); - cinfo.raw_data_in = 0; - cinfo.dct_method = JDCT_IFAST; + jpeg_set_quality(cinfo.get(), jpegQuality, 1); + jpeg_set_colorspace(cinfo.get(), JCS_GRAYSCALE); + cinfo->raw_data_in = 0; + cinfo->dct_method = JDCT_IFAST; - cinfo.comp_info[0].h_samp_factor = 1; - cinfo.comp_info[1].h_samp_factor = 1; - cinfo.comp_info[2].h_samp_factor = 1; - cinfo.comp_info[0].v_samp_factor = 1; - cinfo.comp_info[1].v_samp_factor = 1; - cinfo.comp_info[2].v_samp_factor = 1; + cinfo->comp_info[0].h_samp_factor = 1; + cinfo->comp_info[1].h_samp_factor = 1; + cinfo->comp_info[2].h_samp_factor = 1; + cinfo->comp_info[0].v_samp_factor = 1; + cinfo->comp_info[1].v_samp_factor = 1; + cinfo->comp_info[2].v_samp_factor = 1; - jpeg_start_compress(&cinfo, TRUE); + jpeg_start_compress(cinfo.get(), TRUE); if (exifOrientation != ExifOrientation::ORIENTATION_UNDEFINED) { std::unique_ptr utils(ExifUtils::create()); @@ -204,19 +211,19 @@ status_t encodeGrayscaleJpeg(size_t width, size_t height, uint8_t *in, void *out if (utils->generateApp1()) { const uint8_t* exifBuffer = utils->getApp1Buffer(); size_t exifBufferSize = utils->getApp1Length(); - jpeg_write_marker(&cinfo, JPEG_APP0 + 1, static_cast(exifBuffer), + jpeg_write_marker(cinfo.get(), JPEG_APP0 + 1, static_cast(exifBuffer), exifBufferSize); } else { ALOGE("%s: Unable to generate App1 buffer", __FUNCTION__); } } - for (size_t i = 0; i < cinfo.image_height; i++) { + for (size_t i = 0; i < cinfo->image_height; i++) { auto currentRow = static_cast(in + i*width); - jpeg_write_scanlines(&cinfo, ¤tRow, /*num_lines*/1); + jpeg_write_scanlines(cinfo.get(), ¤tRow, /*num_lines*/1); } - jpeg_finish_compress(&cinfo); + jpeg_finish_compress(cinfo.get()); actualSize = dmgr.mEncodedSize; if (dmgr.mSuccess) { @@ -430,12 +437,12 @@ extern "C" int processDepthPhotoFrame(DepthPhotoInputFrame inputFrame, size_t de return BAD_VALUE; } - // It is not possible to generate an imaging model without instrinsic calibration. - if (inputFrame.mIsInstrinsicCalibrationValid) { + // It is not possible to generate an imaging model without intrinsic calibration. + if (inputFrame.mIsIntrinsicCalibrationValid) { // The camera intrinsic calibration layout is as follows: // [focalLengthX, focalLengthY, opticalCenterX, opticalCenterY, skew] - const dynamic_depth::Point focalLength(inputFrame.mInstrinsicCalibration[0], - inputFrame.mInstrinsicCalibration[1]); + const dynamic_depth::Point focalLength(inputFrame.mIntrinsicCalibration[0], + inputFrame.mIntrinsicCalibration[1]); size_t width = inputFrame.mMainJpegWidth; size_t height = inputFrame.mMainJpegHeight; if (switchDimensions) { @@ -444,9 +451,9 @@ extern "C" int processDepthPhotoFrame(DepthPhotoInputFrame inputFrame, size_t de } const Dimension imageSize(width, height); ImagingModelParams imagingParams(focalLength, imageSize); - imagingParams.principal_point.x = inputFrame.mInstrinsicCalibration[2]; - imagingParams.principal_point.y = inputFrame.mInstrinsicCalibration[3]; - imagingParams.skew = inputFrame.mInstrinsicCalibration[4]; + imagingParams.principal_point.x = inputFrame.mIntrinsicCalibration[2]; + imagingParams.principal_point.y = inputFrame.mIntrinsicCalibration[3]; + imagingParams.skew = inputFrame.mIntrinsicCalibration[4]; // The camera lens distortion contains the following lens correction coefficients. // [kappa_1, kappa_2, kappa_3 kappa_4, kappa_5] diff --git a/services/camera/libcameraservice/common/DepthPhotoProcessor.h b/services/camera/libcameraservice/common/DepthPhotoProcessor.h index 6a2fbffb6b..ba5ca9ec34 100644 --- a/services/camera/libcameraservice/common/DepthPhotoProcessor.h +++ b/services/camera/libcameraservice/common/DepthPhotoProcessor.h @@ -39,8 +39,8 @@ struct DepthPhotoInputFrame { size_t mMaxJpegSize; uint8_t mJpegQuality; uint8_t mIsLogical; - float mInstrinsicCalibration[5]; - uint8_t mIsInstrinsicCalibrationValid; + float mIntrinsicCalibration[5]; + uint8_t mIsIntrinsicCalibrationValid; float mLensDistortion[5]; uint8_t mIsLensDistortionValid; DepthPhotoOrientation mOrientation; @@ -57,8 +57,8 @@ struct DepthPhotoInputFrame { mMaxJpegSize(0), mJpegQuality(100), mIsLogical(0), - mInstrinsicCalibration{0.f}, - mIsInstrinsicCalibrationValid(0), + mIntrinsicCalibration{0.f}, + mIsIntrinsicCalibrationValid(0), mLensDistortion{0.f}, mIsLensDistortionValid(0), mOrientation(DepthPhotoOrientation::DEPTH_ORIENTATION_0_DEGREES) {}