muxer_file_muxer.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #ifndef AV_MUXER_FILE_MUXER_H
  2. #define AV_MUXER_FILE_MUXER_H
  3. #include "muxer_abstract_muxer.h"
  4. #include <string>
  5. #include <memory>
  6. #include <thread>
  7. #include <queue>
  8. #include <condition_variable>
  9. #include <atomic>
  10. extern "C" {
  11. #include <libavformat/avformat.h>
  12. #include <libavcodec/avcodec.h>
  13. #include <libavutil/avutil.h>
  14. }
  15. namespace av {
  16. namespace muxer {
  17. // 文件复用器参数
  18. struct FileMuxerParams : public MuxerParams {
  19. std::string outputFile; // 输出文件路径
  20. bool overwrite = true; // 是否覆盖已存在文件
  21. // 文件特定选项
  22. int64_t maxFileSize = 0; // 最大文件大小(字节,0表示无限制)
  23. int maxDuration = 0; // 最大录制时长(秒,0表示无限制)
  24. bool enableSegmentation = false; // 是否启用分段
  25. int segmentDuration = 600; // 分段时长(秒)
  26. std::string segmentPattern; // 分段文件名模式
  27. // 质量控制
  28. bool enableFastStart = true; // 启用快速开始(moov atom前置)
  29. int movFlags = 0; // MOV标志
  30. // 同步选项
  31. bool syncMode = false; // 同步写入模式
  32. int flushInterval = 5; // 刷新间隔(秒)
  33. FileMuxerParams() : MuxerParams(MuxerType::FILE_MUXER) {}
  34. };
  35. // 包队列项
  36. struct PacketQueueItem {
  37. AVPacket* packet = nullptr;
  38. int streamIndex = -1;
  39. std::chrono::steady_clock::time_point timestamp;
  40. PacketQueueItem() = default;
  41. PacketQueueItem(AVPacket* pkt, int index)
  42. : packet(pkt), streamIndex(index), timestamp(std::chrono::steady_clock::now()) {}
  43. ~PacketQueueItem() {
  44. if (packet) {
  45. av_packet_free(&packet);
  46. }
  47. }
  48. // 禁用拷贝,只允许移动
  49. PacketQueueItem(const PacketQueueItem&) = delete;
  50. PacketQueueItem& operator=(const PacketQueueItem&) = delete;
  51. PacketQueueItem(PacketQueueItem&& other) noexcept
  52. : packet(other.packet), streamIndex(other.streamIndex), timestamp(other.timestamp) {
  53. other.packet = nullptr;
  54. }
  55. PacketQueueItem& operator=(PacketQueueItem&& other) noexcept {
  56. if (this != &other) {
  57. if (packet) {
  58. av_packet_free(&packet);
  59. }
  60. packet = other.packet;
  61. streamIndex = other.streamIndex;
  62. timestamp = other.timestamp;
  63. other.packet = nullptr;
  64. }
  65. return *this;
  66. }
  67. };
  68. // 文件复用器类
  69. class FileMuxer : public AbstractMuxer {
  70. public:
  71. FileMuxer();
  72. ~FileMuxer() override;
  73. // 基础接口实现
  74. ErrorCode initialize(const MuxerParams& params) override;
  75. ErrorCode start() override;
  76. ErrorCode stop() override;
  77. ErrorCode close() override;
  78. // 写入接口实现
  79. ErrorCode writePacket(AVPacket* packet) override;
  80. ErrorCode writeFrame(AVFrame* frame, int streamIndex) override;
  81. ErrorCode flush() override;
  82. // 流管理实现
  83. ErrorCode addStream(const StreamInfo& streamInfo) override;
  84. // 文件特定接口
  85. ErrorCode setOutputFile(const std::string& filename);
  86. std::string getOutputFile() const;
  87. int64_t getCurrentFileSize() const;
  88. double getCurrentDuration() const;
  89. // 分段控制
  90. ErrorCode enableSegmentation(bool enable, int duration = 600);
  91. ErrorCode forceNewSegment();
  92. std::vector<std::string> getSegmentFiles() const;
  93. // 质量控制
  94. ErrorCode setFastStart(bool enable);
  95. ErrorCode setMovFlags(int flags);
  96. // 工厂类
  97. class FileMuxerFactory : public MuxerFactory {
  98. public:
  99. std::unique_ptr<AbstractMuxer> createMuxer(MuxerType type) override;
  100. bool isTypeSupported(MuxerType type) const override;
  101. std::vector<MuxerType> getSupportedTypes() const override;
  102. // 文件复用器特定方法
  103. static std::unique_ptr<FileMuxer> createFileMuxer(const std::string& filename);
  104. static std::unique_ptr<FileMuxer> createSegmentedMuxer(const std::string& pattern, int duration);
  105. };
  106. protected:
  107. // 内部实现方法
  108. ErrorCode setupOutput() override;
  109. ErrorCode writeHeader() override;
  110. ErrorCode writeTrailer() override;
  111. // 文件操作
  112. ErrorCode openOutputFile();
  113. ErrorCode closeOutputFile();
  114. ErrorCode createNewSegment();
  115. // 流设置
  116. ErrorCode setupStreams();
  117. AVStream* createAVStream(const StreamInfo& streamInfo);
  118. // 内部方法
  119. ErrorCode processPacket(AVPacket* packet);
  120. ErrorCode writePacketInternal(AVPacket* packet);
  121. ErrorCode flushInternal(); // 内部刷新方法,假设已持有锁
  122. // 线程函数
  123. void writeThreadFunc();
  124. // 工具方法
  125. std::string generateSegmentFilename(int segmentIndex);
  126. bool shouldCreateNewSegment() const;
  127. ErrorCode validateFilePath(const std::string& path);
  128. // 参数验证
  129. bool validateParams(const MuxerParams& params) override;
  130. private:
  131. FileMuxerParams fileMuxerParams_;
  132. // 文件信息
  133. std::string currentOutputFile_;
  134. int64_t currentFileSize_ = 0;
  135. std::chrono::steady_clock::time_point fileStartTime_;
  136. // 分段相关
  137. bool segmentationEnabled_ = false;
  138. int currentSegmentIndex_ = 0;
  139. std::vector<std::string> segmentFiles_;
  140. // 写入线程
  141. std::thread writeThread_;
  142. std::atomic<bool> shouldStopWriting_{false};
  143. // 包队列
  144. std::queue<std::unique_ptr<PacketQueueItem>> packetQueue_;
  145. mutable std::mutex queueMutex_;
  146. std::condition_variable queueCondition_;
  147. static constexpr size_t MAX_QUEUE_SIZE = 100;
  148. // 同步控制
  149. mutable std::mutex fileMutex_;
  150. std::chrono::steady_clock::time_point lastFlushTime_;
  151. // 性能监控
  152. std::atomic<uint64_t> queuedPackets_{0};
  153. std::atomic<uint64_t> writtenPackets_{0};
  154. std::atomic<double> averageWriteTime_{0.0};
  155. };
  156. } // namespace muxer
  157. } // namespace av
  158. #endif // AV_MUXER_FILE_MUXER_H