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/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 11fa991..d26b730 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -861,6 +861,7 @@
bool isMultiResolution = outputConfiguration.isMultiResolution();
int dynamicRangeProfile = outputConfiguration.getDynamicRangeProfile();
int streamUseCase = outputConfiguration.getStreamUseCase();
+ int timestampBase = outputConfiguration.getTimestampBase();
res = SessionConfigurationUtils::checkSurfaceType(numBufferProducers, deferredConsumer,
outputConfiguration.getSurfaceType());
@@ -905,7 +906,7 @@
res = SessionConfigurationUtils::createSurfaceFromGbp(streamInfo,
isStreamInfoValid, surface, bufferProducer, mCameraIdStr,
mDevice->infoPhysical(physicalCameraId), sensorPixelModesUsed, dynamicRangeProfile,
- streamUseCase);
+ streamUseCase, timestampBase);
if (!res.isOk())
return res;
@@ -951,7 +952,8 @@
static_cast<camera_stream_rotation_t>(outputConfiguration.getRotation()),
&streamId, physicalCameraId, streamInfo.sensorPixelModesUsed, &surfaceIds,
outputConfiguration.getSurfaceSetID(), isShared, isMultiResolution,
- /*consumerUsage*/0, streamInfo.dynamicRangeProfile, streamInfo.streamUseCase);
+ /*consumerUsage*/0, streamInfo.dynamicRangeProfile, streamInfo.streamUseCase,
+ streamInfo.timestampBase);
}
if (err != OK) {
@@ -1062,7 +1064,8 @@
std::forward_as_tuple(width, height, format, dataSpace, consumerUsage,
overriddenSensorPixelModesUsed,
outputConfiguration.getDynamicRangeProfile(),
- outputConfiguration.getStreamUseCase()));
+ outputConfiguration.getStreamUseCase(),
+ outputConfiguration.getTimestampBase()));
ALOGV("%s: Camera %s: Successfully created a new stream ID %d for a deferred surface"
" (%d x %d) stream with format 0x%x.",
@@ -1251,7 +1254,7 @@
const std::vector<int32_t> &sensorPixelModesUsed =
outputConfiguration.getSensorPixelModesUsed();
int streamUseCase = outputConfiguration.getStreamUseCase();
-
+ int timestampBase = outputConfiguration.getTimestampBase();
int dynamicRangeProfile = outputConfiguration.getDynamicRangeProfile();
for (size_t i = 0; i < newOutputsMap.size(); i++) {
@@ -1260,7 +1263,7 @@
res = SessionConfigurationUtils::createSurfaceFromGbp(outInfo,
/*isStreamInfoValid*/ false, surface, newOutputsMap.valueAt(i), mCameraIdStr,
mDevice->infoPhysical(physicalCameraId), sensorPixelModesUsed, dynamicRangeProfile,
- streamUseCase);
+ streamUseCase, timestampBase);
if (!res.isOk())
return res;
@@ -1619,6 +1622,7 @@
outputConfiguration.getSensorPixelModesUsed();
int dynamicRangeProfile = outputConfiguration.getDynamicRangeProfile();
int streamUseCase= outputConfiguration.getStreamUseCase();
+ int timestampBase = outputConfiguration.getTimestampBase();
for (auto& bufferProducer : bufferProducers) {
// Don't create multiple streams for the same target surface
ssize_t index = mStreamMap.indexOfKey(IInterface::asBinder(bufferProducer));
@@ -1632,7 +1636,7 @@
res = SessionConfigurationUtils::createSurfaceFromGbp(mStreamInfoMap[streamId],
true /*isStreamInfoValid*/, surface, bufferProducer, mCameraIdStr,
mDevice->infoPhysical(physicalId), sensorPixelModesUsed, dynamicRangeProfile,
- streamUseCase);
+ streamUseCase, timestampBase);
if (!res.isOk())
return res;
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index 6ddf500..baa21f0 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -184,7 +184,8 @@
bool isShared = false, bool isMultiResolution = false,
uint64_t consumerUsage = 0,
int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
- int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) = 0;
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+ int timestampBase = OutputConfiguration::TIMESTAMP_BASE_DEFAULT) = 0;
/**
* Create an output stream of the requested size, format, rotation and
@@ -203,7 +204,8 @@
bool isShared = false, bool isMultiResolution = false,
uint64_t consumerUsage = 0,
int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
- int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) = 0;
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+ int timestampBase = OutputConfiguration::TIMESTAMP_BASE_DEFAULT) = 0;
/**
* Create an input stream of width, height, and format.
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index c8f6310..f31241c 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -86,6 +86,7 @@
mStatusWaiters(0),
mUsePartialResult(false),
mNumPartialResults(1),
+ mDeviceTimeBaseIsRealtime(false),
mTimestampOffset(0),
mNextResultFrameNumber(0),
mNextReprocessResultFrameNumber(0),
@@ -189,11 +190,12 @@
mIsInputStreamMultiResolution = false;
// Measure the clock domain offset between camera and video/hw_composer
+ mTimestampOffset = getMonoToBoottimeOffset();
camera_metadata_entry timestampSource =
mDeviceInfo.find(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE);
if (timestampSource.count > 0 && timestampSource.data.u8[0] ==
ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME) {
- mTimestampOffset = getMonoToBoottimeOffset();
+ mDeviceTimeBaseIsRealtime = true;
}
// Will the HAL be sending in early partial result metadata?
@@ -978,7 +980,7 @@
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
std::vector<int> *surfaceIds, int streamSetId, bool isShared, bool isMultiResolution,
- uint64_t consumerUsage, int dynamicRangeProfile, int streamUseCase) {
+ uint64_t consumerUsage, int dynamicRangeProfile, int streamUseCase, int timestampBase) {
ATRACE_CALL();
if (consumer == nullptr) {
@@ -992,7 +994,7 @@
return createStream(consumers, /*hasDeferredConsumer*/ false, width, height,
format, dataSpace, rotation, id, physicalCameraId, sensorPixelModesUsed, surfaceIds,
streamSetId, isShared, isMultiResolution, consumerUsage, dynamicRangeProfile,
- streamUseCase);
+ streamUseCase, timestampBase);
}
static bool isRawFormat(int format) {
@@ -1012,16 +1014,18 @@
android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
const String8& physicalCameraId, const std::unordered_set<int32_t> &sensorPixelModesUsed,
std::vector<int> *surfaceIds, int streamSetId, bool isShared, bool isMultiResolution,
- uint64_t consumerUsage, int dynamicRangeProfile, int streamUseCase) {
+ uint64_t consumerUsage, int dynamicRangeProfile, int streamUseCase, int timestampBase) {
ATRACE_CALL();
Mutex::Autolock il(mInterfaceLock);
nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
Mutex::Autolock l(mLock);
ALOGV("Camera %s: Creating new stream %d: %d x %d, format %d, dataspace %d rotation %d"
- " consumer usage %" PRIu64 ", isShared %d, physicalCameraId %s, isMultiResolution %d",
+ " consumer usage %" PRIu64 ", isShared %d, physicalCameraId %s, isMultiResolution %d"
+ " dynamicRangeProfile %d, streamUseCase %d, timestampBase %d",
mId.string(), mNextStreamId, width, height, format, dataSpace, rotation,
- consumerUsage, isShared, physicalCameraId.string(), isMultiResolution);
+ consumerUsage, isShared, physicalCameraId.string(), isMultiResolution,
+ dynamicRangeProfile, streamUseCase, timestampBase);
status_t res;
bool wasActive = false;
@@ -1090,7 +1094,8 @@
newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
width, height, blobBufferSize, format, dataSpace, rotation,
mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
- isMultiResolution, dynamicRangeProfile, streamUseCase);
+ isMultiResolution, dynamicRangeProfile, streamUseCase, mDeviceTimeBaseIsRealtime,
+ timestampBase);
} else if (format == HAL_PIXEL_FORMAT_RAW_OPAQUE) {
bool maxResolution =
sensorPixelModesUsed.find(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) !=
@@ -1104,22 +1109,26 @@
newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
width, height, rawOpaqueBufferSize, format, dataSpace, rotation,
mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
- isMultiResolution, dynamicRangeProfile, streamUseCase);
+ isMultiResolution, dynamicRangeProfile, streamUseCase, mDeviceTimeBaseIsRealtime,
+ timestampBase);
} else if (isShared) {
newStream = new Camera3SharedOutputStream(mNextStreamId, consumers,
width, height, format, consumerUsage, dataSpace, rotation,
mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
- mUseHalBufManager, dynamicRangeProfile, streamUseCase);
+ mUseHalBufManager, dynamicRangeProfile, streamUseCase, mDeviceTimeBaseIsRealtime,
+ timestampBase);
} else if (consumers.size() == 0 && hasDeferredConsumer) {
newStream = new Camera3OutputStream(mNextStreamId,
width, height, format, consumerUsage, dataSpace, rotation,
mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
- isMultiResolution, dynamicRangeProfile, streamUseCase);
+ isMultiResolution, dynamicRangeProfile, streamUseCase, mDeviceTimeBaseIsRealtime,
+ timestampBase);
} else {
newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
width, height, format, dataSpace, rotation,
mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
- isMultiResolution, dynamicRangeProfile, streamUseCase);
+ isMultiResolution, dynamicRangeProfile, streamUseCase, mDeviceTimeBaseIsRealtime,
+ timestampBase);
}
size_t consumerCount = consumers.size();
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index d466ae4..0f5e65b 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -135,7 +135,8 @@
uint64_t consumerUsage = 0,
int dynamicRangeProfile =
ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
- int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) override;
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+ int timestampBase = OutputConfiguration::TIMESTAMP_BASE_DEFAULT) override;
status_t createStream(const std::vector<sp<Surface>>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
@@ -148,7 +149,8 @@
uint64_t consumerUsage = 0,
int dynamicRangeProfile =
ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
- int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) override;
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+ int timestampBase = OutputConfiguration::TIMESTAMP_BASE_DEFAULT) override;
status_t createInputStream(
uint32_t width, uint32_t height, int format, bool isMultiResolution,
@@ -526,6 +528,7 @@
/**** End scope for mLock ****/
+ bool mDeviceTimeBaseIsRealtime;
// The offset converting from clock domain of other subsystem
// (video/hardware composer) to that of camera. Assumption is that this
// offset won't change during the life cycle of the camera device. In other
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
index dc3a6f3..f737ed6 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
@@ -34,11 +34,12 @@
android_dataspace dataSpace, camera_stream_rotation_t rotation,
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
- int setId, bool isMultiResolution, int dynamicRangeProfile, int streamUseCase) :
+ int setId, bool isMultiResolution, int dynamicRangeProfile, int streamUseCase,
+ bool deviceTimeBaseIsRealtime, int timestampBase) :
Camera3Stream(id, type,
width, height, maxSize, format, dataSpace, rotation,
physicalCameraId, sensorPixelModesUsed, setId, isMultiResolution,
- dynamicRangeProfile, streamUseCase),
+ dynamicRangeProfile, streamUseCase, deviceTimeBaseIsRealtime, timestampBase),
mTotalBufferCount(0),
mHandoutTotalBufferCount(0),
mHandoutOutputBufferCount(0),
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
index f2b1536..300f207 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
@@ -39,7 +39,9 @@
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
- int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+ bool deviceTimeBaseIsRealtime = false,
+ int timestampBase = OutputConfiguration::TIMESTAMP_BASE_DEFAULT);
public:
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);
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index 7d2d32e..c7910b7 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -91,7 +91,9 @@
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
- int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+ bool deviceTimeBaseIsRealtime = false,
+ int timestampBase = OutputConfiguration::TIMESTAMP_BASE_DEFAULT);
/**
* Set up a stream for formats that have a variable buffer size for the same
* dimensions, such as compressed JPEG.
@@ -105,7 +107,9 @@
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
- int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+ bool deviceTimeBaseIsRealtime = false,
+ int timestampBase = OutputConfiguration::TIMESTAMP_BASE_DEFAULT);
/**
* Set up a stream with deferred consumer for formats that have 2 dimensions, such as
* RAW and YUV. The consumer must be set before using this stream for output. A valid
@@ -118,7 +122,9 @@
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
- int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+ bool deviceTimeBaseIsRealtime = false,
+ int timestampBase = OutputConfiguration::TIMESTAMP_BASE_DEFAULT);
virtual ~Camera3OutputStream();
@@ -247,7 +253,9 @@
uint64_t consumerUsage = 0, nsecs_t timestampOffset = 0,
int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false,
int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
- int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+ bool deviceTimeBaseIsRealtime = false,
+ int timestampBase = OutputConfiguration::TIMESTAMP_BASE_DEFAULT);
/**
* Note that we release the lock briefly in this function
@@ -289,9 +297,6 @@
// Name of Surface consumer
String8 mConsumerName;
- // Whether consumer assumes MONOTONIC timestamp
- bool mUseMonoTimestamp;
-
/**
* GraphicBuffer manager this stream is registered to. Used to replace the buffer
* allocation/deallocation role of BufferQueue.
@@ -310,7 +315,11 @@
bool mUseBufferManager;
/**
- * Timestamp offset for video and hardware composer consumed streams
+ * Offset used to override camera HAL produced timestamps
+ *
+ * The offset is first initialized to bootTime - monotonicTime in
+ * constructor, and may later be updated based on the client's timestampBase
+ * setting.
*/
nsecs_t mTimestampOffset;
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
index fbd1e56..047897e 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
@@ -34,11 +34,11 @@
nsecs_t timestampOffset, const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId, bool useHalBufManager, int dynamicProfile,
- int streamUseCase) :
+ int streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase) :
Camera3OutputStream(id, CAMERA_STREAM_OUTPUT, width, height,
format, dataSpace, rotation, physicalCameraId, sensorPixelModesUsed,
consumerUsage, timestampOffset, setId, /*isMultiResolution*/false,
- dynamicProfile, streamUseCase),
+ dynamicProfile, streamUseCase, deviceTimeBaseIsRealtime, timestampBase),
mUseHalBufManager(useHalBufManager) {
size_t consumerCount = std::min(surfaces.size(), kMaxOutputs);
if (surfaces.size() > consumerCount) {
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
index 223d52b..dc22c42 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
@@ -42,7 +42,9 @@
int setId = CAMERA3_STREAM_SET_ID_INVALID,
bool useHalBufManager = false,
int dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
- int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
+ int streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+ bool deviceTimeBaseIsRealtime = false,
+ int timestampBase = OutputConfiguration::TIMESTAMP_BASE_DEFAULT);
virtual ~Camera3SharedOutputStream();
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index 6b093b3..3f0299b 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -55,7 +55,7 @@
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId, bool isMultiResolution, int dynamicRangeProfile,
- int streamUseCase) :
+ int streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase) :
camera_stream(),
mId(id),
mSetId(setId),
@@ -80,7 +80,9 @@
mOriginalDataSpace(dataSpace),
mPhysicalCameraId(physicalCameraId),
mLastTimestamp(0),
- mIsMultiResolution(isMultiResolution) {
+ mIsMultiResolution(isMultiResolution),
+ mDeviceTimeBaseIsRealtime(deviceTimeBaseIsRealtime),
+ mTimestampBase(timestampBase) {
camera_stream::stream_type = type;
camera_stream::width = width;
@@ -181,6 +183,14 @@
return camera_stream::use_case;
}
+int Camera3Stream::getTimestampBase() const {
+ return mTimestampBase;
+}
+
+bool Camera3Stream::isDeviceTimeBaseRealtime() const {
+ return mDeviceTimeBaseIsRealtime;
+}
+
void Camera3Stream::setOfflineProcessingSupport(bool support) {
mSupportOfflineProcessing = support;
}
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h
index ada570b..8232ce0 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.h
+++ b/services/camera/libcameraservice/device3/Camera3Stream.h
@@ -179,6 +179,8 @@
int getMaxHalBuffers() const;
const String8& physicalCameraId() const;
int getStreamUseCase() const;
+ int getTimestampBase() const;
+ bool isDeviceTimeBaseRealtime() const;
void setOfflineProcessingSupport(bool) override;
bool getOfflineProcessingSupport() const override;
@@ -507,7 +509,7 @@
const String8& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
int setId, bool isMultiResolution, int dynamicRangeProfile,
- int streamUseCase);
+ int streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase);
wp<Camera3StreamBufferFreedListener> mBufferFreedListener;
@@ -630,6 +632,9 @@
bool mIsMultiResolution = false;
bool mSupportOfflineProcessing = false;
+
+ bool mDeviceTimeBaseIsRealtime;
+ int mTimestampBase;
}; // class Camera3Stream
}; // namespace camera3
diff --git a/services/camera/libcameraservice/device3/Camera3StreamInterface.h b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
index 7b1597b..8962fac 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
@@ -19,6 +19,7 @@
#include <utils/RefBase.h>
+#include <camera/camera2/OutputConfiguration.h>
#include <camera/CameraMetadata.h>
#include "Camera3StreamBufferListener.h"
#include "Camera3StreamBufferFreedListener.h"
@@ -111,18 +112,20 @@
std::unordered_set<int32_t> sensorPixelModesUsed;
int dynamicRangeProfile;
int streamUseCase;
+ int timestampBase;
OutputStreamInfo() :
width(-1), height(-1), format(-1), dataSpace(HAL_DATASPACE_UNKNOWN),
consumerUsage(0),
dynamicRangeProfile(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD),
- streamUseCase(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {}
+ streamUseCase(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT),
+ timestampBase(OutputConfiguration::TIMESTAMP_BASE_DEFAULT) {}
OutputStreamInfo(int _width, int _height, int _format, android_dataspace _dataSpace,
uint64_t _consumerUsage, const std::unordered_set<int32_t>& _sensorPixelModesUsed,
- int _dynamicRangeProfile, int _streamUseCase) :
+ int _dynamicRangeProfile, int _streamUseCase, int _timestampBase) :
width(_width), height(_height), format(_format),
dataSpace(_dataSpace), consumerUsage(_consumerUsage),
sensorPixelModesUsed(_sensorPixelModesUsed), dynamicRangeProfile(_dynamicRangeProfile),
- streamUseCase(_streamUseCase) {}
+ streamUseCase(_streamUseCase), timestampBase(_timestampBase) {}
};
/**
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
index 548fb0b..751f24f 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
@@ -334,7 +334,7 @@
sp<Surface>& surface, const sp<IGraphicBufferProducer>& gbp,
const String8 &logicalCameraId, const CameraMetadata &physicalCameraMetadata,
const std::vector<int32_t> &sensorPixelModesUsed, int dynamicRangeProfile,
- int streamUseCase) {
+ int streamUseCase, int timestampBase) {
// bufferProducer must be non-null
if (gbp == nullptr) {
String8 msg = String8::format("Camera %s: Surface is NULL", logicalCameraId.string());
@@ -454,6 +454,13 @@
ALOGE("%s: %s", __FUNCTION__, msg.string());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
}
+ if (timestampBase < OutputConfiguration::TIMESTAMP_BASE_DEFAULT ||
+ timestampBase > OutputConfiguration::TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED) {
+ String8 msg = String8::format("Camera %s: invalid timestamp base %d",
+ logicalCameraId.string(), timestampBase);
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ }
if (!isStreamInfoValid) {
streamInfo.width = width;
@@ -464,6 +471,7 @@
streamInfo.sensorPixelModesUsed = overriddenSensorPixelModes;
streamInfo.dynamicRangeProfile = dynamicRangeProfile;
streamInfo.streamUseCase = streamUseCase;
+ streamInfo.timestampBase = timestampBase;
return binder::Status::ok();
}
if (width != streamInfo.width) {
@@ -697,6 +705,7 @@
}
int streamUseCase = it.getStreamUseCase();
+ int timestampBase = it.getTimestampBase();
if (deferredConsumer) {
streamInfo.width = it.getWidth();
streamInfo.height = it.getHeight();
@@ -731,7 +740,7 @@
sp<Surface> surface;
res = createSurfaceFromGbp(streamInfo, isStreamInfoValid, surface, bufferProducer,
logicalCameraId, metadataChosen, sensorPixelModesUsed, dynamicRangeProfile,
- streamUseCase);
+ streamUseCase, timestampBase);
if (!res.isOk())
return res;
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
index 8dfc11d..3dcbdbc 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
@@ -98,7 +98,7 @@
sp<Surface>& surface, const sp<IGraphicBufferProducer>& gbp,
const String8 &logicalCameraId, const CameraMetadata &physicalCameraMetadata,
const std::vector<int32_t> &sensorPixelModesUsed, int dynamicRangeProfile,
- int streamUseCase);
+ int streamUseCase, int timestampBase);
void mapStreamInfo(const camera3::OutputStreamInfo &streamInfo,
camera3::camera_stream_rotation_t rotation, String8 physicalId, int32_t groupId,