av_player.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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. double base = m_hasAudio ? m_audioClock.getClock() : m_videoClock.getClock();
  43. seekTo((int32_t) base + time_s);
  44. }
  45. inline void seekTo(int32_t time_s)
  46. {
  47. if (playState() == AV_STOPPED)
  48. return;
  49. if (time_s < 0)
  50. time_s = 0;
  51. double base = m_hasAudio ? m_audioClock.getClock() : m_videoClock.getClock();
  52. m_decoder->seekTo(time_s, time_s - (int32_t) base);
  53. }
  54. inline uint32_t avDuration() { return m_duration; }
  55. inline void setSpeed(float speed) { m_playSpeed = speed; }
  56. signals:
  57. void frameChanged(QSharedPointer<VideoFrame> frame);
  58. void AVTerminate();
  59. void AVPtsChanged(unsigned int pts);
  60. void AVDurationChanged(unsigned int duration);
  61. private:
  62. int initSDL();
  63. int initVideo();
  64. void videoCallback(std::shared_ptr<void> par);
  65. double computeTargetDelay(double delay);
  66. double vpDuration(MyFrame* lastFrame, MyFrame* curFrame);
  67. void displayImage(AVFrame* frame);
  68. void initAVClock();
  69. private:
  70. //解码器实例
  71. Decoder* m_decoder;
  72. AVFormatContext* m_fmtCtx;
  73. AVCodecParameters* m_audioCodecPar;
  74. SwrContext* m_swrCtx;
  75. uint8_t* m_audioBuf;
  76. sonicStream m_sonicStream;
  77. uint32_t m_audioBufSize;
  78. uint32_t m_audioBufIndex;
  79. uint32_t m_duration;
  80. uint32_t m_lastAudPts;
  81. enum AVSampleFormat m_targetSampleFmt;
  82. //记录音视频帧最新播放帧的时间戳,用于同步
  83. // double m_audioPts;
  84. // double m_videoPts;
  85. double m_frameTimer;
  86. std::atomic<float> m_playSpeed;
  87. //延时时间
  88. double m_delay;
  89. //音频播放时钟
  90. AVClock m_audioClock;
  91. //视频播放时钟
  92. AVClock m_videoClock;
  93. int m_targetChannels;
  94. int m_targetFreq;
  95. int m_targetChannelLayout;
  96. int m_targetNbSamples;
  97. int m_volume;
  98. //同步时钟初始化标志,音视频异步线程
  99. //谁先读到初始标志位就由谁初始化时钟
  100. int m_clockInitFlag;
  101. int m_audioIndex;
  102. int m_videoIndex;
  103. int m_imageWidth;
  104. int m_imageHeight;
  105. //终止标志
  106. std::atomic<int> m_exit;
  107. //记录暂停前的时间
  108. double m_pauseTime;
  109. //暂停标志
  110. std::atomic<int> m_pause;
  111. AVFrame* m_audioFrame;
  112. AVCodecParameters* m_videoCodecPar;
  113. enum AVPixelFormat m_dstPixFmt;
  114. int m_swsFlags;
  115. SwsContext* m_swsCtx;
  116. uint8_t* m_buffer;
  117. uint8_t* m_pixels[4];
  118. int m_pitch[4];
  119. // 新增:是否存在音频/视频流
  120. bool m_hasAudio = false;
  121. bool m_hasVideo = false;
  122. };
  123. #endif