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

Commit 13a69633 authored by Shuzhen Wang's avatar Shuzhen Wang
Browse files

Camera3: Selectively set buffer timestamp depends on consumer

Certain consumers such as Hardware Composer and AudioSource
use MONOTONIC timestamp, which causes time misalignment if
camera timestamp is in BOOTTIME.

Do not set buffer time stamp for such streams and let
BufferQueue handle it.

Bug: 22214409
Bug: 26762232
Change-Id: Id1c4b85a181e39827e8f27949a199165bbd445f9
parent a03910b2
Loading
Loading
Loading
Loading
+26 −5
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ Camera3OutputStream::Camera3OutputStream(int id,
        mConsumer(consumer),
        mTransform(0),
        mTraceFirstBuffer(true),
        mTimestampBuffer(true),
        mUseBufferManager(false) {

    if (mConsumer == NULL) {
@@ -61,6 +62,7 @@ Camera3OutputStream::Camera3OutputStream(int id,
        mConsumer(consumer),
        mTransform(0),
        mTraceFirstBuffer(true),
        mTimestampBuffer(true),
        mUseBufferManager(false) {

    if (format != HAL_PIXEL_FORMAT_BLOB && format != HAL_PIXEL_FORMAT_RAW_OPAQUE) {
@@ -228,12 +230,18 @@ status_t Camera3OutputStream::returnBufferCheckedLocked(
            mTraceFirstBuffer = false;
        }

        /* Certain consumers (such as AudioSource or HardwareComposer) use
         * MONOTONIC time, causing time misalignment if camera timestamp is
         * in BOOTTIME. Avoid setting timestamp, and let BufferQueue generate it
         * instead. */
        if (mTimestampBuffer) {
            res = native_window_set_buffers_timestamp(mConsumer.get(), timestamp);
            if (res != OK) {
                ALOGE("%s: Stream %d: Error setting timestamp: %s (%d)",
                      __FUNCTION__, mId, strerror(-res), res);
                return res;
            }
        }

        res = currentConsumer->queueBuffer(currentConsumer.get(),
                container_of(buffer.buffer, ANativeWindowBuffer, handle),
@@ -385,6 +393,7 @@ status_t Camera3OutputStream::configureQueueLocked() {
    mHandoutTotalBufferCount = 0;
    mFrameCount = 0;
    mLastTimestamp = 0;
    mTimestampBuffer = !(isConsumedByHWComposer() | isVideoStream());

    res = native_window_set_buffer_count(mConsumer.get(),
            mTotalBufferCount);
@@ -566,6 +575,18 @@ void Camera3OutputStream::BufferReleasedListener::onBufferReleased() {
       stream->mState = STATE_ERROR;
    }
}

bool Camera3OutputStream::isConsumedByHWComposer() const {
    uint32_t usage = 0;
    status_t res = getEndpointUsage(&usage);
    if (res != OK) {
        ALOGE("%s: getting end point usage failed: %s (%d).", __FUNCTION__, strerror(-res), res);
        return false;
    }

    return (usage & GRALLOC_USAGE_HW_COMPOSER) != 0;
}

}; // namespace camera3

}; // namespace android
+7 −0
Original line number Diff line number Diff line
@@ -112,6 +112,10 @@ class Camera3OutputStream :
     * Return if this output stream is for video encoding.
     */
    bool isVideoStream() const;
    /**
     * Return if this output stream is consumed by hardware composer.
     */
    bool isConsumedByHWComposer() const;

    class BufferReleasedListener : public BnProducerListener {
        public:
@@ -163,6 +167,9 @@ class Camera3OutputStream :
    // Name of Surface consumer
    String8           mConsumerName;

    // Whether to timestamp the output buffer
    bool mTimestampBuffer;

    /**
     * GraphicBuffer manager this stream is registered to. Used to replace the buffer
     * allocation/deallocation role of BufferQueue.