ffmpegvideopuller.h 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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 playLoop();
  47. QString m_url;
  48. std::atomic<bool> m_running{false};
  49. mutable std::mutex m_speedMutex;
  50. float m_speed = 1.0f;
  51. // FFmpeg相关
  52. AVFormatContext* m_fmtCtx = nullptr;
  53. AVCodecContext* m_videoCodecCtx = nullptr;
  54. AVCodecContext* m_audioCodecCtx = nullptr;
  55. int m_videoStreamIdx = -1;
  56. int m_audioStreamIdx = -1;
  57. // 缓冲区
  58. RingBuffer<AVFrame*>* m_videoBuffer = nullptr;
  59. RingBuffer<AVFrame*>* m_audioBuffer = nullptr;
  60. // 线程
  61. QThread* m_decodeThread = nullptr;
  62. QThread* m_playThread = nullptr;
  63. // 播放指针
  64. std::atomic<size_t> m_videoPlayIndex{0};
  65. std::atomic<size_t> m_audioPlayIndex{0};
  66. std::atomic<double> m_currentPts{0.0};
  67. mutable std::mutex m_ptsMutex;
  68. std::function<void(AVFrame*)> m_videoRenderCallback;
  69. std::function<void(AVFrame*)> m_audioPlayCallback;
  70. double m_totalDuration = -1.0;
  71. };
  72. #endif // FFMPEGVIDEOPULLER_H