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

Commit 0663de54 authored by Yin-Chia Yeh's avatar Yin-Chia Yeh Committed by android-build-merger
Browse files

Merge changes I20310606,Ic23b7fb2 into pi-dev

am: ba20b76d

Change-Id: If7a52bb76d066e8edd0da15823254f68c617ce57
parents da6a30de ba20b76d
Loading
Loading
Loading
Loading
+8 −8
Original line number Diff line number Diff line
@@ -983,16 +983,16 @@ bool ExifUtilsImpl::setFromMetadata(const CameraMetadata& metadata,
    camera_metadata_ro_entry entry = metadata.find(ANDROID_LENS_FOCAL_LENGTH);
    if (entry.count) {
        focal_length = entry.data.f[0];
    } else {
        ALOGE("%s: Cannot find focal length in metadata.", __FUNCTION__);
        return false;
    }

        if (!setFocalLength(
                        static_cast<uint32_t>(focal_length * kRationalPrecision),
                        kRationalPrecision)) {
            ALOGE("%s: setting focal length failed.", __FUNCTION__);
            return false;
        }
    } else {
        ALOGV("%s: Cannot find focal length in metadata.", __FUNCTION__);
    }

    if (metadata.exists(ANDROID_JPEG_GPS_COORDINATES)) {
        entry = metadata.find(ANDROID_JPEG_GPS_COORDINATES);
+6 −18
Original line number Diff line number Diff line
@@ -284,13 +284,6 @@ status_t ExternalCameraDevice::initDefaultCharsKeys(
    const int32_t jpegMaxSize = mCfg.maxJpegBufSize;
    UPDATE(ANDROID_JPEG_MAX_SIZE, &jpegMaxSize, 1);

    const uint8_t jpegQuality = 90;
    UPDATE(ANDROID_JPEG_QUALITY, &jpegQuality, 1);
    UPDATE(ANDROID_JPEG_THUMBNAIL_QUALITY, &jpegQuality, 1);

    const int32_t jpegOrientation = 0;
    UPDATE(ANDROID_JPEG_ORIENTATION, &jpegOrientation, 1);

    // android.lens
    const uint8_t focusDistanceCalibration =
            ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED;
@@ -322,7 +315,6 @@ status_t ExternalCameraDevice::initDefaultCharsKeys(
    // This means pipeline latency of X frame intervals. The maximum number is 4.
    const uint8_t requestPipelineMaxDepth = 4;
    UPDATE(ANDROID_REQUEST_PIPELINE_MAX_DEPTH, &requestPipelineMaxDepth, 1);
    UPDATE(ANDROID_REQUEST_PIPELINE_DEPTH, &requestPipelineMaxDepth, 1);

    // Three numbers represent the maximum numbers of different types of output
    // streams simultaneously. The types are raw sensor, processed (but not
@@ -355,7 +347,6 @@ status_t ExternalCameraDevice::initDefaultCharsKeys(
        ANDROID_SENSOR_TEST_PATTERN_MODE_OFF};
    UPDATE(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES, testPatternModes,
           ARRAY_SIZE(testPatternModes));
    UPDATE(ANDROID_SENSOR_TEST_PATTERN_MODE, &testPatternModes[0], 1);

    const uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
    UPDATE(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE, &timestampSource, 1);
@@ -576,7 +567,6 @@ status_t ExternalCameraDevice::initOutputCharsKeys(int fd,
    std::vector<int32_t> streamConfigurations;
    std::vector<int64_t> minFrameDurations;
    std::vector<int64_t> stallDurations;
    int64_t maxFrameDuration = 0;
    int32_t maxFps = std::numeric_limits<int32_t>::min();
    int32_t minFps = std::numeric_limits<int32_t>::max();
    std::set<int32_t> framerates;
@@ -604,9 +594,6 @@ status_t ExternalCameraDevice::initOutputCharsKeys(int fd,
            if (frameDuration < minFrameDuration) {
                minFrameDuration = frameDuration;
            }
            if (frameDuration > maxFrameDuration) {
                maxFrameDuration = frameDuration;
            }
            int32_t frameRateInt = static_cast<int32_t>(fr.getDouble());
            if (minFps > frameRateInt) {
                minFps = frameRateInt;
@@ -639,14 +626,15 @@ status_t ExternalCameraDevice::initOutputCharsKeys(int fd,
    }

    std::vector<int32_t> fpsRanges;
    // Variable range
    fpsRanges.push_back(minFps);
    fpsRanges.push_back(maxFps);
    // Fixed ranges
    // FPS ranges
    for (const auto& framerate : framerates) {
        fpsRanges.push_back(framerate);
        // Empirical: webcams often have close to 2x fps error and cannot support fixed fps range
        fpsRanges.push_back(framerate / 2);
        fpsRanges.push_back(framerate);
    }
    minFps /= 2;
    int64_t maxFrameDuration = 1000000000LL / minFps;

    UPDATE(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, fpsRanges.data(),
           fpsRanges.size());

+63 −21
Original line number Diff line number Diff line
@@ -47,6 +47,9 @@ static constexpr size_t kMetadataMsgQueueSize = 1 << 18 /* 256kB */;
const int kBadFramesAfterStreamOn = 1; // drop x frames after streamOn to get rid of some initial
                                       // bad frames. TODO: develop a better bad frame detection
                                       // method
constexpr int MAX_RETRY = 15; // Allow retry some ioctl failures a few times to account for some
                             // webcam showing temporarily ioctl failures.
constexpr int IOCTL_RETRY_SLEEP_US = 33000; // 33ms * MAX_RETRY = 5 seconds

bool tryLock(Mutex& mutex)
{
@@ -1480,6 +1483,7 @@ int ExternalCameraDeviceSession::OutputThread::createJpegLocked(

    int jpegQuality, thumbQuality;
    Size thumbSize;
    bool outputThumbnail = true;

    if (req->setting.exists(ANDROID_JPEG_QUALITY)) {
        camera_metadata_entry entry =
@@ -1505,6 +1509,9 @@ int ExternalCameraDeviceSession::OutputThread::createJpegLocked(
        thumbSize = Size { static_cast<uint32_t>(entry.data.i32[0]),
                           static_cast<uint32_t>(entry.data.i32[1])
        };
        if (thumbSize.width == 0 && thumbSize.height == 0) {
            outputThumbnail = false;
        }
    } else {
        return lfail(
            "%s: ANDROID_JPEG_THUMBNAIL_SIZE not set", __FUNCTION__);
@@ -1532,15 +1539,17 @@ int ExternalCameraDeviceSession::OutputThread::createJpegLocked(
    /* Hold actual thumbnail and main image code sizes */
    size_t thumbCodeSize = 0, jpegCodeSize = 0;
    /* Temporary thumbnail code buffer */
    std::vector<uint8_t> thumbCode(maxThumbCodeSize);
    std::vector<uint8_t> thumbCode(outputThumbnail ? maxThumbCodeSize : 0);

    YCbCrLayout yu12Thumb;
    if (outputThumbnail) {
        ret = cropAndScaleThumbLocked(mYu12Frame, thumbSize, &yu12Thumb);

        if (ret != 0) {
            return lfail(
                "%s: crop and scale thumbnail failed!", __FUNCTION__);
        }
    }

    /* Scale and crop main jpeg */
    ret = cropAndScaleLocked(mYu12Frame, jpegSize, &yu12Main);
@@ -1550,12 +1559,14 @@ int ExternalCameraDeviceSession::OutputThread::createJpegLocked(
    }

    /* Encode the thumbnail image */
    if (outputThumbnail) {
        ret = encodeJpegYU12(thumbSize, yu12Thumb,
                thumbQuality, 0, 0,
                &thumbCode[0], maxThumbCodeSize, thumbCodeSize);

        if (ret != 0) {
        return lfail("%s: encodeJpegYU12 failed with %d",__FUNCTION__, ret);
            return lfail("%s: thumbnail encodeJpegYU12 failed with %d",__FUNCTION__, ret);
        }
    }

    /* Combine camera characteristics with request settings to form EXIF
@@ -1570,11 +1581,7 @@ int ExternalCameraDeviceSession::OutputThread::createJpegLocked(

    utils->setFromMetadata(meta, jpegSize.width, jpegSize.height);

    /* Check if we made a non-zero-sized thumbnail. Currently not possible
     * that we got this far and the code is size 0, but if this code moves
     * around it might become relevant again */

    ret = utils->generateApp1(thumbCodeSize ? &thumbCode[0] : 0, thumbCodeSize);
    ret = utils->generateApp1(outputThumbnail ? &thumbCode[0] : 0, thumbCodeSize);

    if (!ret) {
        return lfail("%s: generating APP1 failed", __FUNCTION__);
@@ -2108,10 +2115,22 @@ int ExternalCameraDeviceSession::configureV4l2StreamLocked(
    fmt.fmt.pix.height = v4l2Fmt.height;
    fmt.fmt.pix.pixelformat = v4l2Fmt.fourcc;
    ret = TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_S_FMT, &fmt));
    if (ret < 0) {
        int numAttempt = 0;
        while (ret < 0) {
            ALOGW("%s: VIDIOC_S_FMT failed, wait 33ms and try again", __FUNCTION__);
            usleep(IOCTL_RETRY_SLEEP_US); // sleep 100 ms and try again
            ret = TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_S_FMT, &fmt));
            if (numAttempt == MAX_RETRY) {
                break;
            }
            numAttempt++;
        }
        if (ret < 0) {
            ALOGE("%s: S_FMT ioctl failed: %s", __FUNCTION__, strerror(errno));
            return -errno;
        }
    }

    if (v4l2Fmt.width != fmt.fmt.pix.width || v4l2Fmt.height != fmt.fmt.pix.height ||
            v4l2Fmt.fourcc != fmt.fmt.pix.pixelformat) {
@@ -2199,10 +2218,23 @@ int ExternalCameraDeviceSession::configureV4l2StreamLocked(

    // VIDIOC_STREAMON: start streaming
    v4l2_buf_type capture_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_STREAMON, &capture_type)) < 0) {
        ALOGE("%s: VIDIOC_STREAMON failed: %s", __FUNCTION__, strerror(errno));
    ret = TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_STREAMON, &capture_type));
    if (ret < 0) {
        int numAttempt = 0;
        while (ret < 0) {
            ALOGW("%s: VIDIOC_STREAMON failed, wait 33ms and try again", __FUNCTION__);
            usleep(IOCTL_RETRY_SLEEP_US); // sleep 100 ms and try again
            ret = TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_STREAMON, &capture_type));
            if (numAttempt == MAX_RETRY) {
                break;
            }
            numAttempt++;
        }
        if (ret < 0) {
            ALOGE("%s: VIDIOC_STREAMON ioctl failed: %s", __FUNCTION__, strerror(errno));
            return -errno;
        }
    }

    // Swallow first few frames after streamOn to account for bad frames from some devices
    for (int i = 0; i < kBadFramesAfterStreamOn; i++) {
@@ -2220,6 +2252,8 @@ int ExternalCameraDeviceSession::configureV4l2StreamLocked(
        }
    }

    ALOGI("%s: start V4L2 streaming %dx%d@%ffps",
                __FUNCTION__, v4l2Fmt.width, v4l2Fmt.height, fps);
    mV4l2StreamingFmt = v4l2Fmt;
    mV4l2Streaming = true;
    return OK;
@@ -2388,6 +2422,7 @@ Status ExternalCameraDeviceSession::configureStreams(
    uint32_t maxDim = 0;
    for (const auto& stream : config.streams) {
        float aspectRatio = ASPECT_RATIO(stream);
        ALOGI("%s: request stream %dx%d", __FUNCTION__, stream.width, stream.height);
        if ((mCroppingType == VERTICAL && aspectRatio < desiredAr) ||
                (mCroppingType == HORIZONTAL && aspectRatio > desiredAr)) {
            desiredAr = aspectRatio;
@@ -2572,6 +2607,9 @@ status_t ExternalCameraDeviceSession::initDefaultRequests() {
    const uint8_t nrMode = ANDROID_NOISE_REDUCTION_MODE_OFF;
    UPDATE(md, ANDROID_NOISE_REDUCTION_MODE, &nrMode, 1);

    const int32_t testPatternModes = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF;
    UPDATE(md, ANDROID_SENSOR_TEST_PATTERN_MODE, &testPatternModes, 1);

    const uint8_t fdMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
    UPDATE(md, ANDROID_STATISTICS_FACE_DETECT_MODE, &fdMode, 1);

@@ -2596,7 +2634,7 @@ status_t ExternalCameraDeviceSession::initDefaultRequests() {
        }
    }
    int32_t defaultFramerate = support30Fps ? 30 : maxFps;
    int32_t defaultFpsRange[] = {defaultFramerate, defaultFramerate};
    int32_t defaultFpsRange[] = {defaultFramerate / 2, defaultFramerate};
    UPDATE(md, ANDROID_CONTROL_AE_TARGET_FPS_RANGE, defaultFpsRange, ARRAY_SIZE(defaultFpsRange));

    uint8_t antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
@@ -2691,6 +2729,10 @@ status_t ExternalCameraDeviceSession::fillCaptureResult(
    const uint8_t flashState = ANDROID_FLASH_STATE_UNAVAILABLE;
    UPDATE(md, ANDROID_FLASH_STATE, &flashState, 1);

    // This means pipeline latency of X frame intervals. The maximum number is 4.
    const uint8_t requestPipelineMaxDepth = 4;
    UPDATE(md, ANDROID_REQUEST_PIPELINE_DEPTH, &requestPipelineMaxDepth, 1);

    // android.scaler
    const int32_t crop_region[] = {
          active_array_size.data.i32[0], active_array_size.data.i32[1],
+2 −3
Original line number Diff line number Diff line
@@ -283,9 +283,8 @@ ExternalCameraConfig::ExternalCameraConfig() :
        numVideoBuffers(kDefaultNumVideoBuffer),
        numStillBuffers(kDefaultNumStillBuffer) {
    fpsLimits.push_back({/*Size*/{ 640,  480}, /*FPS upper bound*/30.0});
    fpsLimits.push_back({/*Size*/{1280,  720}, /*FPS upper bound*/15.0});
    fpsLimits.push_back({/*Size*/{1920, 1080}, /*FPS upper bound*/10.0});
    fpsLimits.push_back({/*Size*/{4096, 3072}, /*FPS upper bound*/5.0});
    fpsLimits.push_back({/*Size*/{1280,  720}, /*FPS upper bound*/7.5});
    fpsLimits.push_back({/*Size*/{1920, 1080}, /*FPS upper bound*/5.0});
}