av_clock.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #ifndef AVCLOCK_H
  2. #define AVCLOCK_H
  3. #include "ffmpeg_compat.h"
  4. #include "low_latency_config.h"
  5. class AVClock
  6. {
  7. public:
  8. AVClock()
  9. : m_ptsUs(0)
  10. , m_driftUs(0)
  11. , m_baseTimeUs(0)
  12. , m_frameCount(0)
  13. , m_lastResetTimeUs(0)
  14. , m_lastClockValueUs(0)
  15. {}
  16. inline void reset()
  17. {
  18. m_ptsUs = 0;
  19. m_driftUs = 0;
  20. m_baseTimeUs = av_gettime_relative();
  21. m_frameCount = 0;
  22. m_lastResetTimeUs = m_baseTimeUs;
  23. m_lastClockValueUs = 0;
  24. }
  25. // 修改:接受int64_t微秒时间戳,消除double参数类型
  26. inline void setClock(int64_t ptsUs) { setClockAt(ptsUs); }
  27. // 新增:为兼容性提供秒级时间戳设置函数
  28. inline void setClockSeconds(double pts) {
  29. int64_t ptsUs = static_cast<int64_t>(pts * 1000000.0);
  30. setClock(ptsUs);
  31. }
  32. // 修改:返回int64_t微秒时间戳,消除double类型和除法运算
  33. inline int64_t getClock() {
  34. // 优化:全程使用int64微秒时间戳,避免除法运算
  35. int64_t currentTimeUs = av_gettime_relative();
  36. // 定期重置时间基准,防止累积误差
  37. if (++m_frameCount % LowLatencyConfig::TIMER_RESET_INTERVAL == 0) {
  38. resetTimeBase(currentTimeUs);
  39. }
  40. // 使用整数运算保持精度,避免浮点除法
  41. int64_t elapsedUs = currentTimeUs - m_baseTimeUs;
  42. int64_t resultUs = m_driftUs + elapsedUs;
  43. // 检测并补偿精度误差(转换为微秒单位)
  44. if (m_frameCount > 1) {
  45. int64_t driftUs = resultUs - m_lastClockValueUs;
  46. if (driftUs > LowLatencyConfig::MAX_ACCEPTABLE_DRIFT_US) {
  47. resultUs -= LowLatencyConfig::PRECISION_ERROR_COMPENSATION_US;
  48. }
  49. }
  50. m_lastClockValueUs = resultUs;
  51. // 直接返回微秒时间戳,消除除法运算
  52. return resultUs;
  53. }
  54. // 新增:为兼容性提供秒级时间戳转换函数
  55. inline double getClockSeconds() {
  56. return static_cast<double>(getClock()) / 1000000.0;
  57. }
  58. // 新增:获取高精度微秒时间戳
  59. inline int64_t getClockUs() {
  60. int64_t currentTimeUs = av_gettime_relative();
  61. // 定期重置时间基准,防止累积误差
  62. if (++m_frameCount % LowLatencyConfig::TIMER_RESET_INTERVAL == 0) {
  63. resetTimeBase(currentTimeUs);
  64. }
  65. int64_t elapsedUs = currentTimeUs - m_baseTimeUs;
  66. int64_t resultUs = m_driftUs + elapsedUs;
  67. // 检测并补偿精度误差
  68. if (m_frameCount > 1) {
  69. int64_t driftUs = resultUs - m_lastClockValueUs;
  70. if (driftUs > LowLatencyConfig::MAX_ACCEPTABLE_DRIFT_US) {
  71. resultUs -= LowLatencyConfig::PRECISION_ERROR_COMPENSATION_US;
  72. }
  73. }
  74. m_lastClockValueUs = resultUs;
  75. return resultUs;
  76. }
  77. private:
  78. // 修改:接受int64_t微秒时间戳,消除double参数类型
  79. inline void setClockAt(int64_t ptsUs)
  80. {
  81. // 优化:使用高精度整数时间戳,减少转换误差
  82. int64_t currentTimeUs = av_gettime_relative();
  83. if (m_baseTimeUs == 0) {
  84. m_baseTimeUs = currentTimeUs;
  85. }
  86. // 直接使用微秒时间戳,避免浮点转换
  87. int64_t elapsedUs = currentTimeUs - m_baseTimeUs;
  88. m_driftUs = ptsUs - elapsedUs;
  89. m_ptsUs = ptsUs;
  90. }
  91. inline void resetTimeBase(int64_t currentTimeUs)
  92. {
  93. // 定期重置时间基准,防止长时间运行时的累积误差
  94. if (currentTimeUs - m_lastResetTimeUs > LowLatencyConfig::TIMER_RESET_INTERVAL_US) {
  95. int64_t currentClockUs = getClockUs();
  96. m_baseTimeUs = currentTimeUs;
  97. m_driftUs = currentClockUs;
  98. m_lastResetTimeUs = currentTimeUs;
  99. }
  100. }
  101. int64_t m_ptsUs; // 高精度PTS(微秒)
  102. int64_t m_driftUs; // 高精度漂移(微秒)
  103. int64_t m_baseTimeUs; // 高精度时间基准(微秒)
  104. int m_frameCount; // 帧计数器
  105. int64_t m_lastResetTimeUs; // 上次重置时间(微秒)
  106. int64_t m_lastClockValueUs; // 上次时钟值(微秒),用于漂移检测
  107. };
  108. #endif // AVCLOCK_H