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

Commit 0e40a839 authored by Zhijun He's avatar Zhijun He Committed by Android (Google) Code Review
Browse files

Merge "Camera2: fix 4K recording" into lmp-dev

parents 4d22f208 a53021f7
Loading
Loading
Loading
Loading
+67 −18
Original line number Diff line number Diff line
@@ -921,6 +921,13 @@ void Camera2Client::stopPreviewL() {
                        "stop preview: %s (%d)",
                        __FUNCTION__, mCameraId, strerror(-res), res);
            }
            {
                // Ideally we should recover the override after recording stopped, but
                // right now recording stream will live until here, so we are forced to
                // recover here. TODO: find a better way to handle that (b/17495165)
                SharedParameters::Lock l(mParameters);
                l.mParameters.recoverOverriddenJpegSize();
            }
            // no break
        case Parameters::WAITING_FOR_PREVIEW_WINDOW: {
            SharedParameters::Lock l(mParameters);
@@ -1075,15 +1082,52 @@ status_t Camera2Client::startRecordingL(Parameters &params, bool restart) {
    // and we can't fail record start without stagefright asserting.
    params.previewCallbackFlags = 0;

    bool recordingStreamNeedsUpdate;
    res = mStreamingProcessor->recordingStreamNeedsUpdate(params, &recordingStreamNeedsUpdate);
    if (res != OK) {
        ALOGE("%s: Camera %d: Can't query recording stream",
                __FUNCTION__, mCameraId);
        return res;
    }

    if (recordingStreamNeedsUpdate) {
        // Need to stop stream here in case updateRecordingStream fails
        // Right now camera device cannot handle configureStream failure gracefully
        // when device is streaming
        res = mStreamingProcessor->stopStream();
        if (res != OK) {
            ALOGE("%s: Camera %d: Can't stop streaming to update record stream",
                    __FUNCTION__, mCameraId);
            return res;
        }
        res = mDevice->waitUntilDrained();
        if (res != OK) {
            ALOGE("%s: Camera %d: Waiting to stop streaming failed: %s (%d)",
                    __FUNCTION__, mCameraId, strerror(-res), res);
        }
        res = updateProcessorStream<
                StreamingProcessor,
                &StreamingProcessor::updateRecordingStream>(mStreamingProcessor,
                                                            params);

        // updateRecordingStream might trigger a configureStream call and device might fail
        // configureStream due to jpeg size > video size. Try again with jpeg size overridden
        // to video size.
        // TODO: This may not be needed after we add stop streaming above. Remove that if
        // it's the case.
        if (res == BAD_VALUE) {
            overrideVideoSnapshotSize(params);
            res = updateProcessorStream<
                    StreamingProcessor,
                    &StreamingProcessor::updateRecordingStream>(mStreamingProcessor,
                                                                params);
        }
        if (res != OK) {
            ALOGE("%s: Camera %d: Unable to update recording stream: %s (%d)",
                    __FUNCTION__, mCameraId, strerror(-res), res);
            return res;
        }
    }

    Vector<int32_t> outputStreams;
    outputStreams.push(getPreviewStreamId());
@@ -1091,18 +1135,12 @@ 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;
        }
    // startStream might trigger a configureStream call and device might fail
    // configureStream due to jpeg size > video size. Try again with jpeg size overridden
    // to video size.
    if (res == BAD_VALUE) {
        overrideVideoSnapshotSize(params);
        res = mStreamingProcessor->startStream(StreamingProcessor::RECORD,
                outputStreams);
    }
@@ -1146,7 +1184,6 @@ 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",
@@ -1923,6 +1960,18 @@ status_t Camera2Client::updateProcessorStream(sp<ProcessorT> processor,
    return res;
}

status_t Camera2Client::overrideVideoSnapshotSize(Parameters &params) {
    ALOGV("%s: Camera %d: configure still size to video size before recording"
            , __FUNCTION__, mCameraId);
    params.overrideJpegSizeByVideoSize();
    status_t res = updateProcessorStream(mJpegProcessor, params);
    if (res != OK) {
        ALOGE("%s: Camera %d: Can't override video snapshot size to video size: %s (%d)",
                __FUNCTION__, mCameraId, strerror(-res), res);
    }
    return res;
}

const char* Camera2Client::kAutofocusLabel = "autofocus";
const char* Camera2Client::kTakepictureLabel = "take_picture";

+3 −0
Original line number Diff line number Diff line
@@ -208,6 +208,9 @@ private:

    // Wait until the camera device has received the latest control settings
    status_t syncWithDevice();

    // Video snapshot jpeg size overriding helper function
    status_t overrideVideoSnapshotSize(Parameters &params);
};

}; // namespace android
+38 −0
Original line number Diff line number Diff line
@@ -318,6 +318,44 @@ status_t StreamingProcessor::updateRecordingRequest(const Parameters &params) {
    return OK;
}

status_t StreamingProcessor::recordingStreamNeedsUpdate(
        const Parameters &params, bool *needsUpdate) {
    status_t res;

    if (needsUpdate == 0) {
        ALOGE("%s: Camera %d: invalid argument", __FUNCTION__, mId);
        return INVALID_OPERATION;
    }

    if (mRecordingStreamId == NO_STREAM) {
        *needsUpdate = true;
        return OK;
    }

    sp<CameraDeviceBase> device = mDevice.promote();
    if (device == 0) {
        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
        return INVALID_OPERATION;
    }

    uint32_t currentWidth, currentHeight;
    res = device->getStreamInfo(mRecordingStreamId,
            &currentWidth, &currentHeight, 0);
    if (res != OK) {
        ALOGE("%s: Camera %d: Error querying recording output stream info: "
                "%s (%d)", __FUNCTION__, mId,
                strerror(-res), res);
        return res;
    }

    if (mRecordingConsumer == 0 || currentWidth != (uint32_t)params.videoWidth ||
            currentHeight != (uint32_t)params.videoHeight) {
        *needsUpdate = true;
    }
    *needsUpdate = false;
    return res;
}

status_t StreamingProcessor::updateRecordingStream(const Parameters &params) {
    ATRACE_CALL();
    status_t res;
+3 −0
Original line number Diff line number Diff line
@@ -54,6 +54,9 @@ class StreamingProcessor:

    status_t setRecordingBufferCount(size_t count);
    status_t updateRecordingRequest(const Parameters &params);
    // If needsUpdate is set to true, a updateRecordingStream call with params will recreate
    // recording stream
    status_t recordingStreamNeedsUpdate(const Parameters &params, bool *needsUpdate);
    status_t updateRecordingStream(const Parameters &params);
    status_t deleteRecordingStream();
    int getRecordingStreamId() const;