| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066 |
- #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)
- , masterClockType_(ClockType::AUDIO)
- , state_(SyncState::IDLE)
- , 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_;
-
- // 启动后立即进入同步状态
- 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(double pts, double time, int serial) {
- return updateClock(ClockType::AUDIO, pts, time, serial);
- }
- ErrorCode SynchronizerV2::setVideoClock(double pts, double time, int serial) {
- return updateClock(ClockType::VIDEO, pts, time, serial);
- }
- ErrorCode SynchronizerV2::setExternalClock(double time, int serial) {
- if (time < 0) {
- time = getCurrentTime();
- }
- return updateClock(ClockType::EXTERNAL, time, time, serial);
- }
- double SynchronizerV2::getAudioClock(bool predict) const {
- return getClock(ClockType::AUDIO, predict);
- }
- double SynchronizerV2::getVideoClock(bool predict) const {
- return getClock(ClockType::VIDEO, predict);
- }
- double SynchronizerV2::getExternalClock(bool predict) const {
- return getClock(ClockType::EXTERNAL, predict);
- }
- double SynchronizerV2::getMasterClock(bool predict) const {
- return getClock(masterClockType_, predict);
- }
- FrameDecision SynchronizerV2::shouldDisplayVideoFrame(double pts, 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;
- }
-
- // 获取主时钟
- double masterClock = getMasterClock(true); // 使用预测
- decision.targetPts = masterClock;
-
- // 计算同步误差
- double syncError = pts - masterClock;
- decision.syncError = syncError;
-
- // 如果视频是主时钟,直接显示
- if (masterClockType_ == ClockType::VIDEO) {
- decision.action = FrameAction::DISPLAY;
- decision.delay = duration > 0 ? duration : (1.0 / 25.0); // 默认25fps
- decision.reason = "Video master";
- return decision;
- }
-
- // 根据同步误差决定动作
- if (syncError < -config_.frameDropThreshold) {
- // 视频太慢,丢帧
- 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 (syncError > config_.frameDupThreshold) {
- // 视频太快,重复帧或延迟
- if (duration > 0 && syncError < config_.frameDupThreshold * 2) {
- decision.action = FrameAction::DELAY;
- decision.delay = std::min(syncError, config_.maxSyncError);
- decision.reason = "Video too fast, delay";
- } else {
- decision.action = FrameAction::Frame_DUPLICATE;
- 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 = calculateTargetDelay(pts, ClockType::VIDEO);
- decision.reason = "Normal display";
- }
-
- // 更新统计
- {
- std::lock_guard<std::mutex> lock(statsMutex_);
- stats_.totalFrames++;
- stats_.syncError = syncError;
-
- // 更新平均同步误差
- if (stats_.totalFrames == 1) {
- stats_.avgSyncError = std::abs(syncError);
- } else {
- stats_.avgSyncError = stats_.avgSyncError * 0.9 + std::abs(syncError) * 0.1;
- }
-
- // 更新最大同步误差
- stats_.maxSyncError = std::max(stats_.maxSyncError, std::abs(syncError));
- }
-
- return decision;
- }
- FrameDecision SynchronizerV2::shouldPlayAudioFrame(double pts, 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;
- }
-
- // 音频通常作为主时钟,或者需要与主时钟同步
- if (masterClockType_ == ClockType::AUDIO) {
- decision.action = FrameAction::DISPLAY;
- decision.delay = duration > 0 ? duration : 0.023; // 默认23ms (44.1kHz, 1024 samples)
- decision.reason = "Audio master";
- decision.targetPts = pts;
- return decision;
- }
-
- // 与主时钟同步
- double masterClock = getMasterClock(true);
- decision.targetPts = masterClock;
-
- double syncError = pts - masterClock;
- decision.syncError = syncError;
-
- if (std::abs(syncError) > config_.maxSyncError) {
- // 同步误差太大,丢弃或延迟
- if (syncError < 0) {
- decision.action = FrameAction::DROP;
- decision.reason = "Audio too slow, drop";
- } else {
- decision.action = FrameAction::DELAY;
- decision.delay = std::min(syncError, config_.maxSyncError);
- decision.reason = "Audio too fast, delay";
- }
- } else {
- decision.action = FrameAction::DISPLAY;
- decision.delay = calculateTargetDelay(pts, ClockType::AUDIO);
- decision.reason = "Normal audio play";
- }
-
- return decision;
- }
- double SynchronizerV2::calculateTargetDelay(double pts, ClockType clockType) {
- if (!running_) {
- return 0.0;
- }
-
- // 基础延迟
- double baseDelay = 0.0;
- if (clockType == ClockType::VIDEO) {
- baseDelay = 1.0 / 25.0; // 默认25fps
- } else if (clockType == ClockType::AUDIO) {
- baseDelay = 0.023; // 默认23ms
- }
-
- // 如果是主时钟,返回基础延迟
- if (clockType == masterClockType_) {
- return baseDelay;
- }
-
- // 计算与主时钟的差异
- double masterClock = getMasterClock(true);
- double diff = pts - masterClock;
-
- // 调整延迟
- double adjustedDelay = baseDelay;
-
- if (std::abs(diff) < config_.syncThreshold) {
- // 在同步阈值内,正常延迟
- adjustedDelay = baseDelay;
- } else if (diff < 0) {
- // 落后于主时钟,减少延迟
- adjustedDelay = std::max(0.0, baseDelay + diff);
- } else {
- // 超前于主时钟,增加延迟
- adjustedDelay = baseDelay + std::min(diff, config_.maxSyncError);
- }
-
- return adjustedDelay;
- }
- bool SynchronizerV2::shouldDropFrame(double pts, ClockType clockType) {
- if (!running_ || clockType == masterClockType_) {
- return false;
- }
-
- double masterClock = getMasterClock();
- double diff = pts - masterClock;
-
- return diff < -config_.frameDropThreshold;
- }
- bool SynchronizerV2::shouldDuplicateFrame(double pts, ClockType clockType) {
- if (!running_ || clockType == masterClockType_) {
- return false;
- }
-
- double masterClock = getMasterClock();
- double diff = pts - masterClock;
-
- 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导致死锁
- double audioClock = 0.0;
- double videoClock = 0.0;
-
- // 计算音频时钟
- if (!audioClock_.paused) {
- auto now = std::chrono::steady_clock::now();
- double elapsed = std::chrono::duration<double>(now - audioClock_.lastUpdate).count();
- audioClock = audioClock_.pts + elapsed * audioClock_.speed;
- } else {
- audioClock = audioClock_.pts;
- }
-
- // 计算视频时钟
- if (!videoClock_.paused) {
- auto now = std::chrono::steady_clock::now();
- double elapsed = std::chrono::duration<double>(now - videoClock_.lastUpdate).count();
- videoClock = videoClock_.pts + elapsed * videoClock_.speed;
- } else {
- videoClock = videoClock_.pts;
- }
-
- if (audioClock <= 0 || videoClock <= 0) {
- return 0.0;
- }
-
- return std::abs(audioClock - videoClock);
- }
- double SynchronizerV2::calculateAudioDelay(double pts) const {
- if (masterClockType_ == ClockType::AUDIO) {
- return 0.0;
- }
-
- double masterClock = getMasterClock();
- return pts - masterClock;
- }
- double SynchronizerV2::calculateVideoDelay(double pts) const {
- if (masterClockType_ == ClockType::VIDEO) {
- return 0.0;
- }
-
- double masterClock = getMasterClock();
- return pts - masterClock;
- }
- 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, double pts, double time, int serial) {
- if (!initialized_) {
- return ErrorCode::NOT_INITIALIZED;
- }
-
- // 在锁内更新时钟数据
- {
- 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;
- }
-
- if (time < 0) {
- time = getCurrentTime();
- }
-
- // 检查序列号
- if (serial != 0 && clock->serial != serial) {
- // 序列号不匹配,可能是seek操作,重置时钟
- resetClock(type);
- clock->serial = serial;
- }
-
- // 更新时钟
- clock->pts = pts;
- clock->time = time;
- clock->lastUpdate = std::chrono::steady_clock::now();
-
- // 平滑处理
- if (config_.smoothingWindow > 1) {
- clock->smoothedPts = smoothClock(type, pts);
- } else {
- clock->smoothedPts = pts;
- }
-
- // 更新历史记录
- updateClockHistory(type, pts);
-
- // 定期更新统计信息
- 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;
- }
- double 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 getCurrentTime();
- default:
- return 0.0;
- }
-
- if (clock->paused) {
- return clock->pts;
- }
-
- // 计算当前时间
- auto now = std::chrono::steady_clock::now();
- double elapsed = std::chrono::duration<double>(now - clock->lastUpdate).count();
- double currentPts = clock->pts + elapsed * clock->speed;
-
- // 如果启用预测
- 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;
- }
-
- clock->pts = 0.0;
- clock->time = 0.0;
- clock->speed = 1.0;
- clock->serial = 0;
- clock->paused = false;
- clock->lastUpdate = std::chrono::steady_clock::now();
- clock->drift = 0.0;
- clock->smoothedPts = 0.0;
- }
- 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) {
- if (pause) {
- // 暂停时保存当前PTS(直接计算,避免调用getClock导致死锁)
- if (!clock->paused) {
- auto now = std::chrono::steady_clock::now();
- double elapsed = std::chrono::duration<double>(now - clock->lastUpdate).count();
- clock->pts = clock->pts + elapsed * clock->speed;
- }
- }
- clock->paused = pause;
- clock->lastUpdate = std::chrono::steady_clock::now();
- }
- }
- void SynchronizerV2::selectMasterClock() {
- switch (config_.strategy) {
- case SyncStrategy::AUDIO_MASTER:
- masterClockType_ = ClockType::AUDIO;
- break;
- case SyncStrategy::VIDEO_MASTER:
- masterClockType_ = ClockType::VIDEO;
- break;
- case SyncStrategy::EXTERNAL_MASTER:
- masterClockType_ = ClockType::EXTERNAL;
- break;
- case SyncStrategy::ADAPTIVE:
- // 自适应选择逻辑
- if (config_.enableAdaptiveSync) {
- // 改进的自适应逻辑:优先选择音频,如果没有音频则选择视频
- // 注意:不依赖pts值,因为在播放开始时pts可能还是0
- if (hasAudioStream_) {
- masterClockType_ = ClockType::AUDIO;
- } else if (hasVideoStream_) {
- masterClockType_ = ClockType::VIDEO;
- } else {
- masterClockType_ = ClockType::EXTERNAL;
- }
- } else {
- masterClockType_ = ClockType::AUDIO; // 默认音频
- }
- break;
- }
- Logger::instance().info("Master clock selected: "
- + std::to_string(static_cast<int>(masterClockType_.load()))
- + " (hasAudio=" + std::to_string(hasAudioStream_.load())
- + ", hasVideo=" + std::to_string(hasVideoStream_.load()) + ")");
- }
- void SynchronizerV2::updateSyncState() {
- if (!running_) {
- state_ = SyncState::IDLE;
- return;
- }
-
- if (paused_) {
- return;
- }
-
- double syncError = calculateSyncErrorInternal();
-
- SyncState newState = state_;
- bool needRecovery = false;
-
- if (syncError <= config_.syncThreshold) {
- newState = SyncState::SYNCHRONIZED;
- recoveryAttempts_ = 0; // 重置恢复尝试次数
- } else if (syncError <= config_.adaptiveThreshold) {
- newState = SyncState::DRIFT;
- } else if (syncError <= config_.maxSyncError) {
- newState = SyncState::ERROR;
- } else {
- newState = SyncState::ERROR;
- // 标记需要恢复,但不在这里直接调用attemptRecovery避免死锁
- if (recoveryAttempts_ < config_.maxRecoveryAttempts) {
- needRecovery = true;
- newState = SyncState::RECOVERING;
- }
- }
-
- 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() {
- // 统计信息在其他方法中已经更新
- }
- double SynchronizerV2::smoothClock(ClockType type, double newPts) {
- std::lock_guard<std::mutex> lock(historyMutex_);
-
- std::deque<double>* history = nullptr;
- switch (type) {
- case ClockType::AUDIO:
- history = &audioClockHistory_;
- break;
- case ClockType::VIDEO:
- history = &videoClockHistory_;
- break;
- default:
- return newPts;
- }
-
- if (history->empty()) {
- return newPts;
- }
-
- // 简单的指数移动平均
- double lastSmoothed = history->back();
- return lastSmoothed * (1.0 - config_.smoothingFactor) + newPts * config_.smoothingFactor;
- }
- double 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 0.0;
- }
-
- if (clock->paused) {
- return clock->pts;
- }
-
- // 计算当前时间(不调用getClock避免死锁)
- auto now = std::chrono::steady_clock::now();
- double elapsed = std::chrono::duration<double>(now - clock->lastUpdate).count();
- double currentPts = clock->pts + elapsed * clock->speed;
-
- return currentPts + futureTime * clock->speed;
- }
- void SynchronizerV2::updateClockHistory(ClockType type, double pts) {
- std::lock_guard<std::mutex> lock(historyMutex_);
-
- std::deque<double>* 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_的情况下被调用
- // 执行实际的恢复操作
- recoveryAttempts_++;
- lastRecoveryTime_ = std::chrono::steady_clock::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) {
- 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, double pts) {
- if (frameDropCallback_) {
- frameDropCallback_(type, pts);
- }
- }
- void SynchronizerV2::notifyFrameDuplicate(ClockType type, double pts) {
- if (frameDuplicateCallback_) {
- frameDuplicateCallback_(type, pts);
- }
- }
- void SynchronizerV2::notifySyncError(double error, const std::string& reason) {
- if (syncErrorCallback_) {
- syncErrorCallback_(error, reason);
- }
- }
- } // namespace utils
- } // namespace av
|