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

Commit c7ae12bc authored by Jayant Chowdhary's avatar Jayant Chowdhary Committed by Android (Google) Code Review
Browse files

Merge "cameraserver: Add support for stream specific hal buffer manager" into main

parents 7b91d5e1 025e97f5
Loading
Loading
Loading
Loading
+58 −42
Original line number Diff line number Diff line
@@ -81,7 +81,7 @@ using namespace android::hardware::camera;

namespace flags = com::android::internal::camera::flags;
namespace android {
namespace flags = com::android::internal::camera::flags;

Camera3Device::Camera3Device(std::shared_ptr<CameraServiceProxyWrapper>& cameraServiceProxyWrapper,
        const std::string &id, bool overrideForPerfClass, bool overrideToPortrait,
        bool legacyClient):
@@ -146,17 +146,6 @@ status_t Camera3Device::initializeCommonLocked() {
    /** Register in-flight map to the status tracker */
    mInFlightStatusId = mStatusTracker->addComponent("InflightRequests");

    if (mUseHalBufManager) {
        res = mRequestBufferSM.initialize(mStatusTracker);
        if (res != OK) {
            SET_ERR_L("Unable to start request buffer state machine: %s (%d)",
                    strerror(-res), res);
            mInterface->close();
            mStatusTracker.clear();
            return res;
        }
    }

    /** Create buffer manager */
    mBufferManager = new Camera3BufferManager();

@@ -1623,7 +1612,9 @@ status_t Camera3Device::waitUntilStateThenRelock(bool active, nsecs_t timeout,
    mStatusWaiters++;

    bool signalPipelineDrain = false;
    if (!active && mUseHalBufManager) {
    if (!active &&
            (mUseHalBufManager ||
                    (flags::session_hal_buf_manager() && mHalBufManagedStreamIds.size() != 0))) {
        auto streamIds = mOutputStreams.getStreamIds();
        if (mStatus == STATUS_ACTIVE) {
            mRequestThread->signalPipelineDrain(streamIds);
@@ -2539,7 +2530,7 @@ status_t Camera3Device::configureStreamsLocked(int operatingMode,
    }

    config.streams = streams.editArray();
    config.use_hal_buf_manager = mUseHalBufManager;
    config.hal_buffer_managed_streams = mHalBufManagedStreamIds;

    // Do the HAL configuration; will potentially touch stream
    // max_buffers, usage, and priv fields, as well as data_space and format
@@ -2563,13 +2554,17 @@ status_t Camera3Device::configureStreamsLocked(int operatingMode,
                strerror(-res), res);
        return res;
    }
    if (flags::session_hal_buf_manager()) {
        bool prevSessionHalBufManager = mUseHalBufManager;
        // It is possible that configureStreams() changed config.use_hal_buf_manager
    mUseHalBufManager = config.use_hal_buf_manager;
        if (prevSessionHalBufManager && !mUseHalBufManager) {
    if (flags::session_hal_buf_manager()) {
        bool prevSessionHalBufManager = (mHalBufManagedStreamIds.size() != 0);
        // It is possible that configureStreams() changed config.hal_buffer_managed_streams
        mHalBufManagedStreamIds = config.hal_buffer_managed_streams;

        bool thisSessionHalBufManager = mHalBufManagedStreamIds.size() != 0;

        if (prevSessionHalBufManager && !thisSessionHalBufManager) {
            mRequestBufferSM.deInit();
        } else if (!prevSessionHalBufManager && mUseHalBufManager) {
        } else if (!prevSessionHalBufManager && thisSessionHalBufManager) {
            res = mRequestBufferSM.initialize(mStatusTracker);
            if (res != OK) {
                SET_ERR_L("%s: Camera %s: RequestBuffer State machine couldn't be initialized!",
@@ -2577,7 +2572,7 @@ status_t Camera3Device::configureStreamsLocked(int operatingMode,
                return res;
            }
        }
        mRequestThread->setHalBufferManager(mUseHalBufManager);
        mRequestThread->setHalBufferManagedStreams(mHalBufManagedStreamIds);
    }
    // Finish all stream configuration immediately.
    // TODO: Try to relax this later back to lazy completion, which should be
@@ -2905,7 +2900,8 @@ void Camera3Device::flushInflightRequests() {

    FlushInflightReqStates states {
        mId, mInFlightLock, mInFlightMap, mUseHalBufManager,
        listener, *this, *mInterface, *this, mSessionStatsBuilder};
        mHalBufManagedStreamIds, listener, *this, *mInterface, *this,
        mSessionStatsBuilder};

    camera3::flushInflightRequests(states);
}
@@ -2970,6 +2966,11 @@ bool Camera3Device::HalInterface::verifyBufferIds(
    return mBufferRecords.verifyBufferIds(streamId, bufIds);
}

bool Camera3Device::HalInterface::isHalBufferManagedStream(int32_t streamId) const {
    return (mUseHalBufManager || (flags::session_hal_buf_manager() &&
                                  contains(mHalBufManagedStreamIds, streamId)));
}

status_t Camera3Device::HalInterface::popInflightBuffer(
        int32_t frameNumber, int32_t streamId,
        /*out*/ buffer_handle_t **buffer) {
@@ -3288,8 +3289,9 @@ void Camera3Device::RequestThread::setPaused(bool paused) {
    mDoPauseSignal.signal();
}

void Camera3Device::RequestThread::setHalBufferManager(bool enabled) {
    mUseHalBufManager = enabled;
void Camera3Device::RequestThread::setHalBufferManagedStreams(
            const std::set<int32_t> &halBufferManagedStreams) {
    mHalBufManagedStreamIds = halBufferManagedStreams;
}

status_t Camera3Device::RequestThread::waitUntilRequestProcessed(
@@ -3973,11 +3975,15 @@ status_t Camera3Device::RequestThread::prepareHalRequests() {
        nsecs_t waitDuration = kBaseGetBufferWait + parent->getExpectedInFlightDuration();

        SurfaceMap uniqueSurfaceIdMap;
        bool containsHalBufferManagedStream = false;
        for (size_t j = 0; j < captureRequest->mOutputStreams.size(); j++) {
            sp<Camera3OutputStreamInterface> outputStream =
                    captureRequest->mOutputStreams.editItemAt(j);
            int streamId = outputStream->getId();

            if (!containsHalBufferManagedStream) {
                containsHalBufferManagedStream =
                        contains(mHalBufManagedStreamIds, streamId);
            }
            // Prepare video buffers for high speed recording on the first video request.
            if (mPrepareVideoStream && outputStream->isVideoStream()) {
                // Only try to prepare video stream on the first video request.
@@ -4009,7 +4015,7 @@ status_t Camera3Device::RequestThread::prepareHalRequests() {
                uniqueSurfaceIdMap.insert({streamId, std::move(uniqueSurfaceIds)});
            }

            if (mUseHalBufManager) {
            if (parent->isHalBufferManagedStream(streamId)) {
                if (outputStream->isAbandoned()) {
                    ALOGV("%s: stream %d is abandoned, skipping request", __FUNCTION__, streamId);
                    return TIMED_OUT;
@@ -4100,6 +4106,9 @@ status_t Camera3Device::RequestThread::prepareHalRequests() {
                isZslCapture = true;
            }
        }
        bool passSurfaceMap =
                mUseHalBufManager ||
                        (flags::session_hal_buf_manager() && containsHalBufferManagedStream);
        auto expectedDurationInfo = calculateExpectedDurationRange(settings);
        res = parent->registerInFlight(halRequest->frame_number,
                totalNumBuffers, captureRequest->mResultExtras,
@@ -4111,7 +4120,7 @@ status_t Camera3Device::RequestThread::prepareHalRequests() {
                requestedPhysicalCameras, isStillCapture, isZslCapture,
                captureRequest->mRotateAndCropAuto, captureRequest->mAutoframingAuto,
                mPrevCameraIdsWithZoom,
                (mUseHalBufManager) ? uniqueSurfaceIdMap :
                passSurfaceMap ? uniqueSurfaceIdMap :
                                      SurfaceMap{}, captureRequest->mRequestTimeNs);
        ALOGVV("%s: registered in flight requestId = %" PRId32 ", frameNumber = %" PRId64
               ", burstId = %" PRId32 ".",
@@ -4214,7 +4223,8 @@ bool Camera3Device::RequestThread::isOutputSurfacePending(int streamId, size_t s
}

void Camera3Device::RequestThread::signalPipelineDrain(const std::vector<int>& streamIds) {
    if (!mUseHalBufManager) {
    if (!mUseHalBufManager &&
            (flags::session_hal_buf_manager() && mHalBufManagedStreamIds.size() == 0)) {
        ALOGE("%s called for camera device not supporting HAL buffer management", __FUNCTION__);
        return;
    }
@@ -4366,11 +4376,18 @@ void Camera3Device::RequestThread::cleanUpFailedRequests(bool sendRequestError)
            captureRequest->mInputStream->returnInputBuffer(captureRequest->mInputBuffer);
        }

        // No output buffer can be returned when using HAL buffer manager
        if (!mUseHalBufManager) {
        for (size_t i = 0; i < halRequest->num_output_buffers; i++) {
            //Buffers that failed processing could still have
            //valid acquire fence.
            Camera3Stream *stream = Camera3Stream::cast((*outputBuffers)[i].stream);
            int32_t streamId = stream->getId();
            bool skipBufferForStream =
                    mUseHalBufManager || (flags::session_hal_buf_manager() &&
                            contains(mHalBufManagedStreamIds, streamId));
            if (skipBufferForStream) {
                // No output buffer can be returned when using HAL buffer manager for its stream
                continue;
            }
            int acquireFence = (*outputBuffers)[i].acquire_fence;
            if (0 <= acquireFence) {
                close(acquireFence);
@@ -4382,7 +4399,6 @@ void Camera3Device::RequestThread::cleanUpFailedRequests(bool sendRequestError)
                    /*timestampIncreasing*/true, std::vector<size_t> (),
                    captureRequest->mResultExtras.frameNumber);
        }
        }

        if (sendRequestError) {
            Mutex::Autolock l(mRequestLock);
+14 −3
Original line number Diff line number Diff line
@@ -97,6 +97,10 @@ class Camera3Device :
        return mInterface->getTransportType();
    }

    bool isHalBufferManagedStream(int32_t streamId) const {
        return mInterface->isHalBufferManagedStream(streamId);
    };

    /**
     * CameraDeviceBase interface
     */
@@ -476,6 +480,9 @@ class Camera3Device :

        /////////////////////////////////////////////////////////////////////

        //Check if a stream is hal buffer managed
        bool isHalBufferManagedStream(int32_t streamId) const;

        // Get a vector of (frameNumber, streamId) pair of currently inflight
        // buffers
        void getInflightBufferKeys(std::vector<std::pair<int32_t, int32_t>>* out);
@@ -547,7 +554,9 @@ class Camera3Device :

        uint32_t mNextStreamConfigCounter = 1;

        // TODO: This can be removed after flags::session_hal_buf_manager is removed
        bool mUseHalBufManager = false;
        std::set<int32_t > mHalBufManagedStreamIds;
        bool mIsReconfigurationQuerySupported;

        const bool mSupportOfflineProcessing;
@@ -948,11 +957,11 @@ class Camera3Device :
        void     setPaused(bool paused);

        /**
         * Set Hal buffer manager behavior
         * @param enabled Whether HAL buffer manager is enabled for the current session.
         * Set Hal buffer managed streams
         * @param halBufferManagedStreams The streams for which hal buffer manager is enabled
         *
         */
        void setHalBufferManager(bool enabled);
        void setHalBufferManagedStreams(const std::set<int32_t> &halBufferManagedStreams);

        /**
         * Wait until thread processes the capture request with settings'
@@ -1203,6 +1212,7 @@ class Camera3Device :
        std::map<int32_t, std::set<std::string>> mGroupIdPhysicalCameraMap;

        bool               mUseHalBufManager = false;
        std::set<int32_t > mHalBufManagedStreamIds;
        const bool         mSupportCameraMute;
        const bool         mOverrideToPortrait;
        const bool         mSupportSettingsOverride;
@@ -1393,6 +1403,7 @@ class Camera3Device :

    // Whether HAL request buffers through requestStreamBuffers API
    bool mUseHalBufManager = false;
    std::set<int32_t > mHalBufManagedStreamIds;
    bool mSessionHalBufManager = false;
    // Lock to ensure requestStreamBuffers() callbacks are serialized
    std::mutex mRequestBufferInterfaceLock;
+2 −1
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ Camera3OfflineSession::Camera3OfflineSession(const std::string &id,
        mTagMonitor(offlineStates.mTagMonitor),
        mVendorTagId(offlineStates.mVendorTagId),
        mUseHalBufManager(offlineStates.mUseHalBufManager),
        mHalBufManagedStreamIds(offlineStates.mHalBufManagedStreamIds),
        mNeedFixupMonochromeTags(offlineStates.mNeedFixupMonochromeTags),
        mUsePartialResult(offlineStates.mUsePartialResult),
        mNumPartialResults(offlineStates.mNumPartialResults),
@@ -136,7 +137,7 @@ status_t Camera3OfflineSession::disconnectImpl() {

    FlushInflightReqStates states {
        mId, mOfflineReqsLock, mOfflineReqs, mUseHalBufManager,
        listener, *this, mBufferRecords, *this, mSessionStatsBuilder};
        mHalBufManagedStreamIds, listener, *this, mBufferRecords, *this, mSessionStatsBuilder};

    camera3::flushInflightRequests(states);

+6 −2
Original line number Diff line number Diff line
@@ -51,7 +51,8 @@ class Camera3StreamInterface;
struct Camera3OfflineStates {
    Camera3OfflineStates(
            const TagMonitor& tagMonitor, const metadata_vendor_id_t vendorTagId,
            const bool useHalBufManager, const bool needFixupMonochromeTags,
            const bool useHalBufManager, const std::set<int32_t> &halBufferManagedStreamIds,
            const bool needFixupMonochromeTags,
            const bool usePartialResult, const uint32_t numPartialResults,
            const int64_t lastCompletedRegularFN, const int64_t lastCompletedReprocessFN,
            const int64_t lastCompletedZslFN, const uint32_t nextResultFN,
@@ -64,7 +65,8 @@ struct Camera3OfflineStates {
            const std::unordered_map<std::string, camera3::RotateAndCropMapper>&
                rotateAndCropMappers) :
            mTagMonitor(tagMonitor), mVendorTagId(vendorTagId),
            mUseHalBufManager(useHalBufManager), mNeedFixupMonochromeTags(needFixupMonochromeTags),
            mUseHalBufManager(useHalBufManager), mHalBufManagedStreamIds(halBufferManagedStreamIds),
            mNeedFixupMonochromeTags(needFixupMonochromeTags),
            mUsePartialResult(usePartialResult), mNumPartialResults(numPartialResults),
            mLastCompletedRegularFrameNumber(lastCompletedRegularFN),
            mLastCompletedReprocessFrameNumber(lastCompletedReprocessFN),
@@ -85,6 +87,7 @@ struct Camera3OfflineStates {
    const metadata_vendor_id_t mVendorTagId;

    const bool mUseHalBufManager;
    const std::set<int32_t > &mHalBufManagedStreamIds;
    const bool mNeedFixupMonochromeTags;

    const bool mUsePartialResult;
@@ -181,6 +184,7 @@ class Camera3OfflineSession :
    const metadata_vendor_id_t mVendorTagId;

    const bool mUseHalBufManager;
    const std::set<int32_t > &mHalBufManagedStreamIds;
    const bool mNeedFixupMonochromeTags;

    const bool mUsePartialResult;
+18 −6
Original line number Diff line number Diff line
@@ -45,13 +45,17 @@
#include <camera/CameraUtils.h>
#include <camera/StringUtils.h>
#include <camera_metadata_hidden.h>
#include <com_android_internal_camera_flags.h>

#include "device3/Camera3OutputUtils.h"
#include "utils/SessionConfigurationUtils.h"

#include "system/camera_metadata.h"

using namespace android::camera3;
using namespace android::camera3::SessionConfigurationUtils;
using namespace android::hardware::camera;
namespace flags = com::android::internal::camera::flags;

namespace android {
namespace camera3 {
@@ -534,7 +538,8 @@ void removeInFlightRequestIfReadyLocked(CaptureOutputStates& states, int idx) {
               request.pendingOutputBuffers.size() == 0);

        returnOutputBuffers(
            states.useHalBufManager, states.listener,
            states.useHalBufManager, states.halBufManagedStreamIds,
            states.listener,
            request.pendingOutputBuffers.array(),
            request.pendingOutputBuffers.size(), /*timestamp*/0, /*readoutTimestamp*/0,
            /*requested*/true, request.requestTimeNs, states.sessionStatsBuilder,
@@ -794,7 +799,8 @@ void processCaptureResult(CaptureOutputStates& states, const camera_capture_resu
                result->num_output_buffers);
        if (shutterTimestamp != 0) {
            returnAndRemovePendingOutputBuffers(
                states.useHalBufManager, states.listener,
                states.useHalBufManager, states.halBufManagedStreamIds,
                states.listener,
                request, states.sessionStatsBuilder);
        }

@@ -845,6 +851,7 @@ void processCaptureResult(CaptureOutputStates& states, const camera_capture_resu

void returnOutputBuffers(
        bool useHalBufManager,
        const std::set<int32_t> &halBufferManagedStreams,
        sp<NotificationListener> listener,
        const camera_stream_buffer_t *outputBuffers, size_t numBuffers,
        nsecs_t timestamp, nsecs_t readoutTimestamp, bool requested,
@@ -871,7 +878,9 @@ void returnOutputBuffers(
        }

        if (outputBuffers[i].buffer == nullptr) {
            if (!useHalBufManager) {
            if (!useHalBufManager &&
                    !(flags::session_hal_buf_manager() &&
                            contains(halBufferManagedStreams, streamId))) {
                // With HAL buffer management API, HAL sometimes will have to return buffers that
                // has not got a output buffer handle filled yet. This is though illegal if HAL
                // buffer management API is not being used.
@@ -944,13 +953,14 @@ void returnOutputBuffers(
}

void returnAndRemovePendingOutputBuffers(bool useHalBufManager,
        const std::set<int32_t> &halBufferManagedStreams,
        sp<NotificationListener> listener, InFlightRequest& request,
        SessionStatsBuilder& sessionStatsBuilder) {
    bool timestampIncreasing =
            !((request.zslCapture && request.stillCapture) || request.hasInputBuffer);
    nsecs_t readoutTimestamp = request.resultExtras.hasReadoutTimestamp ?
            request.resultExtras.readoutTimestamp : 0;
    returnOutputBuffers(useHalBufManager, listener,
    returnOutputBuffers(useHalBufManager, halBufferManagedStreams, listener,
            request.pendingOutputBuffers.array(),
            request.pendingOutputBuffers.size(),
            request.shutterTimestamp, readoutTimestamp,
@@ -1052,7 +1062,8 @@ void notifyShutter(CaptureOutputStates& states, const camera_shutter_msg_t &msg)
                    r.rotateAndCropAuto, cameraIdsWithZoom, r.physicalMetadatas);
            }
            returnAndRemovePendingOutputBuffers(
                    states.useHalBufManager, states.listener, r, states.sessionStatsBuilder);
                    states.useHalBufManager, states.halBufManagedStreamIds,
                    states.listener, r, states.sessionStatsBuilder);

            removeInFlightRequestIfReadyLocked(states, idx);
        }
@@ -1193,7 +1204,8 @@ void flushInflightRequests(FlushInflightReqStates& states) {
        for (size_t idx = 0; idx < states.inflightMap.size(); idx++) {
            const InFlightRequest &request = states.inflightMap.valueAt(idx);
            returnOutputBuffers(
                states.useHalBufManager, states.listener,
                states.useHalBufManager, states.halBufManagedStreamIds,
                states.listener,
                request.pendingOutputBuffers.array(),
                request.pendingOutputBuffers.size(), /*timestamp*/0, /*readoutTimestamp*/0,
                /*requested*/true, request.requestTimeNs, states.sessionStatsBuilder,
Loading