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/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index 95d19ec..a82d19b 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -47,11 +47,12 @@
nsecs_t timestampOffset, const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId, bool isMultiResolution, int dynamicRangeProfile,
- int streamUseCase) :
+ int streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase) :
Camera3IOStreamBase(id, CAMERA_STREAM_OUTPUT, width, height,
/*maxSize*/0, format, dataSpace, rotation,
physicalCameraId, sensorPixelModesUsed, setId, isMultiResolution,
- dynamicRangeProfile, streamUseCase),
+ dynamicRangeProfile, streamUseCase, deviceTimeBaseIsRealtime,
+ timestampBase),
mConsumer(consumer),
mTransform(0),
mTraceFirstBuffer(true),
@@ -77,14 +78,14 @@
nsecs_t timestampOffset, const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId, bool isMultiResolution, int dynamicRangeProfile,
- int streamUseCase) :
+ int streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase) :
Camera3IOStreamBase(id, CAMERA_STREAM_OUTPUT, width, height, maxSize,
format, dataSpace, rotation, physicalCameraId, sensorPixelModesUsed,
- setId, isMultiResolution, dynamicRangeProfile, streamUseCase),
+ setId, isMultiResolution, dynamicRangeProfile, streamUseCase,
+ deviceTimeBaseIsRealtime, timestampBase),
mConsumer(consumer),
mTransform(0),
mTraceFirstBuffer(true),
- mUseMonoTimestamp(false),
mUseBufferManager(false),
mTimestampOffset(timestampOffset),
mConsumerUsage(0),
@@ -113,11 +114,12 @@
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId, bool isMultiResolution, int dynamicRangeProfile,
- int streamUseCase) :
+ int streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase) :
Camera3IOStreamBase(id, CAMERA_STREAM_OUTPUT, width, height,
/*maxSize*/0, format, dataSpace, rotation,
physicalCameraId, sensorPixelModesUsed, setId, isMultiResolution,
- dynamicRangeProfile, streamUseCase),
+ dynamicRangeProfile, streamUseCase, deviceTimeBaseIsRealtime,
+ timestampBase),
mConsumer(nullptr),
mTransform(0),
mTraceFirstBuffer(true),
@@ -152,18 +154,19 @@
android_dataspace dataSpace,
camera_stream_rotation_t rotation,
const String8& physicalCameraId,
- const std::unordered_set<int32_t> &sensorPixelModesUsed,
+ const std::unordered_set<int32_t> &sensorPixelModesUsed,
uint64_t consumerUsage, nsecs_t timestampOffset,
int setId, bool isMultiResolution,
- int dynamicRangeProfile, int streamUseCase) :
+ int dynamicRangeProfile, int streamUseCase,
+ bool deviceTimeBaseIsRealtime, int timestampBase) :
Camera3IOStreamBase(id, type, width, height,
/*maxSize*/0,
format, dataSpace, rotation,
physicalCameraId, sensorPixelModesUsed, setId, isMultiResolution,
- dynamicRangeProfile, streamUseCase),
+ dynamicRangeProfile, streamUseCase, deviceTimeBaseIsRealtime,
+ timestampBase),
mTransform(0),
mTraceFirstBuffer(true),
- mUseMonoTimestamp(false),
mUseBufferManager(false),
mTimestampOffset(timestampOffset),
mConsumerUsage(consumerUsage),
@@ -365,13 +368,10 @@
dumpImageToDisk(timestamp, anwBuffer, anwReleaseFence);
}
- /* Certain consumers (such as AudioSource or HardwareComposer) use
- * MONOTONIC time, causing time misalignment if camera timestamp is
- * in BOOTTIME. Do the conversion if necessary. */
nsecs_t t = mPreviewFrameScheduler != nullptr ? readoutTimestamp : timestamp;
- nsecs_t adjustedTs = mUseMonoTimestamp ? t - mTimestampOffset : t;
+ t -= mTimestampOffset;
if (mPreviewFrameScheduler != nullptr) {
- res = mPreviewFrameScheduler->queuePreviewBuffer(adjustedTs, transform,
+ res = mPreviewFrameScheduler->queuePreviewBuffer(t, transform,
anwBuffer, anwReleaseFence);
if (res != OK) {
ALOGE("%s: Stream %d: Error queuing buffer to preview buffer scheduler: %s (%d)",
@@ -380,7 +380,7 @@
}
} else {
setTransform(transform);
- res = native_window_set_buffers_timestamp(mConsumer.get(), adjustedTs);
+ res = native_window_set_buffers_timestamp(mConsumer.get(), t);
if (res != OK) {
ALOGE("%s: Stream %d: Error setting timestamp: %s (%d)",
__FUNCTION__, mId, strerror(-res), res);
@@ -572,10 +572,18 @@
}
mTotalBufferCount = maxConsumerBuffers + camera_stream::max_buffers;
- if (allowPreviewScheduler && isConsumedByHWComposer()) {
+
+ int timestampBase = getTimestampBase();
+ bool isDefaultTimeBase = (timestampBase ==
+ OutputConfiguration::TIMESTAMP_BASE_DEFAULT);
+ if (allowPreviewScheduler) {
// We cannot distinguish between a SurfaceView and an ImageReader of
// preview buffer format. The PreviewFrameScheduler needs to handle both.
- if (!property_get_bool("camera.disable_preview_scheduler", false)) {
+ bool forceChoreographer = (timestampBase ==
+ OutputConfiguration::TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED);
+ bool defaultToChoreographer = (isDefaultTimeBase && isConsumedByHWComposer() &&
+ !property_get_bool("camera.disable_preview_scheduler", false));
+ if (forceChoreographer || defaultToChoreographer) {
mPreviewFrameScheduler = std::make_unique<PreviewFrameScheduler>(*this, mConsumer);
mTotalBufferCount += PreviewFrameScheduler::kQueueDepthWatermark;
}
@@ -584,7 +592,27 @@
mHandoutTotalBufferCount = 0;
mFrameCount = 0;
mLastTimestamp = 0;
- mUseMonoTimestamp = (isConsumedByHWComposer() || isVideoStream());
+
+ if (isDeviceTimeBaseRealtime()) {
+ if (isDefaultTimeBase && !isConsumedByHWComposer() && !isVideoStream()) {
+ // Default time base, but not hardware composer or video encoder
+ mTimestampOffset = 0;
+ } else if (timestampBase == OutputConfiguration::TIMESTAMP_BASE_REALTIME ||
+ timestampBase == OutputConfiguration::TIMESTAMP_BASE_SENSOR) {
+ mTimestampOffset = 0;
+ }
+ // If timestampBase is CHOREOGRAPHER SYNCED or MONOTONIC, leave
+ // timestamp offset as bootTime - monotonicTime.
+ } else {
+ if (timestampBase == OutputConfiguration::TIMESTAMP_BASE_REALTIME) {
+ // Reverse offset for monotonicTime -> bootTime
+ mTimestampOffset = -mTimestampOffset;
+ } else {
+ // If timestampBase is DEFAULT, MONOTONIC, SENSOR, or
+ // CHOREOGRAPHER_SYNCED, timestamp offset is 0.
+ mTimestampOffset = 0;
+ }
+ }
res = native_window_set_buffer_count(mConsumer.get(),
mTotalBufferCount);