Loading services/camera/libcameraservice/device3/Camera3Device.cpp +33 −3 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ Camera3Device::Camera3Device(int id): mStatusWaiters(0), mUsePartialResult(false), mNumPartialResults(1), mTimestampOffset(0), mNextResultFrameNumber(0), mNextReprocessResultFrameNumber(0), mNextShutterFrameNumber(0), Loading Loading @@ -204,6 +205,14 @@ status_t Camera3Device::initialize(CameraModule *module) mNeedConfig = true; mPauseStateNotify = false; // Measure the clock domain offset between camera and video/hw_composer 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(); } // Will the HAL be sending in early partial result metadata? if (mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_2) { camera_metadata_entry partialResultsCount = Loading Loading @@ -382,6 +391,24 @@ Camera3Device::Size Camera3Device::getMaxJpegResolution() const { return Size(maxJpegWidth, maxJpegHeight); } nsecs_t Camera3Device::getMonoToBoottimeOffset() { // try three times to get the clock offset, choose the one // with the minimum gap in measurements. const int tries = 3; nsecs_t bestGap, measured; for (int i = 0; i < tries; ++i) { const nsecs_t tmono = systemTime(SYSTEM_TIME_MONOTONIC); const nsecs_t tbase = systemTime(SYSTEM_TIME_BOOTTIME); const nsecs_t tmono2 = systemTime(SYSTEM_TIME_MONOTONIC); const nsecs_t gap = tmono2 - tmono; if (i == 0 || gap < bestGap) { bestGap = gap; measured = tbase - ((tmono + tmono2) >> 1); } } return measured; } ssize_t Camera3Device::getJpegBufferSize(uint32_t width, uint32_t height) const { // Get max jpeg size (area-wise). Size maxJpegResolution = getMaxJpegResolution(); Loading Loading @@ -992,7 +1019,8 @@ status_t Camera3Device::createStream(sp<Surface> consumer, } } newStream = new Camera3OutputStream(mNextStreamId, consumer, width, height, blobBufferSize, format, dataSpace, rotation, streamSetId); width, height, blobBufferSize, format, dataSpace, rotation, mTimestampOffset, streamSetId); } else if (format == HAL_PIXEL_FORMAT_RAW_OPAQUE) { ssize_t rawOpaqueBufferSize = getRawOpaqueBufferSize(width, height); if (rawOpaqueBufferSize <= 0) { Loading @@ -1000,10 +1028,12 @@ status_t Camera3Device::createStream(sp<Surface> consumer, return BAD_VALUE; } newStream = new Camera3OutputStream(mNextStreamId, consumer, width, height, rawOpaqueBufferSize, format, dataSpace, rotation, streamSetId); width, height, rawOpaqueBufferSize, format, dataSpace, rotation, mTimestampOffset, streamSetId); } else { newStream = new Camera3OutputStream(mNextStreamId, consumer, width, height, format, dataSpace, rotation, streamSetId); width, height, format, dataSpace, rotation, mTimestampOffset, streamSetId); } newStream->setStatusTracker(mStatusTracker); Loading services/camera/libcameraservice/device3/Camera3Device.h +13 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <utils/Mutex.h> #include <utils/Thread.h> #include <utils/KeyedVector.h> #include <utils/Timers.h> #include <hardware/camera3.h> #include <camera/CaptureResult.h> #include <camera/camera2/ICameraDeviceUser.h> Loading Loading @@ -251,6 +252,12 @@ class Camera3Device : /**** End scope for mLock ****/ // 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 // words, camera device shouldn't be open during CPU suspend. nsecs_t mTimestampOffset; typedef struct AeTriggerCancelOverride { bool applyAeLock; uint8_t aeLock; Loading Loading @@ -392,6 +399,12 @@ class Camera3Device : */ Size getMaxJpegResolution() const; /** * Helper function to get the offset between MONOTONIC and BOOTTIME * timestamp. */ static nsecs_t getMonoToBoottimeOffset(); struct RequestTrigger { // Metadata tag number, e.g. android.control.aePrecaptureTrigger uint32_t metadataTag; Loading services/camera/libcameraservice/device3/Camera3OutputStream.cpp +18 −16 Original line number Diff line number Diff line Loading @@ -34,14 +34,15 @@ namespace camera3 { Camera3OutputStream::Camera3OutputStream(int id, sp<Surface> consumer, uint32_t width, uint32_t height, int format, android_dataspace dataSpace, camera3_stream_rotation_t rotation, int setId) : android_dataspace dataSpace, camera3_stream_rotation_t rotation, nsecs_t timestampOffset, int setId) : Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height, /*maxSize*/0, format, dataSpace, rotation, setId), mConsumer(consumer), mTransform(0), mTraceFirstBuffer(true), mTimestampBuffer(true), mUseBufferManager(false) { mUseBufferManager(false), mTimestampOffset(timestampOffset) { if (mConsumer == NULL) { ALOGE("%s: Consumer is NULL!", __FUNCTION__); Loading @@ -56,14 +57,16 @@ Camera3OutputStream::Camera3OutputStream(int id, Camera3OutputStream::Camera3OutputStream(int id, sp<Surface> consumer, uint32_t width, uint32_t height, size_t maxSize, int format, android_dataspace dataSpace, camera3_stream_rotation_t rotation, int setId) : android_dataspace dataSpace, camera3_stream_rotation_t rotation, nsecs_t timestampOffset, int setId) : Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height, maxSize, format, dataSpace, rotation, setId), mConsumer(consumer), mTransform(0), mTraceFirstBuffer(true), mTimestampBuffer(true), mUseBufferManager(false) { mUseMonoTimestamp(false), mUseBufferManager(false), mTimestampOffset(timestampOffset) { if (format != HAL_PIXEL_FORMAT_BLOB && format != HAL_PIXEL_FORMAT_RAW_OPAQUE) { ALOGE("%s: Bad format for size-only stream: %d", __FUNCTION__, Loading Loading @@ -92,6 +95,7 @@ Camera3OutputStream::Camera3OutputStream(int id, camera3_stream_type_t type, format, dataSpace, rotation, setId), mTransform(0), mTraceFirstBuffer(true), mUseMonoTimestamp(false), mUseBufferManager(false) { if (setId > CAMERA3_STREAM_SET_ID_INVALID) { Loading Loading @@ -237,16 +241,14 @@ status_t Camera3OutputStream::returnBufferCheckedLocked( /* 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); * in BOOTTIME. Do the conversion if necessary. */ res = native_window_set_buffers_timestamp(mConsumer.get(), mUseMonoTimestamp ? timestamp - mTimestampOffset : 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), Loading Loading @@ -398,7 +400,7 @@ status_t Camera3OutputStream::configureQueueLocked() { mHandoutTotalBufferCount = 0; mFrameCount = 0; mLastTimestamp = 0; mTimestampBuffer = !(isConsumedByHWComposer() | isVideoStream()); mUseMonoTimestamp = (isConsumedByHWComposer() | isVideoStream()); res = native_window_set_buffer_count(mConsumer.get(), mTotalBufferCount); Loading services/camera/libcameraservice/device3/Camera3OutputStream.h +10 −4 Original line number Diff line number Diff line Loading @@ -81,7 +81,7 @@ class Camera3OutputStream : Camera3OutputStream(int id, sp<Surface> consumer, uint32_t width, uint32_t height, int format, android_dataspace dataSpace, camera3_stream_rotation_t rotation, int setId = CAMERA3_STREAM_SET_ID_INVALID); nsecs_t timestampOffset, int setId = CAMERA3_STREAM_SET_ID_INVALID); /** * Set up a stream for formats that have a variable buffer size for the same Loading @@ -92,7 +92,7 @@ class Camera3OutputStream : Camera3OutputStream(int id, sp<Surface> consumer, uint32_t width, uint32_t height, size_t maxSize, int format, android_dataspace dataSpace, camera3_stream_rotation_t rotation, int setId = CAMERA3_STREAM_SET_ID_INVALID); nsecs_t timestampOffset, int setId = CAMERA3_STREAM_SET_ID_INVALID); virtual ~Camera3OutputStream(); Loading Loading @@ -167,8 +167,8 @@ class Camera3OutputStream : // Name of Surface consumer String8 mConsumerName; // Whether to timestamp the output buffer bool mTimestampBuffer; // Whether consumer assumes MONOTONIC timestamp bool mUseMonoTimestamp; /** * GraphicBuffer manager this stream is registered to. Used to replace the buffer Loading @@ -186,6 +186,12 @@ class Camera3OutputStream : * Flag indicating if the buffer manager is used to allocate the stream buffers */ bool mUseBufferManager; /** * Timestamp offset for video and hardware composer consumed streams */ nsecs_t mTimestampOffset; /** * Internal Camera3Stream interface */ Loading Loading
services/camera/libcameraservice/device3/Camera3Device.cpp +33 −3 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ Camera3Device::Camera3Device(int id): mStatusWaiters(0), mUsePartialResult(false), mNumPartialResults(1), mTimestampOffset(0), mNextResultFrameNumber(0), mNextReprocessResultFrameNumber(0), mNextShutterFrameNumber(0), Loading Loading @@ -204,6 +205,14 @@ status_t Camera3Device::initialize(CameraModule *module) mNeedConfig = true; mPauseStateNotify = false; // Measure the clock domain offset between camera and video/hw_composer 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(); } // Will the HAL be sending in early partial result metadata? if (mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_2) { camera_metadata_entry partialResultsCount = Loading Loading @@ -382,6 +391,24 @@ Camera3Device::Size Camera3Device::getMaxJpegResolution() const { return Size(maxJpegWidth, maxJpegHeight); } nsecs_t Camera3Device::getMonoToBoottimeOffset() { // try three times to get the clock offset, choose the one // with the minimum gap in measurements. const int tries = 3; nsecs_t bestGap, measured; for (int i = 0; i < tries; ++i) { const nsecs_t tmono = systemTime(SYSTEM_TIME_MONOTONIC); const nsecs_t tbase = systemTime(SYSTEM_TIME_BOOTTIME); const nsecs_t tmono2 = systemTime(SYSTEM_TIME_MONOTONIC); const nsecs_t gap = tmono2 - tmono; if (i == 0 || gap < bestGap) { bestGap = gap; measured = tbase - ((tmono + tmono2) >> 1); } } return measured; } ssize_t Camera3Device::getJpegBufferSize(uint32_t width, uint32_t height) const { // Get max jpeg size (area-wise). Size maxJpegResolution = getMaxJpegResolution(); Loading Loading @@ -992,7 +1019,8 @@ status_t Camera3Device::createStream(sp<Surface> consumer, } } newStream = new Camera3OutputStream(mNextStreamId, consumer, width, height, blobBufferSize, format, dataSpace, rotation, streamSetId); width, height, blobBufferSize, format, dataSpace, rotation, mTimestampOffset, streamSetId); } else if (format == HAL_PIXEL_FORMAT_RAW_OPAQUE) { ssize_t rawOpaqueBufferSize = getRawOpaqueBufferSize(width, height); if (rawOpaqueBufferSize <= 0) { Loading @@ -1000,10 +1028,12 @@ status_t Camera3Device::createStream(sp<Surface> consumer, return BAD_VALUE; } newStream = new Camera3OutputStream(mNextStreamId, consumer, width, height, rawOpaqueBufferSize, format, dataSpace, rotation, streamSetId); width, height, rawOpaqueBufferSize, format, dataSpace, rotation, mTimestampOffset, streamSetId); } else { newStream = new Camera3OutputStream(mNextStreamId, consumer, width, height, format, dataSpace, rotation, streamSetId); width, height, format, dataSpace, rotation, mTimestampOffset, streamSetId); } newStream->setStatusTracker(mStatusTracker); Loading
services/camera/libcameraservice/device3/Camera3Device.h +13 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <utils/Mutex.h> #include <utils/Thread.h> #include <utils/KeyedVector.h> #include <utils/Timers.h> #include <hardware/camera3.h> #include <camera/CaptureResult.h> #include <camera/camera2/ICameraDeviceUser.h> Loading Loading @@ -251,6 +252,12 @@ class Camera3Device : /**** End scope for mLock ****/ // 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 // words, camera device shouldn't be open during CPU suspend. nsecs_t mTimestampOffset; typedef struct AeTriggerCancelOverride { bool applyAeLock; uint8_t aeLock; Loading Loading @@ -392,6 +399,12 @@ class Camera3Device : */ Size getMaxJpegResolution() const; /** * Helper function to get the offset between MONOTONIC and BOOTTIME * timestamp. */ static nsecs_t getMonoToBoottimeOffset(); struct RequestTrigger { // Metadata tag number, e.g. android.control.aePrecaptureTrigger uint32_t metadataTag; Loading
services/camera/libcameraservice/device3/Camera3OutputStream.cpp +18 −16 Original line number Diff line number Diff line Loading @@ -34,14 +34,15 @@ namespace camera3 { Camera3OutputStream::Camera3OutputStream(int id, sp<Surface> consumer, uint32_t width, uint32_t height, int format, android_dataspace dataSpace, camera3_stream_rotation_t rotation, int setId) : android_dataspace dataSpace, camera3_stream_rotation_t rotation, nsecs_t timestampOffset, int setId) : Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height, /*maxSize*/0, format, dataSpace, rotation, setId), mConsumer(consumer), mTransform(0), mTraceFirstBuffer(true), mTimestampBuffer(true), mUseBufferManager(false) { mUseBufferManager(false), mTimestampOffset(timestampOffset) { if (mConsumer == NULL) { ALOGE("%s: Consumer is NULL!", __FUNCTION__); Loading @@ -56,14 +57,16 @@ Camera3OutputStream::Camera3OutputStream(int id, Camera3OutputStream::Camera3OutputStream(int id, sp<Surface> consumer, uint32_t width, uint32_t height, size_t maxSize, int format, android_dataspace dataSpace, camera3_stream_rotation_t rotation, int setId) : android_dataspace dataSpace, camera3_stream_rotation_t rotation, nsecs_t timestampOffset, int setId) : Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height, maxSize, format, dataSpace, rotation, setId), mConsumer(consumer), mTransform(0), mTraceFirstBuffer(true), mTimestampBuffer(true), mUseBufferManager(false) { mUseMonoTimestamp(false), mUseBufferManager(false), mTimestampOffset(timestampOffset) { if (format != HAL_PIXEL_FORMAT_BLOB && format != HAL_PIXEL_FORMAT_RAW_OPAQUE) { ALOGE("%s: Bad format for size-only stream: %d", __FUNCTION__, Loading Loading @@ -92,6 +95,7 @@ Camera3OutputStream::Camera3OutputStream(int id, camera3_stream_type_t type, format, dataSpace, rotation, setId), mTransform(0), mTraceFirstBuffer(true), mUseMonoTimestamp(false), mUseBufferManager(false) { if (setId > CAMERA3_STREAM_SET_ID_INVALID) { Loading Loading @@ -237,16 +241,14 @@ status_t Camera3OutputStream::returnBufferCheckedLocked( /* 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); * in BOOTTIME. Do the conversion if necessary. */ res = native_window_set_buffers_timestamp(mConsumer.get(), mUseMonoTimestamp ? timestamp - mTimestampOffset : 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), Loading Loading @@ -398,7 +400,7 @@ status_t Camera3OutputStream::configureQueueLocked() { mHandoutTotalBufferCount = 0; mFrameCount = 0; mLastTimestamp = 0; mTimestampBuffer = !(isConsumedByHWComposer() | isVideoStream()); mUseMonoTimestamp = (isConsumedByHWComposer() | isVideoStream()); res = native_window_set_buffer_count(mConsumer.get(), mTotalBufferCount); Loading
services/camera/libcameraservice/device3/Camera3OutputStream.h +10 −4 Original line number Diff line number Diff line Loading @@ -81,7 +81,7 @@ class Camera3OutputStream : Camera3OutputStream(int id, sp<Surface> consumer, uint32_t width, uint32_t height, int format, android_dataspace dataSpace, camera3_stream_rotation_t rotation, int setId = CAMERA3_STREAM_SET_ID_INVALID); nsecs_t timestampOffset, int setId = CAMERA3_STREAM_SET_ID_INVALID); /** * Set up a stream for formats that have a variable buffer size for the same Loading @@ -92,7 +92,7 @@ class Camera3OutputStream : Camera3OutputStream(int id, sp<Surface> consumer, uint32_t width, uint32_t height, size_t maxSize, int format, android_dataspace dataSpace, camera3_stream_rotation_t rotation, int setId = CAMERA3_STREAM_SET_ID_INVALID); nsecs_t timestampOffset, int setId = CAMERA3_STREAM_SET_ID_INVALID); virtual ~Camera3OutputStream(); Loading Loading @@ -167,8 +167,8 @@ class Camera3OutputStream : // Name of Surface consumer String8 mConsumerName; // Whether to timestamp the output buffer bool mTimestampBuffer; // Whether consumer assumes MONOTONIC timestamp bool mUseMonoTimestamp; /** * GraphicBuffer manager this stream is registered to. Used to replace the buffer Loading @@ -186,6 +186,12 @@ class Camera3OutputStream : * Flag indicating if the buffer manager is used to allocate the stream buffers */ bool mUseBufferManager; /** * Timestamp offset for video and hardware composer consumed streams */ nsecs_t mTimestampOffset; /** * Internal Camera3Stream interface */ Loading