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

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

Camera3: Support AE precapture trigger CANCEL

Support AE precapture trigger CANCEL for devices <= API
version 3.2.

Bug: 20494782
Change-Id: I6003ba8057ca4ec9e8dfda47b8411ae6be913d22
parent fa907d4e
Loading
Loading
Loading
Loading
+87 −6
Original line number Diff line number Diff line
@@ -1783,12 +1783,14 @@ void Camera3Device::setErrorStateLockedV(const char *fmt, va_list args) {
 */

status_t Camera3Device::registerInFlight(uint32_t frameNumber,
        int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput) {
        int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput,
        const AeTriggerCancelOverride_t &aeTriggerCancelOverride) {
    ATRACE_CALL();
    Mutex::Autolock l(mInFlightLock);

    ssize_t res;
    res = mInFlightMap.add(frameNumber, InFlightRequest(numBuffers, resultExtras, hasInput));
    res = mInFlightMap.add(frameNumber, InFlightRequest(numBuffers, resultExtras, hasInput,
            aeTriggerCancelOverride));
    if (res < 0) return res;

    return OK;
@@ -2032,7 +2034,8 @@ void Camera3Device::sendCaptureResult(CameraMetadata &pendingMetadata,
        CaptureResultExtras &resultExtras,
        CameraMetadata &collectedPartialResult,
        uint32_t frameNumber,
        bool reprocess) {
        bool reprocess,
        const AeTriggerCancelOverride_t &aeTriggerCancelOverride) {
    if (pendingMetadata.isEmpty())
        return;

@@ -2087,6 +2090,8 @@ void Camera3Device::sendCaptureResult(CameraMetadata &pendingMetadata,
        return;
    }

    overrideResultForPrecaptureCancel(&captureResult.mMetadata, aeTriggerCancelOverride);

    // Valid result, insert into queue
    List<CaptureResult>::iterator queuedResult =
            mResultQueue.insert(mResultQueue.end(), CaptureResult(captureResult));
@@ -2265,7 +2270,8 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) {
                CameraMetadata metadata;
                metadata = result->result;
                sendCaptureResult(metadata, request.resultExtras,
                    collectedPartialResult, frameNumber, hasInputBufferInRequest);
                    collectedPartialResult, frameNumber, hasInputBufferInRequest,
                    request.aeTriggerCancelOverride);
            }
        }

@@ -2428,7 +2434,7 @@ void Camera3Device::notifyShutter(const camera3_shutter_msg_t &msg,
            // send pending result and buffers
            sendCaptureResult(r.pendingMetadata, r.resultExtras,
                r.partialResult.collectedResult, msg.frame_number,
                r.hasInputBuffer);
                r.hasInputBuffer, r.aeTriggerCancelOverride);
            returnOutputBuffers(r.pendingOutputBuffers.array(),
                r.pendingOutputBuffers.size(), r.shutterTimestamp);
            r.pendingOutputBuffers.clear();
@@ -2477,6 +2483,17 @@ Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,
        mCurrentPreCaptureTriggerId(0),
        mRepeatingLastFrameNumber(NO_IN_FLIGHT_REPEATING_FRAMES) {
    mStatusId = statusTracker->addComponent();

    mAeLockAvailable = false;
    sp<Camera3Device> p = parent.promote();
    if (p != NULL) {
        camera_metadata_ro_entry aeLockAvailable =
                p->info().find(ANDROID_CONTROL_AE_LOCK_AVAILABLE);
        if (aeLockAvailable.count > 0) {
            mAeLockAvailable = (aeLockAvailable.data.u8[0] ==
                    ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE);
        }
    }
}

void Camera3Device::RequestThread::setNotificationListener(
@@ -2683,6 +2700,65 @@ void Camera3Device::RequestThread::requestExit() {
    mRequestSignal.signal();
}


/**
 * For devices <= CAMERA_DEVICE_API_VERSION_3_2, AE_PRECAPTURE_TRIGGER_CANCEL is not supported so
 * we need to override AE_PRECAPTURE_TRIGGER_CANCEL to AE_PRECAPTURE_TRIGGER_IDLE and AE_LOCK_OFF
 * to AE_LOCK_ON to start cancelling AE precapture. If AE lock is not available, it still overrides
 * AE_PRECAPTURE_TRIGGER_CANCEL to AE_PRECAPTURE_TRIGGER_IDLE but doesn't add AE_LOCK_ON to the
 * request.
 */
void Camera3Device::RequestThread::handleAePrecaptureCancelRequest(sp<CaptureRequest> request) {
    request->mAeTriggerCancelOverride.applyAeLock = false;
    request->mAeTriggerCancelOverride.applyAePrecaptureTrigger = false;

    if (mHal3Device->common.version > CAMERA_DEVICE_API_VERSION_3_2) {
        return;
    }

    camera_metadata_entry_t aePrecaptureTrigger =
            request->mSettings.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER);
    if (aePrecaptureTrigger.count > 0 &&
            aePrecaptureTrigger.data.u8[0] == ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL) {
        // Always override CANCEL to IDLE
        uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
        request->mSettings.update(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, &aePrecaptureTrigger, 1);
        request->mAeTriggerCancelOverride.applyAePrecaptureTrigger = true;
        request->mAeTriggerCancelOverride.aePrecaptureTrigger =
                ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL;

        if (mAeLockAvailable == true) {
            camera_metadata_entry_t aeLock = request->mSettings.find(ANDROID_CONTROL_AE_LOCK);
            if (aeLock.count == 0 ||  aeLock.data.u8[0] == ANDROID_CONTROL_AE_LOCK_OFF) {
                uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_ON;
                request->mSettings.update(ANDROID_CONTROL_AE_LOCK, &aeLock, 1);
                request->mAeTriggerCancelOverride.applyAeLock = true;
                request->mAeTriggerCancelOverride.aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
            }
        }
    }
}

/**
 * Override result metadata for cancelling AE precapture trigger applied in
 * handleAePrecaptureCancelRequest().
 */
void Camera3Device::overrideResultForPrecaptureCancel(
        CameraMetadata *result, const AeTriggerCancelOverride_t &aeTriggerCancelOverride) {
    if (aeTriggerCancelOverride.applyAeLock) {
        // Only devices <= v3.2 should have this override
        assert(mDeviceVersion <= CAMERA_DEVICE_API_VERSION_3_2);
        result->update(ANDROID_CONTROL_AE_LOCK, &aeTriggerCancelOverride.aeLock, 1);
    }

    if (aeTriggerCancelOverride.applyAePrecaptureTrigger) {
        // Only devices <= v3.2 should have this override
        assert(mDeviceVersion <= CAMERA_DEVICE_API_VERSION_3_2);
        result->update(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
                &aeTriggerCancelOverride.aePrecaptureTrigger, 1);
    }
}

bool Camera3Device::RequestThread::threadLoop() {

    status_t res;
@@ -2822,7 +2898,8 @@ bool Camera3Device::RequestThread::threadLoop() {

    res = parent->registerInFlight(request.frame_number,
            totalNumBuffers, nextRequest->mResultExtras,
            /*hasInput*/request.input_buffer != NULL);
            /*hasInput*/request.input_buffer != NULL,
            nextRequest->mAeTriggerCancelOverride);
    ALOGVV("%s: registered in flight requestId = %" PRId32 ", frameNumber = %" PRId64
           ", burstId = %" PRId32 ".",
            __FUNCTION__,
@@ -3048,6 +3125,9 @@ sp<Camera3Device::CaptureRequest>
            }
        }
    }

    handleAePrecaptureCancelRequest(nextRequest);

    mNextRequest = nextRequest;

    return nextRequest;
@@ -3437,6 +3517,7 @@ void Camera3Device::sProcessCaptureResult(const camera3_callback_ops *cb,
        const camera3_capture_result *result) {
    Camera3Device *d =
            const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));

    d->processCaptureResult(result);
}

+37 −25
Original line number Diff line number Diff line
@@ -234,6 +234,13 @@ class Camera3Device :

    /**** End scope for mLock ****/

    typedef struct AeTriggerCancelOverride {
        bool applyAeLock;
        uint8_t aeLock;
        bool applyAePrecaptureTrigger;
        uint8_t aePrecaptureTrigger;
    } AeTriggerCancelOverride_t;

    class CaptureRequest : public LightRefBase<CaptureRequest> {
      public:
        CameraMetadata                      mSettings;
@@ -242,6 +249,9 @@ class Camera3Device :
        Vector<sp<camera3::Camera3OutputStreamInterface> >
                                            mOutputStreams;
        CaptureResultExtras                 mResultExtras;
        // Used to cancel AE precapture trigger for devices doesn't support
        // CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL
        AeTriggerCancelOverride_t           mAeTriggerCancelOverride;
    };
    typedef List<sp<CaptureRequest> > RequestList;

@@ -492,6 +502,9 @@ class Camera3Device :
        // If the input request is in mRepeatingRequests. Must be called with mRequestLock hold
        bool isRepeatingRequestLocked(const sp<CaptureRequest>);

        // Handle AE precapture trigger cancel for devices <= CAMERA_DEVICE_API_VERSION_3_2.
        void handleAePrecaptureCancelRequest(sp<CaptureRequest> request);

        wp<Camera3Device>  mParent;
        wp<camera3::StatusTracker>  mStatusTracker;
        camera3_device_t  *mHal3Device;
@@ -540,6 +553,9 @@ class Camera3Device :
        uint32_t           mCurrentPreCaptureTriggerId;

        int64_t            mRepeatingLastFrameNumber;

        // Whether the device supports AE lock
        bool               mAeLockAvailable;
    };
    sp<RequestThread> mRequestThread;

@@ -562,7 +578,6 @@ class Camera3Device :
        // If this request has any input buffer
        bool hasInputBuffer;


        // The last metadata that framework receives from HAL and
        // not yet send out because the shutter event hasn't arrived.
        // It's added by process_capture_result and sent when framework
@@ -575,6 +590,10 @@ class Camera3Device :
        // the shutter event.
        Vector<camera3_stream_buffer_t> pendingOutputBuffers;

        // Used to cancel AE precapture trigger for devices doesn't support
        // CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL
        AeTriggerCancelOverride_t aeTriggerCancelOverride;


        // Fields used by the partial result only
        struct PartialResultInFlight {
@@ -595,36 +614,20 @@ class Camera3Device :
                requestStatus(OK),
                haveResultMetadata(false),
                numBuffersLeft(0),
                hasInputBuffer(false){
        }

        InFlightRequest(int numBuffers) :
                shutterTimestamp(0),
                sensorTimestamp(0),
                requestStatus(OK),
                haveResultMetadata(false),
                numBuffersLeft(numBuffers),
                hasInputBuffer(false){
                hasInputBuffer(false),
                aeTriggerCancelOverride({false, 0, false, 0}){
        }

        InFlightRequest(int numBuffers, CaptureResultExtras extras) :
        InFlightRequest(int numBuffers, CaptureResultExtras extras, bool hasInput,
                AeTriggerCancelOverride aeTriggerCancelOverride) :
                shutterTimestamp(0),
                sensorTimestamp(0),
                requestStatus(OK),
                haveResultMetadata(false),
                numBuffersLeft(numBuffers),
                resultExtras(extras),
                hasInputBuffer(false){
        }

        InFlightRequest(int numBuffers, CaptureResultExtras extras, bool hasInput) :
                shutterTimestamp(0),
                sensorTimestamp(0),
                requestStatus(OK),
                haveResultMetadata(false),
                numBuffersLeft(numBuffers),
                resultExtras(extras),
                hasInputBuffer(hasInput){
                hasInputBuffer(hasInput),
                aeTriggerCancelOverride(aeTriggerCancelOverride){
        }
    };

@@ -635,7 +638,8 @@ class Camera3Device :
    InFlightMap            mInFlightMap;

    status_t registerInFlight(uint32_t frameNumber,
            int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput);
            int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput,
            const AeTriggerCancelOverride_t &aeTriggerCancelOverride);

    /**
     * For the partial result, check if all 3A state fields are available
@@ -653,6 +657,14 @@ class Camera3Device :
    template<typename T>
    bool insert3AResult(CameraMetadata &result, int32_t tag, const T* value,
            uint32_t frameNumber);

    /**
     * Override result metadata for cancelling AE precapture trigger applied in
     * handleAePrecaptureCancelRequest().
     */
    void overrideResultForPrecaptureCancel(CameraMetadata* result,
            const AeTriggerCancelOverride_t &aeTriggerCancelOverride);

    /**
     * Tracking for idle detection
     */
@@ -738,7 +750,7 @@ class Camera3Device :
    void sendCaptureResult(CameraMetadata &pendingMetadata,
            CaptureResultExtras &resultExtras,
            CameraMetadata &collectedPartialResult, uint32_t frameNumber,
            bool reprocess);
            bool reprocess, const AeTriggerCancelOverride_t &aeTriggerCancelOverride);

    /**** Scope for mInFlightLock ****/