Camera: encode JPEG/R without hardware JPEG encoder
Bug: b/20133417, b/252835416
Test: Test: atest -c -d \
cts/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java#testJpegR
Change-Id: I17bd9e4f8a83c422d56a2606c4c642a76885e34b
diff --git a/services/camera/libcameraservice/api2/JpegRCompositeStream.cpp b/services/camera/libcameraservice/api2/JpegRCompositeStream.cpp
index fb8979d..9857fd8 100644
--- a/services/camera/libcameraservice/api2/JpegRCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/JpegRCompositeStream.cpp
@@ -285,22 +285,37 @@
}
size_t actualJpegRSize = 0;
- if (mSupportInternalJpeg) {
- recoverymap::jpegr_uncompressed_struct p010;
- recoverymap::jpegr_compressed_struct jpeg;
- recoverymap::jpegr_compressed_struct jpegR;
+ recoverymap::jpegr_uncompressed_struct p010;
+ recoverymap::jpegr_compressed_struct jpegR;
+ recoverymap::RecoveryMap recoveryMap;
- p010.height = inputFrame.p010Buffer.height;
- p010.width = inputFrame.p010Buffer.width;
- p010.colorGamut = recoverymap::jpegr_color_gamut::JPEGR_COLORGAMUT_BT2100;
- size_t yChannelSizeInByte = p010.width * p010.height * 2;
- size_t uvChannelSizeInByte = p010.width * p010.height;
- p010.data = new uint8_t[yChannelSizeInByte + uvChannelSizeInByte];
- std::unique_ptr<uint8_t[]> p010_data;
- p010_data.reset(reinterpret_cast<uint8_t*>(p010.data));
- memcpy((uint8_t*)p010.data, inputFrame.p010Buffer.data, yChannelSizeInByte);
- memcpy((uint8_t*)p010.data + yChannelSizeInByte, inputFrame.p010Buffer.dataCb,
- uvChannelSizeInByte);
+ p010.height = inputFrame.p010Buffer.height;
+ p010.width = inputFrame.p010Buffer.width;
+ p010.colorGamut = recoverymap::jpegr_color_gamut::JPEGR_COLORGAMUT_BT2100;
+ size_t yChannelSizeInByte = p010.width * p010.height * 2;
+ size_t uvChannelSizeInByte = p010.width * p010.height;
+ p010.data = new uint8_t[yChannelSizeInByte + uvChannelSizeInByte];
+ std::unique_ptr<uint8_t[]> p010_data;
+ p010_data.reset(reinterpret_cast<uint8_t*>(p010.data));
+ memcpy((uint8_t*)p010.data, inputFrame.p010Buffer.data, yChannelSizeInByte);
+ memcpy((uint8_t*)p010.data + yChannelSizeInByte, inputFrame.p010Buffer.dataCb,
+ uvChannelSizeInByte);
+
+ jpegR.data = dstBuffer;
+ jpegR.maxLength = maxJpegRBufferSize;
+
+ recoverymap::jpegr_transfer_function transferFunction;
+ switch (mP010DynamicRange) {
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10:
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS:
+ transferFunction = recoverymap::jpegr_transfer_function::JPEGR_TF_PQ;
+ break;
+ default:
+ transferFunction = recoverymap::jpegr_transfer_function::JPEGR_TF_HLG;
+ }
+
+ if (mSupportInternalJpeg) {
+ recoverymap::jpegr_compressed_struct jpeg;
jpeg.data = inputFrame.jpegBuffer.data;
jpeg.length = android::camera2::JpegProcessor::findJpegSize(inputFrame.jpegBuffer.data,
@@ -317,28 +332,7 @@
jpeg.colorGamut = recoverymap::jpegr_color_gamut::JPEGR_COLORGAMUT_BT709;
}
- recoverymap::jpegr_transfer_function transferFunction;
- switch (mP010DynamicRange) {
- case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10:
- case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS:
- transferFunction = recoverymap::jpegr_transfer_function::JPEGR_TF_PQ;
- break;
- default:
- transferFunction = recoverymap::jpegr_transfer_function::JPEGR_TF_HLG;
- }
-
- jpegR.data = dstBuffer;
- jpegR.maxLength = maxJpegRBufferSize;
-
- recoverymap::RecoveryMap recoveryMap;
res = recoveryMap.encodeJPEGR(&p010, &jpeg, transferFunction, &jpegR);
- if (res != OK) {
- ALOGE("%s: Error trying to encode JPEG/R: %s (%d)", __FUNCTION__, strerror(-res), res);
- return res;
- }
-
- actualJpegRSize = jpegR.length;
- p010_data.release();
} else {
const uint8_t* exifBuffer = nullptr;
size_t exifBufferSize = 0;
@@ -352,8 +346,22 @@
} else {
ALOGE("%s: Unable to generate App1 buffer", __FUNCTION__);
}
+
+ recoverymap::jpegr_exif_struct exif;
+ exif.data = reinterpret_cast<void*>(const_cast<uint8_t*>(exifBuffer));
+ exif.length = exifBufferSize;
+
+ res = recoveryMap.encodeJPEGR(&p010, transferFunction, &jpegR, jpegQuality, &exif);
}
+ if (res != OK) {
+ ALOGE("%s: Error trying to encode JPEG/R: %s (%d)", __FUNCTION__, strerror(-res), res);
+ return res;
+ }
+
+ actualJpegRSize = jpegR.length;
+ p010_data.release();
+
size_t finalJpegRSize = actualJpegRSize + sizeof(CameraBlob);
if (finalJpegRSize > maxJpegRBufferSize) {
ALOGE("%s: Final jpeg buffer not large enough for the jpeg blob header", __FUNCTION__);