av_decoder.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #ifndef AV_DECODER_H
  2. #define AV_DECODER_H
  3. #include <QImage>
  4. #include <QVector>
  5. #include <condition_variable>
  6. #include <mutex>
  7. #include <atomic>
  8. extern "C" {
  9. }
  10. #include "ffmpeg_compat.h"
  11. QT_BEGIN_NAMESPACE
  12. namespace AVTool {
  13. typedef struct MediaInfo
  14. {
  15. int duration;
  16. QImage tipImg;
  17. } MediaInfo;
  18. class Decoder
  19. {
  20. public:
  21. typedef struct MyFrame
  22. {
  23. AVFrame frame;
  24. int serial;
  25. double duration;
  26. double pts;
  27. } MyFrame;
  28. private:
  29. typedef struct MyPacket
  30. {
  31. AVPacket pkt;
  32. int serial;
  33. } MyPacket;
  34. typedef struct PacketQueue
  35. {
  36. QVector<MyPacket> pktVec;
  37. int readIndex;
  38. int pushIndex;
  39. int size;
  40. int serial;
  41. std::mutex mutex;
  42. std::condition_variable cond;
  43. } PacketQueue;
  44. typedef struct FrameQueue
  45. {
  46. QVector<MyFrame> frameVec;
  47. int readIndex;
  48. int pushIndex;
  49. int shown;
  50. int size;
  51. std::mutex mutex;
  52. std::condition_variable cond;
  53. } FrameQueue;
  54. typedef struct PktDecoder
  55. {
  56. AVCodecContext* codecCtx;
  57. int serial;
  58. } PktDecoder;
  59. public:
  60. Decoder();
  61. ~Decoder();
  62. //成功探测到媒体信息返回类型实例,否则返回nullptr
  63. AVTool::MediaInfo* detectMediaInfo(const QString& url);
  64. void seekTo(int32_t target, int32_t seekRel);
  65. int getAFrame(AVFrame* frame);
  66. int getRemainingVFrame();
  67. //查看上一帧(即当前显示的画面帧)
  68. Decoder::MyFrame* peekLastVFrame();
  69. //查看将要显示的帧
  70. Decoder::MyFrame* peekVFrame();
  71. //查看将要显示帧再下一帧
  72. Decoder::MyFrame* peekNextVFrame();
  73. //将读索引后移一位
  74. void setNextVFrame();
  75. inline int vidPktSerial() const { return m_videoPacketQueue.serial; }
  76. inline int audioIndex() const { return m_audioIndex; }
  77. inline int videoIndex() const { return m_videoIndex; }
  78. inline AVFormatContext* formatContext() const { return m_fmtCtx; }
  79. inline AVCodecParameters* audioCodecPar() const
  80. {
  81. return m_fmtCtx->streams[m_audioIndex]->codecpar;
  82. }
  83. inline AVCodecParameters* videoCodecPar() const
  84. {
  85. return m_fmtCtx->streams[m_videoIndex]->codecpar;
  86. }
  87. inline uint32_t avDuration() { return m_duration; }
  88. inline int isExit() { return m_exit; }
  89. int decode(const QString& url);
  90. void exit();
  91. private:
  92. PacketQueue m_audioPacketQueue;
  93. PacketQueue m_videoPacketQueue;
  94. FrameQueue m_audioFrameQueue;
  95. FrameQueue m_videoFrameQueue;
  96. PktDecoder m_audioPktDecoder;
  97. PktDecoder m_videoPktDecoder;
  98. AVFormatContext* m_fmtCtx;
  99. const int m_maxFrameQueueSize;
  100. const int m_maxPacketQueueSize;
  101. AVRational m_vidFrameRate;
  102. int m_audioIndex;
  103. int m_videoIndex;
  104. std::atomic<int> m_exit;
  105. //是否执行跳转
  106. int m_isSeek;
  107. //跳转后等待目标帧标志
  108. int m_vidSeek;
  109. int m_audSeek;
  110. //跳转相对时间
  111. int64_t m_seekRel;
  112. //跳转绝对时间
  113. int64_t m_seekTarget;
  114. //流总时长/S
  115. uint32_t m_duration;
  116. char m_errBuf[100];
  117. // 性能优化:动态缓冲区管理
  118. int m_frameQueueAdaptiveSize; // 动态帧队列大小
  119. int64_t m_lastBufferAdjustTime; // 上次缓冲区调整时间
  120. int m_bufferPerformanceCounter; // 缓冲区性能计数器
  121. private:
  122. bool init();
  123. void setInitVal();
  124. void packetQueueFlush(PacketQueue* queue);
  125. void clearQueueCache();
  126. void demux(std::shared_ptr<void> par);
  127. void audioDecode(std::shared_ptr<void> par);
  128. void videoDecode(std::shared_ptr<void> par);
  129. int getPacket(PacketQueue* queue, AVPacket* pkt, PktDecoder* decoder);
  130. void pushPacket(PacketQueue* queue, AVPacket* pkt);
  131. void pushAFrame(AVFrame* frame);
  132. void pushVFrame(AVFrame* frame);
  133. };
  134. } // namespace AVTool
  135. QT_END_NAMESPACE
  136. #endif // AV_DECODER_H