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

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

Camera: Keep a list of outstanding buffers

Keep a list of outstanding buffers in Camera3Stream so that
it won't return invalid buffers or the same buffers twice back
to the buffer queue.

Bug: 27894484
Change-Id: I9f96629b4f531778433c2e1ec32a142f2040832b
parent c526e1ef
Loading
Loading
Loading
Loading
+47 −0
Original line number Diff line number Diff line
@@ -476,16 +476,51 @@ status_t Camera3Stream::getBuffer(camera3_stream_buffer *buffer) {
    res = getBufferLocked(buffer);
    if (res == OK) {
        fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true);
        if (buffer->buffer) {
            mOutstandingBuffers.push_back(*buffer->buffer);
        }
    }

    return res;
}

bool Camera3Stream::isOutstandingBuffer(const camera3_stream_buffer &buffer) {
    if (buffer.buffer == nullptr) {
        return false;
    }

    for (auto b : mOutstandingBuffers) {
        if (b == *buffer.buffer) {
            return true;
        }
    }
    return false;
}

void Camera3Stream::removeOutstandingBuffer(const camera3_stream_buffer &buffer) {
    if (buffer.buffer == nullptr) {
        return;
    }

    for (auto b = mOutstandingBuffers.begin(); b != mOutstandingBuffers.end(); b++) {
        if (*b == *buffer.buffer) {
            mOutstandingBuffers.erase(b);
            return;
        }
    }
}

status_t Camera3Stream::returnBuffer(const camera3_stream_buffer &buffer,
        nsecs_t timestamp) {
    ATRACE_CALL();
    Mutex::Autolock l(mLock);

    // Check if this buffer is outstanding.
    if (!isOutstandingBuffer(buffer)) {
        ALOGE("%s: Stream %d: Returning an unknown buffer.", __FUNCTION__, mId);
        return BAD_VALUE;
    }

    /**
     * TODO: Check that the state is valid first.
     *
@@ -503,6 +538,7 @@ status_t Camera3Stream::returnBuffer(const camera3_stream_buffer &buffer,
    // buffer to be returned.
    mOutputBufferReturnedSignal.signal();

    removeOutstandingBuffer(buffer);
    return res;
}

@@ -535,6 +571,9 @@ status_t Camera3Stream::getInputBuffer(camera3_stream_buffer *buffer) {
    res = getInputBufferLocked(buffer);
    if (res == OK) {
        fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/false);
        if (buffer->buffer) {
            mOutstandingBuffers.push_back(*buffer->buffer);
        }
    }

    return res;
@@ -544,11 +583,19 @@ status_t Camera3Stream::returnInputBuffer(const camera3_stream_buffer &buffer) {
    ATRACE_CALL();
    Mutex::Autolock l(mLock);

    // Check if this buffer is outstanding.
    if (!isOutstandingBuffer(buffer)) {
        ALOGE("%s: Stream %d: Returning an unknown buffer.", __FUNCTION__, mId);
        return BAD_VALUE;
    }

    status_t res = returnInputBufferLocked(buffer);
    if (res == OK) {
        fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/false);
        mInputBufferReturnedSignal.signal();
    }

    removeOutstandingBuffer(buffer);
    return res;
}

+9 −0
Original line number Diff line number Diff line
@@ -457,6 +457,12 @@ class Camera3Stream :

    status_t        cancelPrepareLocked();

    // Return whether the buffer is in the list of outstanding buffers.
    bool isOutstandingBuffer(const camera3_stream_buffer& buffer);

    // Remove the buffer from the list of outstanding buffers.
    void removeOutstandingBuffer(const camera3_stream_buffer& buffer);

    // Tracking for PREPARING state

    // State of buffer preallocation. Only true if either prepareNextBuffer
@@ -470,6 +476,9 @@ class Camera3Stream :
    // Number of buffers allocated on last prepare call.
    size_t mLastMaxCount;

    // Outstanding buffers dequeued from the stream's buffer queue.
    List<buffer_handle_t> mOutstandingBuffers;

}; // class Camera3Stream

}; // namespace camera3