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

Commit 4ceea258 authored by Igor Murashkin's avatar Igor Murashkin Committed by Android (Google) Code Review
Browse files

Merge "Camera: Pause preview when needing to delete jpeg/zsl streams" into jb-mr2-dev

parents c7731ac5 5282713a
Loading
Loading
Loading
Loading
+45 −3
Original line number Diff line number Diff line
@@ -690,7 +690,7 @@ status_t Camera2Client::startPreviewL(Parameters &params, bool restart) {
        outputStreams.push(getCallbackStreamId());
    }
    if (params.zslMode && !params.recordingHint) {
        res = mZslProcessor->updateStream(params);
        res = updateProcessorStream(mZslProcessor, params);
        if (res != OK) {
            ALOGE("%s: Camera %d: Unable to update ZSL stream: %s (%d)",
                    __FUNCTION__, mCameraId, strerror(-res), res);
@@ -718,7 +718,7 @@ status_t Camera2Client::startPreviewL(Parameters &params, bool restart) {
        // assumption that the user will record video. To optimize recording
        // startup time, create the necessary output streams for recording and
        // video snapshot now if they don't already exist.
        res = mJpegProcessor->updateStream(params);
        res = updateProcessorStream(mJpegProcessor, params);
        if (res != OK) {
            ALOGE("%s: Camera %d: Can't pre-configure still image "
                    "stream: %s (%d)",
@@ -1125,7 +1125,7 @@ status_t Camera2Client::takePicture(int msgType) {

        ALOGV("%s: Camera %d: Starting picture capture", __FUNCTION__, mCameraId);

        res = mJpegProcessor->updateStream(l.mParameters);
        res = updateProcessorStream(mJpegProcessor, l.mParameters);
        if (res != OK) {
            ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
                    __FUNCTION__, mCameraId, strerror(-res), res);
@@ -1605,5 +1605,47 @@ status_t Camera2Client::syncWithDevice() {
    return res;
}

template <typename ProcessorT>
status_t Camera2Client::updateProcessorStream(sp<ProcessorT> processor,
                                              camera2::Parameters params) {
    status_t res;

    res = processor->updateStream(params);

    /**
     * Can't update the stream if it's busy?
     *
     * Then we need to stop the device (by temporarily clearing the request
     * queue) and then try again. Resume streaming once we're done.
     */
    if (res == -EBUSY) {
        res = mStreamingProcessor->togglePauseStream(/*pause*/true);
        if (res != OK) {
            ALOGE("%s: Camera %d: Can't pause streaming: %s (%d)",
                    __FUNCTION__, mCameraId, strerror(-res), res);
        }

        res = mDevice->waitUntilDrained();
        if (res != OK) {
            ALOGE("%s: Camera %d: Waiting to stop streaming failed: %s (%d)",
                    __FUNCTION__, mCameraId, strerror(-res), res);
        }

        res = processor->updateStream(params);
        if (res != OK) {
            ALOGE("%s: Camera %d: Failed to update processing stream "
                  " despite having halted streaming first: %s (%d)",
                  __FUNCTION__, mCameraId, strerror(-res), res);
        }

        res = mStreamingProcessor->togglePauseStream(/*pause*/false);
        if (res != OK) {
            ALOGE("%s: Camera %d: Can't unpause streaming: %s (%d)",
                    __FUNCTION__, mCameraId, strerror(-res), res);
        }
    }

    return res;
}

} // namespace android
+3 −0
Original line number Diff line number Diff line
@@ -159,6 +159,9 @@ private:
    // Used with stream IDs
    static const int NO_STREAM = -1;

    template <typename ProcessorT>
    status_t updateProcessorStream(sp<ProcessorT> processor, Parameters params);

    sp<camera2::FrameProcessor> mFrameProcessor;

    /* Preview/Recording related members */
+2 −2
Original line number Diff line number Diff line
@@ -680,8 +680,8 @@ status_t Camera3Device::deleteStream(int id) {
    // CameraDevice semantics require device to already be idle before
    // deleteStream is called, unlike for createStream.
    if (mStatus != STATUS_IDLE) {
        CLOGE("Device not idle");
        return INVALID_OPERATION;
        ALOGV("%s: Camera %d: Device not idle", __FUNCTION__, mId);
        return -EBUSY;
    }

    sp<Camera3StreamInterface> deletedStream;
+5 −1
Original line number Diff line number Diff line
@@ -113,7 +113,11 @@ status_t JpegProcessor::updateStream(const Parameters &params) {
            ALOGV("%s: Camera %d: Deleting stream %d since the buffer dimensions changed",
                __FUNCTION__, mId, mCaptureStreamId);
            res = device->deleteStream(mCaptureStreamId);
            if (res != OK) {
            if (res == -EBUSY) {
                ALOGV("%s: Camera %d: Device is busy, call updateStream again "
                      " after it becomes idle", __FUNCTION__, mId);
                return res;
            } else if (res != OK) {
                ALOGE("%s: Camera %d: Unable to delete old output stream "
                        "for capture: %s (%d)", __FUNCTION__,
                        mId, strerror(-res), res);
+62 −2
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ StreamingProcessor::StreamingProcessor(sp<Camera2Client> client):
        mDevice(client->getCameraDevice()),
        mId(client->getCameraId()),
        mActiveRequest(NONE),
        mPaused(false),
        mPreviewRequestId(Camera2Client::kPreviewRequestIdStart),
        mPreviewStreamId(NO_STREAM),
        mRecordingRequestId(Camera2Client::kRecordingRequestIdStart),
@@ -419,10 +420,59 @@ status_t StreamingProcessor::startStream(StreamType type,
        return res;
    }
    mActiveRequest = type;
    mPaused = false;

    return OK;
}

status_t StreamingProcessor::togglePauseStream(bool pause) {
    ATRACE_CALL();
    status_t res;

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

    ALOGV("%s: Camera %d: toggling pause to %d", __FUNCTION__, mId, pause);

    Mutex::Autolock m(mMutex);

    if (mActiveRequest == NONE) {
        ALOGE("%s: Camera %d: Can't toggle pause, streaming was not started",
              __FUNCTION__, mId);
        return INVALID_OPERATION;
    }

    if (mPaused == pause) {
        return OK;
    }

    if (pause) {
        res = device->clearStreamingRequest();
        if (res != OK) {
            ALOGE("%s: Camera %d: Can't clear stream request: %s (%d)",
                    __FUNCTION__, mId, strerror(-res), res);
            return res;
        }
    } else {
        CameraMetadata &request =
                (mActiveRequest == PREVIEW) ? mPreviewRequest
                                            : mRecordingRequest;
        res = device->setStreamingRequest(request);
        if (res != OK) {
            ALOGE("%s: Camera %d: Unable to set preview request to resume: "
                    "%s (%d)",
                    __FUNCTION__, mId, strerror(-res), res);
            return res;
        }
    }

    mPaused = pause;
    return OK;
}

status_t StreamingProcessor::stopStream() {
    ATRACE_CALL();
    status_t res;
@@ -443,6 +493,7 @@ status_t StreamingProcessor::stopStream() {
    }

    mActiveRequest = NONE;
    mPaused = false;

    return OK;
}
@@ -662,20 +713,29 @@ status_t StreamingProcessor::dump(int fd, const Vector<String16>& /*args*/) {
        result.append("    Preview request:\n");
        write(fd, result.string(), result.size());
        mPreviewRequest.dump(fd, 2, 6);
        result.clear();
    } else {
        result.append("    Preview request: undefined\n");
        write(fd, result.string(), result.size());
    }

    if (mRecordingRequest.entryCount() != 0) {
        result = "    Recording request:\n";
        write(fd, result.string(), result.size());
        mRecordingRequest.dump(fd, 2, 6);
        result.clear();
    } else {
        result = "    Recording request: undefined\n";
        write(fd, result.string(), result.size());
    }

    const char* streamTypeString[] = {
        "none", "preview", "record"
    };
    result.append(String8::format("   Active request: %s (paused: %s)\n",
                                  streamTypeString[mActiveRequest],
                                  mPaused ? "yes" : "no"));

    write(fd, result.string(), result.size());

    return OK;
}

Loading