Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d3176474 authored by Dichen Zhang's avatar Dichen Zhang
Browse files

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
parent 35de0d51
Loading
Loading
Loading
Loading
+43 −35
Original line number Diff line number Diff line
@@ -285,10 +285,9 @@ status_t JpegRCompositeStream::processInputFrame(nsecs_t ts, const InputFrame &i
    }

    size_t actualJpegRSize = 0;
    if (mSupportInternalJpeg) {
    recoverymap::jpegr_uncompressed_struct p010;
        recoverymap::jpegr_compressed_struct jpeg;
    recoverymap::jpegr_compressed_struct jpegR;
    recoverymap::RecoveryMap recoveryMap;

    p010.height = inputFrame.p010Buffer.height;
    p010.width = inputFrame.p010Buffer.width;
@@ -302,6 +301,22 @@ status_t JpegRCompositeStream::processInputFrame(nsecs_t ts, const InputFrame &i
    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,
                inputFrame.jpegBuffer.width);
@@ -317,28 +332,7 @@ status_t JpegRCompositeStream::processInputFrame(nsecs_t ts, const InputFrame &i
            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 @@ status_t JpegRCompositeStream::processInputFrame(nsecs_t ts, const InputFrame &i
        } 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__);