| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- #ifndef AV_UTILS_SYNCHRONIZER_V2_H
- #define AV_UTILS_SYNCHRONIZER_V2_H
- #pragma once
- #include "../base/types.h"
- #include <atomic>
- #include <chrono>
- #include <deque>
- #include <functional>
- #include <limits>
- #include <memory>
- #include <mutex>
- #include <string>
- extern "C" {
- #include <libavutil/avutil.h>
- #include <libavutil/time.h>
- }
- namespace av {
- namespace utils {
- // 同步策略枚举
- enum class SyncStrategy {
- AUDIO_MASTER, // 音频作为主时钟源
- VIDEO_MASTER, // 视频作为主时钟源
- EXTERNAL_MASTER // 外部时钟作为主时钟源
- };
- // 时钟类型枚举
- enum class ClockType {
- AUDIO, // 音频时钟
- VIDEO, // 视频时钟
- EXTERNAL // 外部时钟
- };
- // 帧处理决策枚举
- enum class FrameAction {
- DISPLAY, // 显示帧
- DROP, // 丢弃帧
- DUPLICATE, // 重复帧
- WAIT // 等待
- };
- // 帧决策结构体
- struct FrameDecision {
- FrameAction action = FrameAction::DISPLAY;
- double delay = 0.0; // 延迟时间(秒)
- double syncError = 0.0; // 同步误差(秒)
- std::string reason; // 决策原因
- };
- // 同步器配置结构体
- struct SyncConfigV2 {
- SyncStrategy strategy = SyncStrategy::AUDIO_MASTER; // 同步策略
-
- // 同步阈值(秒)
- double syncThresholdMin = 0.04; // 最小同步阈值
- double syncThresholdMax = 0.1; // 最大同步阈值
-
- // 帧处理阈值
- double frameDropThreshold = 0.1; // 丢帧阈值
- double frameDupThreshold = 0.1; // 重复帧阈值
-
- // 音频同步参数
- double audioDiffThreshold = 0.1; // 音频差异阈值
- double audioDiffAvgCoef = 0.01; // 音频差异平均系数
- int audioDiffAvgCount = 20; // 音频差异平均计数
-
- // 时钟速度调整参数
- double clockSpeedMin = 0.9; // 最小时钟速度
- double clockSpeedMax = 1.1; // 最大时钟速度
- double clockSpeedStep = 0.001; // 时钟速度调整步长
-
- // 缓冲区控制参数
- int minFramesForSync = 2; // 同步所需最小帧数
- int maxFramesForSync = 10; // 同步所需最大帧数
-
- // 无同步阈值(秒)
- double noSyncThreshold = 10.0; // 超过此阈值不进行同步
- };
- // 同步器统计信息结构体
- struct SyncStatsV2 {
- double audioClock = 0.0; // 音频时钟(秒)
- double videoClock = 0.0; // 视频时钟(秒)
- double externalClock = 0.0; // 外部时钟(秒)
- double masterClock = 0.0; // 主时钟(秒)
-
- double audioVideoSyncError = 0.0; // 音视频同步误差(秒)
- double avgSyncError = 0.0; // 平均同步误差(秒)
- double maxSyncError = 0.0; // 最大同步误差(秒)
-
- int64_t droppedFrames = 0; // 丢弃的帧数
- int64_t duplicatedFrames = 0; // 重复的帧数
-
- double playbackSpeed = 1.0; // 播放速度
- };
- // 时钟结构体(基于ffplay.c中的Clock结构体)
- struct Clock {
- double pts = 0.0; // 时钟基准
- double ptsDrift = 0.0; // 时钟基准减去更新时间
- double lastUpdated = 0.0; // 最后更新时间
- double speed = 1.0; // 时钟速度
- int serial = -1; // 时钟基于此序列号的包
- bool paused = false; // 是否暂停
- int queueSerial = -1; // 当前包队列序列号,用于检测过时的时钟
- };
- // 前向声明
- namespace av {
- namespace player {
- class PlayerCoreV2;
- }
- }
- // 同步器类(基于ffplay.c实现)
- class SynchronizerV2 {
- friend class av::player::PlayerCoreV2; // 声明PlayerCoreV2为友元类
- public:
- // 构造函数和析构函数
- explicit SynchronizerV2(const SyncConfigV2& config = SyncConfigV2());
- ~SynchronizerV2();
-
- // 初始化和清理
- ErrorCode initialize();
- void close();
-
- // 控制接口
- ErrorCode start();
- ErrorCode stop();
- ErrorCode pause();
- ErrorCode resume();
- ErrorCode reset();
-
- // 流信息设置
- void setStreamInfo(bool hasAudio, bool hasVideo);
-
- // 时钟操作
- double getClock(ClockType type) const;
- void setClock(ClockType type, double pts, int serial);
- void setClockAt(ClockType type, double pts, int serial, double time);
- void setClockSpeed(ClockType type, double speed);
-
- // 主时钟操作
- ClockType getMasterClockType() const;
- double getMasterClock() const;
-
- // 同步操作
- double computeTargetDelay(double frameDuration, double videoPts) const;
- FrameDecision synchronizeVideo(double pts, int serial, double duration) const;
- int synchronizeAudio(short* samples, int samplesSize, double pts);
-
- // 配置操作
- void setConfig(const SyncConfigV2& config);
- SyncConfigV2 getConfig() const;
- void setSyncStrategy(SyncStrategy strategy);
- SyncStrategy getSyncStrategy() const;
-
- // 播放速度控制
- void setPlaybackSpeed(double speed);
- double getPlaybackSpeed() const;
-
- // 统计信息
- SyncStatsV2 getStats() const;
-
- // 回调设置
- using SyncErrorCallback = std::function<void(double error, const std::string& reason)>;
- using FrameDropCallback = std::function<void(ClockType type, int64_t pts)>;
-
- void setSyncErrorCallback(const SyncErrorCallback& callback);
- void setFrameDropCallback(const FrameDropCallback& callback);
-
- // 调试信息
- std::string getDebugInfo() const;
-
- private:
- // 内部时钟操作
- void initClock(Clock& clock, int serial);
- void syncClockToSlave(Clock& c, const Clock& slave);
- void updateExternalClock();
- void checkExternalClockSpeed();
-
- // 内部状态
- std::atomic<bool> m_initialized{false};
- std::atomic<bool> m_running{false};
- std::atomic<bool> m_paused{false};
-
- // 配置
- SyncConfigV2 m_config;
- std::atomic<SyncStrategy> m_syncStrategy{SyncStrategy::AUDIO_MASTER};
-
- // 时钟
- mutable std::mutex m_clockMutex;
- Clock m_audioClock;
- Clock m_videoClock;
- Clock m_externalClock;
-
- // 流信息
- std::atomic<bool> m_hasAudio{false};
- std::atomic<bool> m_hasVideo{false};
-
- // 序列号
- std::atomic<int> m_audioSerial{0};
- std::atomic<int> m_videoSerial{0};
- std::atomic<int> m_externalSerial{0};
-
- // 音频同步
- double m_audioDiffCum{0.0}; // 用于音视频差异平均计算
- int m_audioDiffAvgCount{0};
-
- // 播放控制
- std::atomic<double> m_playbackSpeed{1.0};
-
- // 统计信息
- mutable std::mutex m_statsMutex;
- mutable SyncStatsV2 m_stats;
-
- // 回调
- mutable std::mutex m_callbackMutex;
- SyncErrorCallback m_syncErrorCallback;
- FrameDropCallback m_frameDropCallback;
-
- // 帧计时器
- mutable double m_frameTimer{0.0};
-
- // 辅助函数
- double getCurrentTime() const;
- void updateStats();
- void notifySyncError(double error, const std::string& reason) const;
- void notifyFrameDrop(ClockType type, int64_t pts) const;
- };
- } // namespace utils
- } // namespace av
- #endif // AV_UTILS_SYNCHRONIZER_V2_H
|