utils_synchronizer_v2.cpp 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033
  1. #include "utils_synchronizer_v2.h"
  2. #include "../base/logger.h"
  3. #include <algorithm>
  4. #include <cmath>
  5. #include <sstream>
  6. #include <iomanip>
  7. namespace av {
  8. namespace utils {
  9. SynchronizerV2::SynchronizerV2(const SyncConfigV2& config)
  10. : config_(config)
  11. , masterClockType_(ClockType::AUDIO)
  12. , state_(SyncState::IDLE)
  13. , initialized_(false)
  14. , running_(false)
  15. , paused_(false)
  16. , recoveryAttempts_(0)
  17. , lastSyncError_(0.0) {
  18. // 初始化时钟
  19. audioClock_ = ClockInfo();
  20. videoClock_ = ClockInfo();
  21. externalClock_ = ClockInfo();
  22. // 初始化历史记录
  23. audioClockHistory_.clear();
  24. videoClockHistory_.clear();
  25. syncErrorHistory_.clear();
  26. Logger::instance().info("SynchronizerV2 created with strategy: " +
  27. std::to_string(static_cast<int>(config_.strategy)));
  28. }
  29. SynchronizerV2::~SynchronizerV2() {
  30. close();
  31. Logger::instance().info("SynchronizerV2 destroyed");
  32. }
  33. ErrorCode SynchronizerV2::initialize() {
  34. if (initialized_) {
  35. return ErrorCode::ALREADY_INITIALIZED;
  36. }
  37. std::lock_guard<std::mutex> clockLock(clockMutex_);
  38. std::lock_guard<std::mutex> statsLock(statsMutex_);
  39. // 重置所有时钟
  40. resetClock(ClockType::AUDIO);
  41. resetClock(ClockType::VIDEO);
  42. resetClock(ClockType::EXTERNAL);
  43. // 选择主时钟
  44. selectMasterClock();
  45. // 重置统计信息
  46. stats_ = SyncStatsV2();
  47. stats_.lastUpdateTime = std::chrono::steady_clock::now();
  48. // 设置开始时间
  49. startTime_ = std::chrono::steady_clock::now();
  50. lastClockUpdate_ = startTime_;
  51. lastStatsUpdate_ = startTime_;
  52. state_ = SyncState::IDLE;
  53. initialized_ = true;
  54. recoveryAttempts_ = 0;
  55. Logger::instance().info("SynchronizerV2 initialized");
  56. return ErrorCode::SUCCESS;
  57. }
  58. ErrorCode SynchronizerV2::start() {
  59. if (!initialized_) {
  60. return ErrorCode::NOT_INITIALIZED;
  61. }
  62. if (running_) {
  63. return ErrorCode::ALREADY_STARTED;
  64. }
  65. running_ = true;
  66. paused_ = false;
  67. state_ = SyncState::INITIALIZING;
  68. startTime_ = std::chrono::steady_clock::now();
  69. lastClockUpdate_ = startTime_;
  70. // 启动后立即进入同步状态
  71. state_ = SyncState::SYNCING;
  72. Logger::instance().info("SynchronizerV2 started");
  73. return ErrorCode::SUCCESS;
  74. }
  75. void SynchronizerV2::setStreamInfo(bool hasAudio, bool hasVideo) {
  76. std::lock_guard<std::mutex> lock(clockMutex_);
  77. hasAudioStream_ = hasAudio;
  78. hasVideoStream_ = hasVideo;
  79. Logger::instance().info("Stream info updated: hasAudio=" + std::to_string(hasAudio) +
  80. ", hasVideo=" + std::to_string(hasVideo));
  81. // 重新选择主时钟
  82. selectMasterClock();
  83. }
  84. ErrorCode SynchronizerV2::stop() {
  85. if (!running_) {
  86. return ErrorCode::NOT_STARTED;
  87. }
  88. running_ = false;
  89. paused_ = false;
  90. state_ = SyncState::IDLE;
  91. Logger::instance().info("SynchronizerV2 stopped");
  92. return ErrorCode::SUCCESS;
  93. }
  94. ErrorCode SynchronizerV2::pause() {
  95. if (!running_) {
  96. return ErrorCode::NOT_STARTED;
  97. }
  98. if (paused_) {
  99. return ErrorCode::ALREADY_PAUSED;
  100. }
  101. std::lock_guard<std::mutex> lock(clockMutex_);
  102. paused_ = true;
  103. // 暂停所有时钟
  104. pauseClock(ClockType::AUDIO, true);
  105. pauseClock(ClockType::VIDEO, true);
  106. pauseClock(ClockType::EXTERNAL, true);
  107. Logger::instance().info("SynchronizerV2 paused");
  108. return ErrorCode::SUCCESS;
  109. }
  110. ErrorCode SynchronizerV2::resume() {
  111. if (!running_) {
  112. return ErrorCode::NOT_STARTED;
  113. }
  114. if (!paused_) {
  115. return ErrorCode::NOT_PAUSED;
  116. }
  117. std::lock_guard<std::mutex> lock(clockMutex_);
  118. paused_ = false;
  119. // 恢复所有时钟
  120. pauseClock(ClockType::AUDIO, false);
  121. pauseClock(ClockType::VIDEO, false);
  122. pauseClock(ClockType::EXTERNAL, false);
  123. state_ = SyncState::SYNCING;
  124. Logger::instance().info("SynchronizerV2 resumed");
  125. return ErrorCode::SUCCESS;
  126. }
  127. ErrorCode SynchronizerV2::reset() {
  128. std::lock_guard<std::mutex> clockLock(clockMutex_);
  129. std::lock_guard<std::mutex> statsLock(statsMutex_);
  130. std::lock_guard<std::mutex> historyLock(historyMutex_);
  131. // 重置时钟
  132. resetClock(ClockType::AUDIO);
  133. resetClock(ClockType::VIDEO);
  134. resetClock(ClockType::EXTERNAL);
  135. // 重置统计信息
  136. stats_ = SyncStatsV2();
  137. stats_.lastUpdateTime = std::chrono::steady_clock::now();
  138. // 清空历史记录
  139. audioClockHistory_.clear();
  140. videoClockHistory_.clear();
  141. syncErrorHistory_.clear();
  142. // 重置状态
  143. state_ = running_ ? SyncState::SYNCING : SyncState::IDLE;
  144. recoveryAttempts_ = 0;
  145. lastSyncError_ = 0.0;
  146. // 重新选择主时钟
  147. selectMasterClock();
  148. Logger::instance().info("SynchronizerV2 reset");
  149. return ErrorCode::SUCCESS;
  150. }
  151. ErrorCode SynchronizerV2::close() {
  152. if (running_) {
  153. stop();
  154. }
  155. initialized_ = false;
  156. Logger::instance().info("SynchronizerV2 closed");
  157. return ErrorCode::SUCCESS;
  158. }
  159. ErrorCode SynchronizerV2::setAudioClock(double pts, double time, int serial) {
  160. return updateClock(ClockType::AUDIO, pts, time, serial);
  161. }
  162. ErrorCode SynchronizerV2::setVideoClock(double pts, double time, int serial) {
  163. return updateClock(ClockType::VIDEO, pts, time, serial);
  164. }
  165. ErrorCode SynchronizerV2::setExternalClock(double time, int serial) {
  166. if (time < 0) {
  167. time = getCurrentTime();
  168. }
  169. return updateClock(ClockType::EXTERNAL, time, time, serial);
  170. }
  171. double SynchronizerV2::getAudioClock(bool predict) const {
  172. return getClock(ClockType::AUDIO, predict);
  173. }
  174. double SynchronizerV2::getVideoClock(bool predict) const {
  175. return getClock(ClockType::VIDEO, predict);
  176. }
  177. double SynchronizerV2::getExternalClock(bool predict) const {
  178. return getClock(ClockType::EXTERNAL, predict);
  179. }
  180. double SynchronizerV2::getMasterClock(bool predict) const {
  181. return getClock(masterClockType_, predict);
  182. }
  183. FrameDecision SynchronizerV2::shouldDisplayVideoFrame(double pts, double duration) {
  184. FrameDecision decision;
  185. decision.actualPts = pts;
  186. if (!running_ || paused_) {
  187. decision.action = FrameAction::DELAY;
  188. decision.delay = 0.01; // 10ms
  189. decision.reason = paused_ ? "Paused" : "Not running";
  190. return decision;
  191. }
  192. // 获取主时钟
  193. double masterClock = getMasterClock(true); // 使用预测
  194. decision.targetPts = masterClock;
  195. // 计算同步误差
  196. double syncError = pts - masterClock;
  197. decision.syncError = syncError;
  198. // 如果视频是主时钟,直接显示
  199. if (masterClockType_ == ClockType::VIDEO) {
  200. decision.action = FrameAction::DISPLAY;
  201. decision.delay = duration > 0 ? duration : (1.0 / 25.0); // 默认25fps
  202. decision.reason = "Video master";
  203. return decision;
  204. }
  205. // 根据同步误差决定动作
  206. if (syncError < -config_.frameDropThreshold) {
  207. // 视频太慢,丢帧
  208. decision.action = FrameAction::DROP;
  209. decision.reason = "Video too slow, drop frame";
  210. // 通知丢帧
  211. if (frameDropCallback_) {
  212. frameDropCallback_(ClockType::VIDEO, pts);
  213. }
  214. // 更新统计
  215. std::lock_guard<std::mutex> lock(statsMutex_);
  216. stats_.droppedFrames++;
  217. } else if (syncError > config_.frameDupThreshold) {
  218. // 视频太快,重复帧或延迟
  219. if (duration > 0 && syncError < config_.frameDupThreshold * 2) {
  220. decision.action = FrameAction::DELAY;
  221. decision.delay = std::min(syncError, config_.maxSyncError);
  222. decision.reason = "Video too fast, delay";
  223. } else {
  224. decision.action = FrameAction::Frame_DUPLICATE;
  225. decision.reason = "Video too fast, duplicate frame";
  226. // 通知重复帧
  227. if (frameDuplicateCallback_) {
  228. frameDuplicateCallback_(ClockType::VIDEO, pts);
  229. }
  230. // 更新统计
  231. std::lock_guard<std::mutex> lock(statsMutex_);
  232. stats_.duplicatedFrames++;
  233. }
  234. } else {
  235. // 正常显示
  236. decision.action = FrameAction::DISPLAY;
  237. decision.delay = calculateTargetDelay(pts, ClockType::VIDEO);
  238. decision.reason = "Normal display";
  239. }
  240. // 更新统计
  241. {
  242. std::lock_guard<std::mutex> lock(statsMutex_);
  243. stats_.totalFrames++;
  244. stats_.syncError = syncError;
  245. // 更新平均同步误差
  246. if (stats_.totalFrames == 1) {
  247. stats_.avgSyncError = std::abs(syncError);
  248. } else {
  249. stats_.avgSyncError = stats_.avgSyncError * 0.9 + std::abs(syncError) * 0.1;
  250. }
  251. // 更新最大同步误差
  252. stats_.maxSyncError = std::max(stats_.maxSyncError, std::abs(syncError));
  253. }
  254. return decision;
  255. }
  256. FrameDecision SynchronizerV2::shouldPlayAudioFrame(double pts, double duration) {
  257. FrameDecision decision;
  258. decision.actualPts = pts;
  259. if (!running_ || paused_) {
  260. decision.action = FrameAction::DELAY;
  261. decision.delay = 0.01; // 10ms
  262. decision.reason = paused_ ? "Paused" : "Not running";
  263. return decision;
  264. }
  265. // 音频通常作为主时钟,或者需要与主时钟同步
  266. if (masterClockType_ == ClockType::AUDIO) {
  267. decision.action = FrameAction::DISPLAY;
  268. decision.delay = duration > 0 ? duration : 0.023; // 默认23ms (44.1kHz, 1024 samples)
  269. decision.reason = "Audio master";
  270. decision.targetPts = pts;
  271. return decision;
  272. }
  273. // 与主时钟同步
  274. double masterClock = getMasterClock(true);
  275. decision.targetPts = masterClock;
  276. double syncError = pts - masterClock;
  277. decision.syncError = syncError;
  278. if (std::abs(syncError) > config_.maxSyncError) {
  279. // 同步误差太大,丢弃或延迟
  280. if (syncError < 0) {
  281. decision.action = FrameAction::DROP;
  282. decision.reason = "Audio too slow, drop";
  283. } else {
  284. decision.action = FrameAction::DELAY;
  285. decision.delay = std::min(syncError, config_.maxSyncError);
  286. decision.reason = "Audio too fast, delay";
  287. }
  288. } else {
  289. decision.action = FrameAction::DISPLAY;
  290. decision.delay = calculateTargetDelay(pts, ClockType::AUDIO);
  291. decision.reason = "Normal audio play";
  292. }
  293. return decision;
  294. }
  295. double SynchronizerV2::calculateTargetDelay(double pts, ClockType clockType) {
  296. if (!running_) {
  297. return 0.0;
  298. }
  299. // 基础延迟
  300. double baseDelay = 0.0;
  301. if (clockType == ClockType::VIDEO) {
  302. baseDelay = 1.0 / 25.0; // 默认25fps
  303. } else if (clockType == ClockType::AUDIO) {
  304. baseDelay = 0.023; // 默认23ms
  305. }
  306. // 如果是主时钟,返回基础延迟
  307. if (clockType == masterClockType_) {
  308. return baseDelay;
  309. }
  310. // 计算与主时钟的差异
  311. double masterClock = getMasterClock(true);
  312. double diff = pts - masterClock;
  313. // 调整延迟
  314. double adjustedDelay = baseDelay;
  315. if (std::abs(diff) < config_.syncThreshold) {
  316. // 在同步阈值内,正常延迟
  317. adjustedDelay = baseDelay;
  318. } else if (diff < 0) {
  319. // 落后于主时钟,减少延迟
  320. adjustedDelay = std::max(0.0, baseDelay + diff);
  321. } else {
  322. // 超前于主时钟,增加延迟
  323. adjustedDelay = baseDelay + std::min(diff, config_.maxSyncError);
  324. }
  325. return adjustedDelay;
  326. }
  327. bool SynchronizerV2::shouldDropFrame(double pts, ClockType clockType) {
  328. if (!running_ || clockType == masterClockType_) {
  329. return false;
  330. }
  331. double masterClock = getMasterClock();
  332. double diff = pts - masterClock;
  333. return diff < -config_.frameDropThreshold;
  334. }
  335. bool SynchronizerV2::shouldDuplicateFrame(double pts, ClockType clockType) {
  336. if (!running_ || clockType == masterClockType_) {
  337. return false;
  338. }
  339. double masterClock = getMasterClock();
  340. double diff = pts - masterClock;
  341. return diff > config_.frameDupThreshold;
  342. }
  343. double SynchronizerV2::calculateSyncError() const {
  344. if (!running_) {
  345. return 0.0;
  346. }
  347. double audioClock = getAudioClock();
  348. double videoClock = getVideoClock();
  349. if (audioClock <= 0 || videoClock <= 0) {
  350. return 0.0;
  351. }
  352. return std::abs(audioClock - videoClock);
  353. }
  354. // 内部版本,假设调用者已经持有clockMutex_锁
  355. double SynchronizerV2::calculateSyncErrorInternal() const {
  356. if (!running_) {
  357. return 0.0;
  358. }
  359. // 直接计算时钟值,避免调用getClock导致死锁
  360. double audioClock = 0.0;
  361. double videoClock = 0.0;
  362. // 计算音频时钟
  363. if (!audioClock_.paused) {
  364. auto now = std::chrono::steady_clock::now();
  365. double elapsed = std::chrono::duration<double>(now - audioClock_.lastUpdate).count();
  366. audioClock = audioClock_.pts + elapsed * audioClock_.speed;
  367. } else {
  368. audioClock = audioClock_.pts;
  369. }
  370. // 计算视频时钟
  371. if (!videoClock_.paused) {
  372. auto now = std::chrono::steady_clock::now();
  373. double elapsed = std::chrono::duration<double>(now - videoClock_.lastUpdate).count();
  374. videoClock = videoClock_.pts + elapsed * videoClock_.speed;
  375. } else {
  376. videoClock = videoClock_.pts;
  377. }
  378. if (audioClock <= 0 || videoClock <= 0) {
  379. return 0.0;
  380. }
  381. return std::abs(audioClock - videoClock);
  382. }
  383. double SynchronizerV2::calculateAudioDelay(double pts) const {
  384. if (masterClockType_ == ClockType::AUDIO) {
  385. return 0.0;
  386. }
  387. double masterClock = getMasterClock();
  388. return pts - masterClock;
  389. }
  390. double SynchronizerV2::calculateVideoDelay(double pts) const {
  391. if (masterClockType_ == ClockType::VIDEO) {
  392. return 0.0;
  393. }
  394. double masterClock = getMasterClock();
  395. return pts - masterClock;
  396. }
  397. void SynchronizerV2::setConfig(const SyncConfigV2& config) {
  398. std::lock_guard<std::mutex> lock(configMutex_);
  399. config_ = config;
  400. // 重新选择主时钟
  401. selectMasterClock();
  402. Logger::instance().info("SynchronizerV2 config updated");
  403. }
  404. SyncConfigV2 SynchronizerV2::getConfig() const {
  405. std::lock_guard<std::mutex> lock(configMutex_);
  406. return config_;
  407. }
  408. void SynchronizerV2::setSyncStrategy(SyncStrategy strategy) {
  409. std::lock_guard<std::mutex> lock(configMutex_);
  410. config_.strategy = strategy;
  411. selectMasterClock();
  412. Logger::instance().info("Sync strategy set to: " + std::to_string(static_cast<int>(strategy)));
  413. }
  414. SyncStrategy SynchronizerV2::getSyncStrategy() const {
  415. std::lock_guard<std::mutex> lock(configMutex_);
  416. return config_.strategy;
  417. }
  418. void SynchronizerV2::setPlaybackSpeed(double speed) {
  419. std::lock_guard<std::mutex> lock(clockMutex_);
  420. audioClock_.speed = speed;
  421. videoClock_.speed = speed;
  422. externalClock_.speed = speed;
  423. Logger::instance().info("Playback speed set to: " + std::to_string(speed) + "x");
  424. }
  425. double SynchronizerV2::getPlaybackSpeed() const {
  426. std::lock_guard<std::mutex> lock(clockMutex_);
  427. return audioClock_.speed;
  428. }
  429. bool SynchronizerV2::isSynchronized() const {
  430. return state_ == SyncState::SYNCHRONIZED;
  431. }
  432. SyncStatsV2 SynchronizerV2::getStats() const {
  433. std::lock_guard<std::mutex> lock(statsMutex_);
  434. SyncStatsV2 stats = stats_;
  435. // 更新当前时钟值
  436. stats.audioClock = getAudioClock();
  437. stats.videoClock = getVideoClock();
  438. stats.externalClock = getExternalClock();
  439. stats.masterClock = getMasterClock();
  440. stats.state = state_;
  441. stats.masterClockType = masterClockType_;
  442. return stats;
  443. }
  444. void SynchronizerV2::resetStats() {
  445. std::lock_guard<std::mutex> lock(statsMutex_);
  446. stats_ = SyncStatsV2();
  447. stats_.lastUpdateTime = std::chrono::steady_clock::now();
  448. Logger::instance().info("SynchronizerV2 stats reset");
  449. }
  450. void SynchronizerV2::setSyncEventCallback(SyncEventCallback callback) {
  451. syncEventCallback_ = callback;
  452. }
  453. void SynchronizerV2::setFrameDropCallback(FrameDropCallback callback) {
  454. frameDropCallback_ = callback;
  455. }
  456. void SynchronizerV2::setFrameDuplicateCallback(FrameDuplicateCallback callback) {
  457. frameDuplicateCallback_ = callback;
  458. }
  459. void SynchronizerV2::setSyncErrorCallback(SyncErrorCallback callback) {
  460. syncErrorCallback_ = callback;
  461. }
  462. void SynchronizerV2::enableAdaptiveSync(bool enable) {
  463. std::lock_guard<std::mutex> lock(configMutex_);
  464. config_.enableAdaptiveSync = enable;
  465. Logger::instance().info("Adaptive sync " + std::string(enable ? "enabled" : "disabled"));
  466. }
  467. void SynchronizerV2::enablePrediction(bool enable) {
  468. std::lock_guard<std::mutex> lock(configMutex_);
  469. config_.enablePrediction = enable;
  470. Logger::instance().info("Prediction " + std::string(enable ? "enabled" : "disabled"));
  471. }
  472. void SynchronizerV2::setClockUpdateInterval(double interval) {
  473. std::lock_guard<std::mutex> lock(configMutex_);
  474. config_.clockUpdateInterval = interval;
  475. Logger::instance().info("Clock update interval set to: " + std::to_string(interval * 1000) + "ms");
  476. }
  477. void SynchronizerV2::setSmoothingWindow(int window) {
  478. std::lock_guard<std::mutex> lock(configMutex_);
  479. config_.smoothingWindow = window;
  480. // 调整历史记录大小
  481. std::lock_guard<std::mutex> historyLock(historyMutex_);
  482. while (audioClockHistory_.size() > static_cast<size_t>(window)) {
  483. audioClockHistory_.pop_front();
  484. }
  485. while (videoClockHistory_.size() > static_cast<size_t>(window)) {
  486. videoClockHistory_.pop_front();
  487. }
  488. while (syncErrorHistory_.size() > static_cast<size_t>(window)) {
  489. syncErrorHistory_.pop_front();
  490. }
  491. Logger::instance().info("Smoothing window set to: " + std::to_string(window));
  492. }
  493. std::string SynchronizerV2::getDebugInfo() const {
  494. std::ostringstream oss;
  495. SyncStatsV2 stats = getStats();
  496. oss << std::fixed << std::setprecision(3);
  497. oss << "SynchronizerV2 Debug Info:\n";
  498. oss << " State: " << static_cast<int>(stats.state) << "\n";
  499. oss << " Master Clock: " << static_cast<int>(stats.masterClockType) << "\n";
  500. oss << " Audio Clock: " << stats.audioClock << "s\n";
  501. oss << " Video Clock: " << stats.videoClock << "s\n";
  502. oss << " External Clock: " << stats.externalClock << "s\n";
  503. oss << " Master Clock: " << stats.masterClock << "s\n";
  504. oss << " Sync Error: " << stats.syncError * 1000 << "ms\n";
  505. oss << " Avg Sync Error: " << stats.avgSyncError * 1000 << "ms\n";
  506. oss << " Max Sync Error: " << stats.maxSyncError * 1000 << "ms\n";
  507. oss << " Total Frames: " << stats.totalFrames << "\n";
  508. oss << " Dropped Frames: " << stats.droppedFrames << "\n";
  509. oss << " Duplicated Frames: " << stats.duplicatedFrames << "\n";
  510. oss << " Running: " << (running_ ? "Yes" : "No") << "\n";
  511. oss << " Paused: " << (paused_ ? "Yes" : "No") << "\n";
  512. return oss.str();
  513. }
  514. void SynchronizerV2::dumpClockInfo() const {
  515. std::lock_guard<std::mutex> lock(clockMutex_);
  516. Logger::instance().info("Clock Info Dump:");
  517. Logger::instance().info(" Audio - PTS: " + std::to_string(audioClock_.pts) +
  518. ", Speed: " + std::to_string(audioClock_.speed) +
  519. ", Paused: " + (audioClock_.paused ? "Yes" : "No"));
  520. Logger::instance().info(" Video - PTS: " + std::to_string(videoClock_.pts) +
  521. ", Speed: " + std::to_string(videoClock_.speed) +
  522. ", Paused: " + (videoClock_.paused ? "Yes" : "No"));
  523. Logger::instance().info(" External - PTS: " + std::to_string(externalClock_.pts) +
  524. ", Speed: " + std::to_string(externalClock_.speed) +
  525. ", Paused: " + (externalClock_.paused ? "Yes" : "No"));
  526. }
  527. // 私有方法实现
  528. ErrorCode SynchronizerV2::updateClock(ClockType type, double pts, double time, int serial) {
  529. if (!initialized_) {
  530. return ErrorCode::NOT_INITIALIZED;
  531. }
  532. std::lock_guard<std::mutex> lock(clockMutex_);
  533. ClockInfo* clock = nullptr;
  534. switch (type) {
  535. case ClockType::AUDIO:
  536. clock = &audioClock_;
  537. break;
  538. case ClockType::VIDEO:
  539. clock = &videoClock_;
  540. break;
  541. case ClockType::EXTERNAL:
  542. clock = &externalClock_;
  543. break;
  544. default:
  545. return ErrorCode::INVALID_PARAMS;
  546. }
  547. if (time < 0) {
  548. time = getCurrentTime();
  549. }
  550. // 检查序列号
  551. if (serial != 0 && clock->serial != serial) {
  552. // 序列号不匹配,可能是seek操作,重置时钟
  553. resetClock(type);
  554. clock->serial = serial;
  555. }
  556. // 更新时钟
  557. clock->pts = pts;
  558. clock->time = time;
  559. clock->lastUpdate = std::chrono::steady_clock::now();
  560. // 平滑处理
  561. if (config_.smoothingWindow > 1) {
  562. clock->smoothedPts = smoothClock(type, pts);
  563. } else {
  564. clock->smoothedPts = pts;
  565. }
  566. // 更新历史记录
  567. updateClockHistory(type, pts);
  568. // 更新同步状态
  569. updateSyncState();
  570. // 定期更新统计信息
  571. auto now = std::chrono::steady_clock::now();
  572. if (std::chrono::duration_cast<std::chrono::milliseconds>(now - lastStatsUpdate_).count() > 100) {
  573. updateStats();
  574. lastStatsUpdate_ = now;
  575. }
  576. return ErrorCode::SUCCESS;
  577. }
  578. double SynchronizerV2::getClock(ClockType type, bool predict) const {
  579. std::lock_guard<std::mutex> lock(clockMutex_);
  580. const ClockInfo* clock = nullptr;
  581. switch (type) {
  582. case ClockType::AUDIO:
  583. clock = &audioClock_;
  584. break;
  585. case ClockType::VIDEO:
  586. clock = &videoClock_;
  587. break;
  588. case ClockType::EXTERNAL:
  589. clock = &externalClock_;
  590. break;
  591. case ClockType::SYSTEM:
  592. return getCurrentTime();
  593. default:
  594. return 0.0;
  595. }
  596. if (clock->paused) {
  597. return clock->pts;
  598. }
  599. // 计算当前时间
  600. auto now = std::chrono::steady_clock::now();
  601. double elapsed = std::chrono::duration<double>(now - clock->lastUpdate).count();
  602. double currentPts = clock->pts + elapsed * clock->speed;
  603. // 如果启用预测
  604. if (predict && config_.enablePrediction) {
  605. return predictClock(type, config_.predictionWindow);
  606. }
  607. return currentPts;
  608. }
  609. void SynchronizerV2::resetClock(ClockType type) {
  610. ClockInfo* clock = nullptr;
  611. switch (type) {
  612. case ClockType::AUDIO:
  613. clock = &audioClock_;
  614. break;
  615. case ClockType::VIDEO:
  616. clock = &videoClock_;
  617. break;
  618. case ClockType::EXTERNAL:
  619. clock = &externalClock_;
  620. break;
  621. default:
  622. return;
  623. }
  624. clock->pts = 0.0;
  625. clock->time = 0.0;
  626. clock->speed = 1.0;
  627. clock->serial = 0;
  628. clock->paused = false;
  629. clock->lastUpdate = std::chrono::steady_clock::now();
  630. clock->drift = 0.0;
  631. clock->smoothedPts = 0.0;
  632. }
  633. void SynchronizerV2::pauseClock(ClockType type, bool pause) {
  634. ClockInfo* clock = nullptr;
  635. switch (type) {
  636. case ClockType::AUDIO:
  637. clock = &audioClock_;
  638. break;
  639. case ClockType::VIDEO:
  640. clock = &videoClock_;
  641. break;
  642. case ClockType::EXTERNAL:
  643. clock = &externalClock_;
  644. break;
  645. default:
  646. return;
  647. }
  648. if (clock->paused != pause) {
  649. if (pause) {
  650. // 暂停时保存当前PTS(直接计算,避免调用getClock导致死锁)
  651. if (!clock->paused) {
  652. auto now = std::chrono::steady_clock::now();
  653. double elapsed = std::chrono::duration<double>(now - clock->lastUpdate).count();
  654. clock->pts = clock->pts + elapsed * clock->speed;
  655. }
  656. }
  657. clock->paused = pause;
  658. clock->lastUpdate = std::chrono::steady_clock::now();
  659. }
  660. }
  661. void SynchronizerV2::selectMasterClock() {
  662. switch (config_.strategy) {
  663. case SyncStrategy::AUDIO_MASTER:
  664. masterClockType_ = ClockType::AUDIO;
  665. break;
  666. case SyncStrategy::VIDEO_MASTER:
  667. masterClockType_ = ClockType::VIDEO;
  668. break;
  669. case SyncStrategy::EXTERNAL_MASTER:
  670. masterClockType_ = ClockType::EXTERNAL;
  671. break;
  672. case SyncStrategy::ADAPTIVE:
  673. // 自适应选择逻辑
  674. if (config_.enableAdaptiveSync) {
  675. // 改进的自适应逻辑:优先选择音频,如果没有音频则选择视频
  676. // 注意:不依赖pts值,因为在播放开始时pts可能还是0
  677. if (hasAudioStream_) {
  678. masterClockType_ = ClockType::AUDIO;
  679. } else if (hasVideoStream_) {
  680. masterClockType_ = ClockType::VIDEO;
  681. } else {
  682. masterClockType_ = ClockType::EXTERNAL;
  683. }
  684. } else {
  685. masterClockType_ = ClockType::AUDIO; // 默认音频
  686. }
  687. break;
  688. }
  689. Logger::instance().info("Master clock selected: "
  690. + std::to_string(static_cast<int>(masterClockType_.load()))
  691. + " (hasAudio=" + std::to_string(hasAudioStream_.load())
  692. + ", hasVideo=" + std::to_string(hasVideoStream_.load()) + ")");
  693. }
  694. void SynchronizerV2::updateSyncState() {
  695. if (!running_) {
  696. state_ = SyncState::IDLE;
  697. return;
  698. }
  699. if (paused_) {
  700. return;
  701. }
  702. double syncError = calculateSyncErrorInternal();
  703. SyncState newState = state_;
  704. if (syncError <= config_.syncThreshold) {
  705. newState = SyncState::SYNCHRONIZED;
  706. recoveryAttempts_ = 0; // 重置恢复尝试次数
  707. } else if (syncError <= config_.adaptiveThreshold) {
  708. newState = SyncState::DRIFT;
  709. } else if (syncError <= config_.maxSyncError) {
  710. newState = SyncState::ERROR;
  711. } else {
  712. newState = SyncState::ERROR;
  713. // 尝试恢复
  714. if (recoveryAttempts_ < config_.maxRecoveryAttempts) {
  715. attemptRecovery();
  716. newState = SyncState::RECOVERING;
  717. }
  718. }
  719. if (newState != state_) {
  720. SyncState oldState = state_;
  721. state_ = newState;
  722. notifyStateChange(newState);
  723. Logger::instance().info("Sync state changed from " + std::to_string(static_cast<int>(oldState)) +
  724. " to " + std::to_string(static_cast<int>(newState)));
  725. }
  726. }
  727. void SynchronizerV2::updateStats() {
  728. // 统计信息在其他方法中已经更新
  729. }
  730. double SynchronizerV2::smoothClock(ClockType type, double newPts) {
  731. std::lock_guard<std::mutex> lock(historyMutex_);
  732. std::deque<double>* history = nullptr;
  733. switch (type) {
  734. case ClockType::AUDIO:
  735. history = &audioClockHistory_;
  736. break;
  737. case ClockType::VIDEO:
  738. history = &videoClockHistory_;
  739. break;
  740. default:
  741. return newPts;
  742. }
  743. if (history->empty()) {
  744. return newPts;
  745. }
  746. // 简单的指数移动平均
  747. double lastSmoothed = history->back();
  748. return lastSmoothed * (1.0 - config_.smoothingFactor) + newPts * config_.smoothingFactor;
  749. }
  750. double SynchronizerV2::predictClock(ClockType type, double futureTime) const {
  751. // 注意:此方法假设调用者已经持有clockMutex_锁
  752. // 不能再调用getClock,否则会导致死锁
  753. const ClockInfo* clock = nullptr;
  754. switch (type) {
  755. case ClockType::AUDIO:
  756. clock = &audioClock_;
  757. break;
  758. case ClockType::VIDEO:
  759. clock = &videoClock_;
  760. break;
  761. case ClockType::EXTERNAL:
  762. clock = &externalClock_;
  763. break;
  764. default:
  765. return 0.0;
  766. }
  767. if (clock->paused) {
  768. return clock->pts;
  769. }
  770. // 计算当前时间(不调用getClock避免死锁)
  771. auto now = std::chrono::steady_clock::now();
  772. double elapsed = std::chrono::duration<double>(now - clock->lastUpdate).count();
  773. double currentPts = clock->pts + elapsed * clock->speed;
  774. return currentPts + futureTime * clock->speed;
  775. }
  776. void SynchronizerV2::updateClockHistory(ClockType type, double pts) {
  777. std::lock_guard<std::mutex> lock(historyMutex_);
  778. std::deque<double>* history = nullptr;
  779. switch (type) {
  780. case ClockType::AUDIO:
  781. history = &audioClockHistory_;
  782. break;
  783. case ClockType::VIDEO:
  784. history = &videoClockHistory_;
  785. break;
  786. default:
  787. return;
  788. }
  789. history->push_back(pts);
  790. while (history->size() > static_cast<size_t>(config_.smoothingWindow)) {
  791. history->pop_front();
  792. }
  793. }
  794. void SynchronizerV2::attemptRecovery() {
  795. recoveryAttempts_++;
  796. lastRecoveryTime_ = std::chrono::steady_clock::now();
  797. Logger::instance().warning("Attempting sync recovery, attempt: " + std::to_string(recoveryAttempts_));
  798. // 重置时钟漂移
  799. std::lock_guard<std::mutex> lock(clockMutex_);
  800. audioClock_.drift = 0.0;
  801. videoClock_.drift = 0.0;
  802. externalClock_.drift = 0.0;
  803. // 可能需要重新选择主时钟
  804. if (config_.enableAdaptiveSync) {
  805. selectMasterClock();
  806. }
  807. }
  808. double SynchronizerV2::getCurrentTime() const {
  809. auto now = std::chrono::steady_clock::now();
  810. return std::chrono::duration<double>(now - startTime_).count();
  811. }
  812. double SynchronizerV2::getSystemTime() const {
  813. return av_gettime_relative() / 1000000.0;
  814. }
  815. void SynchronizerV2::notifyStateChange(SyncState newState) {
  816. if (syncEventCallback_) {
  817. syncEventCallback_(state_, newState);
  818. }
  819. }
  820. void SynchronizerV2::notifyFrameDrop(ClockType type, double pts) {
  821. if (frameDropCallback_) {
  822. frameDropCallback_(type, pts);
  823. }
  824. }
  825. void SynchronizerV2::notifyFrameDuplicate(ClockType type, double pts) {
  826. if (frameDuplicateCallback_) {
  827. frameDuplicateCallback_(type, pts);
  828. }
  829. }
  830. void SynchronizerV2::notifySyncError(double error, const std::string& reason) {
  831. if (syncErrorCallback_) {
  832. syncErrorCallback_(error, reason);
  833. }
  834. }
  835. } // namespace utils
  836. } // namespace av