#include "utils_synchronizer_v2.h" #include "../base/logger.h" #include #include #include #include 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(config_.strategy))); } SynchronizerV2::~SynchronizerV2() { close(); Logger::instance().info("SynchronizerV2 destroyed"); } ErrorCode SynchronizerV2::initialize() { if (initialized_) { return ErrorCode::ALREADY_INITIALIZED; } std::lock_guard clockLock(clockMutex_); std::lock_guard 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 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::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::quiet_NaN(); } } // 启动后立即进入同步状态 state_ = SyncState::SYNCING; Logger::instance().info("SynchronizerV2 started"); return ErrorCode::SUCCESS; } void SynchronizerV2::setStreamInfo(bool hasAudio, bool hasVideo) { std::lock_guard 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 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 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 clockLock(clockMutex_); std::lock_guard statsLock(statsMutex_); std::lock_guard 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 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 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 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 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 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 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 lock(configMutex_); config_ = config; // 重新选择主时钟 selectMasterClock(); Logger::instance().info("SynchronizerV2 config updated"); } SyncConfigV2 SynchronizerV2::getConfig() const { std::lock_guard lock(configMutex_); return config_; } void SynchronizerV2::setSyncStrategy(SyncStrategy strategy) { std::lock_guard lock(configMutex_); config_.strategy = strategy; selectMasterClock(); Logger::instance().info("Sync strategy set to: " + std::to_string(static_cast(strategy))); } SyncStrategy SynchronizerV2::getSyncStrategy() const { std::lock_guard lock(configMutex_); return config_.strategy; } void SynchronizerV2::setPlaybackSpeed(double speed) { std::lock_guard 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 lock(clockMutex_); return audioClock_.speed; } bool SynchronizerV2::isSynchronized() const { return state_ == SyncState::SYNCHRONIZED; } SyncStatsV2 SynchronizerV2::getStats() const { std::lock_guard 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 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 lock(configMutex_); config_.enableAdaptiveSync = enable; Logger::instance().info("Adaptive sync " + std::string(enable ? "enabled" : "disabled")); } void SynchronizerV2::enablePrediction(bool enable) { std::lock_guard lock(configMutex_); config_.enablePrediction = enable; Logger::instance().info("Prediction " + std::string(enable ? "enabled" : "disabled")); } void SynchronizerV2::setClockUpdateInterval(double interval) { std::lock_guard 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 lock(configMutex_); config_.smoothingWindow = window; // 调整历史记录大小 std::lock_guard historyLock(historyMutex_); while (audioClockHistory_.size() > static_cast(window)) { audioClockHistory_.pop_front(); } while (videoClockHistory_.size() > static_cast(window)) { videoClockHistory_.pop_front(); } while (syncErrorHistory_.size() > static_cast(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(stats.state) << "\n"; oss << " Master Clock: " << static_cast(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 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 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::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(ptsInSeconds * AV_TIME_BASE)); } else { clock->smoothedPts = static_cast(ptsInSeconds * AV_TIME_BASE); } // 更新历史记录(转换为AV_TIME_BASE格式) updateClockHistory(type, static_cast(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(now - lastStatsUpdate_).count() > 100) { updateStats(); lastStatsUpdate_ = now; } } // 释放clockMutex_锁 // 在锁外更新同步状态,避免死锁 updateSyncState(); return ErrorCode::SUCCESS; } int64_t SynchronizerV2::getClock(ClockType type, bool predict) const { std::lock_guard 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(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(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::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::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::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(oldMasterClock)) + " to " + std::to_string(static_cast(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(oldState)) + " to " + std::to_string(static_cast(newState))); } // 如果需要恢复,现在可以安全地调用恢复操作(因为updateSyncState现在在锁外被调用) if (needRecovery) { performDelayedRecovery(); } } void SynchronizerV2::updateStats() { // 统计信息在其他方法中已经更新 } int64_t SynchronizerV2::smoothClock(ClockType type, int64_t newPts) { std::lock_guard lock(historyMutex_); std::deque* 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(lastSmoothed) * (1.0 - config_.smoothingFactor) + static_cast(newPts) * config_.smoothingFactor; return static_cast(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(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((currentPtsSeconds + futureTime * clock->speed) * AV_TIME_BASE); } void SynchronizerV2::updateClockHistory(ClockType type, int64_t pts) { std::lock_guard lock(historyMutex_); std::deque* 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(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 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(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 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(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(seconds / timeBase); } } // namespace utils } // namespace av