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

Commit 49eeafc9 authored by Jayant Chowdhary's avatar Jayant Chowdhary
Browse files

camera2 vndk: Fix onCaptureBufferLost extra / incorrect callbacks.



Before this change, we were not matching native handles against the
CaptureRequest for which a buffer error occurred, and therefore
producing extra and incorrect onCaptureBufferLost callbacks.

Also, the buffer handles returned in the callbacks must be the same as
what the app configured capture sessions with. This way the app can
match the native handle with outputs configured without needing to
inspect the internal contents of the native handle.

Bug: 224810366

Test: Artificially produce frame drops by putting cpus in power saving
      mode; use camera2 vndk; confirm buffer native handles are not
      repeated per frame number.

Change-Id: I4b54e007576d29529170bc192308d01f18b95a13
Signed-off-by: default avatarJayant Chowdhary <jchowdhary@google.com>
parent e526939d
Loading
Loading
Loading
Loading
+31 −9
Original line number Diff line number Diff line
@@ -330,7 +330,8 @@ camera_status_t CameraDevice::updateOutputConfigurationLocked(ACaptureSessionOut
                return ACAMERA_ERROR_UNKNOWN;
    }

    mConfiguredOutputs[streamId] = std::make_pair(output->mWindow, outConfigW);
    mConfiguredOutputs[streamId] =
            std::move(std::make_pair(std::move(output->mWindow), std::move(outConfigW)));

    return ACAMERA_OK;
}
@@ -623,7 +624,8 @@ CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outpu
        outConfigInsert.windowHandles[0] = anw;
        outConfigInsert.physicalCameraId = outConfig.mPhysicalCameraId;
        native_handle_ptr_wrapper wrap(anw);
        outputSet.insert(std::make_pair(anw, outConfigInsertW));

        outputSet.emplace(std::make_pair(std::move(anw), std::move(outConfigInsertW)));
    }
    std::set<std::pair<native_handle_ptr_wrapper, OutputConfigurationWrapper>> addSet = outputSet;
    std::vector<int32_t> deleteList;
@@ -680,7 +682,7 @@ CameraDevice::configureStreamsLocked(const ACaptureSessionOutputContainer* outpu
    }

    // add new streams
    for (auto outputPair : addSet) {
    for (const auto &outputPair : addSet) {
        int streamId;
        Status status = Status::UNKNOWN_ERROR;
        auto ret = mRemote->createStream(outputPair.second,
@@ -845,12 +847,32 @@ CameraDevice::onCaptureErrorLocked(
            return;
        }

        const auto& windowHandles = outputPairIt->second.second.mOutputConfiguration.windowHandles;
        for (const auto& outHandle : windowHandles) {
            for (auto streamAndWindowId : request->mCaptureRequest.streamAndWindowIds) {
                int32_t windowId = streamAndWindowId.windowId;
                if (utils::isWindowNativeHandleEqual(windowHandles[windowId],outHandle)) {
                    const native_handle_t* anw = windowHandles[windowId].getNativeHandle();
        // Get the surfaces corresponding to the error stream id, go through
        // them and try to match the surfaces in the corresponding
        // CaptureRequest.
        const auto& errorWindowHandles =
                outputPairIt->second.second.mOutputConfiguration.windowHandles;
        for (const auto& errorWindowHandle : errorWindowHandles) {
            for (const auto &requestStreamAndWindowId :
                        request->mCaptureRequest.streamAndWindowIds) {
                // Go through the surfaces in the capture request and see which
                // ones match the surfaces in the error stream.
                int32_t requestWindowId = requestStreamAndWindowId.windowId;
                auto requestSurfacePairIt =
                        mConfiguredOutputs.find(requestStreamAndWindowId.streamId);
                if (requestSurfacePairIt == mConfiguredOutputs.end()) {
                    ALOGE("%s: Error: request stream id %d does not exist", __FUNCTION__,
                              requestStreamAndWindowId.streamId);
                    setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
                    return;
                }

                const auto &requestWindowHandles =
                        requestSurfacePairIt->second.second.mOutputConfiguration.windowHandles;
                if (utils::isWindowNativeHandleEqual(
                        requestWindowHandles[requestWindowId], errorWindowHandle)) {
                    const native_handle_t* anw =
                            requestWindowHandles[requestWindowId].getNativeHandle();
                    ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64,
                            getId(), anw, frameNumber);

+24 −2
Original line number Diff line number Diff line
@@ -109,8 +109,30 @@ struct OutputConfigurationWrapper {
        mOutputConfiguration.windowGroupId = -1;
    };

    OutputConfigurationWrapper(OutputConfiguration &outputConfiguration)
            : mOutputConfiguration((outputConfiguration)) { }
    OutputConfigurationWrapper(const OutputConfigurationWrapper &other) {
        *this = other;
    }

    // Needed to make sure that OutputConfiguration in
    // OutputConfigurationWrapper, when copied doesn't call hidl_handle's
    // assignment operator / copy constructor, which will lead to native handle
    // cloning, which is not what we want for app callbacks which have the native
    // handle as parameter.
    OutputConfigurationWrapper &operator=(const OutputConfigurationWrapper &other) {
        const OutputConfiguration &outputConfiguration = other.mOutputConfiguration;
        mOutputConfiguration.rotation = outputConfiguration.rotation;
        mOutputConfiguration.isDeferred = outputConfiguration.isDeferred;
        mOutputConfiguration.width = outputConfiguration.width;
        mOutputConfiguration.height = outputConfiguration.height;
        mOutputConfiguration.windowGroupId = outputConfiguration.windowGroupId;
        mOutputConfiguration.windowHandles.resize(outputConfiguration.windowHandles.size());
        mOutputConfiguration.physicalCameraId = outputConfiguration.physicalCameraId;
        size_t i = 0;
        for (const auto &handle : outputConfiguration.windowHandles) {
            mOutputConfiguration.windowHandles[i++] = handle.getNativeHandle();
        }
        return *this;
    }

    bool operator ==(const OutputConfiguration &other) const {
        const OutputConfiguration &self = mOutputConfiguration;