#ifndef AV_PLAYER_H #define AV_PLAYER_H #include #include #include #include #include "av_clock.h" #include "av_decoder.h" #include "sonic.h" extern "C" { #include } #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 }; 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); } // 修改:根据可用主时钟进行seek inline void seekBy(int32_t time_s) { double base = m_hasAudio ? m_audioClock.getClock() : m_videoClock.getClock(); seekTo((int32_t) base + time_s); } inline void seekTo(int32_t time_s) { if (playState() == AV_STOPPED) return; if (time_s < 0) time_s = 0; double base = m_hasAudio ? m_audioClock.getClock() : m_videoClock.getClock(); m_decoder->seekTo(time_s, time_s - (int32_t) base); } inline uint32_t avDuration() { return m_duration; } inline void setSpeed(float speed) { m_playSpeed = speed; } signals: void frameChanged(QSharedPointer frame); void AVTerminate(); void AVPtsChanged(unsigned int pts); void AVDurationChanged(unsigned int duration); private: int initSDL(); int initVideo(); void videoCallback(std::shared_ptr par); double computeTargetDelay(double delay); double vpDuration(MyFrame* lastFrame, MyFrame* curFrame); void displayImage(AVFrame* frame); void initAVClock(); 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; double m_frameTimer; std::atomic m_playSpeed; //延时时间 double m_delay; //音频播放时钟 AVClock m_audioClock; //视频播放时钟 AVClock m_videoClock; 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 m_exit; //记录暂停前的时间 double m_pauseTime; //暂停标志 std::atomic 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; }; #endif