diff --git a/camera/QCamera2/HAL/QCamera2HWI.cpp b/camera/QCamera2/HAL/QCamera2HWI.cpp index 3199311..fd4f2f1 100644 --- a/camera/QCamera2/HAL/QCamera2HWI.cpp +++ b/camera/QCamera2/HAL/QCamera2HWI.cpp @@ -1671,7 +1671,8 @@ QCamera2HardwareInterface::QCamera2HardwareInterface(uint32_t cameraId) mMetadataMem(NULL), mCACDoneReceived(false), m_bNeedRestart(false), - mIgnoredPreviewCount(0) + mIgnoredPreviewCount(0), + mBootToMonoTimestampOffset(0) { #ifdef TARGET_TS_MAKEUP memset(&mFaceRect, -1, sizeof(mFaceRect)); @@ -1959,6 +1960,23 @@ int QCamera2HardwareInterface::openCamera() pthread_mutex_unlock(&gCamLock); } + // Setprop to decide the time source (whether boottime or monotonic). + // By default, use monotonic time. + property_get("persist.camera.time.monotonic", value, "1"); + mBootToMonoTimestampOffset = 0; + if (atoi(value) == 1) { + // if monotonic is set, then need to use time in monotonic. + // So, Measure the clock offset between BOOTTIME and MONOTONIC + // The clock domain source for ISP is BOOTTIME and + // for display is MONOTONIC + // The below offset is used to convert from clock domain of other subsystem + // (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. + mBootToMonoTimestampOffset = getBootToMonoTimeOffset(); + } + LOGH("mBootToMonoTimestampOffset = %lld", mBootToMonoTimestampOffset); + return NO_ERROR; error_exit3: @@ -10075,4 +10093,35 @@ bool QCamera2HardwareInterface::isLowPowerMode() return isLowpower; } +/*=========================================================================== + * FUNCTION : getBootToMonoTimeOffset + * + * DESCRIPTION: Calculate offset that is used to convert from + * clock domain of boot to monotonic + * + * PARAMETERS : + * None + * + * RETURN : clock offset between boottime and monotonic time. + * + *==========================================================================*/ +nsecs_t QCamera2HardwareInterface::getBootToMonoTimeOffset() +{ + // 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; +} + }; // namespace qcamera diff --git a/camera/QCamera2/HAL/QCamera2HWI.h b/camera/QCamera2/HAL/QCamera2HWI.h index 739cba1..9c1506f 100644 --- a/camera/QCamera2/HAL/QCamera2HWI.h +++ b/camera/QCamera2/HAL/QCamera2HWI.h @@ -382,6 +382,7 @@ private: QCameraExif *getExifData(); cam_sensor_t getSensorType(); bool isLowPowerMode(); + nsecs_t getBootToMonoTimeOffset(); int32_t processAutoFocusEvent(cam_auto_focus_data_t &focus_data); int32_t processZoomEvent(cam_crop_data_t &crop_info); @@ -765,7 +766,9 @@ private: Mutex mMapLock; Condition mMapCond; // Count to determine the number of preview frames ignored for displaying. - uint8_t mIgnoredPreviewCount; + uint8_t mIgnoredPreviewCount; + //The offset between BOOTTIME and MONOTONIC timestamps + nsecs_t mBootToMonoTimestampOffset; }; }; // namespace qcamera diff --git a/camera/QCamera2/HAL/QCamera2HWICallbacks.cpp b/camera/QCamera2/HAL/QCamera2HWICallbacks.cpp index 5308df5..7c59bff 100644 --- a/camera/QCamera2/HAL/QCamera2HWICallbacks.cpp +++ b/camera/QCamera2/HAL/QCamera2HWICallbacks.cpp @@ -734,6 +734,9 @@ void QCamera2HardwareInterface::synchronous_stream_cb_routine( } frameTime = nsecs_t(frame->ts.tv_sec) * 1000000000LL + frame->ts.tv_nsec; + // Convert Boottime from camera to Monotime for display if needed. + // Otherwise, mBootToMonoTimestampOffset value will be 0. + frameTime = frameTime - pme->mBootToMonoTimestampOffset; // Calculate the future presentation time stamp for displaying frames at regular interval //mPreviewTimestamp = pme->mCameraDisplay.computePresentationTimeStamp(frameTime); stream->mStreamTimestamp = frameTime; @@ -1538,6 +1541,11 @@ void QCamera2HardwareInterface::video_stream_cb_routine(mm_camera_super_buf_t *s cbArg.cb_type = QCAMERA_DATA_TIMESTAMP_CALLBACK; cbArg.msg_type = CAMERA_MSG_VIDEO_FRAME; cbArg.data = video_mem; + + // Convert Boottime from camera to Monotime for video if needed. + // Otherwise, mBootToMonoTimestampOffset value will be 0. + timeStamp = timeStamp - pme->mBootToMonoTimestampOffset; + LOGD("Final video buffer TimeStamp : %lld ", timeStamp); cbArg.timestamp = timeStamp; int32_t rc = pme->m_cbNotifier.notifyCallback(cbArg); if (rc != NO_ERROR) { diff --git a/camera/QCamera2/HAL3/QCamera3HWI.cpp b/camera/QCamera2/HAL3/QCamera3HWI.cpp index ebb58f4..61e40cc 100644 --- a/camera/QCamera2/HAL3/QCamera3HWI.cpp +++ b/camera/QCamera2/HAL3/QCamera3HWI.cpp @@ -63,6 +63,8 @@ namespace qcamera { #define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX ) +#define TIME_SOURCE ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN + #define EMPTY_PIPELINE_DELAY 2 #define PARTIAL_RESULT_COUNT 2 #define FRAME_SKIP_DELAY 0 @@ -361,7 +363,9 @@ QCamera3HardwareInterface::QCamera3HardwareInterface(uint32_t cameraId, mLdafCalibExist(false), mPowerHintEnabled(false), mLastCustIntentFrmNum(-1), - mState(CLOSED) + mState(CLOSED), + mBootToMonoTimestampOffset(0), + mUseAVTimer(false) { getLogLevel(); m_perfLock.lock_init(); @@ -730,6 +734,23 @@ int QCamera3HardwareInterface::openCamera() pthread_mutex_unlock(&gCamLock); } + // Setprop to decide the time source (whether boottime or monotonic). + // By default, use monotonic time. + property_get("persist.camera.time.monotonic", value, "1"); + mBootToMonoTimestampOffset = 0; + if (atoi(value) == 1) { + // if monotonic is set, then need to use time in monotonic. + // So, Measure the clock offset between BOOTTIME and MONOTONIC + // The clock domain source for ISP is BOOTTIME and + // for display is MONOTONIC + // The below offset is used to convert from clock domain of other subsystem + // (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. + mBootToMonoTimestampOffset = getBootToMonoTimeOffset(); + } + LOGH("mBootToMonoTimestampOffset = %lld", mBootToMonoTimestampOffset); + return NO_ERROR; } @@ -2615,6 +2636,12 @@ void QCamera3HardwareInterface::handleMetadataWithLock( uint32_t frame_number, urgent_frame_number; int64_t capture_time; + // Convert Boottime from camera to Monotime except for VT usecase where AVTimer is used. + uint8_t timestampSource = TIME_SOURCE; + nsecs_t timeOffset = mBootToMonoTimestampOffset; + if (mUseAVTimer || (ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN != timestampSource)) + timeOffset = 0; + int32_t *p_frame_number_valid = POINTER_OF_META(CAM_INTF_META_FRAME_NUMBER_VALID, metadata); uint32_t *p_frame_number = POINTER_OF_META(CAM_INTF_META_FRAME_NUMBER, metadata); @@ -2640,7 +2667,7 @@ void QCamera3HardwareInterface::handleMetadataWithLock( } else { frame_number_valid = *p_frame_number_valid; frame_number = *p_frame_number; - capture_time = *p_capture_time; + capture_time = *p_capture_time - timeOffset; urgent_frame_number_valid = *p_urgent_frame_number_valid; urgent_frame_number = *p_urgent_frame_number; } @@ -3367,6 +3394,7 @@ int QCamera3HardwareInterface::processCaptureRequest( LOGE("Failed to disable CDS for HFR mode"); } + setMobicat(); /* Set fps and hfr mode while sending meta stream info so that sensor @@ -6258,7 +6286,7 @@ int QCamera3HardwareInterface::initStaticMetadata(uint32_t cameraId) staticInfo.update(ANDROID_TONEMAP_MAX_CURVE_POINTS, &gCamCapability[cameraId]->max_tone_map_curve_points, 1); - uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN; + uint8_t timestampSource = TIME_SOURCE; staticInfo.update(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE, ×tampSource, 1); @@ -10109,4 +10137,35 @@ int32_t QCamera3HardwareInterface::setBundleInfo() return rc; } +/*=========================================================================== + * FUNCTION : getBootToMonoTimeOffset + * + * DESCRIPTION: Calculate offset that is used to convert from + * clock domain of boot to monotonic + * + * PARAMETERS : + * None + * + * RETURN : clock offset between boottime and monotonic time. + * + *==========================================================================*/ +nsecs_t QCamera3HardwareInterface::getBootToMonoTimeOffset() +{ + // 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; +} + }; //end namespace qcamera diff --git a/camera/QCamera2/HAL3/QCamera3HWI.h b/camera/QCamera2/HAL3/QCamera3HWI.h index b444e72..6cf6b5d 100644 --- a/camera/QCamera2/HAL3/QCamera3HWI.h +++ b/camera/QCamera2/HAL3/QCamera3HWI.h @@ -64,7 +64,6 @@ using ::android::hardware::camera::common::V1_0::helper::CameraMetadata; #endif /* Time related macros */ -typedef int64_t nsecs_t; #define NSEC_PER_SEC 1000000000LLU #define NSEC_PER_USEC 1000LLU #define NSEC_PER_33MSEC 33000000LLU @@ -292,6 +291,7 @@ private: int32_t notifyErrorForPendingRequests(); int32_t getReprocessibleOutputStreamId(uint32_t &id); int32_t handleCameraDeviceError(); + nsecs_t getBootToMonoTimeOffset(); bool isOnEncoder(const cam_dimension_t max_viewfinder_size, uint32_t width, uint32_t height); @@ -497,6 +497,9 @@ private: uint32_t mSurfaceStridePadding; State mState; + //The offset between BOOTTIME and MONOTONIC timestamps + nsecs_t mBootToMonoTimestampOffset; + bool mUseAVTimer; }; }; // namespace qcamera diff --git a/vendor_prop.mk b/vendor_prop.mk index bcb0091..c7418c2 100644 --- a/vendor_prop.mk +++ b/vendor_prop.mk @@ -16,7 +16,7 @@ # Camera PRODUCT_PROPERTY_OVERRIDES += \ - media.camera.ts.monotonic=0 + media.camera.ts.monotonic=1 # Properties PRODUCT_PROPERTY_OVERRIDES += \