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

Commit bdde5f88 authored by Eino-Ville Talvala's avatar Eino-Ville Talvala Committed by Android (Google) Code Review
Browse files

Camera2: Fix ZSL bugs.

The ZSL processor was discarding buffers too often, and waiting for
new buffers with mutexes held.

Also adds basic fallback to regular capture in case the ZSL queue
doesn't contain a suitable buffer.

Bug: 7147043

Change-Id: I5721267ef08dbc87ef9d8ec47f333db5f67e41c1
parent 359cf1ca
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -253,6 +253,7 @@ CaptureSequencer::CaptureState CaptureSequencer::manageStart(

CaptureSequencer::CaptureState CaptureSequencer::manageZslStart(
        sp<Camera2Client> &client) {
    ALOGV("%s", __FUNCTION__);
    status_t res;
    sp<ZslProcessor> processor = mZslProcessor.promote();
    if (processor == 0) {
@@ -271,7 +272,12 @@ CaptureSequencer::CaptureState CaptureSequencer::manageZslStart(
        return DONE;
    }
    // TODO: Actually select the right thing here.
    processor->pushToReprocess(mCaptureId);
    res = processor->pushToReprocess(mCaptureId);
    if (res != OK) {
        ALOGW("%s: Camera %d: Failed to use ZSL queue, falling back to standard capture",
                __FUNCTION__, client->getCameraId());
        return STANDARD_START;
    }

    mTimeoutCount = kMaxTimeoutsForCaptureEnd;
    return STANDARD_CAPTURE_WAIT;
@@ -279,11 +285,13 @@ CaptureSequencer::CaptureState CaptureSequencer::manageZslStart(

CaptureSequencer::CaptureState CaptureSequencer::manageZslWaiting(
        sp<Camera2Client> &client) {
    ALOGV("%s", __FUNCTION__);
    return DONE;
}

CaptureSequencer::CaptureState CaptureSequencer::manageZslReprocessing(
        sp<Camera2Client> &client) {
    ALOGV("%s", __FUNCTION__);
    return START;
}

+42 −22
Original line number Diff line number Diff line
@@ -235,9 +235,19 @@ status_t ZslProcessor::pushToReprocess(int32_t requestId) {
    if (client == 0) return false;

    if (mZslQueueTail != mZslQueueHead) {
        CameraMetadata request;
        size_t index = mZslQueueTail;
        while (request.isEmpty() && index != mZslQueueHead) {
            request = mZslQueue[index].frame;
            index = (index + 1) % kZslBufferDepth;
        }
        if (request.isEmpty()) {
            ALOGE("No request in ZSL queue to send!");
            return BAD_VALUE;
        }
        buffer_handle_t *handle =
            &(mZslQueue[mZslQueueTail].buffer.mGraphicBuffer->handle);
        CameraMetadata request = mZslQueue[mZslQueueTail].frame;
            &(mZslQueue[index].buffer.mGraphicBuffer->handle);

        uint8_t requestType = ANDROID_REQUEST_TYPE_REPROCESS;
        res = request.update(ANDROID_REQUEST_TYPE,
                &requestType, 1);
@@ -306,9 +316,8 @@ bool ZslProcessor::threadLoop() {
status_t ZslProcessor::processNewZslBuffer(sp<Camera2Client> &client) {
    ATRACE_CALL();
    status_t res;
    Mutex::Autolock l(mInputMutex);

    if (mState == LOCKED) {
    ALOGVV("Trying to get next buffer");
    BufferItemConsumer::BufferItem item;
    res = mZslConsumer->acquireBuffer(&item);
    if (res != OK) {
@@ -316,9 +325,16 @@ status_t ZslProcessor::processNewZslBuffer(sp<Camera2Client> &client) {
            ALOGE("%s: Camera %d: Error receiving ZSL image buffer: "
                    "%s (%d)", __FUNCTION__,
                    client->getCameraId(), strerror(-res), res);
        } else {
            ALOGVV("  No buffer");
        }
        return res;
    }

    Mutex::Autolock l(mInputMutex);

    if (mState == LOCKED) {
        ALOGVV("In capture, discarding new ZSL buffers");
        mZslConsumer->releaseBuffer(item);
        return OK;
    }
@@ -326,6 +342,7 @@ status_t ZslProcessor::processNewZslBuffer(sp<Camera2Client> &client) {
    ALOGVV("Got ZSL buffer: head: %d, tail: %d", mZslQueueHead, mZslQueueTail);

    if ( (mZslQueueHead + 1) % kZslBufferDepth == mZslQueueTail) {
        ALOGVV("Releasing oldest buffer");
        mZslConsumer->releaseBuffer(mZslQueue[mZslQueueTail].buffer);
        mZslQueue.replaceAt(mZslQueueTail);
        mZslQueueTail = (mZslQueueTail + 1) % kZslBufferDepth;
@@ -333,20 +350,12 @@ status_t ZslProcessor::processNewZslBuffer(sp<Camera2Client> &client) {

    ZslPair &queueHead = mZslQueue.editItemAt(mZslQueueHead);

    res = mZslConsumer->acquireBuffer(&(queueHead.buffer));
    if (res != OK) {
        if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) {
            ALOGE("%s: Camera %d: Error receiving ZSL image buffer: "
                    "%s (%d)", __FUNCTION__,
                    client->getCameraId(), strerror(-res), res);
        }
        return res;
    }
    queueHead.buffer = item;
    queueHead.frame.release();

    mZslQueueHead = (mZslQueueHead + 1) % kZslBufferDepth;

    ALOGVV("  Added buffer, timestamp %lld", queueHead.buffer.mTimestamp);
    ALOGVV("  Acquired buffer, timestamp %lld", queueHead.buffer.mTimestamp);

    findMatchesLocked();

@@ -354,9 +363,20 @@ status_t ZslProcessor::processNewZslBuffer(sp<Camera2Client> &client) {
}

void ZslProcessor::findMatchesLocked() {
    ALOGVV("Scanning");
    for (size_t i = 0; i < mZslQueue.size(); i++) {
        ZslPair &queueEntry = mZslQueue.editItemAt(i);
        nsecs_t bufferTimestamp = queueEntry.buffer.mTimestamp;
        IF_ALOGV() {
            camera_metadata_entry_t entry;
            nsecs_t frameTimestamp = 0;
            if (!queueEntry.frame.isEmpty()) {
                entry = queueEntry.frame.find(ANDROID_SENSOR_TIMESTAMP);
                frameTimestamp = entry.data.i64[0];
            }
            ALOGVV("   %d: b: %lld\tf: %lld", i,
                    bufferTimestamp, frameTimestamp );
        }
        if (queueEntry.frame.isEmpty() && bufferTimestamp != 0) {
            // Have buffer, no matching frame. Look for one
            for (size_t j = 0; j < mFrameList.size(); j++) {
+1 −1
Original line number Diff line number Diff line
@@ -93,7 +93,7 @@ class ZslProcessor:
        CameraMetadata frame;
    };

    static const size_t kZslBufferDepth = 3;
    static const size_t kZslBufferDepth = 4;
    static const size_t kFrameListDepth = kZslBufferDepth * 2;
    Vector<CameraMetadata> mFrameList;
    size_t mFrameListHead;