codec_abstract_codec.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. #include "codec_abstract_codec.h"
  2. #include "codec_video_encoder.h"
  3. #include "codec_audio_encoder.h"
  4. #include "codec_video_decoder.h"
  5. #include "codec_audio_decoder.h"
  6. #include "../base/media_common.h"
  7. #include "../base/logger.h"
  8. #include <chrono>
  9. extern "C" {
  10. #include <libavcodec/avcodec.h>
  11. #include <libavutil/opt.h>
  12. }
  13. namespace av {
  14. namespace codec {
  15. AbstractCodec::AbstractCodec(MediaType mediaType, CodecType codecType)
  16. : mediaType_(mediaType)
  17. , codecType_(codecType)
  18. , state_(CodecState::IDLE)
  19. , codec_(nullptr) {
  20. AV_LOGGER_DEBUGF("创建{}编解码器, 媒体类型: {}",
  21. codecType == CodecType::ENCODER ? "编码" : "解码",
  22. static_cast<int>(mediaType));
  23. }
  24. AbstractCodec::~AbstractCodec() {
  25. if (state_ != CodecState::CLOSED && state_ != CodecState::IDLE) {
  26. AV_LOGGER_WARNING("编解码器析构时状态不正确,强制关闭");
  27. close();
  28. }
  29. AV_LOGGER_DEBUG("编解码器已析构");
  30. }
  31. ErrorCode AbstractCodec::reset() {
  32. AV_LOGGER_DEBUG("重置编解码器");
  33. if (state_ == CodecState::IDLE || state_ == CodecState::CLOSED) {
  34. return ErrorCode::SUCCESS;
  35. }
  36. // 先刷新缓冲区
  37. ErrorCode result = flush();
  38. if (result != ErrorCode::SUCCESS) {
  39. AV_LOGGER_ERRORF("刷新编解码器失败: {}", static_cast<int>(result));
  40. return result;
  41. }
  42. // 重置统计信息
  43. resetStatistics();
  44. setState(CodecState::OPENED);
  45. return ErrorCode::SUCCESS;
  46. }
  47. void AbstractCodec::resetStatistics() {
  48. std::lock_guard<std::mutex> lock(statsMutex_);
  49. stats_ = Statistics{};
  50. AV_LOGGER_DEBUG("统计信息已重置");
  51. }
  52. void AbstractCodec::setState(CodecState state) {
  53. std::unique_lock<std::shared_mutex> lock(stateMutex_);
  54. if (state_ != state) {
  55. AV_LOGGER_DEBUGF("编解码器状态变更: {} -> {}",
  56. static_cast<int>(state_), static_cast<int>(state));
  57. state_ = state;
  58. }
  59. }
  60. void AbstractCodec::reportError(ErrorCode error, const std::string& message) {
  61. setState(CodecState::ERROR);
  62. // 更新错误统计
  63. {
  64. std::lock_guard<std::mutex> lock(statsMutex_);
  65. stats_.errorCount++;
  66. }
  67. std::string fullMessage = message.empty() ?
  68. ffmpeg_utils::errorToString(static_cast<int>(error)) : message;
  69. AV_LOGGER_ERRORF("编解码器错误: {} ({})", fullMessage, static_cast<int>(error));
  70. if (errorCallback_) {
  71. errorCallback_(error, fullMessage);
  72. }
  73. }
  74. void AbstractCodec::updateStats(bool success, double processTime, uint64_t bytes) {
  75. std::lock_guard<std::mutex> lock(statsMutex_);
  76. if (success) {
  77. stats_.processedFrames++;
  78. stats_.totalBytes += bytes;
  79. // 更新平均处理时间
  80. if (stats_.processedFrames == 1) {
  81. stats_.avgProcessTime = processTime;
  82. } else {
  83. stats_.avgProcessTime = (stats_.avgProcessTime * (stats_.processedFrames - 1) + processTime) / stats_.processedFrames;
  84. }
  85. } else {
  86. stats_.droppedFrames++;
  87. }
  88. }
  89. // CodecFactory 实现
  90. std::unique_ptr<AbstractEncoder> CodecFactory::createEncoder(MediaType mediaType, const std::string& codecName) {
  91. AV_LOGGER_INFOF("创建编码器: {} (媒体类型: {})", codecName, static_cast<int>(mediaType));
  92. // 查找编码器
  93. const AVCodec* codec = avcodec_find_encoder_by_name(codecName.c_str());
  94. if (!codec) {
  95. AV_LOGGER_ERRORF("未找到编码器: {}", codecName);
  96. return nullptr;
  97. }
  98. // 检查媒体类型匹配
  99. AVMediaType expectedType = (mediaType == MediaType::VIDEO) ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO;
  100. if (codec->type != expectedType) {
  101. AV_LOGGER_ERRORF("编码器媒体类型不匹配: {} (期望: {}, 实际: {})",
  102. codecName, expectedType, codec->type);
  103. return nullptr;
  104. }
  105. // 根据媒体类型创建具体的编码器实例
  106. try {
  107. if (mediaType == MediaType::VIDEO) {
  108. auto encoder = std::make_unique<VideoEncoder>();
  109. AV_LOGGER_INFOF("成功创建视频编码器: {}", codecName);
  110. return std::move(encoder);
  111. } else if (mediaType == MediaType::AUDIO) {
  112. auto encoder = std::make_unique<AudioEncoder>();
  113. AV_LOGGER_INFOF("成功创建音频编码器: {}", codecName);
  114. return std::move(encoder);
  115. } else {
  116. AV_LOGGER_ERRORF("不支持的媒体类型: {}", static_cast<int>(mediaType));
  117. return nullptr;
  118. }
  119. } catch (const std::exception& e) {
  120. AV_LOGGER_ERRORF("创建编码器实例失败: {}", e.what());
  121. return nullptr;
  122. }
  123. }
  124. std::unique_ptr<AbstractDecoder> CodecFactory::createDecoder(MediaType mediaType, const std::string& codecName) {
  125. AV_LOGGER_INFOF("创建解码器: {} (媒体类型: {})", codecName, static_cast<int>(mediaType));
  126. // 查找解码器
  127. const AVCodec* codec = avcodec_find_decoder_by_name(codecName.c_str());
  128. if (!codec) {
  129. AV_LOGGER_ERRORF("未找到解码器: {}", codecName);
  130. return nullptr;
  131. }
  132. // 检查媒体类型匹配
  133. AVMediaType expectedType = (mediaType == MediaType::VIDEO) ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO;
  134. if (codec->type != expectedType) {
  135. AV_LOGGER_ERRORF("解码器媒体类型不匹配: {} (期望: {}, 实际: {})",
  136. codecName, expectedType, codec->type);
  137. return nullptr;
  138. }
  139. // 根据媒体类型创建具体的解码器实例
  140. try {
  141. if (mediaType == MediaType::VIDEO) {
  142. auto decoder = std::make_unique<VideoDecoder>();
  143. AV_LOGGER_INFOF("成功创建视频解码器: {}", codecName);
  144. return std::move(decoder);
  145. } else if (mediaType == MediaType::AUDIO) {
  146. auto decoder = std::make_unique<AudioDecoder>();
  147. AV_LOGGER_INFOF("成功创建音频解码器: {}", codecName);
  148. return std::move(decoder);
  149. } else {
  150. AV_LOGGER_ERRORF("不支持的媒体类型: {}", static_cast<int>(mediaType));
  151. return nullptr;
  152. }
  153. } catch (const std::exception& e) {
  154. AV_LOGGER_ERRORF("创建解码器实例失败: {}", e.what());
  155. return nullptr;
  156. }
  157. }
  158. std::vector<std::string> CodecFactory::getSupportedEncoders(MediaType mediaType) {
  159. std::vector<std::string> encoders;
  160. AVMediaType avMediaType = (mediaType == MediaType::VIDEO) ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO;
  161. void* iter = nullptr;
  162. const AVCodec* codec = nullptr;
  163. while ((codec = av_codec_iterate(&iter)) != nullptr) {
  164. if (av_codec_is_encoder(codec) && codec->type == avMediaType) {
  165. encoders.emplace_back(codec->name);
  166. }
  167. }
  168. AV_LOGGER_INFOF("找到 {} 个{}编码器", encoders.size(),
  169. mediaType == MediaType::VIDEO ? "视频" : "音频");
  170. return encoders;
  171. }
  172. std::vector<std::string> CodecFactory::getSupportedDecoders(MediaType mediaType) {
  173. std::vector<std::string> decoders;
  174. AVMediaType avMediaType = (mediaType == MediaType::VIDEO) ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO;
  175. void* iter = nullptr;
  176. const AVCodec* codec = nullptr;
  177. while ((codec = av_codec_iterate(&iter)) != nullptr) {
  178. if (av_codec_is_decoder(codec) && codec->type == avMediaType) {
  179. decoders.emplace_back(codec->name);
  180. }
  181. }
  182. AV_LOGGER_INFOF("找到 {} 个{}解码器", decoders.size(),
  183. mediaType == MediaType::VIDEO ? "视频" : "音频");
  184. return decoders;
  185. }
  186. bool CodecFactory::isCodecSupported(const std::string& codecName, CodecType type, MediaType mediaType) {
  187. const AVCodec* codec = nullptr;
  188. if (type == CodecType::ENCODER) {
  189. codec = avcodec_find_encoder_by_name(codecName.c_str());
  190. } else {
  191. codec = avcodec_find_decoder_by_name(codecName.c_str());
  192. }
  193. if (!codec) {
  194. return false;
  195. }
  196. AVMediaType expectedType = (mediaType == MediaType::VIDEO) ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO;
  197. return codec->type == expectedType;
  198. }
  199. void AbstractCodec::close() {
  200. AV_LOGGER_DEBUG("关闭编解码器");
  201. // 使用RAII确保异常安全
  202. try {
  203. std::unique_lock<std::shared_mutex> stateLock(stateMutex_);
  204. if (state_ == CodecState::CLOSED || state_ == CodecState::IDLE) {
  205. return;
  206. }
  207. // 设置状态为关闭中,防止其他操作
  208. state_ = CodecState::CLOSED;
  209. stateLock.unlock();
  210. // 获取资源锁进行清理
  211. std::lock_guard<std::mutex> resourceLock(resourceMutex_);
  212. // 释放编解码上下文
  213. if (codecCtx_) {
  214. AVCodecContext* ctx = codecCtx_.release();
  215. avcodec_free_context(&ctx);
  216. }
  217. codec_ = nullptr;
  218. AV_LOGGER_DEBUG("编解码器已关闭");
  219. } catch (const std::exception& e) {
  220. AV_LOGGER_ERRORF("关闭编解码器时发生异常: {}", e.what());
  221. // 确保状态被设置为错误
  222. try {
  223. setState(CodecState::ERROR);
  224. } catch (...) {
  225. // 忽略setState可能的异常,因为我们已经在异常处理中
  226. }
  227. } catch (...) {
  228. AV_LOGGER_ERROR("关闭编解码器时发生未知异常");
  229. try {
  230. setState(CodecState::ERROR);
  231. } catch (...) {
  232. // 忽略setState可能的异常
  233. }
  234. }
  235. }
  236. ErrorCode AbstractCodec::flush() {
  237. AV_LOGGER_DEBUG("刷新编解码器缓冲区");
  238. if (state_ != CodecState::OPENED && state_ != CodecState::RUNNING) {
  239. AV_LOGGER_WARNING("编解码器未打开,无法刷新");
  240. return ErrorCode::INVALID_STATE;
  241. }
  242. if (!codecCtx_) {
  243. AV_LOGGER_ERROR("编解码上下文为空");
  244. return ErrorCode::INVALID_STATE;
  245. }
  246. // 刷新编解码器
  247. avcodec_flush_buffers(codecCtx_.get());
  248. AV_LOGGER_DEBUG("编解码器缓冲区已刷新");
  249. return ErrorCode::SUCCESS;
  250. }
  251. // 错误码转换工具实现
  252. ErrorCode AbstractCodec::convertFFmpegError(int ffmpegError) {
  253. if (ffmpegError >= 0) {
  254. return ErrorCode::SUCCESS;
  255. }
  256. // 根据FFmpeg错误码映射到项目中已定义的错误码
  257. switch (ffmpegError) {
  258. case AVERROR(EINVAL):
  259. return ErrorCode::INVALID_PARAMS;
  260. case AVERROR(ENOMEM):
  261. return ErrorCode::MEMORY_ALLOC_FAILED;
  262. case AVERROR(EAGAIN):
  263. return ErrorCode::PROCESSING_ERROR; // 使用PROCESSING_ERROR代替RESOURCE_BUSY
  264. case AVERROR_EOF:
  265. return ErrorCode::END_OF_STREAM;
  266. case AVERROR(ENOSYS):
  267. return ErrorCode::NOT_SUPPORTED;
  268. case AVERROR(EPIPE):
  269. return ErrorCode::OPERATION_FAILED; // 使用OPERATION_FAILED代替BROKEN_PIPE
  270. case AVERROR(EIO):
  271. return ErrorCode::FILE_OPERATION_FAILED; // 使用FILE_OPERATION_FAILED代替IO_ERROR
  272. case AVERROR(EACCES):
  273. return ErrorCode::FILE_OPEN_FAILED; // 使用FILE_OPEN_FAILED代替ACCESS_DENIED
  274. case AVERROR_DECODER_NOT_FOUND:
  275. return ErrorCode::CODEC_NOT_FOUND; // 使用CODEC_NOT_FOUND代替DECODER_NOT_FOUND
  276. case AVERROR_ENCODER_NOT_FOUND:
  277. return ErrorCode::CODEC_NOT_FOUND; // 使用CODEC_NOT_FOUND代替ENCODER_NOT_FOUND
  278. case AVERROR_DEMUXER_NOT_FOUND:
  279. return ErrorCode::NOT_FOUND; // 使用通用NOT_FOUND
  280. case AVERROR_MUXER_NOT_FOUND:
  281. return ErrorCode::NOT_FOUND; // 使用通用NOT_FOUND
  282. case AVERROR_PROTOCOL_NOT_FOUND:
  283. return ErrorCode::NOT_FOUND; // 使用通用NOT_FOUND
  284. case AVERROR_STREAM_NOT_FOUND:
  285. return ErrorCode::STREAM_NOT_FOUND;
  286. case AVERROR_BUG:
  287. return ErrorCode::UNKNOWN_ERROR; // 使用UNKNOWN_ERROR代替INTERNAL_ERROR
  288. case AVERROR_UNKNOWN:
  289. return ErrorCode::UNKNOWN_ERROR;
  290. case AVERROR_EXPERIMENTAL:
  291. return ErrorCode::NOT_SUPPORTED;
  292. case AVERROR_INPUT_CHANGED:
  293. return ErrorCode::FORMAT_NOT_SUPPORTED; // 使用FORMAT_NOT_SUPPORTED代替FORMAT_CHANGED
  294. case AVERROR_OUTPUT_CHANGED:
  295. return ErrorCode::FORMAT_NOT_SUPPORTED; // 使用FORMAT_NOT_SUPPORTED代替FORMAT_CHANGED
  296. case AVERROR_BSF_NOT_FOUND:
  297. return ErrorCode::NOT_FOUND; // 使用通用NOT_FOUND代替FILTER_NOT_FOUND
  298. case AVERROR_BUG2:
  299. return ErrorCode::UNKNOWN_ERROR; // 使用UNKNOWN_ERROR代替INTERNAL_ERROR
  300. case AVERROR_BUFFER_TOO_SMALL:
  301. return ErrorCode::MEMORY_ALLOC_FAILED; // 使用MEMORY_ALLOC_FAILED代替BUFFER_TOO_SMALL
  302. case AVERROR_EXTERNAL:
  303. return ErrorCode::OPERATION_FAILED; // 使用OPERATION_FAILED代替EXTERNAL_ERROR
  304. case AVERROR_INVALIDDATA:
  305. return ErrorCode::INVALID_PARAMS; // 使用INVALID_PARAMS代替INVALID_DATA
  306. case AVERROR_PATCHWELCOME:
  307. return ErrorCode::NOT_SUPPORTED; // 使用NOT_SUPPORTED代替NOT_IMPLEMENTED
  308. default:
  309. // 对于未映射的错误,记录原始错误码
  310. AV_LOGGER_WARNING("未映射的FFmpeg错误码,使用通用错误");
  311. return ErrorCode::UNKNOWN_ERROR;
  312. }
  313. }
  314. std::string AbstractCodec::getErrorDescription(ErrorCode error) {
  315. switch (error) {
  316. case ErrorCode::SUCCESS:
  317. return "成功";
  318. case ErrorCode::INVALID_PARAMS:
  319. return "无效参数";
  320. case ErrorCode::INVALID_PATH:
  321. return "无效路径";
  322. case ErrorCode::CODEC_NOT_FOUND:
  323. return "编解码器未找到";
  324. case ErrorCode::CODEC_OPEN_FAILED:
  325. return "编解码器打开失败";
  326. case ErrorCode::ENCODE_FAILED:
  327. return "编码失败";
  328. case ErrorCode::DECODE_FAILED:
  329. return "解码失败";
  330. case ErrorCode::MEMORY_ALLOC_FAILED:
  331. return "内存分配失败";
  332. case ErrorCode::FILE_OPEN_FAILED:
  333. return "文件打开失败";
  334. case ErrorCode::FILE_EXISTS:
  335. return "文件已存在";
  336. case ErrorCode::FILE_OPERATION_FAILED:
  337. return "文件操作失败";
  338. case ErrorCode::INVALID_STATE:
  339. return "无效状态";
  340. case ErrorCode::NOT_STARTED:
  341. return "未开始";
  342. case ErrorCode::NOT_PAUSED:
  343. return "未暂停";
  344. case ErrorCode::ALREADY_INITIALIZED:
  345. return "已经初始化";
  346. case ErrorCode::NOT_INITIALIZED:
  347. return "未初始化";
  348. case ErrorCode::ALREADY_STARTED:
  349. return "已经开始";
  350. case ErrorCode::ALREADY_PAUSED:
  351. return "已经暂停";
  352. case ErrorCode::CONVERSION_FAILED:
  353. return "转换失败";
  354. case ErrorCode::FORMAT_NOT_SUPPORTED:
  355. return "格式不支持";
  356. case ErrorCode::NOT_SUPPORTED:
  357. return "不支持的操作";
  358. case ErrorCode::HARDWARE_ERROR:
  359. return "硬件错误";
  360. case ErrorCode::DEVICE_NOT_FOUND:
  361. return "设备未找到";
  362. case ErrorCode::STREAM_NOT_FOUND:
  363. return "流未找到";
  364. case ErrorCode::STREAM_EXISTS:
  365. return "流已存在";
  366. case ErrorCode::STREAM_CREATE_FAILED:
  367. return "流创建失败";
  368. case ErrorCode::END_OF_STREAM:
  369. return "流结束";
  370. case ErrorCode::THREAD_ERROR:
  371. return "线程错误";
  372. case ErrorCode::QUEUE_FULL:
  373. return "队列满";
  374. case ErrorCode::SYNC_ERROR:
  375. return "同步错误";
  376. case ErrorCode::ALREADY_EXISTS:
  377. return "已存在";
  378. case ErrorCode::NOT_FOUND:
  379. return "未找到";
  380. case ErrorCode::TIMEOUT:
  381. return "超时";
  382. case ErrorCode::COPY_FAILED:
  383. return "拷贝失败";
  384. case ErrorCode::PROCESSING_ERROR:
  385. return "处理错误";
  386. case ErrorCode::INITIALIZATION_FAILED:
  387. return "初始化失败";
  388. case ErrorCode::OPERATION_FAILED:
  389. return "操作失败";
  390. case ErrorCode::UNKNOWN_ERROR:
  391. return "未知错误";
  392. default:
  393. return "未知错误码: " + std::to_string(static_cast<int>(error));
  394. }
  395. }
  396. } // namespace codec
  397. } // namespace av