utils_synchronizer_v2.cpp 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537
  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. , state_(SyncState::IDLE)
  12. , masterClockType_(ClockType::AUDIO)
  13. , initialized_(false)
  14. , running_(false)
  15. , paused_(false)
  16. , recoveryAttempts_(0)
  17. , lastSyncError_(0.0)
  18. {
  19. // 初始化时钟
  20. audioClock_ = ClockInfo();
  21. videoClock_ = ClockInfo();
  22. externalClock_ = ClockInfo();
  23. // 初始化历史记录
  24. audioClockHistory_.clear();
  25. videoClockHistory_.clear();
  26. syncErrorHistory_.clear();
  27. Logger::instance().info("SynchronizerV2 created with strategy: " +
  28. std::to_string(static_cast<int>(config_.strategy)));
  29. }
  30. SynchronizerV2::~SynchronizerV2() {
  31. close();
  32. Logger::instance().info("SynchronizerV2 destroyed");
  33. }
  34. ErrorCode SynchronizerV2::initialize() {
  35. if (initialized_) {
  36. return ErrorCode::ALREADY_INITIALIZED;
  37. }
  38. std::lock_guard<std::mutex> clockLock(clockMutex_);
  39. std::lock_guard<std::mutex> statsLock(statsMutex_);
  40. // 重置所有时钟
  41. resetClock(ClockType::AUDIO);
  42. resetClock(ClockType::VIDEO);
  43. resetClock(ClockType::EXTERNAL);
  44. // 选择主时钟
  45. selectMasterClock();
  46. // 重置统计信息
  47. stats_ = SyncStatsV2();
  48. stats_.lastUpdateTime = std::chrono::steady_clock::now();
  49. // 设置开始时间
  50. startTime_ = std::chrono::steady_clock::now();
  51. lastClockUpdate_ = startTime_;
  52. lastStatsUpdate_ = startTime_;
  53. state_ = SyncState::IDLE;
  54. initialized_ = true;
  55. recoveryAttempts_ = 0;
  56. Logger::instance().info("SynchronizerV2 initialized");
  57. return ErrorCode::SUCCESS;
  58. }
  59. ErrorCode SynchronizerV2::start() {
  60. if (!initialized_) {
  61. return ErrorCode::NOT_INITIALIZED;
  62. }
  63. if (running_) {
  64. return ErrorCode::ALREADY_STARTED;
  65. }
  66. running_ = true;
  67. paused_ = false;
  68. state_ = SyncState::INITIALIZING;
  69. startTime_ = std::chrono::steady_clock::now();
  70. lastClockUpdate_ = startTime_;
  71. // 按照packets_sync.cpp的init_clock逻辑初始化外部时钟
  72. // 外部时钟应该初始化为NAN,而不是系统时间
  73. {
  74. std::lock_guard<std::mutex> lock(clockMutex_);
  75. if (std::isnan(externalClock_.pts)) {
  76. // 严格按照packets_sync.cpp的init_clock实现
  77. // 外部时钟初始化为NAN,不使用系统时间
  78. double currentTime = av_gettime_relative() / 1000000.0;
  79. externalClock_.pts = std::numeric_limits<double>::quiet_NaN(); // 初始化为NAN
  80. externalClock_.pts_drift = 0.0; // 初始化pts_drift
  81. externalClock_.lastUpdate = currentTime;
  82. externalClock_.speed = 1.0;
  83. externalClock_.serial = -1;
  84. externalClock_.paused = false;
  85. externalClock_.time = currentTime;
  86. externalClock_.drift = 0.0;
  87. externalClock_.smoothedPts = std::numeric_limits<double>::quiet_NaN();
  88. }
  89. }
  90. // 启动后立即进入同步状态
  91. state_ = SyncState::SYNCING;
  92. Logger::instance().info("SynchronizerV2 started");
  93. return ErrorCode::SUCCESS;
  94. }
  95. void SynchronizerV2::setStreamInfo(bool hasAudio, bool hasVideo) {
  96. std::lock_guard<std::mutex> lock(clockMutex_);
  97. hasAudioStream_ = hasAudio;
  98. hasVideoStream_ = hasVideo;
  99. Logger::instance().info("Stream info updated: hasAudio=" + std::to_string(hasAudio) +
  100. ", hasVideo=" + std::to_string(hasVideo));
  101. // 重新选择主时钟
  102. selectMasterClock();
  103. }
  104. ErrorCode SynchronizerV2::stop() {
  105. if (!running_) {
  106. return ErrorCode::NOT_STARTED;
  107. }
  108. running_ = false;
  109. paused_ = false;
  110. state_ = SyncState::IDLE;
  111. Logger::instance().info("SynchronizerV2 stopped");
  112. return ErrorCode::SUCCESS;
  113. }
  114. ErrorCode SynchronizerV2::pause() {
  115. if (!running_) {
  116. return ErrorCode::NOT_STARTED;
  117. }
  118. if (paused_) {
  119. return ErrorCode::ALREADY_PAUSED;
  120. }
  121. std::lock_guard<std::mutex> lock(clockMutex_);
  122. paused_ = true;
  123. // 暂停所有时钟
  124. pauseClock(ClockType::AUDIO, true);
  125. pauseClock(ClockType::VIDEO, true);
  126. pauseClock(ClockType::EXTERNAL, true);
  127. Logger::instance().info("SynchronizerV2 paused");
  128. return ErrorCode::SUCCESS;
  129. }
  130. ErrorCode SynchronizerV2::resume() {
  131. if (!running_) {
  132. return ErrorCode::NOT_STARTED;
  133. }
  134. if (!paused_) {
  135. return ErrorCode::NOT_PAUSED;
  136. }
  137. std::lock_guard<std::mutex> lock(clockMutex_);
  138. paused_ = false;
  139. // 恢复所有时钟
  140. pauseClock(ClockType::AUDIO, false);
  141. pauseClock(ClockType::VIDEO, false);
  142. pauseClock(ClockType::EXTERNAL, false);
  143. state_ = SyncState::SYNCING;
  144. Logger::instance().info("SynchronizerV2 resumed");
  145. return ErrorCode::SUCCESS;
  146. }
  147. ErrorCode SynchronizerV2::reset() {
  148. std::lock_guard<std::mutex> clockLock(clockMutex_);
  149. std::lock_guard<std::mutex> statsLock(statsMutex_);
  150. std::lock_guard<std::mutex> historyLock(historyMutex_);
  151. // 重置时钟
  152. resetClock(ClockType::AUDIO);
  153. resetClock(ClockType::VIDEO);
  154. resetClock(ClockType::EXTERNAL);
  155. // 重置统计信息
  156. stats_ = SyncStatsV2();
  157. stats_.lastUpdateTime = std::chrono::steady_clock::now();
  158. // 清空历史记录
  159. audioClockHistory_.clear();
  160. videoClockHistory_.clear();
  161. syncErrorHistory_.clear();
  162. // 重置状态
  163. state_ = running_ ? SyncState::SYNCING : SyncState::IDLE;
  164. recoveryAttempts_ = 0;
  165. lastSyncError_ = 0.0;
  166. // 重新选择主时钟
  167. selectMasterClock();
  168. Logger::instance().info("SynchronizerV2 reset");
  169. return ErrorCode::SUCCESS;
  170. }
  171. ErrorCode SynchronizerV2::close() {
  172. if (running_) {
  173. stop();
  174. }
  175. initialized_ = false;
  176. Logger::instance().info("SynchronizerV2 closed");
  177. return ErrorCode::SUCCESS;
  178. }
  179. ErrorCode SynchronizerV2::setAudioClock(int64_t pts, double timeBase, int serial) {
  180. return updateClock(ClockType::AUDIO, pts, timeBase, serial);
  181. }
  182. ErrorCode SynchronizerV2::setVideoClock(int64_t pts, double timeBase, int serial) {
  183. return updateClock(ClockType::VIDEO, pts, timeBase, serial);
  184. }
  185. ErrorCode SynchronizerV2::setExternalClock(int64_t pts, double timeBase, int serial) {
  186. return updateClock(ClockType::EXTERNAL, pts, timeBase, serial);
  187. }
  188. int64_t SynchronizerV2::getAudioClock(bool predict) const {
  189. return getClock(ClockType::AUDIO, predict);
  190. }
  191. int64_t SynchronizerV2::getVideoClock(bool predict) const {
  192. return getClock(ClockType::VIDEO, predict);
  193. }
  194. int64_t SynchronizerV2::getExternalClock(bool predict) const {
  195. return getClock(ClockType::EXTERNAL, predict);
  196. }
  197. int64_t SynchronizerV2::getMasterClock(bool predict) const {
  198. return getClock(masterClockType_, predict);
  199. }
  200. FrameDecision SynchronizerV2::shouldDisplayVideoFrame(int64_t pts, double timeBase, double duration) {
  201. FrameDecision decision;
  202. decision.actualPts = pts;
  203. if (!running_ || paused_) {
  204. decision.action = FrameAction::DELAY;
  205. decision.delay = 0.01; // 10ms
  206. decision.reason = paused_ ? "Paused" : "Not running";
  207. return decision;
  208. }
  209. // 参考AVPlayer2的视频帧显示决策算法
  210. double delay = duration > 0 ? duration : (1.0 / 25.0); // 默认25fps
  211. // 如果视频是主时钟,直接显示
  212. if (masterClockType_ == ClockType::VIDEO) {
  213. decision.action = FrameAction::DISPLAY;
  214. decision.delay = delay;
  215. decision.reason = "Video master";
  216. decision.targetPts = pts;
  217. return decision;
  218. }
  219. // 获取主时钟并计算同步误差
  220. int64_t masterClock = getMasterClock(false); // 不使用预测,获取当前值
  221. decision.targetPts = masterClock;
  222. double videoPts = ptsToSeconds(pts, timeBase);
  223. double masterPts = ptsToSeconds(masterClock, timeBase);
  224. double diff = videoPts - masterPts;
  225. decision.syncError = diff;
  226. // 添加调试日志(仅在同步误差较大时)
  227. if (std::abs(diff) > 1.0) { // 超过1秒时记录
  228. Logger::instance().warning("Large video sync error: videoPTS=" +
  229. std::to_string(videoPts) + "s, masterPTS=" +
  230. std::to_string(masterPts) + "s, diff=" +
  231. std::to_string(diff) + "s, masterClock=" +
  232. std::to_string(masterClock) + ", timeBase=" +
  233. std::to_string(timeBase));
  234. }
  235. // 参考packets_sync.cpp的AV_NOSYNC_THRESHOLD检查
  236. if (std::isnan(diff) || std::isinf(diff) || std::abs(diff) >= config_.noSyncThreshold) {
  237. // 同步误差过大,强制显示帧,不进行同步校正
  238. decision.action = FrameAction::DISPLAY;
  239. decision.delay = delay;
  240. decision.reason = "Large sync error, force display (diff: " + std::to_string(diff * 1000) + "ms)";
  241. decision.targetPts = pts;
  242. Logger::instance().warningf(
  243. "Video sync error exceeds AV_NOSYNC_THRESHOLD: " + std::to_string(diff * 1000) + "ms");
  244. return decision;
  245. }
  246. // 参考AVPlayer2的compute_target_delay算法进行同步调整
  247. double sync_threshold = std::max(config_.syncThreshold, std::min(0.1, delay));
  248. // 检查差异是否在合理范围内(避免异常值)
  249. if (!std::isnan(diff) && std::abs(diff) < config_.maxSyncError) {
  250. if (diff <= -sync_threshold) {
  251. // 视频落后太多,丢帧追赶
  252. decision.action = FrameAction::DROP;
  253. decision.reason = "Video too slow, drop frame";
  254. // 通知丢帧
  255. if (frameDropCallback_) {
  256. frameDropCallback_(ClockType::VIDEO, pts);
  257. }
  258. // 更新统计
  259. std::lock_guard<std::mutex> lock(statsMutex_);
  260. stats_.droppedFrames++;
  261. } else if (diff >= sync_threshold && delay > config_.frameDupThreshold) {
  262. // 视频超前且延迟足够大,增加延迟
  263. decision.action = FrameAction::DELAY;
  264. decision.delay = delay + diff;
  265. decision.reason = "Video too fast, increase delay";
  266. } else if (diff >= sync_threshold) {
  267. // 视频超前但延迟较小,重复帧
  268. decision.action = FrameAction::Frame_DUPLICATE;
  269. decision.delay = 2 * delay;
  270. decision.reason = "Video too fast, duplicate frame";
  271. // 通知重复帧
  272. if (frameDuplicateCallback_) {
  273. frameDuplicateCallback_(ClockType::VIDEO, pts);
  274. }
  275. // 更新统计
  276. std::lock_guard<std::mutex> lock(statsMutex_);
  277. stats_.duplicatedFrames++;
  278. } else {
  279. // 正常显示
  280. decision.action = FrameAction::DISPLAY;
  281. decision.delay = delay;
  282. decision.reason = "Normal display";
  283. }
  284. } else {
  285. // 同步误差过大或异常,需要智能处理
  286. if (std::isnan(diff) || std::isinf(diff)) {
  287. // 异常值,强制显示
  288. decision.action = FrameAction::DISPLAY;
  289. decision.delay = delay;
  290. decision.reason = "Invalid sync value, force display";
  291. } else if (diff < -config_.maxSyncError) {
  292. // 视频严重落后,丢帧追赶
  293. decision.action = FrameAction::DROP;
  294. decision.reason = "Video severely behind, drop frame";
  295. // 通知丢帧
  296. if (frameDropCallback_) {
  297. frameDropCallback_(ClockType::VIDEO, pts);
  298. }
  299. // 更新统计
  300. std::lock_guard<std::mutex> lock(statsMutex_);
  301. stats_.droppedFrames++;
  302. } else if (diff > config_.maxSyncError) {
  303. // 视频严重超前,大幅延迟
  304. decision.action = FrameAction::DELAY;
  305. decision.delay = std::min(delay + diff, 0.5); // 最大延迟500ms
  306. decision.reason = "Video severely ahead, large delay";
  307. } else {
  308. // 其他情况,使用默认延迟
  309. decision.action = FrameAction::DISPLAY;
  310. decision.delay = delay;
  311. decision.reason = "Sync error large, default display";
  312. }
  313. // 触发恢复机制
  314. if (state_ != SyncState::RECOVERING && recoveryAttempts_ < config_.maxRecoveryAttempts) {
  315. state_ = SyncState::RECOVERING;
  316. recoveryAttempts_++;
  317. }
  318. }
  319. // 更新统计
  320. {
  321. std::lock_guard<std::mutex> lock(statsMutex_);
  322. stats_.totalFrames++;
  323. stats_.syncError = diff;
  324. // 更新平均同步误差
  325. if (stats_.totalFrames == 1) {
  326. stats_.avgSyncError = std::abs(diff);
  327. } else {
  328. stats_.avgSyncError = stats_.avgSyncError * 0.9 + std::abs(diff) * 0.1;
  329. }
  330. // 更新最大同步误差
  331. stats_.maxSyncError = std::max(stats_.maxSyncError, std::abs(diff));
  332. }
  333. return decision;
  334. }
  335. FrameDecision SynchronizerV2::shouldPlayAudioFrame(int64_t pts, double timeBase, double duration) {
  336. FrameDecision decision;
  337. decision.actualPts = pts;
  338. if (!running_ || paused_) {
  339. decision.action = FrameAction::DELAY;
  340. decision.delay = 0.01; // 10ms
  341. decision.reason = paused_ ? "Paused" : "Not running";
  342. return decision;
  343. }
  344. // 参考AVPlayer2的音频帧播放决策算法
  345. double delay = duration > 0 ? duration : 0.02; // 默认20ms
  346. // 如果音频是主时钟,直接播放
  347. if (masterClockType_ == ClockType::AUDIO) {
  348. decision.action = FrameAction::DISPLAY;
  349. decision.delay = delay;
  350. decision.reason = "Audio master";
  351. decision.targetPts = pts;
  352. return decision;
  353. }
  354. // 获取主时钟并计算同步误差
  355. int64_t masterClock = getMasterClock(false); // 不使用预测,获取当前值
  356. decision.targetPts = masterClock;
  357. // 检查主时钟是否有效
  358. if (masterClock == AV_NOPTS_VALUE) {
  359. decision.action = FrameAction::DISPLAY;
  360. decision.delay = delay;
  361. decision.reason = "Master clock invalid, force play";
  362. return decision;
  363. }
  364. double audioPts = ptsToSeconds(pts, timeBase);
  365. double masterPts = ptsToSeconds(masterClock, timeBase);
  366. double diff = audioPts - masterPts;
  367. decision.syncError = diff;
  368. // 参考packets_sync.cpp的AV_NOSYNC_THRESHOLD检查
  369. if (std::isnan(diff) || std::isinf(diff) || std::abs(diff) >= config_.noSyncThreshold) {
  370. // 同步误差过大,不进行同步修正,直接播放
  371. decision.action = FrameAction::DISPLAY;
  372. decision.delay = delay;
  373. decision.reason = "Sync error too large (>" + std::to_string(config_.noSyncThreshold) + "s), no sync";
  374. // 记录大误差日志
  375. if (std::abs(diff) > 1.0) {
  376. Logger::instance().warning("Large audio sync error: audioPTS=" +
  377. std::to_string(audioPts) + "s, masterPTS=" +
  378. std::to_string(masterPts) + "s, diff=" +
  379. std::to_string(diff) + "s");
  380. }
  381. return decision;
  382. }
  383. // 参考packets_sync.cpp的音频同步算法
  384. double sync_threshold = config_.syncThreshold;
  385. // 正常同步处理
  386. if (diff <= -sync_threshold) {
  387. // 音频落后太多,丢帧追赶
  388. decision.action = FrameAction::DROP;
  389. decision.reason = "Audio too slow, drop frame (diff=" + std::to_string(diff * 1000) + "ms)";
  390. // 通知丢帧
  391. if (frameDropCallback_) {
  392. frameDropCallback_(ClockType::AUDIO, pts);
  393. }
  394. // 更新统计
  395. std::lock_guard<std::mutex> lock(statsMutex_);
  396. stats_.droppedFrames++;
  397. } else if (diff >= sync_threshold) {
  398. // 音频超前,延迟播放
  399. decision.action = FrameAction::DELAY;
  400. decision.delay = delay + diff;
  401. decision.reason = "Audio too fast, delay (diff=" + std::to_string(diff * 1000) + "ms)";
  402. } else {
  403. // 正常播放
  404. decision.action = FrameAction::DISPLAY;
  405. decision.delay = delay;
  406. decision.reason = "Normal play (diff=" + std::to_string(diff * 1000) + "ms)";
  407. }
  408. // 更新统计
  409. {
  410. std::lock_guard<std::mutex> lock(statsMutex_);
  411. stats_.totalFrames++;
  412. stats_.syncError = diff;
  413. // 更新平均同步误差
  414. if (stats_.totalFrames == 1) {
  415. stats_.avgSyncError = std::abs(diff);
  416. } else {
  417. stats_.avgSyncError = stats_.avgSyncError * 0.9 + std::abs(diff) * 0.1;
  418. }
  419. // 更新最大同步误差
  420. stats_.maxSyncError = std::max(stats_.maxSyncError, std::abs(diff));
  421. }
  422. return decision;
  423. }
  424. double SynchronizerV2::calculateTargetDelay(int64_t pts, double timeBase, ClockType clockType) {
  425. if (!running_) {
  426. return 0.0;
  427. }
  428. // 参考packets_sync.cpp的compute_target_delay算法
  429. double delay = 0.0;
  430. // 基础帧延迟
  431. if (clockType == ClockType::VIDEO) {
  432. delay = 1.0 / 25.0; // 默认25fps,40ms
  433. } else {
  434. delay = 0.0; // 音频不需要基础延迟
  435. }
  436. // 如果不是视频主时钟模式,需要进行同步调整
  437. if (masterClockType_ != ClockType::VIDEO && clockType == ClockType::VIDEO) {
  438. // 获取主时钟
  439. int64_t masterClock = getMasterClock(true);
  440. if (masterClock == AV_NOPTS_VALUE) {
  441. return delay; // 主时钟无效,返回基础延迟
  442. }
  443. // 计算视频时钟与主时钟的差异
  444. double videoPts = ptsToSeconds(pts, timeBase);
  445. double masterPts = ptsToSeconds(masterClock, timeBase);
  446. double diff = videoPts - masterPts;
  447. // 参考packets_sync.cpp的AV_NOSYNC_THRESHOLD检查
  448. if (std::isnan(diff) || std::isinf(diff) || std::abs(diff) >= config_.noSyncThreshold) {
  449. // 同步误差过大,不进行同步校正,返回基础延迟
  450. return delay;
  451. }
  452. // 计算同步阈值,参考packets_sync.cpp的动态阈值算法
  453. double sync_threshold = std::max(config_.syncThreshold, std::min(0.1, delay));
  454. // 检查差异是否在合理范围内(避免异常值)
  455. if (!std::isnan(diff) && std::abs(diff) < config_.maxSyncError) {
  456. if (diff <= -sync_threshold) {
  457. // 视频落后,减少延迟以追赶
  458. delay = std::max(0.0, delay + diff);
  459. } else if (diff >= sync_threshold && delay > config_.frameDupThreshold) {
  460. // 视频超前且延迟足够大,增加延迟
  461. delay = delay + diff;
  462. } else if (diff >= sync_threshold) {
  463. // 视频超前但延迟较小,加倍延迟
  464. delay = 2 * delay;
  465. }
  466. }
  467. }
  468. return delay;
  469. }
  470. bool SynchronizerV2::shouldDropFrame(int64_t pts, double timeBase, ClockType clockType) {
  471. if (!running_ || clockType == masterClockType_) {
  472. return false;
  473. }
  474. int64_t masterClock = getMasterClock();
  475. if (masterClock == AV_NOPTS_VALUE) {
  476. return false; // 主时钟无效,不丢帧
  477. }
  478. double ptsInSeconds = ptsToSeconds(pts, timeBase);
  479. double masterClockInSeconds = ptsToSeconds(masterClock, timeBase);
  480. double diff = ptsInSeconds - masterClockInSeconds;
  481. // 参考packets_sync.cpp的AV_NOSYNC_THRESHOLD检查
  482. if (std::isnan(diff) || std::isinf(diff) || std::abs(diff) >= config_.noSyncThreshold) {
  483. return false; // 同步误差过大,不丢帧
  484. }
  485. return diff < -config_.frameDropThreshold;
  486. }
  487. bool SynchronizerV2::shouldDuplicateFrame(int64_t pts, double timeBase, ClockType clockType) {
  488. if (!running_ || clockType == masterClockType_) {
  489. return false;
  490. }
  491. int64_t masterClock = getMasterClock();
  492. if (masterClock == AV_NOPTS_VALUE) {
  493. return false; // 主时钟无效,不复制帧
  494. }
  495. double ptsInSeconds = ptsToSeconds(pts, timeBase);
  496. double masterClockInSeconds = ptsToSeconds(masterClock, timeBase);
  497. double diff = ptsInSeconds - masterClockInSeconds;
  498. // 参考packets_sync.cpp的AV_NOSYNC_THRESHOLD检查
  499. if (std::isnan(diff) || std::isinf(diff) || std::abs(diff) >= config_.noSyncThreshold) {
  500. return false; // 同步误差过大,不复制帧
  501. }
  502. return diff > config_.frameDupThreshold;
  503. }
  504. double SynchronizerV2::calculateSyncError() const {
  505. if (!running_) {
  506. return 0.0;
  507. }
  508. double audioClock = getAudioClock();
  509. double videoClock = getVideoClock();
  510. if (audioClock <= 0 || videoClock <= 0) {
  511. return 0.0;
  512. }
  513. return std::abs(audioClock - videoClock);
  514. }
  515. // 内部版本,假设调用者已经持有clockMutex_锁
  516. double SynchronizerV2::calculateSyncErrorInternal() const {
  517. if (!running_) {
  518. return 0.0;
  519. }
  520. // 直接计算时钟值,避免调用getClock导致死锁,使用packets_sync.cpp的算法
  521. double audioClock = 0.0;
  522. double videoClock = 0.0;
  523. double currentTime = getSystemTime();
  524. // 计算音频时钟,使用packets_sync.cpp的get_clock算法
  525. if (!std::isnan(audioClock_.pts)) {
  526. if (audioClock_.paused) {
  527. audioClock = audioClock_.pts;
  528. } else {
  529. // 使用packets_sync.cpp的算法:pts + pts_drift + (current_time - last_updated) * speed
  530. audioClock = audioClock_.pts + audioClock_.pts_drift + (currentTime - audioClock_.lastUpdate) * audioClock_.speed;
  531. }
  532. }
  533. // 计算视频时钟,使用packets_sync.cpp的get_clock算法
  534. if (!std::isnan(videoClock_.pts)) {
  535. if (videoClock_.paused) {
  536. videoClock = videoClock_.pts;
  537. } else {
  538. // 使用packets_sync.cpp的算法:pts + pts_drift + (current_time - last_updated) * speed
  539. videoClock = videoClock_.pts + videoClock_.pts_drift + (currentTime - videoClock_.lastUpdate) * videoClock_.speed;
  540. }
  541. }
  542. if (audioClock <= 0 || videoClock <= 0) {
  543. return 0.0;
  544. }
  545. return std::abs(audioClock - videoClock);
  546. }
  547. double SynchronizerV2::calculateAudioDelay(int64_t pts, double timeBase) const {
  548. if (masterClockType_ == ClockType::AUDIO) {
  549. return 0.0;
  550. }
  551. int64_t masterClock = getMasterClock();
  552. double ptsInSeconds = ptsToSeconds(pts, timeBase);
  553. double masterClockInSeconds = ptsToSeconds(masterClock, timeBase);
  554. return ptsInSeconds - masterClockInSeconds;
  555. }
  556. double SynchronizerV2::calculateVideoDelay(int64_t pts, double timeBase) const {
  557. if (masterClockType_ == ClockType::VIDEO) {
  558. return 0.0;
  559. }
  560. int64_t masterClock = getMasterClock();
  561. double ptsInSeconds = ptsToSeconds(pts, timeBase);
  562. double masterClockInSeconds = ptsToSeconds(masterClock, timeBase);
  563. return ptsInSeconds - masterClockInSeconds;
  564. }
  565. void SynchronizerV2::setConfig(const SyncConfigV2& config) {
  566. std::lock_guard<std::mutex> lock(configMutex_);
  567. config_ = config;
  568. // 重新选择主时钟
  569. selectMasterClock();
  570. Logger::instance().info("SynchronizerV2 config updated");
  571. }
  572. SyncConfigV2 SynchronizerV2::getConfig() const {
  573. std::lock_guard<std::mutex> lock(configMutex_);
  574. return config_;
  575. }
  576. void SynchronizerV2::setSyncStrategy(SyncStrategy strategy) {
  577. std::lock_guard<std::mutex> lock(configMutex_);
  578. config_.strategy = strategy;
  579. selectMasterClock();
  580. Logger::instance().info("Sync strategy set to: " + std::to_string(static_cast<int>(strategy)));
  581. }
  582. SyncStrategy SynchronizerV2::getSyncStrategy() const {
  583. std::lock_guard<std::mutex> lock(configMutex_);
  584. return config_.strategy;
  585. }
  586. void SynchronizerV2::setPlaybackSpeed(double speed) {
  587. std::lock_guard<std::mutex> lock(clockMutex_);
  588. audioClock_.speed = speed;
  589. videoClock_.speed = speed;
  590. externalClock_.speed = speed;
  591. Logger::instance().info("Playback speed set to: " + std::to_string(speed) + "x");
  592. }
  593. double SynchronizerV2::getPlaybackSpeed() const {
  594. std::lock_guard<std::mutex> lock(clockMutex_);
  595. return audioClock_.speed;
  596. }
  597. bool SynchronizerV2::isSynchronized() const {
  598. return state_ == SyncState::SYNCHRONIZED;
  599. }
  600. SyncStatsV2 SynchronizerV2::getStats() const {
  601. std::lock_guard<std::mutex> lock(statsMutex_);
  602. SyncStatsV2 stats = stats_;
  603. // 更新当前时钟值
  604. stats.audioClock = getAudioClock();
  605. stats.videoClock = getVideoClock();
  606. stats.externalClock = getExternalClock();
  607. stats.masterClock = getMasterClock();
  608. stats.state = state_;
  609. stats.masterClockType = masterClockType_;
  610. return stats;
  611. }
  612. void SynchronizerV2::resetStats() {
  613. std::lock_guard<std::mutex> lock(statsMutex_);
  614. stats_ = SyncStatsV2();
  615. stats_.lastUpdateTime = std::chrono::steady_clock::now();
  616. Logger::instance().info("SynchronizerV2 stats reset");
  617. }
  618. void SynchronizerV2::setSyncEventCallback(SyncEventCallback callback) {
  619. syncEventCallback_ = callback;
  620. }
  621. void SynchronizerV2::setFrameDropCallback(FrameDropCallback callback) {
  622. frameDropCallback_ = callback;
  623. }
  624. void SynchronizerV2::setFrameDuplicateCallback(FrameDuplicateCallback callback) {
  625. frameDuplicateCallback_ = callback;
  626. }
  627. void SynchronizerV2::setSyncErrorCallback(SyncErrorCallback callback) {
  628. syncErrorCallback_ = callback;
  629. }
  630. void SynchronizerV2::enableAdaptiveSync(bool enable) {
  631. std::lock_guard<std::mutex> lock(configMutex_);
  632. config_.enableAdaptiveSync = enable;
  633. Logger::instance().info("Adaptive sync " + std::string(enable ? "enabled" : "disabled"));
  634. }
  635. void SynchronizerV2::enablePrediction(bool enable) {
  636. std::lock_guard<std::mutex> lock(configMutex_);
  637. config_.enablePrediction = enable;
  638. Logger::instance().info("Prediction " + std::string(enable ? "enabled" : "disabled"));
  639. }
  640. void SynchronizerV2::setClockUpdateInterval(double interval) {
  641. std::lock_guard<std::mutex> lock(configMutex_);
  642. config_.clockUpdateInterval = interval;
  643. Logger::instance().info("Clock update interval set to: " + std::to_string(interval * 1000) + "ms");
  644. }
  645. void SynchronizerV2::setSmoothingWindow(int window) {
  646. std::lock_guard<std::mutex> lock(configMutex_);
  647. config_.smoothingWindow = window;
  648. // 调整历史记录大小
  649. std::lock_guard<std::mutex> historyLock(historyMutex_);
  650. while (audioClockHistory_.size() > static_cast<size_t>(window)) {
  651. audioClockHistory_.pop_front();
  652. }
  653. while (videoClockHistory_.size() > static_cast<size_t>(window)) {
  654. videoClockHistory_.pop_front();
  655. }
  656. while (syncErrorHistory_.size() > static_cast<size_t>(window)) {
  657. syncErrorHistory_.pop_front();
  658. }
  659. Logger::instance().info("Smoothing window set to: " + std::to_string(window));
  660. }
  661. std::string SynchronizerV2::getDebugInfo() const {
  662. std::ostringstream oss;
  663. SyncStatsV2 stats = getStats();
  664. oss << std::fixed << std::setprecision(3);
  665. oss << "SynchronizerV2 Debug Info:\n";
  666. oss << " State: " << static_cast<int>(stats.state) << "\n";
  667. oss << " Master Clock: " << static_cast<int>(stats.masterClockType) << "\n";
  668. oss << " Audio Clock: " << stats.audioClock << "s\n";
  669. oss << " Video Clock: " << stats.videoClock << "s\n";
  670. oss << " External Clock: " << stats.externalClock << "s\n";
  671. oss << " Master Clock: " << stats.masterClock << "s\n";
  672. oss << " Sync Error: " << stats.syncError * 1000 << "ms\n";
  673. oss << " Avg Sync Error: " << stats.avgSyncError * 1000 << "ms\n";
  674. oss << " Max Sync Error: " << stats.maxSyncError * 1000 << "ms\n";
  675. oss << " Total Frames: " << stats.totalFrames << "\n";
  676. oss << " Dropped Frames: " << stats.droppedFrames << "\n";
  677. oss << " Duplicated Frames: " << stats.duplicatedFrames << "\n";
  678. oss << " Running: " << (running_ ? "Yes" : "No") << "\n";
  679. oss << " Paused: " << (paused_ ? "Yes" : "No") << "\n";
  680. return oss.str();
  681. }
  682. void SynchronizerV2::dumpClockInfo() const {
  683. std::lock_guard<std::mutex> lock(clockMutex_);
  684. Logger::instance().info("Clock Info Dump:");
  685. Logger::instance().info(" Audio - PTS: " + std::to_string(audioClock_.pts) +
  686. ", Speed: " + std::to_string(audioClock_.speed) +
  687. ", Paused: " + (audioClock_.paused ? "Yes" : "No"));
  688. Logger::instance().info(" Video - PTS: " + std::to_string(videoClock_.pts) +
  689. ", Speed: " + std::to_string(videoClock_.speed) +
  690. ", Paused: " + (videoClock_.paused ? "Yes" : "No"));
  691. Logger::instance().info(" External - PTS: " + std::to_string(externalClock_.pts) +
  692. ", Speed: " + std::to_string(externalClock_.speed) +
  693. ", Paused: " + (externalClock_.paused ? "Yes" : "No"));
  694. }
  695. // 私有方法实现
  696. ErrorCode SynchronizerV2::updateClock(ClockType type, int64_t pts, double timeBase, int serial) {
  697. if (!initialized_) {
  698. return ErrorCode::NOT_INITIALIZED;
  699. }
  700. // 参考packets_sync.cpp的set_clock_at实现,确保与AVPlayer2一致
  701. double currentTime = getSystemTime();
  702. double ptsInSeconds = ptsToSeconds(pts, timeBase);
  703. // 在锁内更新时钟数据
  704. {
  705. std::lock_guard<std::mutex> lock(clockMutex_);
  706. ClockInfo* clock = nullptr;
  707. switch (type) {
  708. case ClockType::AUDIO:
  709. clock = &audioClock_;
  710. break;
  711. case ClockType::VIDEO:
  712. clock = &videoClock_;
  713. break;
  714. case ClockType::EXTERNAL:
  715. clock = &externalClock_;
  716. break;
  717. default:
  718. return ErrorCode::INVALID_PARAMS;
  719. }
  720. // 检查序列号,参考packets_sync.cpp的序列号检查机制
  721. if (serial != 0 && clock->serial != serial) {
  722. // 序列号不匹配,可能是seek操作,重置时钟
  723. resetClock(type);
  724. clock->serial = serial;
  725. }
  726. // 严格按照packets_sync.cpp的set_clock_at算法更新时钟
  727. if (pts != AV_NOPTS_VALUE) {
  728. // 参考packets_sync.cpp: clock->pts_drift = pts - time
  729. clock->pts_drift = ptsInSeconds - currentTime;
  730. clock->pts = ptsInSeconds; // 存储转换后的秒值,与packets_sync.cpp一致
  731. clock->lastUpdate = currentTime;
  732. } else {
  733. clock->pts = std::numeric_limits<double>::quiet_NaN();
  734. clock->pts_drift = 0.0;
  735. clock->lastUpdate = currentTime;
  736. }
  737. clock->time = currentTime;
  738. clock->serial = serial;
  739. // 添加调试日志
  740. static int logCounter = 0;
  741. if (++logCounter % 100 == 0) { // 每100次更新记录一次
  742. std::string clockName = (type == ClockType::AUDIO) ? "Audio" :
  743. (type == ClockType::VIDEO) ? "Video" : "External";
  744. Logger::instance().info("Clock Update [" + clockName + "]: PTS=" +
  745. std::to_string(pts) + ", PTSSeconds=" +
  746. std::to_string(ptsInSeconds) + ", SystemTime=" +
  747. std::to_string(currentTime) + ", Drift=" +
  748. std::to_string(clock->drift));
  749. }
  750. // 平滑处理(保持原有逻辑,但确保使用正确的PTS值)
  751. if (config_.smoothingWindow > 1) {
  752. clock->smoothedPts = smoothClock(type, static_cast<int64_t>(ptsInSeconds * AV_TIME_BASE));
  753. } else {
  754. clock->smoothedPts = static_cast<int64_t>(ptsInSeconds * AV_TIME_BASE);
  755. }
  756. // 更新历史记录(转换为AV_TIME_BASE格式)
  757. updateClockHistory(type, static_cast<int64_t>(ptsInSeconds * AV_TIME_BASE));
  758. // 如果这是主时钟,同步外部时钟到主时钟
  759. if (type == masterClockType_ && type != ClockType::EXTERNAL) {
  760. syncClockToSlave(&externalClock_, clock);
  761. }
  762. // 定期更新统计信息
  763. auto now = std::chrono::steady_clock::now();
  764. if (std::chrono::duration_cast<std::chrono::milliseconds>(now - lastStatsUpdate_).count() > 100) {
  765. updateStats();
  766. lastStatsUpdate_ = now;
  767. }
  768. } // 释放clockMutex_锁
  769. // 在锁外更新同步状态,避免死锁
  770. updateSyncState();
  771. return ErrorCode::SUCCESS;
  772. }
  773. int64_t SynchronizerV2::getClock(ClockType type, bool predict) const {
  774. std::lock_guard<std::mutex> lock(clockMutex_);
  775. const ClockInfo* clock = nullptr;
  776. switch (type) {
  777. case ClockType::AUDIO:
  778. clock = &audioClock_;
  779. break;
  780. case ClockType::VIDEO:
  781. clock = &videoClock_;
  782. break;
  783. case ClockType::EXTERNAL:
  784. clock = &externalClock_;
  785. break;
  786. case ClockType::SYSTEM:
  787. return static_cast<int64_t>(getSystemTime() * AV_TIME_BASE);
  788. default:
  789. return AV_NOPTS_VALUE;
  790. }
  791. // 严格按照packets_sync.cpp的get_clock实现
  792. // 检查时钟是否有效(pts不为NAN,与packets_sync.cpp一致)
  793. if (std::isnan(clock->pts)) {
  794. return AV_NOPTS_VALUE;
  795. }
  796. double clockValue;
  797. if (clock->paused) {
  798. // 暂停状态下,直接返回暂停时的PTS值
  799. clockValue = clock->pts;
  800. } else {
  801. // 运行状态下,使用packets_sync.cpp的get_clock算法
  802. // get_clock算法:pts_drift + time - (time - last_updated) * (1.0 - speed)
  803. // 等价于:pts + pts_drift + (current_time - last_updated) * speed
  804. double currentTime = av_gettime_relative() / 1000000.0;
  805. clockValue = clock->pts_drift + currentTime - (currentTime - clock->lastUpdate) * (1.0 - clock->speed);
  806. }
  807. // 转换为AV_TIME_BASE时间基准
  808. int64_t currentPts = static_cast<int64_t>(clockValue * AV_TIME_BASE);
  809. // 如果启用预测
  810. if (predict && config_.enablePrediction) {
  811. return predictClock(type, config_.predictionWindow);
  812. }
  813. return currentPts;
  814. }
  815. void SynchronizerV2::resetClock(ClockType type) {
  816. ClockInfo* clock = nullptr;
  817. switch (type) {
  818. case ClockType::AUDIO:
  819. clock = &audioClock_;
  820. break;
  821. case ClockType::VIDEO:
  822. clock = &videoClock_;
  823. break;
  824. case ClockType::EXTERNAL:
  825. clock = &externalClock_;
  826. break;
  827. default:
  828. return;
  829. }
  830. // 严格按照packets_sync.cpp的init_clock实现
  831. // init_clock调用set_clock(c, NAN, -1),而set_clock使用av_gettime_relative
  832. double currentTime = av_gettime_relative() / 1000000.0;
  833. // 统一初始化所有时钟,与packets_sync.cpp保持一致
  834. clock->speed = 1.0;
  835. clock->paused = false;
  836. // 调用set_clock(c, NAN, -1)的等价操作
  837. clock->pts = std::numeric_limits<double>::quiet_NaN(); // 使用NAN,与packets_sync.cpp一致
  838. clock->pts_drift = clock->pts - currentTime; // set_clock_at的逻辑
  839. clock->lastUpdate = currentTime;
  840. clock->serial = -1;
  841. // 保留SynchronizerV2特有的字段
  842. clock->time = currentTime;
  843. clock->drift = 0.0;
  844. clock->smoothedPts = AV_NOPTS_VALUE;
  845. }
  846. // 严格按照packets_sync.cpp的sync_clock_to_slave实现
  847. void SynchronizerV2::syncClockToSlave(ClockInfo* slave, const ClockInfo* master) {
  848. if (!slave || !master) {
  849. return;
  850. }
  851. double currentTime = getSystemTime();
  852. // 计算主时钟当前值,使用packets_sync.cpp的get_clock算法
  853. double masterClock = std::numeric_limits<double>::quiet_NaN();
  854. if (!std::isnan(master->pts)) {
  855. if (master->paused) {
  856. masterClock = master->pts;
  857. } else {
  858. // 使用packets_sync.cpp的get_clock算法:pts_drift + time - (time - last_updated) * (1.0 - speed)
  859. masterClock = master->pts_drift + currentTime - (currentTime - master->lastUpdate) * (1.0 - master->speed);
  860. }
  861. }
  862. // 计算从时钟当前值,使用packets_sync.cpp的get_clock算法
  863. double slaveClock = std::numeric_limits<double>::quiet_NaN();
  864. if (!std::isnan(slave->pts)) {
  865. if (slave->paused) {
  866. slaveClock = slave->pts;
  867. } else {
  868. // 使用packets_sync.cpp的get_clock算法:pts_drift + time - (time - last_updated) * (1.0 - speed)
  869. slaveClock = slave->pts_drift + currentTime - (currentTime - slave->lastUpdate) * (1.0 - slave->speed);
  870. }
  871. }
  872. // 参考packets_sync.cpp的sync_clock_to_slave逻辑
  873. if (!std::isnan(masterClock) &&
  874. (std::isnan(slaveClock) || std::abs(masterClock - slaveClock) > config_.noSyncThreshold)) {
  875. // 按照packets_sync.cpp的set_clock_at算法同步从时钟到主时钟
  876. slave->pts = masterClock;
  877. slave->pts_drift = masterClock - currentTime;
  878. slave->lastUpdate = currentTime;
  879. slave->serial = master->serial;
  880. // 保留SynchronizerV2特有的字段
  881. slave->time = currentTime;
  882. slave->drift = masterClock - currentTime;
  883. }
  884. }
  885. void SynchronizerV2::pauseClock(ClockType type, bool pause) {
  886. ClockInfo* clock = nullptr;
  887. switch (type) {
  888. case ClockType::AUDIO:
  889. clock = &audioClock_;
  890. break;
  891. case ClockType::VIDEO:
  892. clock = &videoClock_;
  893. break;
  894. case ClockType::EXTERNAL:
  895. clock = &externalClock_;
  896. break;
  897. default:
  898. return;
  899. }
  900. if (clock->paused != pause) {
  901. double currentTime = getSystemTime();
  902. if (pause) {
  903. // 暂停时保存当前PTS,使用packets_sync.cpp的get_clock算法计算当前值
  904. if (!clock->paused && !std::isnan(clock->pts)) {
  905. clock->pts = clock->pts_drift + currentTime - (currentTime - clock->lastUpdate) * (1.0 - clock->speed);
  906. clock->pts_drift = 0.0; // 暂停后drift重置为0
  907. }
  908. } else {
  909. // 恢复时重新设置pts_drift,参考packets_sync.cpp的set_clock_at
  910. if (!std::isnan(clock->pts)) {
  911. clock->pts_drift = clock->pts - currentTime;
  912. }
  913. }
  914. clock->paused = pause;
  915. clock->lastUpdate = currentTime;
  916. clock->time = currentTime; // 保留SynchronizerV2特有字段
  917. }
  918. }
  919. void SynchronizerV2::selectMasterClock() {
  920. ClockType newMasterClock = masterClockType_;
  921. switch (config_.strategy) {
  922. case SyncStrategy::AUDIO_MASTER:
  923. newMasterClock = ClockType::AUDIO;
  924. break;
  925. case SyncStrategy::VIDEO_MASTER:
  926. newMasterClock = ClockType::VIDEO;
  927. break;
  928. case SyncStrategy::EXTERNAL_MASTER:
  929. newMasterClock = ClockType::EXTERNAL;
  930. break;
  931. case SyncStrategy::ADAPTIVE: {
  932. // 参考AVPlayer2的自适应主时钟选择算法
  933. if (config_.enableAdaptiveSync) {
  934. bool hasAudio = (hasAudioStream_ && !std::isnan(audioClock_.pts) && !audioClock_.paused);
  935. bool hasVideo = (hasVideoStream_ && !std::isnan(videoClock_.pts) && !videoClock_.paused);
  936. if (hasAudio && hasVideo) {
  937. // 音视频都存在时,评估时钟质量
  938. double currentTime = getSystemTime();
  939. // 计算音频时钟的稳定性
  940. double audioStability = 1.0;
  941. if (audioClock_.time > 0) {
  942. double audioAge = currentTime - audioClock_.time;
  943. audioStability = std::exp(-audioAge / 2.0); // 2秒衰减
  944. }
  945. // 计算视频时钟的稳定性
  946. double videoStability = 1.0;
  947. if (videoClock_.time > 0) {
  948. double videoAge = currentTime - videoClock_.time;
  949. videoStability = std::exp(-videoAge / 2.0); // 2秒衰减
  950. }
  951. // 考虑时钟漂移
  952. double audioDrift = std::abs(audioClock_.drift);
  953. double videoDrift = std::abs(videoClock_.drift);
  954. // 音频时钟通常更稳定,给予优先权
  955. double audioScore = audioStability * 1.2 / (1.0 + audioDrift * 10.0);
  956. double videoScore = videoStability / (1.0 + videoDrift * 10.0);
  957. if (audioScore > videoScore && audioScore > 0.3) {
  958. newMasterClock = ClockType::AUDIO;
  959. } else if (videoScore > 0.3) {
  960. newMasterClock = ClockType::VIDEO;
  961. } else {
  962. newMasterClock = ClockType::EXTERNAL;
  963. }
  964. } else if (hasAudio) {
  965. // 只有音频
  966. newMasterClock = ClockType::AUDIO;
  967. } else if (hasVideo) {
  968. // 只有视频
  969. newMasterClock = ClockType::VIDEO;
  970. } else {
  971. // 都没有,使用外部时钟
  972. newMasterClock = ClockType::EXTERNAL;
  973. }
  974. } else {
  975. // 简单逻辑:优先音频,但要检查时钟有效性
  976. bool hasValidAudio = (hasAudioStream_ && !std::isnan(audioClock_.pts));
  977. bool hasValidVideo = (hasVideoStream_ && !std::isnan(videoClock_.pts));
  978. if (hasValidAudio) {
  979. newMasterClock = ClockType::AUDIO;
  980. } else if (hasValidVideo) {
  981. newMasterClock = ClockType::VIDEO;
  982. } else {
  983. // 音视频时钟都无效,使用外部时钟
  984. newMasterClock = ClockType::EXTERNAL;
  985. }
  986. }
  987. break;
  988. }
  989. }
  990. // 如果选择外部时钟作为主时钟,但外部时钟无效,则初始化它
  991. if (newMasterClock == ClockType::EXTERNAL && std::isnan(externalClock_.pts)) {
  992. double currentTime = av_gettime_relative() / 1000000.0;
  993. externalClock_.pts = currentTime;
  994. externalClock_.pts_drift = 0.0;
  995. externalClock_.lastUpdate = currentTime;
  996. externalClock_.time = currentTime;
  997. externalClock_.serial = 0;
  998. externalClock_.paused = false;
  999. externalClock_.speed = 1.0;
  1000. externalClock_.drift = 0.0;
  1001. Logger::instance().info("External clock initialized as master with current time: " + std::to_string(currentTime));
  1002. }
  1003. // 只有当主时钟真正改变时才更新和记录日志
  1004. if (newMasterClock != masterClockType_) {
  1005. ClockType oldMasterClock = masterClockType_;
  1006. masterClockType_ = newMasterClock;
  1007. // 获取时钟状态信息用于调试
  1008. std::string audioStatus = "invalid";
  1009. std::string videoStatus = "invalid";
  1010. std::string externalStatus = "invalid";
  1011. if (!std::isnan(audioClock_.pts)) {
  1012. audioStatus = "valid(pts=" + std::to_string(audioClock_.pts) + ")";
  1013. }
  1014. if (!std::isnan(videoClock_.pts)) {
  1015. videoStatus = "valid(pts=" + std::to_string(videoClock_.pts) + ")";
  1016. }
  1017. if (!std::isnan(externalClock_.pts)) {
  1018. externalStatus = "valid(pts=" + std::to_string(externalClock_.pts) + ")";
  1019. }
  1020. Logger::instance().info("Master clock changed from "
  1021. + std::to_string(static_cast<int>(oldMasterClock))
  1022. + " to " + std::to_string(static_cast<int>(masterClockType_.load()))
  1023. + " (hasAudio=" + std::to_string(hasAudioStream_.load())
  1024. + ", hasVideo=" + std::to_string(hasVideoStream_.load())
  1025. + ", audio=" + audioStatus
  1026. + ", video=" + videoStatus
  1027. + ", external=" + externalStatus + ")");
  1028. }
  1029. }
  1030. void SynchronizerV2::updateSyncState() {
  1031. if (!running_) {
  1032. state_ = SyncState::IDLE;
  1033. return;
  1034. }
  1035. if (paused_) {
  1036. return;
  1037. }
  1038. double syncError = calculateSyncErrorInternal();
  1039. SyncState newState = state_;
  1040. bool needRecovery = false;
  1041. // 参考AVPlayer2的同步状态管理算法
  1042. if (syncError <= config_.syncThreshold) {
  1043. // 同步误差在可接受范围内
  1044. if (state_ == SyncState::RECOVERING || state_ == SyncState::INITIALIZING) {
  1045. // 从恢复或初始化状态转为同步状态
  1046. newState = SyncState::SYNCHRONIZED;
  1047. recoveryAttempts_ = 0;
  1048. } else if (state_ != SyncState::SYNCHRONIZED) {
  1049. newState = SyncState::SYNCHRONIZED;
  1050. }
  1051. } else if (syncError <= config_.adaptiveThreshold) {
  1052. // 轻微漂移状态
  1053. if (state_ == SyncState::SYNCHRONIZED) {
  1054. newState = SyncState::DRIFT;
  1055. } else if (state_ == SyncState::RECOVERING) {
  1056. // 恢复中但误差仍较大,继续恢复
  1057. double recoveryDuration = getCurrentTime() - recoveryStartTime_;
  1058. if (recoveryDuration > 3.0) { // 3秒恢复超时
  1059. if (recoveryAttempts_ < config_.maxRecoveryAttempts) {
  1060. needRecovery = true;
  1061. } else {
  1062. newState = SyncState::ERROR;
  1063. }
  1064. }
  1065. }
  1066. } else if (syncError <= config_.maxSyncError) {
  1067. // 同步误差较大但仍在可恢复范围内
  1068. if (state_ != SyncState::RECOVERING) {
  1069. newState = SyncState::ERROR;
  1070. if (recoveryAttempts_ < config_.maxRecoveryAttempts) {
  1071. needRecovery = true;
  1072. newState = SyncState::RECOVERING;
  1073. }
  1074. } else {
  1075. // 已在恢复状态,检查恢复超时
  1076. double recoveryDuration = getCurrentTime() - recoveryStartTime_;
  1077. if (recoveryDuration > 5.0) { // 5秒恢复超时
  1078. if (recoveryAttempts_ < config_.maxRecoveryAttempts) {
  1079. needRecovery = true;
  1080. } else {
  1081. newState = SyncState::ERROR;
  1082. }
  1083. }
  1084. }
  1085. } else {
  1086. // 同步误差过大
  1087. newState = SyncState::ERROR;
  1088. // 标记需要恢复,但不在这里直接调用attemptRecovery避免死锁
  1089. if (recoveryAttempts_ < config_.maxRecoveryAttempts) {
  1090. needRecovery = true;
  1091. newState = SyncState::RECOVERING;
  1092. }
  1093. }
  1094. // 检查长时间失同步的情况
  1095. if (newState == SyncState::ERROR && recoveryAttempts_ >= config_.maxRecoveryAttempts) {
  1096. static double lastResetTime = 0;
  1097. double currentTime = getCurrentTime();
  1098. if (currentTime - lastResetTime > 10.0) { // 10秒重置一次
  1099. // 尝试重新初始化同步
  1100. recoveryAttempts_ = 0;
  1101. newState = SyncState::INITIALIZING;
  1102. lastResetTime = currentTime;
  1103. Logger::instance().warning("Sync error persists, attempting full reset");
  1104. }
  1105. }
  1106. if (newState != state_) {
  1107. SyncState oldState = state_;
  1108. state_ = newState;
  1109. notifyStateChange(newState);
  1110. Logger::instance().info("Sync state changed from " + std::to_string(static_cast<int>(oldState)) +
  1111. " to " + std::to_string(static_cast<int>(newState)));
  1112. }
  1113. // 如果需要恢复,现在可以安全地调用恢复操作(因为updateSyncState现在在锁外被调用)
  1114. if (needRecovery) {
  1115. performDelayedRecovery();
  1116. }
  1117. }
  1118. void SynchronizerV2::updateStats() {
  1119. // 统计信息在其他方法中已经更新
  1120. }
  1121. int64_t SynchronizerV2::smoothClock(ClockType type, int64_t newPts) {
  1122. std::lock_guard<std::mutex> lock(historyMutex_);
  1123. std::deque<int64_t>* history = nullptr;
  1124. switch (type) {
  1125. case ClockType::AUDIO:
  1126. history = &audioClockHistory_;
  1127. break;
  1128. case ClockType::VIDEO:
  1129. history = &videoClockHistory_;
  1130. break;
  1131. default:
  1132. return newPts;
  1133. }
  1134. if (history->empty() || newPts == AV_NOPTS_VALUE) {
  1135. return newPts;
  1136. }
  1137. // 简单的指数移动平均
  1138. int64_t lastSmoothed = history->back();
  1139. if (lastSmoothed == AV_NOPTS_VALUE) {
  1140. return newPts;
  1141. }
  1142. double smoothed = static_cast<double>(lastSmoothed) * (1.0 - config_.smoothingFactor) +
  1143. static_cast<double>(newPts) * config_.smoothingFactor;
  1144. return static_cast<int64_t>(smoothed);
  1145. }
  1146. int64_t SynchronizerV2::predictClock(ClockType type, double futureTime) const {
  1147. // 注意:此方法假设调用者已经持有clockMutex_锁
  1148. // 不能再调用getClock,否则会导致死锁
  1149. const ClockInfo* clock = nullptr;
  1150. switch (type) {
  1151. case ClockType::AUDIO:
  1152. clock = &audioClock_;
  1153. break;
  1154. case ClockType::VIDEO:
  1155. clock = &videoClock_;
  1156. break;
  1157. case ClockType::EXTERNAL:
  1158. clock = &externalClock_;
  1159. break;
  1160. default:
  1161. return AV_NOPTS_VALUE;
  1162. }
  1163. if (clock->paused || std::isnan(clock->pts)) {
  1164. return static_cast<int64_t>(clock->pts * AV_TIME_BASE);
  1165. }
  1166. // 计算当前时间(不调用getClock避免死锁),使用packets_sync.cpp的get_clock算法
  1167. double currentTime = getSystemTime();
  1168. // 使用packets_sync.cpp的算法:pts + pts_drift + (current_time - last_updated) * speed
  1169. double currentPtsSeconds = clock->pts + clock->pts_drift + (currentTime - clock->lastUpdate) * clock->speed;
  1170. return static_cast<int64_t>((currentPtsSeconds + futureTime * clock->speed) * AV_TIME_BASE);
  1171. }
  1172. void SynchronizerV2::updateClockHistory(ClockType type, int64_t pts) {
  1173. std::lock_guard<std::mutex> lock(historyMutex_);
  1174. std::deque<int64_t>* history = nullptr;
  1175. switch (type) {
  1176. case ClockType::AUDIO:
  1177. history = &audioClockHistory_;
  1178. break;
  1179. case ClockType::VIDEO:
  1180. history = &videoClockHistory_;
  1181. break;
  1182. default:
  1183. return;
  1184. }
  1185. history->push_back(pts);
  1186. while (history->size() > static_cast<size_t>(config_.smoothingWindow)) {
  1187. history->pop_front();
  1188. }
  1189. }
  1190. void SynchronizerV2::attemptRecovery() {
  1191. recoveryAttempts_++;
  1192. lastRecoveryTime_ = std::chrono::steady_clock::now();
  1193. Logger::instance().warning("Attempting sync recovery, attempt: " + std::to_string(recoveryAttempts_));
  1194. // 重置时钟漂移
  1195. {
  1196. std::lock_guard<std::mutex> lock(clockMutex_);
  1197. audioClock_.drift = 0.0;
  1198. videoClock_.drift = 0.0;
  1199. externalClock_.drift = 0.0;
  1200. }
  1201. // 可能需要重新选择主时钟(在锁外面调用避免死锁)
  1202. if (config_.enableAdaptiveSync) {
  1203. selectMasterClock();
  1204. }
  1205. }
  1206. void SynchronizerV2::performDelayedRecovery() {
  1207. // 这个方法在不持有clockMutex_的情况下被调用
  1208. // 执行实际的恢复操作
  1209. // 检查恢复间隔,避免过于频繁的恢复
  1210. auto now = std::chrono::steady_clock::now();
  1211. auto timeSinceLastRecovery = std::chrono::duration<double>(now - lastRecoveryTime_).count();
  1212. if (timeSinceLastRecovery < 1.0) { // 至少间隔1秒
  1213. return;
  1214. }
  1215. recoveryAttempts_++;
  1216. lastRecoveryTime_ = now;
  1217. Logger::instance().warning("Performing delayed sync recovery, attempt: " + std::to_string(recoveryAttempts_));
  1218. // 重置时钟漂移
  1219. {
  1220. std::lock_guard<std::mutex> lock(clockMutex_);
  1221. audioClock_.drift = 0.0;
  1222. videoClock_.drift = 0.0;
  1223. externalClock_.drift = 0.0;
  1224. }
  1225. // 只有在恢复次数较少时才重新选择主时钟,避免频繁切换
  1226. if (config_.enableAdaptiveSync && recoveryAttempts_ <= 3) {
  1227. selectMasterClock();
  1228. }
  1229. }
  1230. double SynchronizerV2::getCurrentTime() const {
  1231. auto now = std::chrono::steady_clock::now();
  1232. return std::chrono::duration<double>(now - startTime_).count();
  1233. }
  1234. double SynchronizerV2::getSystemTime() const {
  1235. return av_gettime_relative() / 1000000.0;
  1236. }
  1237. void SynchronizerV2::notifyStateChange(SyncState newState) {
  1238. if (syncEventCallback_) {
  1239. syncEventCallback_(state_, newState);
  1240. }
  1241. }
  1242. void SynchronizerV2::notifyFrameDrop(ClockType type, int64_t pts) {
  1243. if (frameDropCallback_) {
  1244. frameDropCallback_(type, pts);
  1245. }
  1246. }
  1247. void SynchronizerV2::notifyFrameDuplicate(ClockType type, int64_t pts) {
  1248. if (frameDuplicateCallback_) {
  1249. frameDuplicateCallback_(type, pts);
  1250. }
  1251. }
  1252. void SynchronizerV2::notifySyncError(double error, const std::string& reason) {
  1253. if (syncErrorCallback_) {
  1254. syncErrorCallback_(error, reason);
  1255. }
  1256. }
  1257. // PTS转换辅助方法实现
  1258. double SynchronizerV2::ptsToSeconds(int64_t pts, double timeBase) const {
  1259. if (pts == AV_NOPTS_VALUE) {
  1260. return 0.0;
  1261. }
  1262. return pts * timeBase;
  1263. }
  1264. int64_t SynchronizerV2::secondsToPts(double seconds, double timeBase) const {
  1265. if (timeBase <= 0.0) {
  1266. return AV_NOPTS_VALUE;
  1267. }
  1268. return static_cast<int64_t>(seconds / timeBase);
  1269. }
  1270. } // namespace utils
  1271. } // namespace av