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

Commit 2efd6be6 authored by Shuzhen Wang's avatar Shuzhen Wang
Browse files

Camera: Use slowJpeg if JPEG minimum duration is less than preview fps

If the minimum duration of JPEG is less than the frame duration derived
from maximum fps, enable slowJpeg mode so that JPEG doesn't slow down
preview.

Cap the default max fps to 30 so that the switch between different
sensor modes can be minimized while still allowing the app to go higher
than 30fps.

Test: Camera1 CTS
Bug: 36692074
Change-Id: If4d367ac587c0f4d3620ca2d25063c5a12ebfceb
parent 061d5b8c
Loading
Loading
Loading
Loading
+36 −10
Original line number Diff line number Diff line
@@ -940,7 +940,7 @@ status_t Parameters::initialize(const CameraMetadata *info, int deviceVersion) {
            CameraParameters::FALSE);
    }

    bool isZslReprocessPresent = false;
    isZslReprocessPresent = false;
    camera_metadata_ro_entry_t availableCapabilities =
        staticInfo(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
    if (0 < availableCapabilities.count) {
@@ -999,7 +999,7 @@ status_t Parameters::buildFastInfo() {
        return NO_INIT;
    }

    // Get supported preview fps ranges.
    // Get supported preview fps ranges, up to default maximum.
    Vector<Size> supportedPreviewSizes;
    Vector<FpsRange> supportedPreviewFpsRanges;
    const Size PREVIEW_SIZE_BOUND = { MAX_PREVIEW_WIDTH, MAX_PREVIEW_HEIGHT };
@@ -1007,7 +1007,8 @@ status_t Parameters::buildFastInfo() {
    if (res != OK) return res;
    for (size_t i=0; i < availableFpsRanges.count; i += 2) {
        if (!isFpsSupported(supportedPreviewSizes,
                HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, availableFpsRanges.data.i32[i+1])) {
                HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, availableFpsRanges.data.i32[i+1]) ||
                availableFpsRanges.data.i32[i+1] > MAX_DEFAULT_FPS) {
            continue;
        }
        FpsRange fpsRange = {availableFpsRanges.data.i32[i], availableFpsRanges.data.i32[i+1]};
@@ -1436,30 +1437,43 @@ status_t Parameters::set(const String8& paramString) {
              *
              * Either way, in case of multiple ranges, break the tie by
              * selecting the smaller range.
              *
              * Always select range within 30fps if one exists.
              */

            // all ranges which have previewFps
            Vector<Range> candidateRanges;
            Vector<Range> candidateFastRanges;
            for (i = 0; i < availableFrameRates.count; i+=2) {
                Range r = {
                            availableFrameRates.data.i32[i],
                            availableFrameRates.data.i32[i+1]
                };
                if (!isFpsSupported(availablePreviewSizes,
                        HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, r.max)) {
                    continue;
                }

                if (r.min <= previewFps && previewFps <= r.max) {
                    if (r.max <= MAX_DEFAULT_FPS) {
                        candidateRanges.push(r);
                    } else {
                        candidateFastRanges.push(r);
                    }
                }
            }
            if (candidateRanges.isEmpty()) {
            if (candidateRanges.isEmpty() && candidateFastRanges.isEmpty()) {
                ALOGE("%s: Requested preview frame rate %d is not supported",
                        __FUNCTION__, previewFps);
                return BAD_VALUE;
            }
            // most applicable range with targetFps
            Range bestRange = candidateRanges[0];
            for (i = 1; i < candidateRanges.size(); ++i) {
                Range r = candidateRanges[i];

            // most applicable range with targetFps
            Vector<Range>& ranges =
                    candidateRanges.size() > 0 ? candidateRanges : candidateFastRanges;
            Range bestRange = ranges[0];
            for (i = 1; i < ranges.size(); ++i) {
                Range r = ranges[i];
                // Find by largest minIndex in recording mode
                if (validatedParams.recordingHint) {
                    if (r.min > bestRange.min) {
@@ -1977,6 +1991,19 @@ status_t Parameters::set(const String8& paramString) {
    paramsFlattened = newParams.flatten();
    params = newParams;

    slowJpegMode = false;
    Size pictureSize = { pictureWidth, pictureHeight };
    int64_t minFrameDurationNs = getJpegStreamMinFrameDurationNs(pictureSize);
    if (previewFpsRange[1] > 1e9/minFrameDurationNs + FPS_MARGIN) {
        slowJpegMode = true;
    }
    if (slowJpegMode || property_get_bool("camera.disable_zsl_mode", false)) {
        allowZslMode = false;
    } else {
        allowZslMode = isZslReprocessPresent;
    }
    ALOGV("%s: allowZslMode: %d slowJpegMode %d", __FUNCTION__, allowZslMode, slowJpegMode);

    return OK;
}

@@ -2984,7 +3011,6 @@ bool Parameters::isFpsSupported(const Vector<Size> &sizes, int format, int32_t f
    }

    // Get min frame duration for each size and check if the given fps range can be supported.
    const int32_t FPS_MARGIN = 1;
    for (size_t i = 0 ; i < sizes.size(); i++) {
        int64_t minFrameDuration = getMinFrameDurationNs(sizes[i], format);
        if (minFrameDuration <= 0) {
+6 −0
Original line number Diff line number Diff line
@@ -173,6 +173,8 @@ struct Parameters {
    // Whether the jpeg stream is slower than 30FPS and can slow down preview.
    // When slowJpegMode is true, allowZslMode must be false to avoid slowing down preview.
    bool slowJpegMode;
    // Whether ZSL reprocess is supported by the device.
    bool isZslReprocessPresent;

    // Overall camera state
    enum State {
@@ -199,6 +201,10 @@ struct Parameters {
    static const CONSTEXPR float ASPECT_RATIO_TOLERANCE = 0.001;
    // Threshold for slow jpeg mode
    static const int64_t kSlowJpegModeThreshold = 33400000LL; // 33.4 ms
    // Margin for checking FPS
    static const int32_t FPS_MARGIN = 1;
    // Max FPS for default parameters
    static const int32_t MAX_DEFAULT_FPS = 30;

    // Full static camera info, object owned by someone else, such as
    // Camera2Device.