| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- #ifndef AV_PLAYER_H
- #define AV_PLAYER_H
- #include <QObject>
- #include <QSharedPointer>
- #include <QSize>
- #include <atomic>
- #include "av_clock.h"
- #include "av_decoder.h"
- #include "sonic.h"
- extern "C" {
- #include <SDL.h>
- }
- #include "ffmpeg_compat.h"
- using AVTool::Decoder;
- class VideoFrame;
- typedef Decoder::MyFrame MyFrame;
- class AVPlayer : public QObject
- {
- Q_OBJECT
- friend void fillAStreamCallback(void* userdata, uint8_t* stream, int len);
- public:
- enum PlayState { AV_STOPPED, AV_PLAYING, AV_PAUSED };
- // 新增:同步主时钟类型
- enum SyncType { SYNC_AUDIO, SYNC_VIDEO, SYNC_EXTERNAL };
- AVPlayer();
- ~AVPlayer();
- int play(const QString& url);
- void pause(bool isPause);
- void clearPlayer();
- AVTool::MediaInfo* detectMediaInfo(const QString& url);
- AVPlayer::PlayState playState();
- void setVFrameSize(const QSize& size)
- {
- m_imageWidth = size.width();
- m_imageHeight = size.height();
- }
- inline void setVolume(int volumePer)
- {
- m_volume = (volumePer * SDL_MIX_MAXVOLUME / 100) % (SDL_MIX_MAXVOLUME + 1);
- }
- // 新增:设置同步主时钟类型(默认外部时钟,适合直播/RTSP)
- inline void setSyncType(SyncType type) { m_syncType = type; }
- // 修改:根据选定主时钟进行seek,使用微秒时间戳
- inline void seekBy(int32_t time_s)
- {
- int64_t baseUs = masterClockUs();
- int32_t baseSeconds = static_cast<int32_t>(baseUs / 1000000);
- seekTo(baseSeconds + time_s);
- }
- inline void seekTo(int32_t time_s)
- {
- if (playState() == AV_STOPPED)
- return;
- if (time_s < 0)
- time_s = 0;
- int64_t baseUs = masterClockUs();
- int32_t baseSeconds = static_cast<int32_t>(baseUs / 1000000);
- m_decoder->seekTo(time_s, time_s - baseSeconds);
- }
- inline uint32_t avDuration() { return m_duration; }
- inline void setSpeed(float speed) { m_playSpeed = speed; }
- signals:
- void frameChanged(QSharedPointer<VideoFrame> frame);
- void AVTerminate();
- void AVPtsChanged(unsigned int pts);
- void AVDurationChanged(unsigned int duration);
- private:
- int initSDL();
- int initVideo();
- void videoCallback(std::shared_ptr<void> par);
- double computeTargetDelay(double delay);
- double vpDuration(MyFrame* lastFrame, MyFrame* curFrame);
- void displayImage(AVFrame* frame);
- void initAVClock();
- // 新增:获取当前主时钟(微秒)
- inline int64_t masterClockUs()
- {
- switch (m_syncType) {
- case SYNC_AUDIO:
- return m_audioClock.getClock();
- case SYNC_VIDEO:
- return m_videoClock.getClock();
- case SYNC_EXTERNAL:
- default:
- return m_extClock.getClock();
- }
- }
- private:
- //解码器实例
- Decoder* m_decoder;
- AVFormatContext* m_fmtCtx;
- AVCodecParameters* m_audioCodecPar;
- SwrContext* m_swrCtx;
- uint8_t* m_audioBuf;
- sonicStream m_sonicStream;
- uint32_t m_audioBufSize;
- uint32_t m_audioBufIndex;
- uint32_t m_duration;
- uint32_t m_lastAudPts;
- enum AVSampleFormat m_targetSampleFmt;
- //记录音视频帧最新播放帧的时间戳,用于同步
- // double m_audioPts;
- // double m_videoPts;
- std::atomic<float> m_playSpeed;
- //延时时间
- double m_delay;
- //音频播放时钟
- AVClock m_audioClock;
- //视频播放时钟
- AVClock m_videoClock;
- // 新增:外部时钟(以系统时钟为基准)
- AVClock m_extClock;
- // 新增:PTS基线(微秒),用于将首帧归零,避免绝对PTS导致的巨幅偏差
- int64_t m_audioStartPtsUs = -1;
- int64_t m_videoStartPtsUs = -1;
- int m_targetChannels;
- int m_targetFreq;
- int m_targetChannelLayout;
- int m_targetNbSamples;
- int m_volume;
- //同步时钟初始化标志,音视频异步线程
- //谁先读到初始标志位就由谁初始化时钟
- int m_clockInitFlag;
- int m_audioIndex;
- int m_videoIndex;
- int m_imageWidth;
- int m_imageHeight;
- //终止标志
- std::atomic<int> m_exit;
- //记录暂停前的时间(微秒)
- int64_t m_pauseTimeUs;
- //暂停时钟快照(微秒)
- int64_t m_pauseAudClockUs = 0;
- int64_t m_pauseVidClockUs = 0;
- int64_t m_pauseExtClockUs = 0;
- //暂停标志
- std::atomic<int> m_pause;
- AVFrame* m_audioFrame;
- AVCodecParameters* m_videoCodecPar;
- enum AVPixelFormat m_dstPixFmt;
- int m_swsFlags;
- SwsContext* m_swsCtx;
- uint8_t* m_buffer;
- uint8_t* m_pixels[4];
- int m_pitch[4];
- // 新增:是否存在音频/视频流
- bool m_hasAudio = false;
- bool m_hasVideo = false;
-
- // 性能优化:添加高精度时间基准(微秒)
- int64_t m_baseTimeUs = 0; // 高精度时间基准(微秒)
- int64_t m_frameTimerUs = 0; // 高精度帧定时器(微秒)
- int m_performanceFrameCount = 0; // 性能监控帧计数
- double m_lastDelayValue = 0.0; // 上次延迟值,用于延迟累积检测
- // 新增:同步主时钟类型(默认外部时钟,同步策略更接近ffplay -sync ext)
- SyncType m_syncType = SYNC_EXTERNAL;
- };
- #endif
|