#include "codec_abstract_codec.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() { stats_ = Statistics{}; AV_LOGGER_DEBUG("统计信息已重置"); } void AbstractCodec::setState(CodecState state) { 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); 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) { 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; } // 这里需要根据具体的编码器类型创建实例 // 暂时返回nullptr,具体实现在子类中 AV_LOGGER_WARNING("CodecFactory::createEncoder 需要在具体实现中完成"); 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; } // 这里需要根据具体的解码器类型创建实例 // 暂时返回nullptr,具体实现在子类中 AV_LOGGER_WARNING("CodecFactory::createDecoder 需要在具体实现中完成"); 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("关闭编解码器"); if (state_ == CodecState::CLOSED || state_ == CodecState::IDLE) { return; } // 释放编解码上下文 if (codecCtx_) { AVCodecContext* ctx = codecCtx_.release(); avcodec_free_context(&ctx); } codec_ = nullptr; setState(CodecState::CLOSED); AV_LOGGER_DEBUG("编解码器已关闭"); } 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; } } // namespace codec } // namespace av