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
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index c721144..e42d839 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -40,6 +40,7 @@
         mConsumer(consumer),
         mTransform(0),
         mTraceFirstBuffer(true),
+        mTimestampBuffer(true),
         mUseBufferManager(false) {
 
     if (mConsumer == NULL) {
@@ -61,6 +62,7 @@
         mConsumer(consumer),
         mTransform(0),
         mTraceFirstBuffer(true),
+        mTimestampBuffer(true),
         mUseBufferManager(false) {
 
     if (format != HAL_PIXEL_FORMAT_BLOB && format != HAL_PIXEL_FORMAT_RAW_OPAQUE) {
@@ -228,11 +230,17 @@
             mTraceFirstBuffer = false;
         }
 
-        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;
+        /* 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(),
@@ -385,6 +393,7 @@
     mHandoutTotalBufferCount = 0;
     mFrameCount = 0;
     mLastTimestamp = 0;
+    mTimestampBuffer = !(isConsumedByHWComposer() | isVideoStream());
 
     res = native_window_set_buffer_count(mConsumer.get(),
             mTotalBufferCount);
@@ -566,6 +575,18 @@
        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
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index e222e2c..c2c3452 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -112,6 +112,10 @@
      * 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 @@
     // 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.