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

Commit 3ea3fcd0 authored by Yin-Chia Yeh's avatar Yin-Chia Yeh
Browse files

Camera2: reconfigure video snapshot size if needed

When recording fails to start due to stream configuration failed,
try configure stream again by setting jpeg stream to video size.

Bug: 16162133
Change-Id: Ib20271e787ae07719ce419f0b15c7f86434f7ebb
parent e7494680
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -1088,6 +1088,22 @@ status_t Camera2Client::startRecordingL(Parameters &params, bool restart) {

    res = mStreamingProcessor->startStream(StreamingProcessor::RECORD,
            outputStreams);
    // try to reconfigure jpeg to video size if configureStreams failed
    if (res == BAD_VALUE) {

        ALOGV("%s: Camera %d: configure still size to video size before recording"
                , __FUNCTION__, mCameraId);
        params.overrideJpegSizeByVideoSize();
        res = updateProcessorStream(mJpegProcessor, params);
        if (res != OK) {
            ALOGE("%s: Camera %d: Can't configure still image size to video size: %s (%d)",
                    __FUNCTION__, mCameraId, strerror(-res), res);
            return res;
        }
        res = mStreamingProcessor->startStream(StreamingProcessor::RECORD,
                outputStreams);
    }

    if (res != OK) {
        ALOGE("%s: Camera %d: Unable to start recording stream: %s (%d)",
                __FUNCTION__, mCameraId, strerror(-res), res);
@@ -1127,6 +1143,7 @@ void Camera2Client::stopRecording() {

    mCameraService->playSound(CameraService::SOUND_RECORDING);

    l.mParameters.recoverOverriddenJpegSize();
    res = startPreviewL(l.mParameters, true);
    if (res != OK) {
        ALOGE("%s: Camera %d: Unable to return to preview",
+52 −2
Original line number Diff line number Diff line
@@ -249,6 +249,9 @@ status_t Parameters::initialize(const CameraMetadata *info, int deviceVersion) {
    // TODO: Pick maximum
    pictureWidth = availableJpegSizes[0].width;
    pictureHeight = availableJpegSizes[0].height;
    pictureWidthLastSet = pictureWidth;
    pictureHeightLastSet = pictureHeight;
    pictureSizeOverriden = false;

    params.setPictureSize(pictureWidth,
            pictureHeight);
@@ -1381,8 +1384,8 @@ status_t Parameters::set(const String8& paramString) {
    // PICTURE_SIZE
    newParams.getPictureSize(&validatedParams.pictureWidth,
            &validatedParams.pictureHeight);
    if (validatedParams.pictureWidth == pictureWidth ||
            validatedParams.pictureHeight == pictureHeight) {
    if (validatedParams.pictureWidth != pictureWidth ||
            validatedParams.pictureHeight != pictureHeight) {
        Vector<Size> availablePictureSizes = getAvailableJpegSizes();
        for (i = 0; i < availablePictureSizes.size(); i++) {
            if ((availablePictureSizes[i].width ==
@@ -1798,6 +1801,7 @@ status_t Parameters::set(const String8& paramString) {
    /** Update internal parameters */

    *this = validatedParams;
    updateOverriddenJpegSize();

    /** Update external parameters calculated from the internal ones */

@@ -2115,6 +2119,52 @@ status_t Parameters::updateRequestJpeg(CameraMetadata *request) const {
    return OK;
}

status_t Parameters::overrideJpegSizeByVideoSize() {
    if (pictureSizeOverriden) {
        ALOGV("Picture size has been overridden. Skip overriding");
        return OK;
    }

    pictureSizeOverriden = true;
    pictureWidthLastSet = pictureWidth;
    pictureHeightLastSet = pictureHeight;
    pictureWidth = videoWidth;
    pictureHeight = videoHeight;
    // This change of picture size is invisible to app layer.
    // Do not update app visible params
    return OK;
}

status_t Parameters::updateOverriddenJpegSize() {
    if (!pictureSizeOverriden) {
        ALOGV("Picture size has not been overridden. Skip checking");
        return OK;
    }

    pictureWidthLastSet = pictureWidth;
    pictureHeightLastSet = pictureHeight;

    if (pictureWidth <= videoWidth && pictureHeight <= videoHeight) {
        // Picture size is now smaller than video size. No need to override anymore
        return recoverOverriddenJpegSize();
    }

    pictureWidth = videoWidth;
    pictureHeight = videoHeight;

    return OK;
}

status_t Parameters::recoverOverriddenJpegSize() {
    if (!pictureSizeOverriden) {
        ALOGV("Picture size has not been overridden. Skip recovering");
        return OK;
    }
    pictureSizeOverriden = false;
    pictureWidth = pictureWidthLastSet;
    pictureHeight = pictureHeightLastSet;
    return OK;
}

const char* Parameters::getStateName(State state) {
#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
+15 −0
Original line number Diff line number Diff line
@@ -52,6 +52,9 @@ struct Parameters {
    int previewTransform; // set by CAMERA_CMD_SET_DISPLAY_ORIENTATION

    int pictureWidth, pictureHeight;
    // Store the picture size before they are overriden by video snapshot
    int pictureWidthLastSet, pictureHeightLastSet;
    bool pictureSizeOverriden;

    int32_t jpegThumbSize[2];
    uint8_t jpegQuality, jpegThumbQuality;
@@ -253,6 +256,12 @@ struct Parameters {
    // Add/update JPEG entries in metadata
    status_t updateRequestJpeg(CameraMetadata *request) const;

    /* Helper functions to override jpeg size for video snapshot */
    // Override jpeg size by video size. Called during startRecording.
    status_t overrideJpegSizeByVideoSize();
    // Recover overridden jpeg size.  Called during stopRecording.
    status_t recoverOverriddenJpegSize();

    // Calculate the crop region rectangle based on current stream sizes
    struct CropRegion {
        float left;
@@ -348,6 +357,12 @@ private:
    // Get max size (from the size array) that matches the given aspect ratio.
    Size getMaxSizeForRatio(float ratio, const int32_t* sizeArray, size_t count);

    // Helper function for overriding jpeg size for video snapshot
    // Check if overridden jpeg size needs to be updated after Parameters::set.
    // The behavior of this function is tailored to the implementation of Parameters::set.
    // Do not use this function for other purpose.
    status_t updateOverriddenJpegSize();

    struct StreamConfiguration {
        int32_t format;
        int32_t width;
+8 −0
Original line number Diff line number Diff line
@@ -601,10 +601,18 @@ sp<Camera3Device::CaptureRequest> Camera3Device::setUpRequestLocked(

    if (mStatus == STATUS_UNCONFIGURED || mNeedConfig) {
        res = configureStreamsLocked();
        // Stream configuration failed due to unsupported configuration.
        // Device back to unconfigured state. Client might try other configuraitons
        if (res == BAD_VALUE && mStatus == STATUS_UNCONFIGURED) {
            CLOGE("No streams configured");
            return NULL;
        }
        // Stream configuration failed for other reason. Fatal.
        if (res != OK) {
            SET_ERR_L("Can't set up streams: %s (%d)", strerror(-res), res);
            return NULL;
        }
        // Stream configuration successfully configure to empty stream configuration.
        if (mStatus == STATUS_UNCONFIGURED) {
            CLOGE("No streams configured");
            return NULL;
+1 −2
Original line number Diff line number Diff line
@@ -233,8 +233,7 @@ status_t Camera3Stream::cancelConfiguration() {
    camera3_stream::usage = oldUsage;
    camera3_stream::max_buffers = oldMaxBuffers;

    mState = STATE_CONSTRUCTED;

    mState = (mState == STATE_IN_RECONFIG) ? STATE_CONFIGURED : STATE_CONSTRUCTED;
    return OK;
}