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

Commit e8c535e8 authored by Chien-Yu Chen's avatar Chien-Yu Chen
Browse files

Camera: Stop repeating request if its output is abandoned

Stop repeating request if any of its output stream is abandoned.
Add a callback to notify the repeating request has been stopped
with frame number of the last frame.

Update NDK with the new callback and behavior.

Bug: 21270879

Change-Id: I3553775c7807a77104aa1650609480ca3321310c
parent bc0c73e0
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -37,4 +37,11 @@ interface ICameraDeviceCallbacks
    oneway void onResultReceived(in CameraMetadataNative result,
                                 in CaptureResultExtras resultExtras);
    oneway void onPrepared(int streamId);

    /**
     * Repeating request encountered an error and was stopped.
     *
     * @param lastFrameNumber Frame number of the last frame of the streaming request.
     */
    oneway void onRepeatingRequestError(in long lastFrameNumber);
}
+4 −1
Original line number Diff line number Diff line
@@ -36,7 +36,10 @@ interface ICameraDeviceUser
     * Cancel the repeating request specified by requestId
     * Returns the frame number of the last frame that will be produced from this
     * repeating request, or NO_IN_FLIGHT_REPEATING_FRAMES if no frames were produced
     * by this repeating request
     * by this repeating request.
     *
     * Repeating request may be stopped by camera device due to an error. Canceling a stopped
     * repeating request will trigger ERROR_ILLEGAL_ARGUMENT.
     */
    long cancelRequest(int requestId);

+25 −1
Original line number Diff line number Diff line
@@ -380,7 +380,11 @@ CameraDevice::stopRepeatingLocked() {

        int64_t lastFrameNumber;
        binder::Status remoteRet = mRemote->cancelRequest(repeatingSequenceId, &lastFrameNumber);
        if (!remoteRet.isOk()) {
        if (remoteRet.serviceSpecificErrorCode() ==
                hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
            ALOGV("Repeating request is already stopped.");
            return ACAMERA_OK;
        } else if (!remoteRet.isOk()) {
            ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().string());
            return ACAMERA_ERROR_UNKNOWN;
        }
@@ -1342,4 +1346,24 @@ CameraDevice::ServiceCallback::onPrepared(int) {
    return binder::Status::ok();
}

binder::Status
CameraDevice::ServiceCallback::onRepeatingRequestError(int64_t lastFrameNumber) {
    binder::Status ret = binder::Status::ok();

    sp<CameraDevice> dev = mDevice.promote();
    if (dev == nullptr) {
        return ret; // device has been closed
    }

    Mutex::Autolock _l(dev->mDeviceLock);

    int repeatingSequenceId = dev->mRepeatingSequenceId;
    dev->mRepeatingSequenceId = REQUEST_ID_NONE;

    dev->checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);

    return ret;
}


} // namespace android
+1 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ class CameraDevice final : public RefBase {
        binder::Status onResultReceived(const CameraMetadata& metadata,
                              const CaptureResultExtras& resultExtras) override;
        binder::Status onPrepared(int streamId) override;
        binder::Status onRepeatingRequestError(int64_t lastFrameNumber) override;
      private:
        const wp<CameraDevice> mDevice;
    };
+11 −1
Original line number Diff line number Diff line
@@ -149,7 +149,8 @@ public:
        PREPARED,
        RUNNING,
        SENT_RESULT,
        UNINITIALIZED
        UNINITIALIZED,
        REPEATING_REQUEST_ERROR,
    };

protected:
@@ -215,6 +216,15 @@ public:
        return binder::Status::ok();
    }

    virtual binder::Status onRepeatingRequestError(int64_t lastFrameNumber) {
        (void) lastFrameNumber;
        Mutex::Autolock l(mLock);
        mLastStatus = REPEATING_REQUEST_ERROR;
        mStatusesHit.push_back(mLastStatus);
        mStatusCondition.broadcast();
        return binder::Status::ok();
    }

    // Test helper functions:

    bool hadError() const {
Loading