muxer_abstract_muxer.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. #include "muxer_abstract_muxer.h"
  2. #include "../base/logger.h"
  3. #include <algorithm>
  4. #include <cmath>
  5. extern "C" {
  6. #include <libavformat/avformat.h>
  7. #include <libavutil/opt.h>
  8. #include <libavutil/time.h>
  9. }
  10. namespace av {
  11. namespace muxer {
  12. AbstractMuxer::AbstractMuxer() {
  13. AV_LOGGER_DEBUG("创建抽象复用器");
  14. stats_.startTime = std::chrono::steady_clock::now();
  15. lastStatsUpdate_ = stats_.startTime;
  16. }
  17. AbstractMuxer::~AbstractMuxer() {
  18. close();
  19. AV_LOGGER_DEBUG("抽象复用器已销毁");
  20. }
  21. ErrorCode AbstractMuxer::pause() {
  22. if (getState() != MuxerState::STARTED) {
  23. AV_LOGGER_ERROR("复用器状态无效,无法暂停");
  24. return ErrorCode::INVALID_STATE;
  25. }
  26. setState(MuxerState::PAUSED);
  27. AV_LOGGER_INFO("复用器已暂停");
  28. return ErrorCode::OK;
  29. }
  30. ErrorCode AbstractMuxer::resume() {
  31. if (getState() != MuxerState::PAUSED) {
  32. AV_LOGGER_ERROR("复用器状态无效,无法恢复");
  33. return ErrorCode::INVALID_STATE;
  34. }
  35. setState(MuxerState::STARTED);
  36. AV_LOGGER_INFO("复用器已恢复");
  37. return ErrorCode::OK;
  38. }
  39. ErrorCode AbstractMuxer::reset() {
  40. ErrorCode result = stop();
  41. if (result != ErrorCode::OK) {
  42. return result;
  43. }
  44. // 清理流信息
  45. {
  46. std::lock_guard<std::mutex> lock(streamsMutex_);
  47. streams_.clear();
  48. streamMap_.clear();
  49. }
  50. // 重置统计信息
  51. resetStats();
  52. setState(MuxerState::INITIALIZED);
  53. AV_LOGGER_INFO("复用器已重置");
  54. return ErrorCode::OK;
  55. }
  56. ErrorCode AbstractMuxer::removeStream(int streamIndex) {
  57. std::lock_guard<std::mutex> lock(streamsMutex_);
  58. auto it = std::find_if(streams_.begin(), streams_.end(),
  59. [streamIndex](const StreamInfo& info) {
  60. return info.index == streamIndex;
  61. });
  62. if (it == streams_.end()) {
  63. AV_LOGGER_ERRORF("流索引 {} 不存在", streamIndex);
  64. return ErrorCode::STREAM_NOT_FOUND;
  65. }
  66. streams_.erase(it);
  67. streamMap_.erase(streamIndex);
  68. AV_LOGGER_INFOF("已移除流: 索引={}", streamIndex);
  69. return ErrorCode::OK;
  70. }
  71. std::vector<StreamInfo> AbstractMuxer::getStreams() const {
  72. std::lock_guard<std::mutex> lock(streamsMutex_);
  73. return streams_;
  74. }
  75. StreamInfo AbstractMuxer::getStreamInfo(int streamIndex) const {
  76. std::lock_guard<std::mutex> lock(streamsMutex_);
  77. auto it = std::find_if(streams_.begin(), streams_.end(),
  78. [streamIndex](const StreamInfo& info) {
  79. return info.index == streamIndex;
  80. });
  81. if (it != streams_.end()) {
  82. return *it;
  83. }
  84. return StreamInfo{}; // 返回空的流信息
  85. }
  86. MuxerStats AbstractMuxer::getStats() const {
  87. std::lock_guard<std::mutex> lock(statsMutex_);
  88. MuxerStats stats = stats_;
  89. // 计算持续时间
  90. auto now = std::chrono::steady_clock::now();
  91. stats.duration = std::chrono::duration<double>(now - stats_.startTime).count();
  92. return stats;
  93. }
  94. void AbstractMuxer::resetStats() {
  95. std::lock_guard<std::mutex> lock(statsMutex_);
  96. stats_ = MuxerStats{};
  97. stats_.startTime = std::chrono::steady_clock::now();
  98. lastStatsUpdate_ = stats_.startTime;
  99. AV_LOGGER_DEBUG("复用器统计信息已重置");
  100. }
  101. std::string AbstractMuxer::getLastError() const {
  102. return lastError_;
  103. }
  104. std::vector<std::string> AbstractMuxer::getSupportedFormats() {
  105. std::vector<std::string> formats;
  106. const AVOutputFormat* format = nullptr;
  107. void* opaque = nullptr;
  108. while ((format = av_muxer_iterate(&opaque))) {
  109. if (format->name) {
  110. formats.push_back(format->name);
  111. }
  112. }
  113. std::sort(formats.begin(), formats.end());
  114. return formats;
  115. }
  116. std::vector<std::string> AbstractMuxer::getSupportedCodecs(const std::string& format) {
  117. std::vector<std::string> codecs;
  118. const AVOutputFormat* outputFormat = av_guess_format(format.c_str(), nullptr, nullptr);
  119. if (!outputFormat) {
  120. AV_LOGGER_ERRORF("不支持的格式: {}", format);
  121. return codecs;
  122. }
  123. // 获取支持的视频编解码器
  124. if (outputFormat->video_codec != AV_CODEC_ID_NONE) {
  125. const AVCodec* codec = avcodec_find_encoder(outputFormat->video_codec);
  126. if (codec && codec->name) {
  127. codecs.push_back(std::string("video:") + codec->name);
  128. }
  129. }
  130. // 获取支持的音频编解码器
  131. if (outputFormat->audio_codec != AV_CODEC_ID_NONE) {
  132. const AVCodec* codec = avcodec_find_encoder(outputFormat->audio_codec);
  133. if (codec && codec->name) {
  134. codecs.push_back(std::string("audio:") + codec->name);
  135. }
  136. }
  137. // 遍历所有编解码器,查找支持该格式的
  138. const AVCodec* codec = nullptr;
  139. void* opaque = nullptr;
  140. while ((codec = av_codec_iterate(&opaque))) {
  141. if (av_codec_is_encoder(codec)) {
  142. // 检查编解码器是否支持该格式
  143. if (avformat_query_codec(outputFormat, codec->id, FF_COMPLIANCE_NORMAL) == 1) {
  144. std::string codecName = codec->name;
  145. std::string prefix = (codec->type == AVMEDIA_TYPE_VIDEO) ? "video:" : "audio:";
  146. std::string fullName = prefix + codecName;
  147. if (std::find(codecs.begin(), codecs.end(), fullName) == codecs.end()) {
  148. codecs.push_back(fullName);
  149. }
  150. }
  151. }
  152. }
  153. std::sort(codecs.begin(), codecs.end());
  154. return codecs;
  155. }
  156. bool AbstractMuxer::isFormatSupported(const std::string& format) {
  157. const AVOutputFormat* outputFormat = av_guess_format(format.c_str(), nullptr, nullptr);
  158. return outputFormat != nullptr;
  159. }
  160. std::string AbstractMuxer::getFormatFromExtension(const std::string& filename) {
  161. const AVOutputFormat* format = av_guess_format(nullptr, filename.c_str(), nullptr);
  162. if (format && format->name) {
  163. return format->name;
  164. }
  165. return "";
  166. }
  167. std::string AbstractMuxer::getDefaultExtension(const std::string& format) {
  168. const AVOutputFormat* outputFormat = av_guess_format(format.c_str(), nullptr, nullptr);
  169. if (outputFormat && outputFormat->extensions) {
  170. std::string extensions = outputFormat->extensions;
  171. size_t commaPos = extensions.find(',');
  172. if (commaPos != std::string::npos) {
  173. return extensions.substr(0, commaPos);
  174. }
  175. return extensions;
  176. }
  177. return "";
  178. }
  179. void AbstractMuxer::setState(MuxerState state) {
  180. MuxerState oldState = state_.exchange(state);
  181. if (oldState != state) {
  182. AV_LOGGER_DEBUGF("复用器状态变更: {} -> {}",
  183. static_cast<int>(oldState), static_cast<int>(state));
  184. }
  185. }
  186. void AbstractMuxer::onError(ErrorCode code, const std::string& message) {
  187. lastError_ = message;
  188. setState(MuxerState::ERROR_STATE);
  189. {
  190. std::lock_guard<std::mutex> lock(statsMutex_);
  191. stats_.errorCount++;
  192. }
  193. AV_LOGGER_ERRORF("复用器错误: {} (代码: {})", message, static_cast<int>(code));
  194. if (errorCallback_) {
  195. errorCallback_(code, message);
  196. }
  197. }
  198. void AbstractMuxer::updateStats(AVPacket* packet) {
  199. if (!packet) {
  200. return;
  201. }
  202. std::lock_guard<std::mutex> lock(statsMutex_);
  203. stats_.totalPackets++;
  204. stats_.totalBytes += packet->size;
  205. stats_.lastPacketTime = std::chrono::steady_clock::now();
  206. // 更新流统计
  207. stats_.streamPackets[packet->stream_index]++;
  208. stats_.streamBytes[packet->stream_index] += packet->size;
  209. // 定期更新码率
  210. auto now = std::chrono::steady_clock::now();
  211. auto elapsed = std::chrono::duration<double>(now - lastStatsUpdate_).count();
  212. if (elapsed >= STATS_UPDATE_INTERVAL) {
  213. updateBitrate();
  214. lastStatsUpdate_ = now;
  215. // 触发统计回调
  216. if (statsCallback_) {
  217. MuxerStats currentStats = stats_;
  218. currentStats.duration = std::chrono::duration<double>(now - stats_.startTime).count();
  219. statsCallback_(currentStats);
  220. }
  221. }
  222. }
  223. void AbstractMuxer::updateBitrate() {
  224. auto now = std::chrono::steady_clock::now();
  225. double totalDuration = std::chrono::duration<double>(now - stats_.startTime).count();
  226. if (totalDuration > 0) {
  227. stats_.averageBitrate = (stats_.totalBytes * 8.0) / totalDuration;
  228. // 计算当前码率(基于最近的数据)
  229. double recentDuration = std::chrono::duration<double>(now - lastStatsUpdate_).count();
  230. if (recentDuration > 0) {
  231. static uint64_t lastTotalBytes = 0;
  232. uint64_t recentBytes = stats_.totalBytes - lastTotalBytes;
  233. stats_.currentBitrate = (recentBytes * 8.0) / recentDuration;
  234. lastTotalBytes = stats_.totalBytes;
  235. }
  236. }
  237. }
  238. bool AbstractMuxer::validateParams(const MuxerParams& params) {
  239. if (params.outputPath.empty()) {
  240. AV_LOGGER_ERROR("输出路径不能为空");
  241. return false;
  242. }
  243. if (params.format.empty()) {
  244. AV_LOGGER_ERROR("输出格式不能为空");
  245. return false;
  246. }
  247. if (!isFormatSupported(params.format)) {
  248. AV_LOGGER_ERRORF("不支持的输出格式: {}", params.format);
  249. return false;
  250. }
  251. if (params.streams.empty()) {
  252. AV_LOGGER_ERROR("至少需要一个流");
  253. return false;
  254. }
  255. // 验证流参数
  256. for (const auto& stream : params.streams) {
  257. if (stream.codecId == AV_CODEC_ID_NONE) {
  258. AV_LOGGER_ERRORF("流 {} 的编解码器ID无效", stream.index);
  259. return false;
  260. }
  261. if (stream.type == StreamType::VIDEO) {
  262. if (stream.width <= 0 || stream.height <= 0) {
  263. AV_LOGGER_ERRORF("视频流 {} 的分辨率无效: {}x{}",
  264. stream.index, stream.width, stream.height);
  265. return false;
  266. }
  267. if (stream.frameRate.num <= 0 || stream.frameRate.den <= 0) {
  268. AV_LOGGER_ERRORF("视频流 {} 的帧率无效: {}/{}",
  269. stream.index, stream.frameRate.num, stream.frameRate.den);
  270. return false;
  271. }
  272. } else if (stream.type == StreamType::AUDIO) {
  273. if (stream.sampleRate <= 0) {
  274. AV_LOGGER_ERRORF("音频流 {} 的采样率无效: {}",
  275. stream.index, stream.sampleRate);
  276. return false;
  277. }
  278. if (stream.channels <= 0) {
  279. AV_LOGGER_ERRORF("音频流 {} 的声道数无效: {}",
  280. stream.index, stream.channels);
  281. return false;
  282. }
  283. }
  284. }
  285. if (params.bufferSize <= 0) {
  286. AV_LOGGER_ERROR("缓冲区大小必须大于0");
  287. return false;
  288. }
  289. if (params.maxDelay < 0) {
  290. AV_LOGGER_ERROR("最大延迟不能为负数");
  291. return false;
  292. }
  293. return true;
  294. }
  295. std::string MuxerFactory::getTypeName(MuxerType type) const {
  296. switch (type) {
  297. case MuxerType::FILE_MUXER:
  298. return "文件复用器";
  299. case MuxerType::STREAM_MUXER:
  300. return "流复用器";
  301. case MuxerType::RTMP_MUXER:
  302. return "RTMP推流";
  303. case MuxerType::UDP_MUXER:
  304. return "UDP推流";
  305. case MuxerType::TCP_MUXER:
  306. return "TCP推流";
  307. case MuxerType::HLS_MUXER:
  308. return "HLS分片";
  309. case MuxerType::DASH_MUXER:
  310. return "DASH分片";
  311. default:
  312. return "未知类型";
  313. }
  314. }
  315. } // namespace muxer
  316. } // namespace av