| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- #include "codec_abstract_codec.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() {
- stats_ = Statistics{};
- AV_LOGGER_DEBUG("统计信息已重置");
- }
- void AbstractCodec::setState(CodecState state) {
- 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);
- 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) {
- 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;
- }
-
- // 这里需要根据具体的编码器类型创建实例
- // 暂时返回nullptr,具体实现在子类中
- AV_LOGGER_WARNING("CodecFactory::createEncoder 需要在具体实现中完成");
- 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;
- }
-
- // 这里需要根据具体的解码器类型创建实例
- // 暂时返回nullptr,具体实现在子类中
- AV_LOGGER_WARNING("CodecFactory::createDecoder 需要在具体实现中完成");
- 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("关闭编解码器");
-
- 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
|