ffmpegvideopuller.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #ifndef FFMPEGVIDEOPULLER_H
  2. #define FFMPEGVIDEOPULLER_H
  3. #pragma once
  4. extern "C" {
  5. #include <libavcodec/avcodec.h>
  6. #include <libavformat/avformat.h>
  7. }
  8. #include <QObject>
  9. #include <QString>
  10. #include <QThread>
  11. #include <atomic>
  12. #include <functional>
  13. #include "RingBuffer.h"
  14. class FFmpegVideoPuller : public QObject
  15. {
  16. Q_OBJECT
  17. public:
  18. explicit FFmpegVideoPuller(QObject* parent = nullptr);
  19. ~FFmpegVideoPuller();
  20. bool open(const QString& url,
  21. int videoBufferSec = 300,
  22. int audioBufferSec = 300); // 默认缓存5分钟
  23. void setSpeed(float speed); // 设置倍速
  24. float getSpeed() const;
  25. void start();
  26. void stop();
  27. // 进度相关
  28. double getFirstPts() const;
  29. double getLastPts() const;
  30. double getCurrentPts() const;
  31. void seekToPts(double pts); // 跳转到指定pts
  32. // 取帧接口
  33. AVFrame* getCurrentVideoFrame();
  34. AVFrame* getCurrentAudioFrame();
  35. // 播放指针前进
  36. void nextVideoFrame();
  37. void nextAudioFrame();
  38. // 缓冲区大小
  39. size_t videoBufferSize() const;
  40. size_t audioBufferSize() const;
  41. void setVideoRenderCallback(std::function<void(AVFrame*)> cb) { m_videoRenderCallback = cb; }
  42. void setAudioPlayCallback(std::function<void(AVFrame*)> cb) { m_audioPlayCallback = cb; }
  43. double getTotalDuration() const { return m_totalDuration; }
  44. private:
  45. void decodeLoop();
  46. void videoPlayLoop();
  47. void audioPlayLoop();
  48. // 音视频同步
  49. std::atomic<double> m_audioPts{0.0};
  50. std::atomic<double> m_videoPts{0.0};
  51. std::mutex m_syncMutex;
  52. QString m_url;
  53. std::atomic<bool> m_running{false};
  54. mutable std::mutex m_speedMutex;
  55. float m_speed = 1.0f;
  56. // FFmpeg相关
  57. AVFormatContext* m_fmtCtx = nullptr;
  58. AVCodecContext* m_videoCodecCtx = nullptr;
  59. AVCodecContext* m_audioCodecCtx = nullptr;
  60. int m_videoStreamIdx = -1;
  61. int m_audioStreamIdx = -1;
  62. // 缓冲区
  63. RingBuffer<AVFrame*>* m_videoBuffer = nullptr;
  64. RingBuffer<AVFrame*>* m_audioBuffer = nullptr;
  65. // 线程
  66. QThread* m_decodeThread = nullptr;
  67. QThread* m_videoPlayThread = nullptr;
  68. QThread* m_audioPlayThread = nullptr;
  69. // 播放指针
  70. std::atomic<size_t> m_videoPlayIndex{0};
  71. std::atomic<size_t> m_audioPlayIndex{0};
  72. std::atomic<double> m_currentPts{0.0};
  73. mutable std::mutex m_ptsMutex;
  74. std::function<void(AVFrame*)> m_videoRenderCallback;
  75. std::function<void(AVFrame*)> m_audioPlayCallback;
  76. double m_totalDuration = -1.0;
  77. };
  78. #endif // FFMPEGVIDEOPULLER_H