| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456 |
- #include "codec_abstract_codec.h"
- #include "codec_video_encoder.h"
- #include "codec_audio_encoder.h"
- #include "codec_video_decoder.h"
- #include "codec_audio_decoder.h"
- #include "../base/media_common.h"
- #include "../base/logger.h"
- #include <chrono>
- extern "C" {
- #include <libavcodec/avcodec.h>
- #include <libavutil/opt.h>
- }
- namespace av {
- namespace codec {
- AbstractCodec::AbstractCodec(MediaType mediaType, CodecType codecType)
- : mediaType_(mediaType)
- , codecType_(codecType)
- , state_(CodecState::IDLE)
- , codec_(nullptr) {
- AV_LOGGER_DEBUGF("创建{}编解码器, 媒体类型: {}",
- codecType == CodecType::ENCODER ? "编码" : "解码",
- static_cast<int>(mediaType));
- }
- AbstractCodec::~AbstractCodec() {
- if (state_ != CodecState::CLOSED && state_ != CodecState::IDLE) {
- AV_LOGGER_WARNING("编解码器析构时状态不正确,强制关闭");
- close();
- }
- AV_LOGGER_DEBUG("编解码器已析构");
- }
- ErrorCode AbstractCodec::reset() {
- AV_LOGGER_DEBUG("重置编解码器");
-
- if (state_ == CodecState::IDLE || state_ == CodecState::CLOSED) {
- return ErrorCode::SUCCESS;
- }
-
- // 先刷新缓冲区
- ErrorCode result = flush();
- if (result != ErrorCode::SUCCESS) {
- AV_LOGGER_ERRORF("刷新编解码器失败: {}", static_cast<int>(result));
- return result;
- }
-
- // 重置统计信息
- resetStatistics();
-
- setState(CodecState::OPENED);
- return ErrorCode::SUCCESS;
- }
- void AbstractCodec::resetStatistics() {
- std::lock_guard<std::mutex> lock(statsMutex_);
- stats_ = Statistics{};
- AV_LOGGER_DEBUG("统计信息已重置");
- }
- void AbstractCodec::setState(CodecState state) {
- std::unique_lock<std::shared_mutex> lock(stateMutex_);
- if (state_ != state) {
- AV_LOGGER_DEBUGF("编解码器状态变更: {} -> {}",
- static_cast<int>(state_), static_cast<int>(state));
- state_ = state;
- }
- }
- void AbstractCodec::reportError(ErrorCode error, const std::string& message) {
- setState(CodecState::ERROR);
-
- // 更新错误统计
- {
- std::lock_guard<std::mutex> lock(statsMutex_);
- stats_.errorCount++;
- }
-
- std::string fullMessage = message.empty() ?
- ffmpeg_utils::errorToString(static_cast<int>(error)) : message;
-
- AV_LOGGER_ERRORF("编解码器错误: {} ({})", fullMessage, static_cast<int>(error));
-
- if (errorCallback_) {
- errorCallback_(error, fullMessage);
- }
- }
- void AbstractCodec::updateStats(bool success, double processTime, uint64_t bytes) {
- std::lock_guard<std::mutex> lock(statsMutex_);
- if (success) {
- stats_.processedFrames++;
- stats_.totalBytes += bytes;
-
- // 更新平均处理时间
- if (stats_.processedFrames == 1) {
- stats_.avgProcessTime = processTime;
- } else {
- stats_.avgProcessTime = (stats_.avgProcessTime * (stats_.processedFrames - 1) + processTime) / stats_.processedFrames;
- }
- } else {
- stats_.droppedFrames++;
- }
- }
- // CodecFactory 实现
- std::unique_ptr<AbstractEncoder> CodecFactory::createEncoder(MediaType mediaType, const std::string& codecName) {
- AV_LOGGER_INFOF("创建编码器: {} (媒体类型: {})", codecName, static_cast<int>(mediaType));
-
- // 查找编码器
- const AVCodec* codec = avcodec_find_encoder_by_name(codecName.c_str());
- if (!codec) {
- AV_LOGGER_ERRORF("未找到编码器: {}", codecName);
- return nullptr;
- }
-
- // 检查媒体类型匹配
- AVMediaType expectedType = (mediaType == MediaType::VIDEO) ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO;
- if (codec->type != expectedType) {
- AV_LOGGER_ERRORF("编码器媒体类型不匹配: {} (期望: {}, 实际: {})",
- codecName, expectedType, codec->type);
- return nullptr;
- }
-
- // 根据媒体类型创建具体的编码器实例
- try {
- if (mediaType == MediaType::VIDEO) {
- auto encoder = std::make_unique<VideoEncoder>();
- AV_LOGGER_INFOF("成功创建视频编码器: {}", codecName);
- return std::move(encoder);
- } else if (mediaType == MediaType::AUDIO) {
- auto encoder = std::make_unique<AudioEncoder>();
- AV_LOGGER_INFOF("成功创建音频编码器: {}", codecName);
- return std::move(encoder);
- } else {
- AV_LOGGER_ERRORF("不支持的媒体类型: {}", static_cast<int>(mediaType));
- return nullptr;
- }
- } catch (const std::exception& e) {
- AV_LOGGER_ERRORF("创建编码器实例失败: {}", e.what());
- return nullptr;
- }
- }
- std::unique_ptr<AbstractDecoder> CodecFactory::createDecoder(MediaType mediaType, const std::string& codecName) {
- AV_LOGGER_INFOF("创建解码器: {} (媒体类型: {})", codecName, static_cast<int>(mediaType));
-
- // 查找解码器
- const AVCodec* codec = avcodec_find_decoder_by_name(codecName.c_str());
- if (!codec) {
- AV_LOGGER_ERRORF("未找到解码器: {}", codecName);
- return nullptr;
- }
-
- // 检查媒体类型匹配
- AVMediaType expectedType = (mediaType == MediaType::VIDEO) ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO;
- if (codec->type != expectedType) {
- AV_LOGGER_ERRORF("解码器媒体类型不匹配: {} (期望: {}, 实际: {})",
- codecName, expectedType, codec->type);
- return nullptr;
- }
-
- // 根据媒体类型创建具体的解码器实例
- try {
- if (mediaType == MediaType::VIDEO) {
- auto decoder = std::make_unique<VideoDecoder>();
- AV_LOGGER_INFOF("成功创建视频解码器: {}", codecName);
- return std::move(decoder);
- } else if (mediaType == MediaType::AUDIO) {
- auto decoder = std::make_unique<AudioDecoder>();
- AV_LOGGER_INFOF("成功创建音频解码器: {}", codecName);
- return std::move(decoder);
- } else {
- AV_LOGGER_ERRORF("不支持的媒体类型: {}", static_cast<int>(mediaType));
- return nullptr;
- }
- } catch (const std::exception& e) {
- AV_LOGGER_ERRORF("创建解码器实例失败: {}", e.what());
- return nullptr;
- }
- }
- std::vector<std::string> CodecFactory::getSupportedEncoders(MediaType mediaType) {
- std::vector<std::string> encoders;
-
- AVMediaType avMediaType = (mediaType == MediaType::VIDEO) ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO;
-
- void* iter = nullptr;
- const AVCodec* codec = nullptr;
-
- while ((codec = av_codec_iterate(&iter)) != nullptr) {
- if (av_codec_is_encoder(codec) && codec->type == avMediaType) {
- encoders.emplace_back(codec->name);
- }
- }
-
- AV_LOGGER_INFOF("找到 {} 个{}编码器", encoders.size(),
- mediaType == MediaType::VIDEO ? "视频" : "音频");
-
- return encoders;
- }
- std::vector<std::string> CodecFactory::getSupportedDecoders(MediaType mediaType) {
- std::vector<std::string> decoders;
-
- AVMediaType avMediaType = (mediaType == MediaType::VIDEO) ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO;
-
- void* iter = nullptr;
- const AVCodec* codec = nullptr;
-
- while ((codec = av_codec_iterate(&iter)) != nullptr) {
- if (av_codec_is_decoder(codec) && codec->type == avMediaType) {
- decoders.emplace_back(codec->name);
- }
- }
-
- AV_LOGGER_INFOF("找到 {} 个{}解码器", decoders.size(),
- mediaType == MediaType::VIDEO ? "视频" : "音频");
-
- return decoders;
- }
- bool CodecFactory::isCodecSupported(const std::string& codecName, CodecType type, MediaType mediaType) {
- const AVCodec* codec = nullptr;
-
- if (type == CodecType::ENCODER) {
- codec = avcodec_find_encoder_by_name(codecName.c_str());
- } else {
- codec = avcodec_find_decoder_by_name(codecName.c_str());
- }
-
- if (!codec) {
- return false;
- }
-
- AVMediaType expectedType = (mediaType == MediaType::VIDEO) ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO;
- return codec->type == expectedType;
- }
- void AbstractCodec::close() {
- AV_LOGGER_DEBUG("关闭编解码器");
-
- // 使用RAII确保异常安全
- try {
- std::unique_lock<std::shared_mutex> stateLock(stateMutex_);
- if (state_ == CodecState::CLOSED || state_ == CodecState::IDLE) {
- return;
- }
-
- // 设置状态为关闭中,防止其他操作
- state_ = CodecState::CLOSED;
- stateLock.unlock();
-
- // 获取资源锁进行清理
- std::lock_guard<std::mutex> resourceLock(resourceMutex_);
-
- // 释放编解码上下文
- if (codecCtx_) {
- AVCodecContext* ctx = codecCtx_.release();
- avcodec_free_context(&ctx);
- }
-
- codec_ = nullptr;
-
- AV_LOGGER_DEBUG("编解码器已关闭");
-
- } catch (const std::exception& e) {
- AV_LOGGER_ERRORF("关闭编解码器时发生异常: {}", e.what());
- // 确保状态被设置为错误
- try {
- setState(CodecState::ERROR);
- } catch (...) {
- // 忽略setState可能的异常,因为我们已经在异常处理中
- }
- } catch (...) {
- AV_LOGGER_ERROR("关闭编解码器时发生未知异常");
- try {
- setState(CodecState::ERROR);
- } catch (...) {
- // 忽略setState可能的异常
- }
- }
- }
- ErrorCode AbstractCodec::flush() {
- AV_LOGGER_DEBUG("刷新编解码器缓冲区");
-
- if (state_ != CodecState::OPENED && state_ != CodecState::RUNNING) {
- AV_LOGGER_WARNING("编解码器未打开,无法刷新");
- return ErrorCode::INVALID_STATE;
- }
-
- if (!codecCtx_) {
- AV_LOGGER_ERROR("编解码上下文为空");
- return ErrorCode::INVALID_STATE;
- }
-
- // 刷新编解码器
- avcodec_flush_buffers(codecCtx_.get());
-
- AV_LOGGER_DEBUG("编解码器缓冲区已刷新");
- return ErrorCode::SUCCESS;
- }
- // 错误码转换工具实现
- ErrorCode AbstractCodec::convertFFmpegError(int ffmpegError) {
- if (ffmpegError >= 0) {
- return ErrorCode::SUCCESS;
- }
-
- // 根据FFmpeg错误码映射到项目中已定义的错误码
- switch (ffmpegError) {
- case AVERROR(EINVAL):
- return ErrorCode::INVALID_PARAMS;
- case AVERROR(ENOMEM):
- return ErrorCode::MEMORY_ALLOC_FAILED;
- case AVERROR(EAGAIN):
- return ErrorCode::PROCESSING_ERROR; // 使用PROCESSING_ERROR代替RESOURCE_BUSY
- case AVERROR_EOF:
- return ErrorCode::END_OF_STREAM;
- case AVERROR(ENOSYS):
- return ErrorCode::NOT_SUPPORTED;
- case AVERROR(EPIPE):
- return ErrorCode::OPERATION_FAILED; // 使用OPERATION_FAILED代替BROKEN_PIPE
- case AVERROR(EIO):
- return ErrorCode::FILE_OPERATION_FAILED; // 使用FILE_OPERATION_FAILED代替IO_ERROR
- case AVERROR(EACCES):
- return ErrorCode::FILE_OPEN_FAILED; // 使用FILE_OPEN_FAILED代替ACCESS_DENIED
- case AVERROR_DECODER_NOT_FOUND:
- return ErrorCode::CODEC_NOT_FOUND; // 使用CODEC_NOT_FOUND代替DECODER_NOT_FOUND
- case AVERROR_ENCODER_NOT_FOUND:
- return ErrorCode::CODEC_NOT_FOUND; // 使用CODEC_NOT_FOUND代替ENCODER_NOT_FOUND
- case AVERROR_DEMUXER_NOT_FOUND:
- return ErrorCode::NOT_FOUND; // 使用通用NOT_FOUND
- case AVERROR_MUXER_NOT_FOUND:
- return ErrorCode::NOT_FOUND; // 使用通用NOT_FOUND
- case AVERROR_PROTOCOL_NOT_FOUND:
- return ErrorCode::NOT_FOUND; // 使用通用NOT_FOUND
- case AVERROR_STREAM_NOT_FOUND:
- return ErrorCode::STREAM_NOT_FOUND;
- case AVERROR_BUG:
- return ErrorCode::UNKNOWN_ERROR; // 使用UNKNOWN_ERROR代替INTERNAL_ERROR
- case AVERROR_UNKNOWN:
- return ErrorCode::UNKNOWN_ERROR;
- case AVERROR_EXPERIMENTAL:
- return ErrorCode::NOT_SUPPORTED;
- case AVERROR_INPUT_CHANGED:
- return ErrorCode::FORMAT_NOT_SUPPORTED; // 使用FORMAT_NOT_SUPPORTED代替FORMAT_CHANGED
- case AVERROR_OUTPUT_CHANGED:
- return ErrorCode::FORMAT_NOT_SUPPORTED; // 使用FORMAT_NOT_SUPPORTED代替FORMAT_CHANGED
- case AVERROR_BSF_NOT_FOUND:
- return ErrorCode::NOT_FOUND; // 使用通用NOT_FOUND代替FILTER_NOT_FOUND
- case AVERROR_BUG2:
- return ErrorCode::UNKNOWN_ERROR; // 使用UNKNOWN_ERROR代替INTERNAL_ERROR
- case AVERROR_BUFFER_TOO_SMALL:
- return ErrorCode::MEMORY_ALLOC_FAILED; // 使用MEMORY_ALLOC_FAILED代替BUFFER_TOO_SMALL
- case AVERROR_EXTERNAL:
- return ErrorCode::OPERATION_FAILED; // 使用OPERATION_FAILED代替EXTERNAL_ERROR
- case AVERROR_INVALIDDATA:
- return ErrorCode::INVALID_PARAMS; // 使用INVALID_PARAMS代替INVALID_DATA
- case AVERROR_PATCHWELCOME:
- return ErrorCode::NOT_SUPPORTED; // 使用NOT_SUPPORTED代替NOT_IMPLEMENTED
- default:
- // 对于未映射的错误,记录原始错误码
- AV_LOGGER_WARNING("未映射的FFmpeg错误码,使用通用错误");
- return ErrorCode::UNKNOWN_ERROR;
- }
- }
- std::string AbstractCodec::getErrorDescription(ErrorCode error) {
- switch (error) {
- case ErrorCode::SUCCESS:
- return "成功";
- case ErrorCode::INVALID_PARAMS:
- return "无效参数";
- case ErrorCode::INVALID_PATH:
- return "无效路径";
- case ErrorCode::CODEC_NOT_FOUND:
- return "编解码器未找到";
- case ErrorCode::CODEC_OPEN_FAILED:
- return "编解码器打开失败";
- case ErrorCode::ENCODE_FAILED:
- return "编码失败";
- case ErrorCode::DECODE_FAILED:
- return "解码失败";
- case ErrorCode::MEMORY_ALLOC_FAILED:
- return "内存分配失败";
- case ErrorCode::FILE_OPEN_FAILED:
- return "文件打开失败";
- case ErrorCode::FILE_EXISTS:
- return "文件已存在";
- case ErrorCode::FILE_OPERATION_FAILED:
- return "文件操作失败";
- case ErrorCode::INVALID_STATE:
- return "无效状态";
- case ErrorCode::NOT_STARTED:
- return "未开始";
- case ErrorCode::NOT_PAUSED:
- return "未暂停";
- case ErrorCode::ALREADY_INITIALIZED:
- return "已经初始化";
- case ErrorCode::NOT_INITIALIZED:
- return "未初始化";
- case ErrorCode::ALREADY_STARTED:
- return "已经开始";
- case ErrorCode::ALREADY_PAUSED:
- return "已经暂停";
- case ErrorCode::CONVERSION_FAILED:
- return "转换失败";
- case ErrorCode::FORMAT_NOT_SUPPORTED:
- return "格式不支持";
- case ErrorCode::NOT_SUPPORTED:
- return "不支持的操作";
- case ErrorCode::HARDWARE_ERROR:
- return "硬件错误";
- case ErrorCode::DEVICE_NOT_FOUND:
- return "设备未找到";
- case ErrorCode::STREAM_NOT_FOUND:
- return "流未找到";
- case ErrorCode::STREAM_EXISTS:
- return "流已存在";
- case ErrorCode::STREAM_CREATE_FAILED:
- return "流创建失败";
- case ErrorCode::END_OF_STREAM:
- return "流结束";
- case ErrorCode::THREAD_ERROR:
- return "线程错误";
- case ErrorCode::QUEUE_FULL:
- return "队列满";
- case ErrorCode::SYNC_ERROR:
- return "同步错误";
- case ErrorCode::ALREADY_EXISTS:
- return "已存在";
- case ErrorCode::NOT_FOUND:
- return "未找到";
- case ErrorCode::TIMEOUT:
- return "超时";
- case ErrorCode::COPY_FAILED:
- return "拷贝失败";
- case ErrorCode::PROCESSING_ERROR:
- return "处理错误";
- case ErrorCode::INITIALIZATION_FAILED:
- return "初始化失败";
- case ErrorCode::OPERATION_FAILED:
- return "操作失败";
- case ErrorCode::UNKNOWN_ERROR:
- return "未知错误";
- default:
- return "未知错误码: " + std::to_string(static_cast<int>(error));
- }
- }
- } // namespace codec
- } // namespace av
|