codec_abstract_codec.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. #include "codec_abstract_codec.h"
  2. #include "../base/media_common.h"
  3. #include "../base/logger.h"
  4. #include <chrono>
  5. extern "C" {
  6. #include <libavcodec/avcodec.h>
  7. #include <libavutil/opt.h>
  8. }
  9. namespace av {
  10. namespace codec {
  11. AbstractCodec::AbstractCodec(MediaType mediaType, CodecType codecType)
  12. : mediaType_(mediaType)
  13. , codecType_(codecType)
  14. , state_(CodecState::IDLE)
  15. , codec_(nullptr) {
  16. AV_LOGGER_DEBUGF("创建{}编解码器, 媒体类型: {}",
  17. codecType == CodecType::ENCODER ? "编码" : "解码",
  18. static_cast<int>(mediaType));
  19. }
  20. AbstractCodec::~AbstractCodec() {
  21. if (state_ != CodecState::CLOSED && state_ != CodecState::IDLE) {
  22. AV_LOGGER_WARNING("编解码器析构时状态不正确,强制关闭");
  23. close();
  24. }
  25. AV_LOGGER_DEBUG("编解码器已析构");
  26. }
  27. ErrorCode AbstractCodec::reset() {
  28. AV_LOGGER_DEBUG("重置编解码器");
  29. if (state_ == CodecState::IDLE || state_ == CodecState::CLOSED) {
  30. return ErrorCode::SUCCESS;
  31. }
  32. // 先刷新缓冲区
  33. ErrorCode result = flush();
  34. if (result != ErrorCode::SUCCESS) {
  35. AV_LOGGER_ERRORF("刷新编解码器失败: {}", static_cast<int>(result));
  36. return result;
  37. }
  38. // 重置统计信息
  39. resetStatistics();
  40. setState(CodecState::OPENED);
  41. return ErrorCode::SUCCESS;
  42. }
  43. void AbstractCodec::resetStatistics() {
  44. stats_ = Statistics{};
  45. AV_LOGGER_DEBUG("统计信息已重置");
  46. }
  47. void AbstractCodec::setState(CodecState state) {
  48. if (state_ != state) {
  49. AV_LOGGER_DEBUGF("编解码器状态变更: {} -> {}",
  50. static_cast<int>(state_), static_cast<int>(state));
  51. state_ = state;
  52. }
  53. }
  54. void AbstractCodec::reportError(ErrorCode error, const std::string& message) {
  55. setState(CodecState::ERROR);
  56. stats_.errorCount++;
  57. std::string fullMessage = message.empty() ?
  58. ffmpeg_utils::errorToString(static_cast<int>(error)) : message;
  59. AV_LOGGER_ERRORF("编解码器错误: {} ({})", fullMessage, static_cast<int>(error));
  60. if (errorCallback_) {
  61. errorCallback_(error, fullMessage);
  62. }
  63. }
  64. void AbstractCodec::updateStats(bool success, double processTime, uint64_t bytes) {
  65. if (success) {
  66. stats_.processedFrames++;
  67. stats_.totalBytes += bytes;
  68. // 更新平均处理时间
  69. if (stats_.processedFrames == 1) {
  70. stats_.avgProcessTime = processTime;
  71. } else {
  72. stats_.avgProcessTime = (stats_.avgProcessTime * (stats_.processedFrames - 1) + processTime) / stats_.processedFrames;
  73. }
  74. } else {
  75. stats_.droppedFrames++;
  76. }
  77. }
  78. // CodecFactory 实现
  79. std::unique_ptr<AbstractEncoder> CodecFactory::createEncoder(MediaType mediaType, const std::string& codecName) {
  80. AV_LOGGER_INFOF("创建编码器: {} (媒体类型: {})", codecName, static_cast<int>(mediaType));
  81. // 查找编码器
  82. const AVCodec* codec = avcodec_find_encoder_by_name(codecName.c_str());
  83. if (!codec) {
  84. AV_LOGGER_ERRORF("未找到编码器: {}", codecName);
  85. return nullptr;
  86. }
  87. // 检查媒体类型匹配
  88. AVMediaType expectedType = (mediaType == MediaType::VIDEO) ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO;
  89. if (codec->type != expectedType) {
  90. AV_LOGGER_ERRORF("编码器媒体类型不匹配: {} (期望: {}, 实际: {})",
  91. codecName, expectedType, codec->type);
  92. return nullptr;
  93. }
  94. // 这里需要根据具体的编码器类型创建实例
  95. // 暂时返回nullptr,具体实现在子类中
  96. AV_LOGGER_WARNING("CodecFactory::createEncoder 需要在具体实现中完成");
  97. return nullptr;
  98. }
  99. std::unique_ptr<AbstractDecoder> CodecFactory::createDecoder(MediaType mediaType, const std::string& codecName) {
  100. AV_LOGGER_INFOF("创建解码器: {} (媒体类型: {})", codecName, static_cast<int>(mediaType));
  101. // 查找解码器
  102. const AVCodec* codec = avcodec_find_decoder_by_name(codecName.c_str());
  103. if (!codec) {
  104. AV_LOGGER_ERRORF("未找到解码器: {}", codecName);
  105. return nullptr;
  106. }
  107. // 检查媒体类型匹配
  108. AVMediaType expectedType = (mediaType == MediaType::VIDEO) ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO;
  109. if (codec->type != expectedType) {
  110. AV_LOGGER_ERRORF("解码器媒体类型不匹配: {} (期望: {}, 实际: {})",
  111. codecName, expectedType, codec->type);
  112. return nullptr;
  113. }
  114. // 这里需要根据具体的解码器类型创建实例
  115. // 暂时返回nullptr,具体实现在子类中
  116. AV_LOGGER_WARNING("CodecFactory::createDecoder 需要在具体实现中完成");
  117. return nullptr;
  118. }
  119. std::vector<std::string> CodecFactory::getSupportedEncoders(MediaType mediaType) {
  120. std::vector<std::string> encoders;
  121. AVMediaType avMediaType = (mediaType == MediaType::VIDEO) ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO;
  122. void* iter = nullptr;
  123. const AVCodec* codec = nullptr;
  124. while ((codec = av_codec_iterate(&iter)) != nullptr) {
  125. if (av_codec_is_encoder(codec) && codec->type == avMediaType) {
  126. encoders.emplace_back(codec->name);
  127. }
  128. }
  129. AV_LOGGER_INFOF("找到 {} 个{}编码器", encoders.size(),
  130. mediaType == MediaType::VIDEO ? "视频" : "音频");
  131. return encoders;
  132. }
  133. std::vector<std::string> CodecFactory::getSupportedDecoders(MediaType mediaType) {
  134. std::vector<std::string> decoders;
  135. AVMediaType avMediaType = (mediaType == MediaType::VIDEO) ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO;
  136. void* iter = nullptr;
  137. const AVCodec* codec = nullptr;
  138. while ((codec = av_codec_iterate(&iter)) != nullptr) {
  139. if (av_codec_is_decoder(codec) && codec->type == avMediaType) {
  140. decoders.emplace_back(codec->name);
  141. }
  142. }
  143. AV_LOGGER_INFOF("找到 {} 个{}解码器", decoders.size(),
  144. mediaType == MediaType::VIDEO ? "视频" : "音频");
  145. return decoders;
  146. }
  147. bool CodecFactory::isCodecSupported(const std::string& codecName, CodecType type, MediaType mediaType) {
  148. const AVCodec* codec = nullptr;
  149. if (type == CodecType::ENCODER) {
  150. codec = avcodec_find_encoder_by_name(codecName.c_str());
  151. } else {
  152. codec = avcodec_find_decoder_by_name(codecName.c_str());
  153. }
  154. if (!codec) {
  155. return false;
  156. }
  157. AVMediaType expectedType = (mediaType == MediaType::VIDEO) ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO;
  158. return codec->type == expectedType;
  159. }
  160. void AbstractCodec::close() {
  161. AV_LOGGER_DEBUG("关闭编解码器");
  162. if (state_ == CodecState::CLOSED || state_ == CodecState::IDLE) {
  163. return;
  164. }
  165. // 释放编解码上下文
  166. if (codecCtx_) {
  167. AVCodecContext* ctx = codecCtx_.release();
  168. avcodec_free_context(&ctx);
  169. }
  170. codec_ = nullptr;
  171. setState(CodecState::CLOSED);
  172. AV_LOGGER_DEBUG("编解码器已关闭");
  173. }
  174. ErrorCode AbstractCodec::flush() {
  175. AV_LOGGER_DEBUG("刷新编解码器缓冲区");
  176. if (state_ != CodecState::OPENED && state_ != CodecState::RUNNING) {
  177. AV_LOGGER_WARNING("编解码器未打开,无法刷新");
  178. return ErrorCode::INVALID_STATE;
  179. }
  180. if (!codecCtx_) {
  181. AV_LOGGER_ERROR("编解码上下文为空");
  182. return ErrorCode::INVALID_STATE;
  183. }
  184. // 刷新编解码器
  185. avcodec_flush_buffers(codecCtx_.get());
  186. AV_LOGGER_DEBUG("编解码器缓冲区已刷新");
  187. return ErrorCode::SUCCESS;
  188. }
  189. } // namespace codec
  190. } // namespace av