| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537 |
- #include "utils_synchronizer_v2.h"
- #include "../base/logger.h"
- #include <algorithm>
- #include <cmath>
- #include <sstream>
- #include <iomanip>
- namespace av {
- namespace utils {
- SynchronizerV2::SynchronizerV2(const SyncConfigV2& config)
- : config_(config)
- , state_(SyncState::IDLE)
- , masterClockType_(ClockType::AUDIO)
- , initialized_(false)
- , running_(false)
- , paused_(false)
- , recoveryAttempts_(0)
- , lastSyncError_(0.0)
- {
- // 初始化时钟
- audioClock_ = ClockInfo();
- videoClock_ = ClockInfo();
- externalClock_ = ClockInfo();
-
- // 初始化历史记录
- audioClockHistory_.clear();
- videoClockHistory_.clear();
- syncErrorHistory_.clear();
-
- Logger::instance().info("SynchronizerV2 created with strategy: " +
- std::to_string(static_cast<int>(config_.strategy)));
- }
- SynchronizerV2::~SynchronizerV2() {
- close();
- Logger::instance().info("SynchronizerV2 destroyed");
- }
- ErrorCode SynchronizerV2::initialize() {
- if (initialized_) {
- return ErrorCode::ALREADY_INITIALIZED;
- }
-
- std::lock_guard<std::mutex> clockLock(clockMutex_);
- std::lock_guard<std::mutex> statsLock(statsMutex_);
-
- // 重置所有时钟
- resetClock(ClockType::AUDIO);
- resetClock(ClockType::VIDEO);
- resetClock(ClockType::EXTERNAL);
-
- // 选择主时钟
- selectMasterClock();
-
- // 重置统计信息
- stats_ = SyncStatsV2();
- stats_.lastUpdateTime = std::chrono::steady_clock::now();
-
- // 设置开始时间
- startTime_ = std::chrono::steady_clock::now();
- lastClockUpdate_ = startTime_;
- lastStatsUpdate_ = startTime_;
-
- state_ = SyncState::IDLE;
- initialized_ = true;
- recoveryAttempts_ = 0;
-
- Logger::instance().info("SynchronizerV2 initialized");
- return ErrorCode::SUCCESS;
- }
- ErrorCode SynchronizerV2::start() {
- if (!initialized_) {
- return ErrorCode::NOT_INITIALIZED;
- }
-
- if (running_) {
- return ErrorCode::ALREADY_STARTED;
- }
-
- running_ = true;
- paused_ = false;
- state_ = SyncState::INITIALIZING;
-
- startTime_ = std::chrono::steady_clock::now();
- lastClockUpdate_ = startTime_;
-
- // 按照packets_sync.cpp的init_clock逻辑初始化外部时钟
- // 外部时钟应该初始化为NAN,而不是系统时间
- {
- std::lock_guard<std::mutex> lock(clockMutex_);
- if (std::isnan(externalClock_.pts)) {
- // 严格按照packets_sync.cpp的init_clock实现
- // 外部时钟初始化为NAN,不使用系统时间
- double currentTime = av_gettime_relative() / 1000000.0;
- externalClock_.pts = std::numeric_limits<double>::quiet_NaN(); // 初始化为NAN
- externalClock_.pts_drift = 0.0; // 初始化pts_drift
- externalClock_.lastUpdate = currentTime;
- externalClock_.speed = 1.0;
- externalClock_.serial = -1;
- externalClock_.paused = false;
- externalClock_.time = currentTime;
- externalClock_.drift = 0.0;
- externalClock_.smoothedPts = std::numeric_limits<double>::quiet_NaN();
- }
- }
-
- // 启动后立即进入同步状态
- state_ = SyncState::SYNCING;
-
- Logger::instance().info("SynchronizerV2 started");
- return ErrorCode::SUCCESS;
- }
- void SynchronizerV2::setStreamInfo(bool hasAudio, bool hasVideo) {
- std::lock_guard<std::mutex> lock(clockMutex_);
- hasAudioStream_ = hasAudio;
- hasVideoStream_ = hasVideo;
-
- Logger::instance().info("Stream info updated: hasAudio=" + std::to_string(hasAudio) +
- ", hasVideo=" + std::to_string(hasVideo));
-
- // 重新选择主时钟
- selectMasterClock();
- }
- ErrorCode SynchronizerV2::stop() {
- if (!running_) {
- return ErrorCode::NOT_STARTED;
- }
-
- running_ = false;
- paused_ = false;
- state_ = SyncState::IDLE;
-
- Logger::instance().info("SynchronizerV2 stopped");
- return ErrorCode::SUCCESS;
- }
- ErrorCode SynchronizerV2::pause() {
- if (!running_) {
- return ErrorCode::NOT_STARTED;
- }
-
- if (paused_) {
- return ErrorCode::ALREADY_PAUSED;
- }
-
- std::lock_guard<std::mutex> lock(clockMutex_);
-
- paused_ = true;
-
- // 暂停所有时钟
- pauseClock(ClockType::AUDIO, true);
- pauseClock(ClockType::VIDEO, true);
- pauseClock(ClockType::EXTERNAL, true);
-
- Logger::instance().info("SynchronizerV2 paused");
- return ErrorCode::SUCCESS;
- }
- ErrorCode SynchronizerV2::resume() {
- if (!running_) {
- return ErrorCode::NOT_STARTED;
- }
-
- if (!paused_) {
- return ErrorCode::NOT_PAUSED;
- }
-
- std::lock_guard<std::mutex> lock(clockMutex_);
-
- paused_ = false;
-
- // 恢复所有时钟
- pauseClock(ClockType::AUDIO, false);
- pauseClock(ClockType::VIDEO, false);
- pauseClock(ClockType::EXTERNAL, false);
-
- state_ = SyncState::SYNCING;
-
- Logger::instance().info("SynchronizerV2 resumed");
- return ErrorCode::SUCCESS;
- }
- ErrorCode SynchronizerV2::reset() {
- std::lock_guard<std::mutex> clockLock(clockMutex_);
- std::lock_guard<std::mutex> statsLock(statsMutex_);
- std::lock_guard<std::mutex> historyLock(historyMutex_);
-
- // 重置时钟
- resetClock(ClockType::AUDIO);
- resetClock(ClockType::VIDEO);
- resetClock(ClockType::EXTERNAL);
-
- // 重置统计信息
- stats_ = SyncStatsV2();
- stats_.lastUpdateTime = std::chrono::steady_clock::now();
-
- // 清空历史记录
- audioClockHistory_.clear();
- videoClockHistory_.clear();
- syncErrorHistory_.clear();
-
- // 重置状态
- state_ = running_ ? SyncState::SYNCING : SyncState::IDLE;
- recoveryAttempts_ = 0;
- lastSyncError_ = 0.0;
-
- // 重新选择主时钟
- selectMasterClock();
-
- Logger::instance().info("SynchronizerV2 reset");
- return ErrorCode::SUCCESS;
- }
- ErrorCode SynchronizerV2::close() {
- if (running_) {
- stop();
- }
-
- initialized_ = false;
-
- Logger::instance().info("SynchronizerV2 closed");
- return ErrorCode::SUCCESS;
- }
- ErrorCode SynchronizerV2::setAudioClock(int64_t pts, double timeBase, int serial) {
- return updateClock(ClockType::AUDIO, pts, timeBase, serial);
- }
- ErrorCode SynchronizerV2::setVideoClock(int64_t pts, double timeBase, int serial) {
- return updateClock(ClockType::VIDEO, pts, timeBase, serial);
- }
- ErrorCode SynchronizerV2::setExternalClock(int64_t pts, double timeBase, int serial) {
- return updateClock(ClockType::EXTERNAL, pts, timeBase, serial);
- }
- int64_t SynchronizerV2::getAudioClock(bool predict) const {
- return getClock(ClockType::AUDIO, predict);
- }
- int64_t SynchronizerV2::getVideoClock(bool predict) const {
- return getClock(ClockType::VIDEO, predict);
- }
- int64_t SynchronizerV2::getExternalClock(bool predict) const {
- return getClock(ClockType::EXTERNAL, predict);
- }
- int64_t SynchronizerV2::getMasterClock(bool predict) const {
- return getClock(masterClockType_, predict);
- }
- FrameDecision SynchronizerV2::shouldDisplayVideoFrame(int64_t pts, double timeBase, double duration) {
- FrameDecision decision;
- decision.actualPts = pts;
-
- if (!running_ || paused_) {
- decision.action = FrameAction::DELAY;
- decision.delay = 0.01; // 10ms
- decision.reason = paused_ ? "Paused" : "Not running";
- return decision;
- }
-
- // 参考AVPlayer2的视频帧显示决策算法
- double delay = duration > 0 ? duration : (1.0 / 25.0); // 默认25fps
-
- // 如果视频是主时钟,直接显示
- if (masterClockType_ == ClockType::VIDEO) {
- decision.action = FrameAction::DISPLAY;
- decision.delay = delay;
- decision.reason = "Video master";
- decision.targetPts = pts;
- return decision;
- }
-
- // 获取主时钟并计算同步误差
- int64_t masterClock = getMasterClock(false); // 不使用预测,获取当前值
- decision.targetPts = masterClock;
-
- double videoPts = ptsToSeconds(pts, timeBase);
- double masterPts = ptsToSeconds(masterClock, timeBase);
- double diff = videoPts - masterPts;
- decision.syncError = diff;
-
- // 添加调试日志(仅在同步误差较大时)
- if (std::abs(diff) > 1.0) { // 超过1秒时记录
- Logger::instance().warning("Large video sync error: videoPTS=" +
- std::to_string(videoPts) + "s, masterPTS=" +
- std::to_string(masterPts) + "s, diff=" +
- std::to_string(diff) + "s, masterClock=" +
- std::to_string(masterClock) + ", timeBase=" +
- std::to_string(timeBase));
- }
-
- // 参考packets_sync.cpp的AV_NOSYNC_THRESHOLD检查
- if (std::isnan(diff) || std::isinf(diff) || std::abs(diff) >= config_.noSyncThreshold) {
- // 同步误差过大,强制显示帧,不进行同步校正
- decision.action = FrameAction::DISPLAY;
- decision.delay = delay;
- decision.reason = "Large sync error, force display (diff: " + std::to_string(diff * 1000) + "ms)";
- decision.targetPts = pts;
- Logger::instance().warningf(
- "Video sync error exceeds AV_NOSYNC_THRESHOLD: " + std::to_string(diff * 1000) + "ms");
- return decision;
- }
-
- // 参考AVPlayer2的compute_target_delay算法进行同步调整
- double sync_threshold = std::max(config_.syncThreshold, std::min(0.1, delay));
-
- // 检查差异是否在合理范围内(避免异常值)
- if (!std::isnan(diff) && std::abs(diff) < config_.maxSyncError) {
- if (diff <= -sync_threshold) {
- // 视频落后太多,丢帧追赶
- decision.action = FrameAction::DROP;
- decision.reason = "Video too slow, drop frame";
-
- // 通知丢帧
- if (frameDropCallback_) {
- frameDropCallback_(ClockType::VIDEO, pts);
- }
-
- // 更新统计
- std::lock_guard<std::mutex> lock(statsMutex_);
- stats_.droppedFrames++;
-
- } else if (diff >= sync_threshold && delay > config_.frameDupThreshold) {
- // 视频超前且延迟足够大,增加延迟
- decision.action = FrameAction::DELAY;
- decision.delay = delay + diff;
- decision.reason = "Video too fast, increase delay";
-
- } else if (diff >= sync_threshold) {
- // 视频超前但延迟较小,重复帧
- decision.action = FrameAction::Frame_DUPLICATE;
- decision.delay = 2 * delay;
- decision.reason = "Video too fast, duplicate frame";
-
- // 通知重复帧
- if (frameDuplicateCallback_) {
- frameDuplicateCallback_(ClockType::VIDEO, pts);
- }
-
- // 更新统计
- std::lock_guard<std::mutex> lock(statsMutex_);
- stats_.duplicatedFrames++;
-
- } else {
- // 正常显示
- decision.action = FrameAction::DISPLAY;
- decision.delay = delay;
- decision.reason = "Normal display";
- }
- } else {
- // 同步误差过大或异常,需要智能处理
- if (std::isnan(diff) || std::isinf(diff)) {
- // 异常值,强制显示
- decision.action = FrameAction::DISPLAY;
- decision.delay = delay;
- decision.reason = "Invalid sync value, force display";
- } else if (diff < -config_.maxSyncError) {
- // 视频严重落后,丢帧追赶
- decision.action = FrameAction::DROP;
- decision.reason = "Video severely behind, drop frame";
-
- // 通知丢帧
- if (frameDropCallback_) {
- frameDropCallback_(ClockType::VIDEO, pts);
- }
-
- // 更新统计
- std::lock_guard<std::mutex> lock(statsMutex_);
- stats_.droppedFrames++;
- } else if (diff > config_.maxSyncError) {
- // 视频严重超前,大幅延迟
- decision.action = FrameAction::DELAY;
- decision.delay = std::min(delay + diff, 0.5); // 最大延迟500ms
- decision.reason = "Video severely ahead, large delay";
- } else {
- // 其他情况,使用默认延迟
- decision.action = FrameAction::DISPLAY;
- decision.delay = delay;
- decision.reason = "Sync error large, default display";
- }
-
- // 触发恢复机制
- if (state_ != SyncState::RECOVERING && recoveryAttempts_ < config_.maxRecoveryAttempts) {
- state_ = SyncState::RECOVERING;
- recoveryAttempts_++;
- }
- }
-
- // 更新统计
- {
- std::lock_guard<std::mutex> lock(statsMutex_);
- stats_.totalFrames++;
- stats_.syncError = diff;
-
- // 更新平均同步误差
- if (stats_.totalFrames == 1) {
- stats_.avgSyncError = std::abs(diff);
- } else {
- stats_.avgSyncError = stats_.avgSyncError * 0.9 + std::abs(diff) * 0.1;
- }
-
- // 更新最大同步误差
- stats_.maxSyncError = std::max(stats_.maxSyncError, std::abs(diff));
- }
-
- return decision;
- }
- FrameDecision SynchronizerV2::shouldPlayAudioFrame(int64_t pts, double timeBase, double duration) {
- FrameDecision decision;
- decision.actualPts = pts;
-
- if (!running_ || paused_) {
- decision.action = FrameAction::DELAY;
- decision.delay = 0.01; // 10ms
- decision.reason = paused_ ? "Paused" : "Not running";
- return decision;
- }
-
- // 参考AVPlayer2的音频帧播放决策算法
- double delay = duration > 0 ? duration : 0.02; // 默认20ms
-
- // 如果音频是主时钟,直接播放
- if (masterClockType_ == ClockType::AUDIO) {
- decision.action = FrameAction::DISPLAY;
- decision.delay = delay;
- decision.reason = "Audio master";
- decision.targetPts = pts;
- return decision;
- }
-
- // 获取主时钟并计算同步误差
- int64_t masterClock = getMasterClock(false); // 不使用预测,获取当前值
- decision.targetPts = masterClock;
-
- // 检查主时钟是否有效
- if (masterClock == AV_NOPTS_VALUE) {
- decision.action = FrameAction::DISPLAY;
- decision.delay = delay;
- decision.reason = "Master clock invalid, force play";
- return decision;
- }
-
- double audioPts = ptsToSeconds(pts, timeBase);
- double masterPts = ptsToSeconds(masterClock, timeBase);
- double diff = audioPts - masterPts;
- decision.syncError = diff;
-
- // 参考packets_sync.cpp的AV_NOSYNC_THRESHOLD检查
- if (std::isnan(diff) || std::isinf(diff) || std::abs(diff) >= config_.noSyncThreshold) {
- // 同步误差过大,不进行同步修正,直接播放
- decision.action = FrameAction::DISPLAY;
- decision.delay = delay;
- decision.reason = "Sync error too large (>" + std::to_string(config_.noSyncThreshold) + "s), no sync";
-
- // 记录大误差日志
- if (std::abs(diff) > 1.0) {
- Logger::instance().warning("Large audio sync error: audioPTS=" +
- std::to_string(audioPts) + "s, masterPTS=" +
- std::to_string(masterPts) + "s, diff=" +
- std::to_string(diff) + "s");
- }
-
- return decision;
- }
-
- // 参考packets_sync.cpp的音频同步算法
- double sync_threshold = config_.syncThreshold;
-
- // 正常同步处理
- if (diff <= -sync_threshold) {
- // 音频落后太多,丢帧追赶
- decision.action = FrameAction::DROP;
- decision.reason = "Audio too slow, drop frame (diff=" + std::to_string(diff * 1000) + "ms)";
-
- // 通知丢帧
- if (frameDropCallback_) {
- frameDropCallback_(ClockType::AUDIO, pts);
- }
-
- // 更新统计
- std::lock_guard<std::mutex> lock(statsMutex_);
- stats_.droppedFrames++;
-
- } else if (diff >= sync_threshold) {
- // 音频超前,延迟播放
- decision.action = FrameAction::DELAY;
- decision.delay = delay + diff;
- decision.reason = "Audio too fast, delay (diff=" + std::to_string(diff * 1000) + "ms)";
-
- } else {
- // 正常播放
- decision.action = FrameAction::DISPLAY;
- decision.delay = delay;
- decision.reason = "Normal play (diff=" + std::to_string(diff * 1000) + "ms)";
- }
-
- // 更新统计
- {
- std::lock_guard<std::mutex> lock(statsMutex_);
- stats_.totalFrames++;
- stats_.syncError = diff;
-
- // 更新平均同步误差
- if (stats_.totalFrames == 1) {
- stats_.avgSyncError = std::abs(diff);
- } else {
- stats_.avgSyncError = stats_.avgSyncError * 0.9 + std::abs(diff) * 0.1;
- }
-
- // 更新最大同步误差
- stats_.maxSyncError = std::max(stats_.maxSyncError, std::abs(diff));
- }
-
- return decision;
- }
- double SynchronizerV2::calculateTargetDelay(int64_t pts, double timeBase, ClockType clockType) {
- if (!running_) {
- return 0.0;
- }
-
- // 参考packets_sync.cpp的compute_target_delay算法
- double delay = 0.0;
-
- // 基础帧延迟
- if (clockType == ClockType::VIDEO) {
- delay = 1.0 / 25.0; // 默认25fps,40ms
- } else {
- delay = 0.0; // 音频不需要基础延迟
- }
-
- // 如果不是视频主时钟模式,需要进行同步调整
- if (masterClockType_ != ClockType::VIDEO && clockType == ClockType::VIDEO) {
- // 获取主时钟
- int64_t masterClock = getMasterClock(true);
- if (masterClock == AV_NOPTS_VALUE) {
- return delay; // 主时钟无效,返回基础延迟
- }
-
- // 计算视频时钟与主时钟的差异
- double videoPts = ptsToSeconds(pts, timeBase);
- double masterPts = ptsToSeconds(masterClock, timeBase);
- double diff = videoPts - masterPts;
-
- // 参考packets_sync.cpp的AV_NOSYNC_THRESHOLD检查
- if (std::isnan(diff) || std::isinf(diff) || std::abs(diff) >= config_.noSyncThreshold) {
- // 同步误差过大,不进行同步校正,返回基础延迟
- return delay;
- }
-
- // 计算同步阈值,参考packets_sync.cpp的动态阈值算法
- double sync_threshold = std::max(config_.syncThreshold, std::min(0.1, delay));
-
- // 检查差异是否在合理范围内(避免异常值)
- if (!std::isnan(diff) && std::abs(diff) < config_.maxSyncError) {
- if (diff <= -sync_threshold) {
- // 视频落后,减少延迟以追赶
- delay = std::max(0.0, delay + diff);
- } else if (diff >= sync_threshold && delay > config_.frameDupThreshold) {
- // 视频超前且延迟足够大,增加延迟
- delay = delay + diff;
- } else if (diff >= sync_threshold) {
- // 视频超前但延迟较小,加倍延迟
- delay = 2 * delay;
- }
- }
- }
-
- return delay;
- }
- bool SynchronizerV2::shouldDropFrame(int64_t pts, double timeBase, ClockType clockType) {
- if (!running_ || clockType == masterClockType_) {
- return false;
- }
-
- int64_t masterClock = getMasterClock();
- if (masterClock == AV_NOPTS_VALUE) {
- return false; // 主时钟无效,不丢帧
- }
-
- double ptsInSeconds = ptsToSeconds(pts, timeBase);
- double masterClockInSeconds = ptsToSeconds(masterClock, timeBase);
- double diff = ptsInSeconds - masterClockInSeconds;
-
- // 参考packets_sync.cpp的AV_NOSYNC_THRESHOLD检查
- if (std::isnan(diff) || std::isinf(diff) || std::abs(diff) >= config_.noSyncThreshold) {
- return false; // 同步误差过大,不丢帧
- }
-
- return diff < -config_.frameDropThreshold;
- }
- bool SynchronizerV2::shouldDuplicateFrame(int64_t pts, double timeBase, ClockType clockType) {
- if (!running_ || clockType == masterClockType_) {
- return false;
- }
-
- int64_t masterClock = getMasterClock();
- if (masterClock == AV_NOPTS_VALUE) {
- return false; // 主时钟无效,不复制帧
- }
-
- double ptsInSeconds = ptsToSeconds(pts, timeBase);
- double masterClockInSeconds = ptsToSeconds(masterClock, timeBase);
- double diff = ptsInSeconds - masterClockInSeconds;
-
- // 参考packets_sync.cpp的AV_NOSYNC_THRESHOLD检查
- if (std::isnan(diff) || std::isinf(diff) || std::abs(diff) >= config_.noSyncThreshold) {
- return false; // 同步误差过大,不复制帧
- }
-
- return diff > config_.frameDupThreshold;
- }
- double SynchronizerV2::calculateSyncError() const {
- if (!running_) {
- return 0.0;
- }
-
- double audioClock = getAudioClock();
- double videoClock = getVideoClock();
-
- if (audioClock <= 0 || videoClock <= 0) {
- return 0.0;
- }
-
- return std::abs(audioClock - videoClock);
- }
- // 内部版本,假设调用者已经持有clockMutex_锁
- double SynchronizerV2::calculateSyncErrorInternal() const {
- if (!running_) {
- return 0.0;
- }
-
- // 直接计算时钟值,避免调用getClock导致死锁,使用packets_sync.cpp的算法
- double audioClock = 0.0;
- double videoClock = 0.0;
- double currentTime = getSystemTime();
-
- // 计算音频时钟,使用packets_sync.cpp的get_clock算法
- if (!std::isnan(audioClock_.pts)) {
- if (audioClock_.paused) {
- audioClock = audioClock_.pts;
- } else {
- // 使用packets_sync.cpp的算法:pts + pts_drift + (current_time - last_updated) * speed
- audioClock = audioClock_.pts + audioClock_.pts_drift + (currentTime - audioClock_.lastUpdate) * audioClock_.speed;
- }
- }
-
- // 计算视频时钟,使用packets_sync.cpp的get_clock算法
- if (!std::isnan(videoClock_.pts)) {
- if (videoClock_.paused) {
- videoClock = videoClock_.pts;
- } else {
- // 使用packets_sync.cpp的算法:pts + pts_drift + (current_time - last_updated) * speed
- videoClock = videoClock_.pts + videoClock_.pts_drift + (currentTime - videoClock_.lastUpdate) * videoClock_.speed;
- }
- }
-
- if (audioClock <= 0 || videoClock <= 0) {
- return 0.0;
- }
-
- return std::abs(audioClock - videoClock);
- }
- double SynchronizerV2::calculateAudioDelay(int64_t pts, double timeBase) const {
- if (masterClockType_ == ClockType::AUDIO) {
- return 0.0;
- }
-
- int64_t masterClock = getMasterClock();
- double ptsInSeconds = ptsToSeconds(pts, timeBase);
- double masterClockInSeconds = ptsToSeconds(masterClock, timeBase);
- return ptsInSeconds - masterClockInSeconds;
- }
- double SynchronizerV2::calculateVideoDelay(int64_t pts, double timeBase) const {
- if (masterClockType_ == ClockType::VIDEO) {
- return 0.0;
- }
-
- int64_t masterClock = getMasterClock();
- double ptsInSeconds = ptsToSeconds(pts, timeBase);
- double masterClockInSeconds = ptsToSeconds(masterClock, timeBase);
- return ptsInSeconds - masterClockInSeconds;
- }
- void SynchronizerV2::setConfig(const SyncConfigV2& config) {
- std::lock_guard<std::mutex> lock(configMutex_);
- config_ = config;
-
- // 重新选择主时钟
- selectMasterClock();
-
- Logger::instance().info("SynchronizerV2 config updated");
- }
- SyncConfigV2 SynchronizerV2::getConfig() const {
- std::lock_guard<std::mutex> lock(configMutex_);
- return config_;
- }
- void SynchronizerV2::setSyncStrategy(SyncStrategy strategy) {
- std::lock_guard<std::mutex> lock(configMutex_);
- config_.strategy = strategy;
- selectMasterClock();
-
- Logger::instance().info("Sync strategy set to: " + std::to_string(static_cast<int>(strategy)));
- }
- SyncStrategy SynchronizerV2::getSyncStrategy() const {
- std::lock_guard<std::mutex> lock(configMutex_);
- return config_.strategy;
- }
- void SynchronizerV2::setPlaybackSpeed(double speed) {
- std::lock_guard<std::mutex> lock(clockMutex_);
-
- audioClock_.speed = speed;
- videoClock_.speed = speed;
- externalClock_.speed = speed;
-
- Logger::instance().info("Playback speed set to: " + std::to_string(speed) + "x");
- }
- double SynchronizerV2::getPlaybackSpeed() const {
- std::lock_guard<std::mutex> lock(clockMutex_);
- return audioClock_.speed;
- }
- bool SynchronizerV2::isSynchronized() const {
- return state_ == SyncState::SYNCHRONIZED;
- }
- SyncStatsV2 SynchronizerV2::getStats() const {
- std::lock_guard<std::mutex> lock(statsMutex_);
- SyncStatsV2 stats = stats_;
-
- // 更新当前时钟值
- stats.audioClock = getAudioClock();
- stats.videoClock = getVideoClock();
- stats.externalClock = getExternalClock();
- stats.masterClock = getMasterClock();
- stats.state = state_;
- stats.masterClockType = masterClockType_;
-
- return stats;
- }
- void SynchronizerV2::resetStats() {
- std::lock_guard<std::mutex> lock(statsMutex_);
- stats_ = SyncStatsV2();
- stats_.lastUpdateTime = std::chrono::steady_clock::now();
-
- Logger::instance().info("SynchronizerV2 stats reset");
- }
- void SynchronizerV2::setSyncEventCallback(SyncEventCallback callback) {
- syncEventCallback_ = callback;
- }
- void SynchronizerV2::setFrameDropCallback(FrameDropCallback callback) {
- frameDropCallback_ = callback;
- }
- void SynchronizerV2::setFrameDuplicateCallback(FrameDuplicateCallback callback) {
- frameDuplicateCallback_ = callback;
- }
- void SynchronizerV2::setSyncErrorCallback(SyncErrorCallback callback) {
- syncErrorCallback_ = callback;
- }
- void SynchronizerV2::enableAdaptiveSync(bool enable) {
- std::lock_guard<std::mutex> lock(configMutex_);
- config_.enableAdaptiveSync = enable;
-
- Logger::instance().info("Adaptive sync " + std::string(enable ? "enabled" : "disabled"));
- }
- void SynchronizerV2::enablePrediction(bool enable) {
- std::lock_guard<std::mutex> lock(configMutex_);
- config_.enablePrediction = enable;
-
- Logger::instance().info("Prediction " + std::string(enable ? "enabled" : "disabled"));
- }
- void SynchronizerV2::setClockUpdateInterval(double interval) {
- std::lock_guard<std::mutex> lock(configMutex_);
- config_.clockUpdateInterval = interval;
-
- Logger::instance().info("Clock update interval set to: " + std::to_string(interval * 1000) + "ms");
- }
- void SynchronizerV2::setSmoothingWindow(int window) {
- std::lock_guard<std::mutex> lock(configMutex_);
- config_.smoothingWindow = window;
-
- // 调整历史记录大小
- std::lock_guard<std::mutex> historyLock(historyMutex_);
- while (audioClockHistory_.size() > static_cast<size_t>(window)) {
- audioClockHistory_.pop_front();
- }
- while (videoClockHistory_.size() > static_cast<size_t>(window)) {
- videoClockHistory_.pop_front();
- }
- while (syncErrorHistory_.size() > static_cast<size_t>(window)) {
- syncErrorHistory_.pop_front();
- }
-
- Logger::instance().info("Smoothing window set to: " + std::to_string(window));
- }
- std::string SynchronizerV2::getDebugInfo() const {
- std::ostringstream oss;
-
- SyncStatsV2 stats = getStats();
-
- oss << std::fixed << std::setprecision(3);
- oss << "SynchronizerV2 Debug Info:\n";
- oss << " State: " << static_cast<int>(stats.state) << "\n";
- oss << " Master Clock: " << static_cast<int>(stats.masterClockType) << "\n";
- oss << " Audio Clock: " << stats.audioClock << "s\n";
- oss << " Video Clock: " << stats.videoClock << "s\n";
- oss << " External Clock: " << stats.externalClock << "s\n";
- oss << " Master Clock: " << stats.masterClock << "s\n";
- oss << " Sync Error: " << stats.syncError * 1000 << "ms\n";
- oss << " Avg Sync Error: " << stats.avgSyncError * 1000 << "ms\n";
- oss << " Max Sync Error: " << stats.maxSyncError * 1000 << "ms\n";
- oss << " Total Frames: " << stats.totalFrames << "\n";
- oss << " Dropped Frames: " << stats.droppedFrames << "\n";
- oss << " Duplicated Frames: " << stats.duplicatedFrames << "\n";
- oss << " Running: " << (running_ ? "Yes" : "No") << "\n";
- oss << " Paused: " << (paused_ ? "Yes" : "No") << "\n";
-
- return oss.str();
- }
- void SynchronizerV2::dumpClockInfo() const {
- std::lock_guard<std::mutex> lock(clockMutex_);
-
- Logger::instance().info("Clock Info Dump:");
- Logger::instance().info(" Audio - PTS: " + std::to_string(audioClock_.pts) +
- ", Speed: " + std::to_string(audioClock_.speed) +
- ", Paused: " + (audioClock_.paused ? "Yes" : "No"));
- Logger::instance().info(" Video - PTS: " + std::to_string(videoClock_.pts) +
- ", Speed: " + std::to_string(videoClock_.speed) +
- ", Paused: " + (videoClock_.paused ? "Yes" : "No"));
- Logger::instance().info(" External - PTS: " + std::to_string(externalClock_.pts) +
- ", Speed: " + std::to_string(externalClock_.speed) +
- ", Paused: " + (externalClock_.paused ? "Yes" : "No"));
- }
- // 私有方法实现
- ErrorCode SynchronizerV2::updateClock(ClockType type, int64_t pts, double timeBase, int serial) {
- if (!initialized_) {
- return ErrorCode::NOT_INITIALIZED;
- }
-
- // 参考packets_sync.cpp的set_clock_at实现,确保与AVPlayer2一致
- double currentTime = getSystemTime();
- double ptsInSeconds = ptsToSeconds(pts, timeBase);
-
- // 在锁内更新时钟数据
- {
- std::lock_guard<std::mutex> lock(clockMutex_);
-
- ClockInfo* clock = nullptr;
- switch (type) {
- case ClockType::AUDIO:
- clock = &audioClock_;
- break;
- case ClockType::VIDEO:
- clock = &videoClock_;
- break;
- case ClockType::EXTERNAL:
- clock = &externalClock_;
- break;
- default:
- return ErrorCode::INVALID_PARAMS;
- }
-
- // 检查序列号,参考packets_sync.cpp的序列号检查机制
- if (serial != 0 && clock->serial != serial) {
- // 序列号不匹配,可能是seek操作,重置时钟
- resetClock(type);
- clock->serial = serial;
- }
-
- // 严格按照packets_sync.cpp的set_clock_at算法更新时钟
- if (pts != AV_NOPTS_VALUE) {
- // 参考packets_sync.cpp: clock->pts_drift = pts - time
- clock->pts_drift = ptsInSeconds - currentTime;
- clock->pts = ptsInSeconds; // 存储转换后的秒值,与packets_sync.cpp一致
- clock->lastUpdate = currentTime;
- } else {
- clock->pts = std::numeric_limits<double>::quiet_NaN();
- clock->pts_drift = 0.0;
- clock->lastUpdate = currentTime;
- }
-
- clock->time = currentTime;
- clock->serial = serial;
-
- // 添加调试日志
- static int logCounter = 0;
- if (++logCounter % 100 == 0) { // 每100次更新记录一次
- std::string clockName = (type == ClockType::AUDIO) ? "Audio" :
- (type == ClockType::VIDEO) ? "Video" : "External";
- Logger::instance().info("Clock Update [" + clockName + "]: PTS=" +
- std::to_string(pts) + ", PTSSeconds=" +
- std::to_string(ptsInSeconds) + ", SystemTime=" +
- std::to_string(currentTime) + ", Drift=" +
- std::to_string(clock->drift));
- }
-
- // 平滑处理(保持原有逻辑,但确保使用正确的PTS值)
- if (config_.smoothingWindow > 1) {
- clock->smoothedPts = smoothClock(type, static_cast<int64_t>(ptsInSeconds * AV_TIME_BASE));
- } else {
- clock->smoothedPts = static_cast<int64_t>(ptsInSeconds * AV_TIME_BASE);
- }
-
- // 更新历史记录(转换为AV_TIME_BASE格式)
- updateClockHistory(type, static_cast<int64_t>(ptsInSeconds * AV_TIME_BASE));
-
- // 如果这是主时钟,同步外部时钟到主时钟
- if (type == masterClockType_ && type != ClockType::EXTERNAL) {
- syncClockToSlave(&externalClock_, clock);
- }
-
- // 定期更新统计信息
- auto now = std::chrono::steady_clock::now();
- if (std::chrono::duration_cast<std::chrono::milliseconds>(now - lastStatsUpdate_).count() > 100) {
- updateStats();
- lastStatsUpdate_ = now;
- }
- } // 释放clockMutex_锁
-
- // 在锁外更新同步状态,避免死锁
- updateSyncState();
-
- return ErrorCode::SUCCESS;
- }
- int64_t SynchronizerV2::getClock(ClockType type, bool predict) const {
- std::lock_guard<std::mutex> lock(clockMutex_);
-
- const ClockInfo* clock = nullptr;
- switch (type) {
- case ClockType::AUDIO:
- clock = &audioClock_;
- break;
- case ClockType::VIDEO:
- clock = &videoClock_;
- break;
- case ClockType::EXTERNAL:
- clock = &externalClock_;
- break;
- case ClockType::SYSTEM:
- return static_cast<int64_t>(getSystemTime() * AV_TIME_BASE);
- default:
- return AV_NOPTS_VALUE;
- }
-
- // 严格按照packets_sync.cpp的get_clock实现
- // 检查时钟是否有效(pts不为NAN,与packets_sync.cpp一致)
- if (std::isnan(clock->pts)) {
- return AV_NOPTS_VALUE;
- }
-
- double clockValue;
- if (clock->paused) {
- // 暂停状态下,直接返回暂停时的PTS值
- clockValue = clock->pts;
- } else {
- // 运行状态下,使用packets_sync.cpp的get_clock算法
- // get_clock算法:pts_drift + time - (time - last_updated) * (1.0 - speed)
- // 等价于:pts + pts_drift + (current_time - last_updated) * speed
- double currentTime = av_gettime_relative() / 1000000.0;
- clockValue = clock->pts_drift + currentTime - (currentTime - clock->lastUpdate) * (1.0 - clock->speed);
- }
-
- // 转换为AV_TIME_BASE时间基准
- int64_t currentPts = static_cast<int64_t>(clockValue * AV_TIME_BASE);
-
- // 如果启用预测
- if (predict && config_.enablePrediction) {
- return predictClock(type, config_.predictionWindow);
- }
-
- return currentPts;
- }
- void SynchronizerV2::resetClock(ClockType type) {
- ClockInfo* clock = nullptr;
- switch (type) {
- case ClockType::AUDIO:
- clock = &audioClock_;
- break;
- case ClockType::VIDEO:
- clock = &videoClock_;
- break;
- case ClockType::EXTERNAL:
- clock = &externalClock_;
- break;
- default:
- return;
- }
-
- // 严格按照packets_sync.cpp的init_clock实现
- // init_clock调用set_clock(c, NAN, -1),而set_clock使用av_gettime_relative
- double currentTime = av_gettime_relative() / 1000000.0;
- // 统一初始化所有时钟,与packets_sync.cpp保持一致
- clock->speed = 1.0;
- clock->paused = false;
-
- // 调用set_clock(c, NAN, -1)的等价操作
- clock->pts = std::numeric_limits<double>::quiet_NaN(); // 使用NAN,与packets_sync.cpp一致
- clock->pts_drift = clock->pts - currentTime; // set_clock_at的逻辑
- clock->lastUpdate = currentTime;
- clock->serial = -1;
-
- // 保留SynchronizerV2特有的字段
- clock->time = currentTime;
- clock->drift = 0.0;
- clock->smoothedPts = AV_NOPTS_VALUE;
- }
- // 严格按照packets_sync.cpp的sync_clock_to_slave实现
- void SynchronizerV2::syncClockToSlave(ClockInfo* slave, const ClockInfo* master) {
- if (!slave || !master) {
- return;
- }
-
- double currentTime = getSystemTime();
-
- // 计算主时钟当前值,使用packets_sync.cpp的get_clock算法
- double masterClock = std::numeric_limits<double>::quiet_NaN();
- if (!std::isnan(master->pts)) {
- if (master->paused) {
- masterClock = master->pts;
- } else {
- // 使用packets_sync.cpp的get_clock算法:pts_drift + time - (time - last_updated) * (1.0 - speed)
- masterClock = master->pts_drift + currentTime - (currentTime - master->lastUpdate) * (1.0 - master->speed);
- }
- }
-
- // 计算从时钟当前值,使用packets_sync.cpp的get_clock算法
- double slaveClock = std::numeric_limits<double>::quiet_NaN();
- if (!std::isnan(slave->pts)) {
- if (slave->paused) {
- slaveClock = slave->pts;
- } else {
- // 使用packets_sync.cpp的get_clock算法:pts_drift + time - (time - last_updated) * (1.0 - speed)
- slaveClock = slave->pts_drift + currentTime - (currentTime - slave->lastUpdate) * (1.0 - slave->speed);
- }
- }
-
- // 参考packets_sync.cpp的sync_clock_to_slave逻辑
- if (!std::isnan(masterClock) &&
- (std::isnan(slaveClock) || std::abs(masterClock - slaveClock) > config_.noSyncThreshold)) {
- // 按照packets_sync.cpp的set_clock_at算法同步从时钟到主时钟
- slave->pts = masterClock;
- slave->pts_drift = masterClock - currentTime;
- slave->lastUpdate = currentTime;
- slave->serial = master->serial;
-
- // 保留SynchronizerV2特有的字段
- slave->time = currentTime;
- slave->drift = masterClock - currentTime;
- }
- }
- void SynchronizerV2::pauseClock(ClockType type, bool pause) {
- ClockInfo* clock = nullptr;
- switch (type) {
- case ClockType::AUDIO:
- clock = &audioClock_;
- break;
- case ClockType::VIDEO:
- clock = &videoClock_;
- break;
- case ClockType::EXTERNAL:
- clock = &externalClock_;
- break;
- default:
- return;
- }
-
- if (clock->paused != pause) {
- double currentTime = getSystemTime();
-
- if (pause) {
- // 暂停时保存当前PTS,使用packets_sync.cpp的get_clock算法计算当前值
- if (!clock->paused && !std::isnan(clock->pts)) {
- clock->pts = clock->pts_drift + currentTime - (currentTime - clock->lastUpdate) * (1.0 - clock->speed);
- clock->pts_drift = 0.0; // 暂停后drift重置为0
- }
- } else {
- // 恢复时重新设置pts_drift,参考packets_sync.cpp的set_clock_at
- if (!std::isnan(clock->pts)) {
- clock->pts_drift = clock->pts - currentTime;
- }
- }
-
- clock->paused = pause;
- clock->lastUpdate = currentTime;
- clock->time = currentTime; // 保留SynchronizerV2特有字段
- }
- }
- void SynchronizerV2::selectMasterClock() {
- ClockType newMasterClock = masterClockType_;
-
- switch (config_.strategy) {
- case SyncStrategy::AUDIO_MASTER:
- newMasterClock = ClockType::AUDIO;
- break;
-
- case SyncStrategy::VIDEO_MASTER:
- newMasterClock = ClockType::VIDEO;
- break;
-
- case SyncStrategy::EXTERNAL_MASTER:
- newMasterClock = ClockType::EXTERNAL;
- break;
-
- case SyncStrategy::ADAPTIVE: {
- // 参考AVPlayer2的自适应主时钟选择算法
- if (config_.enableAdaptiveSync) {
- bool hasAudio = (hasAudioStream_ && !std::isnan(audioClock_.pts) && !audioClock_.paused);
- bool hasVideo = (hasVideoStream_ && !std::isnan(videoClock_.pts) && !videoClock_.paused);
-
- if (hasAudio && hasVideo) {
- // 音视频都存在时,评估时钟质量
- double currentTime = getSystemTime();
-
- // 计算音频时钟的稳定性
- double audioStability = 1.0;
- if (audioClock_.time > 0) {
- double audioAge = currentTime - audioClock_.time;
- audioStability = std::exp(-audioAge / 2.0); // 2秒衰减
- }
-
- // 计算视频时钟的稳定性
- double videoStability = 1.0;
- if (videoClock_.time > 0) {
- double videoAge = currentTime - videoClock_.time;
- videoStability = std::exp(-videoAge / 2.0); // 2秒衰减
- }
-
- // 考虑时钟漂移
- double audioDrift = std::abs(audioClock_.drift);
- double videoDrift = std::abs(videoClock_.drift);
-
- // 音频时钟通常更稳定,给予优先权
- double audioScore = audioStability * 1.2 / (1.0 + audioDrift * 10.0);
- double videoScore = videoStability / (1.0 + videoDrift * 10.0);
-
- if (audioScore > videoScore && audioScore > 0.3) {
- newMasterClock = ClockType::AUDIO;
- } else if (videoScore > 0.3) {
- newMasterClock = ClockType::VIDEO;
- } else {
- newMasterClock = ClockType::EXTERNAL;
- }
- } else if (hasAudio) {
- // 只有音频
- newMasterClock = ClockType::AUDIO;
- } else if (hasVideo) {
- // 只有视频
- newMasterClock = ClockType::VIDEO;
- } else {
- // 都没有,使用外部时钟
- newMasterClock = ClockType::EXTERNAL;
- }
- } else {
- // 简单逻辑:优先音频,但要检查时钟有效性
- bool hasValidAudio = (hasAudioStream_ && !std::isnan(audioClock_.pts));
- bool hasValidVideo = (hasVideoStream_ && !std::isnan(videoClock_.pts));
-
- if (hasValidAudio) {
- newMasterClock = ClockType::AUDIO;
- } else if (hasValidVideo) {
- newMasterClock = ClockType::VIDEO;
- } else {
- // 音视频时钟都无效,使用外部时钟
- newMasterClock = ClockType::EXTERNAL;
- }
- }
- break;
- }
- }
-
- // 如果选择外部时钟作为主时钟,但外部时钟无效,则初始化它
- if (newMasterClock == ClockType::EXTERNAL && std::isnan(externalClock_.pts)) {
- double currentTime = av_gettime_relative() / 1000000.0;
- externalClock_.pts = currentTime;
- externalClock_.pts_drift = 0.0;
- externalClock_.lastUpdate = currentTime;
- externalClock_.time = currentTime;
- externalClock_.serial = 0;
- externalClock_.paused = false;
- externalClock_.speed = 1.0;
- externalClock_.drift = 0.0;
-
- Logger::instance().info("External clock initialized as master with current time: " + std::to_string(currentTime));
- }
-
- // 只有当主时钟真正改变时才更新和记录日志
- if (newMasterClock != masterClockType_) {
- ClockType oldMasterClock = masterClockType_;
- masterClockType_ = newMasterClock;
-
- // 获取时钟状态信息用于调试
- std::string audioStatus = "invalid";
- std::string videoStatus = "invalid";
- std::string externalStatus = "invalid";
-
- if (!std::isnan(audioClock_.pts)) {
- audioStatus = "valid(pts=" + std::to_string(audioClock_.pts) + ")";
- }
- if (!std::isnan(videoClock_.pts)) {
- videoStatus = "valid(pts=" + std::to_string(videoClock_.pts) + ")";
- }
- if (!std::isnan(externalClock_.pts)) {
- externalStatus = "valid(pts=" + std::to_string(externalClock_.pts) + ")";
- }
-
- Logger::instance().info("Master clock changed from "
- + std::to_string(static_cast<int>(oldMasterClock))
- + " to " + std::to_string(static_cast<int>(masterClockType_.load()))
- + " (hasAudio=" + std::to_string(hasAudioStream_.load())
- + ", hasVideo=" + std::to_string(hasVideoStream_.load())
- + ", audio=" + audioStatus
- + ", video=" + videoStatus
- + ", external=" + externalStatus + ")");
- }
- }
- void SynchronizerV2::updateSyncState() {
- if (!running_) {
- state_ = SyncState::IDLE;
- return;
- }
-
- if (paused_) {
- return;
- }
-
- double syncError = calculateSyncErrorInternal();
-
- SyncState newState = state_;
- bool needRecovery = false;
-
- // 参考AVPlayer2的同步状态管理算法
- if (syncError <= config_.syncThreshold) {
- // 同步误差在可接受范围内
- if (state_ == SyncState::RECOVERING || state_ == SyncState::INITIALIZING) {
- // 从恢复或初始化状态转为同步状态
- newState = SyncState::SYNCHRONIZED;
- recoveryAttempts_ = 0;
- } else if (state_ != SyncState::SYNCHRONIZED) {
- newState = SyncState::SYNCHRONIZED;
- }
- } else if (syncError <= config_.adaptiveThreshold) {
- // 轻微漂移状态
- if (state_ == SyncState::SYNCHRONIZED) {
- newState = SyncState::DRIFT;
- } else if (state_ == SyncState::RECOVERING) {
- // 恢复中但误差仍较大,继续恢复
- double recoveryDuration = getCurrentTime() - recoveryStartTime_;
- if (recoveryDuration > 3.0) { // 3秒恢复超时
- if (recoveryAttempts_ < config_.maxRecoveryAttempts) {
- needRecovery = true;
- } else {
- newState = SyncState::ERROR;
- }
- }
- }
- } else if (syncError <= config_.maxSyncError) {
- // 同步误差较大但仍在可恢复范围内
- if (state_ != SyncState::RECOVERING) {
- newState = SyncState::ERROR;
- if (recoveryAttempts_ < config_.maxRecoveryAttempts) {
- needRecovery = true;
- newState = SyncState::RECOVERING;
- }
- } else {
- // 已在恢复状态,检查恢复超时
- double recoveryDuration = getCurrentTime() - recoveryStartTime_;
- if (recoveryDuration > 5.0) { // 5秒恢复超时
- if (recoveryAttempts_ < config_.maxRecoveryAttempts) {
- needRecovery = true;
- } else {
- newState = SyncState::ERROR;
- }
- }
- }
- } else {
- // 同步误差过大
- newState = SyncState::ERROR;
- // 标记需要恢复,但不在这里直接调用attemptRecovery避免死锁
- if (recoveryAttempts_ < config_.maxRecoveryAttempts) {
- needRecovery = true;
- newState = SyncState::RECOVERING;
- }
- }
-
- // 检查长时间失同步的情况
- if (newState == SyncState::ERROR && recoveryAttempts_ >= config_.maxRecoveryAttempts) {
- static double lastResetTime = 0;
- double currentTime = getCurrentTime();
- if (currentTime - lastResetTime > 10.0) { // 10秒重置一次
- // 尝试重新初始化同步
- recoveryAttempts_ = 0;
- newState = SyncState::INITIALIZING;
- lastResetTime = currentTime;
- Logger::instance().warning("Sync error persists, attempting full reset");
- }
- }
-
- if (newState != state_) {
- SyncState oldState = state_;
- state_ = newState;
- notifyStateChange(newState);
-
- Logger::instance().info("Sync state changed from " + std::to_string(static_cast<int>(oldState)) +
- " to " + std::to_string(static_cast<int>(newState)));
- }
-
- // 如果需要恢复,现在可以安全地调用恢复操作(因为updateSyncState现在在锁外被调用)
- if (needRecovery) {
- performDelayedRecovery();
- }
- }
- void SynchronizerV2::updateStats() {
- // 统计信息在其他方法中已经更新
- }
- int64_t SynchronizerV2::smoothClock(ClockType type, int64_t newPts) {
- std::lock_guard<std::mutex> lock(historyMutex_);
-
- std::deque<int64_t>* history = nullptr;
- switch (type) {
- case ClockType::AUDIO:
- history = &audioClockHistory_;
- break;
- case ClockType::VIDEO:
- history = &videoClockHistory_;
- break;
- default:
- return newPts;
- }
-
- if (history->empty() || newPts == AV_NOPTS_VALUE) {
- return newPts;
- }
-
- // 简单的指数移动平均
- int64_t lastSmoothed = history->back();
- if (lastSmoothed == AV_NOPTS_VALUE) {
- return newPts;
- }
-
- double smoothed = static_cast<double>(lastSmoothed) * (1.0 - config_.smoothingFactor) +
- static_cast<double>(newPts) * config_.smoothingFactor;
- return static_cast<int64_t>(smoothed);
- }
- int64_t SynchronizerV2::predictClock(ClockType type, double futureTime) const {
- // 注意:此方法假设调用者已经持有clockMutex_锁
- // 不能再调用getClock,否则会导致死锁
-
- const ClockInfo* clock = nullptr;
- switch (type) {
- case ClockType::AUDIO:
- clock = &audioClock_;
- break;
- case ClockType::VIDEO:
- clock = &videoClock_;
- break;
- case ClockType::EXTERNAL:
- clock = &externalClock_;
- break;
- default:
- return AV_NOPTS_VALUE;
- }
-
- if (clock->paused || std::isnan(clock->pts)) {
- return static_cast<int64_t>(clock->pts * AV_TIME_BASE);
- }
-
- // 计算当前时间(不调用getClock避免死锁),使用packets_sync.cpp的get_clock算法
- double currentTime = getSystemTime();
- // 使用packets_sync.cpp的算法:pts + pts_drift + (current_time - last_updated) * speed
- double currentPtsSeconds = clock->pts + clock->pts_drift + (currentTime - clock->lastUpdate) * clock->speed;
-
- return static_cast<int64_t>((currentPtsSeconds + futureTime * clock->speed) * AV_TIME_BASE);
- }
- void SynchronizerV2::updateClockHistory(ClockType type, int64_t pts) {
- std::lock_guard<std::mutex> lock(historyMutex_);
-
- std::deque<int64_t>* history = nullptr;
- switch (type) {
- case ClockType::AUDIO:
- history = &audioClockHistory_;
- break;
- case ClockType::VIDEO:
- history = &videoClockHistory_;
- break;
- default:
- return;
- }
-
- history->push_back(pts);
- while (history->size() > static_cast<size_t>(config_.smoothingWindow)) {
- history->pop_front();
- }
- }
- void SynchronizerV2::attemptRecovery() {
- recoveryAttempts_++;
- lastRecoveryTime_ = std::chrono::steady_clock::now();
-
- Logger::instance().warning("Attempting sync recovery, attempt: " + std::to_string(recoveryAttempts_));
-
- // 重置时钟漂移
- {
- std::lock_guard<std::mutex> lock(clockMutex_);
- audioClock_.drift = 0.0;
- videoClock_.drift = 0.0;
- externalClock_.drift = 0.0;
- }
-
- // 可能需要重新选择主时钟(在锁外面调用避免死锁)
- if (config_.enableAdaptiveSync) {
- selectMasterClock();
- }
- }
- void SynchronizerV2::performDelayedRecovery() {
- // 这个方法在不持有clockMutex_的情况下被调用
- // 执行实际的恢复操作
-
- // 检查恢复间隔,避免过于频繁的恢复
- auto now = std::chrono::steady_clock::now();
- auto timeSinceLastRecovery = std::chrono::duration<double>(now - lastRecoveryTime_).count();
- if (timeSinceLastRecovery < 1.0) { // 至少间隔1秒
- return;
- }
-
- recoveryAttempts_++;
- lastRecoveryTime_ = now;
-
- Logger::instance().warning("Performing delayed sync recovery, attempt: " + std::to_string(recoveryAttempts_));
-
- // 重置时钟漂移
- {
- std::lock_guard<std::mutex> lock(clockMutex_);
- audioClock_.drift = 0.0;
- videoClock_.drift = 0.0;
- externalClock_.drift = 0.0;
- }
-
- // 只有在恢复次数较少时才重新选择主时钟,避免频繁切换
- if (config_.enableAdaptiveSync && recoveryAttempts_ <= 3) {
- selectMasterClock();
- }
- }
- double SynchronizerV2::getCurrentTime() const {
- auto now = std::chrono::steady_clock::now();
- return std::chrono::duration<double>(now - startTime_).count();
- }
- double SynchronizerV2::getSystemTime() const {
- return av_gettime_relative() / 1000000.0;
- }
- void SynchronizerV2::notifyStateChange(SyncState newState) {
- if (syncEventCallback_) {
- syncEventCallback_(state_, newState);
- }
- }
- void SynchronizerV2::notifyFrameDrop(ClockType type, int64_t pts) {
- if (frameDropCallback_) {
- frameDropCallback_(type, pts);
- }
- }
- void SynchronizerV2::notifyFrameDuplicate(ClockType type, int64_t pts) {
- if (frameDuplicateCallback_) {
- frameDuplicateCallback_(type, pts);
- }
- }
- void SynchronizerV2::notifySyncError(double error, const std::string& reason) {
- if (syncErrorCallback_) {
- syncErrorCallback_(error, reason);
- }
- }
- // PTS转换辅助方法实现
- double SynchronizerV2::ptsToSeconds(int64_t pts, double timeBase) const {
- if (pts == AV_NOPTS_VALUE) {
- return 0.0;
- }
- return pts * timeBase;
- }
- int64_t SynchronizerV2::secondsToPts(double seconds, double timeBase) const {
- if (timeBase <= 0.0) {
- return AV_NOPTS_VALUE;
- }
- return static_cast<int64_t>(seconds / timeBase);
- }
- } // namespace utils
- } // namespace av
|