#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 extern "C" { #include #include } 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(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(result)); return result; } // 重置统计信息 resetStatistics(); setState(CodecState::OPENED); return ErrorCode::SUCCESS; } void AbstractCodec::resetStatistics() { std::lock_guard lock(statsMutex_); stats_ = Statistics{}; AV_LOGGER_DEBUG("统计信息已重置"); } void AbstractCodec::setState(CodecState state) { std::unique_lock lock(stateMutex_); if (state_ != state) { AV_LOGGER_DEBUGF("编解码器状态变更: {} -> {}", static_cast(state_), static_cast(state)); state_ = state; } } void AbstractCodec::reportError(ErrorCode error, const std::string& message) { setState(CodecState::ERROR); // 更新错误统计 { std::lock_guard lock(statsMutex_); stats_.errorCount++; } std::string fullMessage = message.empty() ? ffmpeg_utils::errorToString(static_cast(error)) : message; AV_LOGGER_ERRORF("编解码器错误: {} ({})", fullMessage, static_cast(error)); if (errorCallback_) { errorCallback_(error, fullMessage); } } void AbstractCodec::updateStats(bool success, double processTime, uint64_t bytes) { std::lock_guard 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 CodecFactory::createEncoder(MediaType mediaType, const std::string& codecName) { AV_LOGGER_INFOF("创建编码器: {} (媒体类型: {})", codecName, static_cast(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(); AV_LOGGER_INFOF("成功创建视频编码器: {}", codecName); return std::move(encoder); } else if (mediaType == MediaType::AUDIO) { auto encoder = std::make_unique(); AV_LOGGER_INFOF("成功创建音频编码器: {}", codecName); return std::move(encoder); } else { AV_LOGGER_ERRORF("不支持的媒体类型: {}", static_cast(mediaType)); return nullptr; } } catch (const std::exception& e) { AV_LOGGER_ERRORF("创建编码器实例失败: {}", e.what()); return nullptr; } } std::unique_ptr CodecFactory::createDecoder(MediaType mediaType, const std::string& codecName) { AV_LOGGER_INFOF("创建解码器: {} (媒体类型: {})", codecName, static_cast(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(); AV_LOGGER_INFOF("成功创建视频解码器: {}", codecName); return std::move(decoder); } else if (mediaType == MediaType::AUDIO) { auto decoder = std::make_unique(); AV_LOGGER_INFOF("成功创建音频解码器: {}", codecName); return std::move(decoder); } else { AV_LOGGER_ERRORF("不支持的媒体类型: {}", static_cast(mediaType)); return nullptr; } } catch (const std::exception& e) { AV_LOGGER_ERRORF("创建解码器实例失败: {}", e.what()); return nullptr; } } std::vector CodecFactory::getSupportedEncoders(MediaType mediaType) { std::vector 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 CodecFactory::getSupportedDecoders(MediaType mediaType) { std::vector 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 stateLock(stateMutex_); if (state_ == CodecState::CLOSED || state_ == CodecState::IDLE) { return; } // 设置状态为关闭中,防止其他操作 state_ = CodecState::CLOSED; stateLock.unlock(); // 获取资源锁进行清理 std::lock_guard 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(error)); } } } // namespace codec } // namespace av