Camera: Add timestamp base in OutputConfiguration

Timestamp base allows the application to select the preferred
timestamp behavior for a particular stream.

Test: Camera CTS
Bug: 186700251
Bug: 200306379
Change-Id: I066eac4a95bddc007facfc9d68bc024a3f0884db
diff --git a/camera/camera2/OutputConfiguration.cpp b/camera/camera2/OutputConfiguration.cpp
index 0982bba..a16e747 100644
--- a/camera/camera2/OutputConfiguration.cpp
+++ b/camera/camera2/OutputConfiguration.cpp
@@ -85,6 +85,10 @@
     return mStreamUseCase;
 }
 
+int OutputConfiguration::getTimestampBase() const {
+    return mTimestampBase;
+}
+
 OutputConfiguration::OutputConfiguration() :
         mRotation(INVALID_ROTATION),
         mSurfaceSetID(INVALID_SET_ID),
@@ -95,7 +99,8 @@
         mIsShared(false),
         mIsMultiResolution(false),
         mDynamicRangeProfile(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD),
-        mStreamUseCase(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {
+        mStreamUseCase(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT),
+        mTimestampBase(TIMESTAMP_BASE_DEFAULT) {
 }
 
 OutputConfiguration::OutputConfiguration(const android::Parcel& parcel) :
@@ -188,6 +193,12 @@
         return err;
     }
 
+    int timestampBase = TIMESTAMP_BASE_DEFAULT;
+    if ((err = parcel->readInt32(&timestampBase)) != OK) {
+        ALOGE("%s: Failed to read timestamp base from parcel", __FUNCTION__);
+        return err;
+    }
+
     mRotation = rotation;
     mSurfaceSetID = setID;
     mSurfaceType = surfaceType;
@@ -197,6 +208,7 @@
     mIsShared = isShared != 0;
     mIsMultiResolution = isMultiResolution != 0;
     mStreamUseCase = streamUseCase;
+    mTimestampBase = timestampBase;
     for (auto& surface : surfaceShims) {
         ALOGV("%s: OutputConfiguration: %p, name %s", __FUNCTION__,
                 surface.graphicBufferProducer.get(),
@@ -208,9 +220,9 @@
     mDynamicRangeProfile = dynamicProfile;
 
     ALOGV("%s: OutputConfiguration: rotation = %d, setId = %d, surfaceType = %d,"
-          " physicalCameraId = %s, isMultiResolution = %d, streamUseCase = %d", __FUNCTION__,
-          mRotation, mSurfaceSetID, mSurfaceType, String8(mPhysicalCameraId).string(),
-          mIsMultiResolution, mStreamUseCase);
+          " physicalCameraId = %s, isMultiResolution = %d, streamUseCase = %d, timestampBase = %d",
+          __FUNCTION__, mRotation, mSurfaceSetID, mSurfaceType,
+          String8(mPhysicalCameraId).string(), mIsMultiResolution, mStreamUseCase, timestampBase);
 
     return err;
 }
@@ -227,6 +239,7 @@
     mIsMultiResolution = false;
     mDynamicRangeProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD;
     mStreamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
+    mTimestampBase = TIMESTAMP_BASE_DEFAULT;
 }
 
 OutputConfiguration::OutputConfiguration(
@@ -237,7 +250,8 @@
     mWidth(width), mHeight(height), mIsDeferred(false), mIsShared(isShared),
     mPhysicalCameraId(physicalCameraId), mIsMultiResolution(false),
     mDynamicRangeProfile(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD),
-    mStreamUseCase(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) { }
+    mStreamUseCase(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT),
+    mTimestampBase(TIMESTAMP_BASE_DEFAULT) { }
 
 status_t OutputConfiguration::writeToParcel(android::Parcel* parcel) const {
 
@@ -290,6 +304,9 @@
     err = parcel->writeInt32(mStreamUseCase);
     if (err != OK) return err;
 
+    err = parcel->writeInt32(mTimestampBase);
+    if (err != OK) return err;
+
     return OK;
 }
 
diff --git a/camera/include/camera/camera2/OutputConfiguration.h b/camera/include/camera/camera2/OutputConfiguration.h
index f1cb6bd..9a91cc0 100644
--- a/camera/include/camera/camera2/OutputConfiguration.h
+++ b/camera/include/camera/camera2/OutputConfiguration.h
@@ -38,6 +38,14 @@
         SURFACE_TYPE_SURFACE_VIEW = 0,
         SURFACE_TYPE_SURFACE_TEXTURE = 1
     };
+    enum TimestampBaseByte {
+        TIMESTAMP_BASE_DEFAULT = 0,
+        TIMESTAMP_BASE_SENSOR = 1,
+        TIMESTAMP_BASE_MONOTONIC = 2,
+        TIMESTAMP_BASE_REALTIME = 3,
+        TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED = 4
+    };
+
     const std::vector<sp<IGraphicBufferProducer>>& getGraphicBufferProducers() const;
     int                        getRotation() const;
     int                        getSurfaceSetID() const;
@@ -50,6 +58,7 @@
     String16                   getPhysicalCameraId() const;
     bool                       isMultiResolution() const;
     int                        getStreamUseCase() const;
+    int                        getTimestampBase() const;
 
     // set of sensor pixel mode resolutions allowed {MAX_RESOLUTION, DEFAULT_MODE};
     const std::vector<int32_t>&            getSensorPixelModesUsed() const;
@@ -93,7 +102,8 @@
                 mIsMultiResolution == other.mIsMultiResolution &&
                 sensorPixelModesUsedEqual(other) &&
                 mDynamicRangeProfile == other.mDynamicRangeProfile &&
-                mStreamUseCase == other.mStreamUseCase );
+                mStreamUseCase == other.mStreamUseCase &&
+                mTimestampBase == other.mTimestampBase);
     }
     bool operator != (const OutputConfiguration& other) const {
         return !(*this == other);
@@ -136,6 +146,9 @@
         if (mStreamUseCase != other.mStreamUseCase) {
             return mStreamUseCase < other.mStreamUseCase;
         }
+        if (mTimestampBase != other.mTimestampBase) {
+            return mTimestampBase < other.mTimestampBase;
+        }
         return gbpsLessThan(other);
     }
 
@@ -162,6 +175,7 @@
     std::vector<int32_t>       mSensorPixelModesUsed;
     int                        mDynamicRangeProfile;
     int                        mStreamUseCase;
+    int                        mTimestampBase;
 };
 } // namespace params
 } // namespace camera2