av_player.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #ifndef AV_PLAYER_H
  2. #define AV_PLAYER_H
  3. #include <QObject>
  4. #include <QSharedPointer>
  5. #include <QSize>
  6. #include <atomic>
  7. #include "av_clock.h"
  8. #include "av_decoder.h"
  9. #include "sonic.h"
  10. extern "C" {
  11. #include <SDL.h>
  12. }
  13. #include "ffmpeg_compat.h"
  14. using AVTool::Decoder;
  15. class VideoFrame;
  16. typedef Decoder::MyFrame MyFrame;
  17. class AVPlayer : public QObject
  18. {
  19. Q_OBJECT
  20. friend void fillAStreamCallback(void* userdata, uint8_t* stream, int len);
  21. public:
  22. enum PlayState { AV_STOPPED, AV_PLAYING, AV_PAUSED };
  23. AVPlayer();
  24. ~AVPlayer();
  25. int play(const QString& url);
  26. void pause(bool isPause);
  27. void clearPlayer();
  28. AVTool::MediaInfo* detectMediaInfo(const QString& url);
  29. AVPlayer::PlayState playState();
  30. void setVFrameSize(const QSize& size)
  31. {
  32. m_imageWidth = size.width();
  33. m_imageHeight = size.height();
  34. }
  35. inline void setVolume(int volumePer)
  36. {
  37. m_volume = (volumePer * SDL_MIX_MAXVOLUME / 100) % (SDL_MIX_MAXVOLUME + 1);
  38. }
  39. // 修改:根据可用主时钟进行seek,使用微秒时间戳
  40. inline void seekBy(int32_t time_s)
  41. {
  42. int64_t baseUs = m_hasAudio ? m_audioClock.getClock() : m_videoClock.getClock();
  43. int32_t baseSeconds = static_cast<int32_t>(baseUs / 1000000);
  44. seekTo(baseSeconds + time_s);
  45. }
  46. inline void seekTo(int32_t time_s)
  47. {
  48. if (playState() == AV_STOPPED)
  49. return;
  50. if (time_s < 0)
  51. time_s = 0;
  52. int64_t baseUs = m_hasAudio ? m_audioClock.getClock() : m_videoClock.getClock();
  53. int32_t baseSeconds = static_cast<int32_t>(baseUs / 1000000);
  54. m_decoder->seekTo(time_s, time_s - baseSeconds);
  55. }
  56. inline uint32_t avDuration() { return m_duration; }
  57. inline void setSpeed(float speed) { m_playSpeed = speed; }
  58. signals:
  59. void frameChanged(QSharedPointer<VideoFrame> frame);
  60. void AVTerminate();
  61. void AVPtsChanged(unsigned int pts);
  62. void AVDurationChanged(unsigned int duration);
  63. private:
  64. int initSDL();
  65. int initVideo();
  66. void videoCallback(std::shared_ptr<void> par);
  67. double computeTargetDelay(double delay);
  68. double vpDuration(MyFrame* lastFrame, MyFrame* curFrame);
  69. void displayImage(AVFrame* frame);
  70. void initAVClock();
  71. private:
  72. //解码器实例
  73. Decoder* m_decoder;
  74. AVFormatContext* m_fmtCtx;
  75. AVCodecParameters* m_audioCodecPar;
  76. SwrContext* m_swrCtx;
  77. uint8_t* m_audioBuf;
  78. sonicStream m_sonicStream;
  79. uint32_t m_audioBufSize;
  80. uint32_t m_audioBufIndex;
  81. uint32_t m_duration;
  82. uint32_t m_lastAudPts;
  83. enum AVSampleFormat m_targetSampleFmt;
  84. //记录音视频帧最新播放帧的时间戳,用于同步
  85. // double m_audioPts;
  86. // double m_videoPts;
  87. std::atomic<float> m_playSpeed;
  88. //延时时间
  89. double m_delay;
  90. //音频播放时钟
  91. AVClock m_audioClock;
  92. //视频播放时钟
  93. AVClock m_videoClock;
  94. int m_targetChannels;
  95. int m_targetFreq;
  96. int m_targetChannelLayout;
  97. int m_targetNbSamples;
  98. int m_volume;
  99. //同步时钟初始化标志,音视频异步线程
  100. //谁先读到初始标志位就由谁初始化时钟
  101. int m_clockInitFlag;
  102. int m_audioIndex;
  103. int m_videoIndex;
  104. int m_imageWidth;
  105. int m_imageHeight;
  106. //终止标志
  107. std::atomic<int> m_exit;
  108. //记录暂停前的时间(微秒)
  109. int64_t m_pauseTimeUs;
  110. //暂停标志
  111. std::atomic<int> m_pause;
  112. AVFrame* m_audioFrame;
  113. AVCodecParameters* m_videoCodecPar;
  114. enum AVPixelFormat m_dstPixFmt;
  115. int m_swsFlags;
  116. SwsContext* m_swsCtx;
  117. uint8_t* m_buffer;
  118. uint8_t* m_pixels[4];
  119. int m_pitch[4];
  120. // 新增:是否存在音频/视频流
  121. bool m_hasAudio = false;
  122. bool m_hasVideo = false;
  123. // 性能优化:添加高精度时间基准(微秒)
  124. int64_t m_baseTimeUs = 0; // 高精度时间基准(微秒)
  125. int64_t m_frameTimerUs = 0; // 高精度帧定时器(微秒)
  126. int m_performanceFrameCount = 0; // 性能监控帧计数
  127. double m_lastDelayValue = 0.0; // 上次延迟值,用于延迟累积检测
  128. };
  129. #endif