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

Commit 364a2677 authored by Eino-Ville Talvala's avatar Eino-Ville Talvala Committed by Android Git Automerger
Browse files

am a691ff3c: Camera2/3: Don\'t allow recording and callbacks to coexist.

* commit 'a691ff3c':
  Camera2/3: Don't allow recording and callbacks to coexist.
parents bdebd481 a691ff3c
Loading
Loading
Loading
Loading
+67 −25
Original line number Diff line number Diff line
@@ -611,29 +611,37 @@ void Camera2Client::setPreviewCallbackFlag(int flag) {

void Camera2Client::setPreviewCallbackFlagL(Parameters &params, int flag) {
    status_t res = OK;

    switch(params.state) {
        case Parameters::STOPPED:
        case Parameters::WAITING_FOR_PREVIEW_WINDOW:
        case Parameters::PREVIEW:
            // OK
            break;
        default:
            if (flag & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) {
                ALOGE("%s: Camera %d: Can't use preview callbacks "
                        "in state %d", __FUNCTION__, mCameraId, params.state);
                return;
            }
    }

    if (flag & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
        ALOGV("%s: setting oneshot", __FUNCTION__);
        params.previewCallbackOneShot = true;
    }
    if (params.previewCallbackFlags != (uint32_t)flag) {
        params.previewCallbackFlags = flag;
        switch(params.state) {
        case Parameters::PREVIEW:

        if (params.state == Parameters::PREVIEW) {
            res = startPreviewL(params, true);
            break;
        case Parameters::RECORD:
        case Parameters::VIDEO_SNAPSHOT:
            res = startRecordingL(params, true);
            break;
        default:
            break;
        }
            if (res != OK) {
                ALOGE("%s: Camera %d: Unable to refresh request in state %s",
                        __FUNCTION__, mCameraId,
                        Parameters::getStateName(params.state));
            }
        }
    }

}

@@ -702,6 +710,26 @@ status_t Camera2Client::startPreviewL(Parameters &params, bool restart) {
    bool callbacksEnabled = params.previewCallbackFlags &
        CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
    if (callbacksEnabled) {
        // Can't have recording stream hanging around when enabling callbacks,
        // since it exceeds the max stream count on some devices.
        if (mStreamingProcessor->getRecordingStreamId() != NO_STREAM) {
            ALOGV("%s: Camera %d: Clearing out recording stream before "
                    "creating callback stream", __FUNCTION__, mCameraId);
            res = mStreamingProcessor->stopStream();
            if (res != OK) {
                ALOGE("%s: Camera %d: Can't stop streaming to delete "
                        "recording stream", __FUNCTION__, mCameraId);
                return res;
            }
            res = mStreamingProcessor->deleteRecordingStream();
            if (res != OK) {
                ALOGE("%s: Camera %d: Unable to delete recording stream before "
                        "enabling callbacks: %s (%d)", __FUNCTION__, mCameraId,
                        strerror(-res), res);
                return res;
            }
        }

        res = mCallbackProcessor->updateStream(params);
        if (res != OK) {
            ALOGE("%s: Camera %d: Unable to update callback stream: %s (%d)",
@@ -898,6 +926,29 @@ status_t Camera2Client::startRecordingL(Parameters &params, bool restart) {
        }
    }

    // Not all devices can support a preview callback stream and a recording
    // stream at the same time, so assume none of them can.
    if (mCallbackProcessor->getStreamId() != NO_STREAM) {
        ALOGV("%s: Camera %d: Clearing out callback stream before "
                "creating recording stream", __FUNCTION__, mCameraId);
        res = mStreamingProcessor->stopStream();
        if (res != OK) {
            ALOGE("%s: Camera %d: Can't stop streaming to delete callback stream",
                    __FUNCTION__, mCameraId);
            return res;
        }
        res = mCallbackProcessor->deleteStream();
        if (res != OK) {
            ALOGE("%s: Camera %d: Unable to delete callback stream before "
                    "record: %s (%d)", __FUNCTION__, mCameraId,
                    strerror(-res), res);
            return res;
        }
    }
    // Disable callbacks if they're enabled; can't record and use callbacks,
    // and we can't fail record start without stagefright asserting.
    params.previewCallbackFlags = 0;

    res = updateProcessorStream<
            StreamingProcessor,
            &StreamingProcessor::updateRecordingStream>(mStreamingProcessor,
@@ -909,17 +960,6 @@ status_t Camera2Client::startRecordingL(Parameters &params, bool restart) {
    }

    Vector<uint8_t> outputStreams;
    bool callbacksEnabled = params.previewCallbackFlags &
        CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
    if (callbacksEnabled) {
        res = mCallbackProcessor->updateStream(params);
        if (res != OK) {
            ALOGE("%s: Camera %d: Unable to update callback stream: %s (%d)",
                    __FUNCTION__, mCameraId, strerror(-res), res);
            return res;
        }
        outputStreams.push(getCallbackStreamId());
    }
    outputStreams.push(getPreviewStreamId());
    outputStreams.push(getRecordingStreamId());

@@ -1651,6 +1691,8 @@ status_t Camera2Client::updateProcessorStream(sp<ProcessorT> processor,
     * queue) and then try again. Resume streaming once we're done.
     */
    if (res == -EBUSY) {
        ALOGV("%s: Camera %d: Pausing to update stream", __FUNCTION__,
                mCameraId);
        res = mStreamingProcessor->togglePauseStream(/*pause*/true);
        if (res != OK) {
            ALOGE("%s: Camera %d: Can't pause streaming: %s (%d)",
+18 −4
Original line number Diff line number Diff line
@@ -74,8 +74,10 @@ status_t CallbackProcessor::updateStream(const Parameters &params) {
    }

    if (mCallbackConsumer == 0) {
        // Create CPU buffer queue endpoint
        mCallbackConsumer = new CpuConsumer(kCallbackHeapCount);
        // Create CPU buffer queue endpoint. Make it async to avoid disconnect
        // deadlocks.
        mCallbackConsumer = new CpuConsumer(kCallbackHeapCount,
                /*synchronized*/ false);
        mCallbackConsumer->setFrameAvailableListener(this);
        mCallbackConsumer->setName(String8("Camera2Client::CallbackConsumer"));
        mCallbackWindow = new Surface(
@@ -133,7 +135,7 @@ status_t CallbackProcessor::updateStream(const Parameters &params) {
status_t CallbackProcessor::deleteStream() {
    ATRACE_CALL();
    sp<CameraDeviceBase> device;

    status_t res;
    {
        Mutex::Autolock l(mInputMutex);

@@ -146,7 +148,19 @@ status_t CallbackProcessor::deleteStream() {
            return INVALID_OPERATION;
        }
    }
    device->deleteStream(mCallbackStreamId);
    res = device->waitUntilDrained();
    if (res != OK) {
        ALOGE("%s: Error waiting for HAL to drain: %s (%d)",
                __FUNCTION__, strerror(-res), res);
        return res;
    }

    res = device->deleteStream(mCallbackStreamId);
    if (res != OK) {
        ALOGE("%s: Unable to delete callback stream: %s (%d)",
                __FUNCTION__, strerror(-res), res);
        return res;
    }

    {
        Mutex::Autolock l(mInputMutex);