| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- #ifndef AVCLOCK_H
- #define AVCLOCK_H
- #include "ffmpeg_compat.h"
- #include "low_latency_config.h"
- class AVClock
- {
- public:
- AVClock()
- : m_ptsUs(0)
- , m_driftUs(0)
- , m_baseTimeUs(0)
- , m_frameCount(0)
- , m_lastResetTimeUs(0)
- , m_lastClockValueUs(0)
- {}
- inline void reset()
- {
- m_ptsUs = 0;
- m_driftUs = 0;
- m_baseTimeUs = av_gettime_relative();
- m_frameCount = 0;
- m_lastResetTimeUs = m_baseTimeUs;
- m_lastClockValueUs = 0;
- }
- // 修改:接受int64_t微秒时间戳,消除double参数类型
- inline void setClock(int64_t ptsUs) { setClockAt(ptsUs); }
- // 新增:为兼容性提供秒级时间戳设置函数
- inline void setClockSeconds(double pts) {
- int64_t ptsUs = static_cast<int64_t>(pts * 1000000.0);
- setClock(ptsUs);
- }
- // 修改:返回int64_t微秒时间戳,消除double类型和除法运算
- inline int64_t getClock() {
- // 优化:全程使用int64微秒时间戳,避免除法运算
- int64_t currentTimeUs = av_gettime_relative();
-
- // 定期重置时间基准,防止累积误差
- if (++m_frameCount % LowLatencyConfig::TIMER_RESET_INTERVAL == 0) {
- resetTimeBase(currentTimeUs);
- }
-
- // 使用整数运算保持精度,避免浮点除法
- int64_t elapsedUs = currentTimeUs - m_baseTimeUs;
- int64_t resultUs = m_driftUs + elapsedUs;
-
- // 检测并补偿精度误差(转换为微秒单位)
- if (m_frameCount > 1) {
- int64_t driftUs = resultUs - m_lastClockValueUs;
- if (driftUs > LowLatencyConfig::MAX_ACCEPTABLE_DRIFT_US) {
- resultUs -= LowLatencyConfig::PRECISION_ERROR_COMPENSATION_US;
- }
- }
- m_lastClockValueUs = resultUs;
-
- // 直接返回微秒时间戳,消除除法运算
- return resultUs;
- }
- // 新增:为兼容性提供秒级时间戳转换函数
- inline double getClockSeconds() {
- return static_cast<double>(getClock()) / 1000000.0;
- }
- // 新增:获取高精度微秒时间戳
- inline int64_t getClockUs() {
- int64_t currentTimeUs = av_gettime_relative();
-
- // 定期重置时间基准,防止累积误差
- if (++m_frameCount % LowLatencyConfig::TIMER_RESET_INTERVAL == 0) {
- resetTimeBase(currentTimeUs);
- }
-
- int64_t elapsedUs = currentTimeUs - m_baseTimeUs;
- int64_t resultUs = m_driftUs + elapsedUs;
-
- // 检测并补偿精度误差
- if (m_frameCount > 1) {
- int64_t driftUs = resultUs - m_lastClockValueUs;
- if (driftUs > LowLatencyConfig::MAX_ACCEPTABLE_DRIFT_US) {
- resultUs -= LowLatencyConfig::PRECISION_ERROR_COMPENSATION_US;
- }
- }
- m_lastClockValueUs = resultUs;
-
- return resultUs;
- }
- private:
- // 修改:接受int64_t微秒时间戳,消除double参数类型
- inline void setClockAt(int64_t ptsUs)
- {
- // 优化:使用高精度整数时间戳,减少转换误差
- int64_t currentTimeUs = av_gettime_relative();
- if (m_baseTimeUs == 0) {
- m_baseTimeUs = currentTimeUs;
- }
-
- // 直接使用微秒时间戳,避免浮点转换
- int64_t elapsedUs = currentTimeUs - m_baseTimeUs;
- m_driftUs = ptsUs - elapsedUs;
- m_ptsUs = ptsUs;
- }
-
- inline void resetTimeBase(int64_t currentTimeUs)
- {
- // 定期重置时间基准,防止长时间运行时的累积误差
- if (currentTimeUs - m_lastResetTimeUs > LowLatencyConfig::TIMER_RESET_INTERVAL_US) {
- // 修复:避免在此处调用 getClockUs() 造成递归/重入
- int64_t currentClockUs = m_driftUs + (currentTimeUs - m_baseTimeUs);
- m_baseTimeUs = currentTimeUs;
- m_driftUs = currentClockUs;
- m_lastResetTimeUs = currentTimeUs;
- }
- }
- int64_t m_ptsUs; // 高精度PTS(微秒)
- int64_t m_driftUs; // 高精度漂移(微秒)
- int64_t m_baseTimeUs; // 高精度时间基准(微秒)
- int m_frameCount; // 帧计数器
- int64_t m_lastResetTimeUs; // 上次重置时间(微秒)
- int64_t m_lastClockValueUs; // 上次时钟值(微秒),用于漂移检测
- };
- #endif // AVCLOCK_H
|