#include "codec_video_encoder.h"
#include "../base/logger.h"
#include <algorithm>
#include <chrono>

extern "C" {
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>
#include <libavutil/pixdesc.h>
}

namespace av {
namespace codec {

// 静态成员初始化
std::vector<std::string> VideoEncoder::supportedEncoders_;
std::once_flag VideoEncoder::encodersInitFlag_;

// PixelFormatConverter 实现
PixelFormatConverter::PixelFormatConverter(AVPixelFormat srcFormat, AVPixelFormat dstFormat)
    : swsCtx_(nullptr)
    , srcFormat_(srcFormat)
    , dstFormat_(dstFormat)
    , width_(0)
    , height_(0) {
}

PixelFormatConverter::~PixelFormatConverter() {
    if (swsCtx_) {
        sws_freeContext(swsCtx_);
    }
}

bool PixelFormatConverter::setSize(int width, int height) {
    if (width_ == width && height_ == height && swsCtx_) {
        return true;
    }
    
    width_ = width;
    height_ = height;
    
    if (swsCtx_) {
        sws_freeContext(swsCtx_);
    }
    
    swsCtx_ = sws_getContext(
        width, height, srcFormat_,
        width, height, dstFormat_,
        SWS_BILINEAR, nullptr, nullptr, nullptr
    );
    
    if (!swsCtx_) {
        AV_LOGGER_ERRORF("创建像素格式转换器失败: {}x{} format:{} -> {}",
                         width, height,
                         static_cast<int>(srcFormat_),
                         static_cast<int>(dstFormat_));
        return false;
    }
    
    // 创建目标帧
    dstFrame_ = makeAVFrame();
    if (!dstFrame_) {
        AV_LOGGER_ERROR("分配目标帧失败");
        return false;
    }
    
    dstFrame_->format = dstFormat_;
    dstFrame_->width = width;
    dstFrame_->height = height;
    
    if (av_frame_get_buffer(dstFrame_.get(), 32) < 0) {
        AV_LOGGER_ERROR("分配帧缓冲区失败");
        return false;
    }
    
    return true;
}

AVFramePtr PixelFormatConverter::convert(const AVFramePtr& srcFrame) {
    if (!srcFrame || !swsCtx_) {
        return nullptr;
    }
    
    if (!setSize(srcFrame->width, srcFrame->height)) {
        return nullptr;
    }
    
    // 复制时间戳等信息
    av_frame_copy_props(dstFrame_.get(), srcFrame.get());
    
    // 执行格式转换
    int ret = sws_scale(
        swsCtx_,
        srcFrame->data, srcFrame->linesize,
        0, srcFrame->height,
        dstFrame_->data, dstFrame_->linesize
    );
    
    if (ret < 0) {
        AV_LOGGER_ERRORF("像素格式转换失败: {}", ffmpeg_utils::errorToString(ret));
        return nullptr;
    }
    
    // 创建一个新的帧来返回，完全独立的副本
    AVFramePtr resultFrame = makeAVFrame();
    if (!resultFrame) {
        return nullptr;
    }
    
    // 复制帧格式信息
    resultFrame->format = dstFrame_->format;
    resultFrame->width = dstFrame_->width;
    resultFrame->height = dstFrame_->height;
    
    // 分配新的缓冲区
    if (av_frame_get_buffer(resultFrame.get(), 32) < 0) {
        return nullptr;
    }
    
    // 复制帧数据（避免引用计数问题）
    if (av_frame_copy(resultFrame.get(), dstFrame_.get()) < 0) {
        return nullptr;
    }
    
    // 复制帧属性
    if (av_frame_copy_props(resultFrame.get(), dstFrame_.get()) < 0) {
        return nullptr;
    }
    
    return resultFrame;
}

// VideoEncoder 实现
VideoEncoder::VideoEncoder()
    : AbstractEncoder(MediaType::VIDEO)
    , isHardwareEncoder_(false)
    , hwDeviceCtx_(nullptr) {
    AV_LOGGER_DEBUG("创建视频编码器");
}

VideoEncoder::~VideoEncoder() {
    close();
    AV_LOGGER_DEBUG("视频编码器已销毁");
}

ErrorCode VideoEncoder::open(const CodecParams& params) {
    std::lock_guard<std::mutex> lock(encodeMutex_);
    
    if (state_ != CodecState::IDLE && state_ != CodecState::CLOSED) {
        AV_LOGGER_WARNING("编码器已打开，先关闭再重新打开");
        close();
    }
    
    if (!validateParams(params)) {
        return ErrorCode::INVALID_PARAMS;
    }
    
    videoParams_ = static_cast<const VideoEncoderParams&>(params);
    params_ = params;
    
    ErrorCode result = initEncoder();
    if (result != ErrorCode::SUCCESS) {
        close();
        return result;
    }
    
    setState(CodecState::OPENED);
    AV_LOGGER_INFOF("视频编码器已打开: {} ({}x{} @ {}fps)", 
                 videoParams_.codecName, videoParams_.width, 
                 videoParams_.height, videoParams_.fps);
    
    return ErrorCode::SUCCESS;
}

void VideoEncoder::close() {
    std::lock_guard<std::mutex> lock(encodeMutex_);
    
    if (state_ == CodecState::CLOSED || state_ == CodecState::IDLE) {
        return;
    }
    
    // 清理硬件资源
    if (hwDeviceCtx_) {
        av_buffer_unref(&hwDeviceCtx_);
        hwDeviceCtx_ = nullptr;
    }
    
    hwFrame_.reset();
    convertedFrame_.reset();
    converter_.reset();
    
    // 清理编解码上下文
    codecCtx_.reset();
    codec_ = nullptr;
    
    setState(CodecState::CLOSED);
    AV_LOGGER_DEBUG("视频编码器已关闭");
}

ErrorCode VideoEncoder::flush() {
    std::lock_guard<std::mutex> lock(encodeMutex_);
    
    if (state_ != CodecState::OPENED && state_ != CodecState::RUNNING) {
        return ErrorCode::INVALID_STATE;
    }
    
    setState(CodecState::FLUSHING);
    
    // 发送空帧来刷新编码器
    int ret = avcodec_send_frame(codecCtx_.get(), nullptr);
    if (ret < 0 && ret != AVERROR_EOF) {
        AV_LOGGER_ERRORF("刷新编码器失败: {}", ffmpeg_utils::errorToString(ret));
        reportError(static_cast<ErrorCode>(ret));
        return static_cast<ErrorCode>(ret);
    }
    
    setState(CodecState::OPENED);
    return ErrorCode::SUCCESS;
}

ErrorCode VideoEncoder::encode(const AVFramePtr& frame, std::vector<AVPacketPtr>& packets) {
    std::lock_guard<std::mutex> lock(encodeMutex_);
    
    if (state_ != CodecState::OPENED && state_ != CodecState::RUNNING) {
        return ErrorCode::INVALID_STATE;
    }
    
    setState(CodecState::RUNNING);
    
    auto startTime = std::chrono::high_resolution_clock::now();
    
    ErrorCode result = encodeFrame(frame, packets);
    
    auto endTime = std::chrono::high_resolution_clock::now();
    double processTime = std::chrono::duration<double, std::milli>(endTime - startTime).count();
    
    updateStats(result == ErrorCode::SUCCESS, processTime, 
                frame ? frame->width * frame->height * 3 / 2 : 0);
    
    if (frameCallback_ && frame) {
        frameCallback_(frame);
    }
    
    for (const auto& packet : packets) {
        if (packetCallback_) {
            packetCallback_(packet);
        }
    }
    
    return result;
}

ErrorCode VideoEncoder::finishEncode(std::vector<AVPacketPtr>& packets) {
    return flush();
}

bool VideoEncoder::validateParams(const CodecParams& params) {
    if (params.type != MediaType::VIDEO) {
        AV_LOGGER_ERROR("参数媒体类型不是视频");
        return false;
    }
    
    const auto& videoParams = static_cast<const VideoEncoderParams&>(params);
    
    if (videoParams.width <= 0 || videoParams.height <= 0) {
        AV_LOGGER_ERROR("视频尺寸无效");
        return false;
    }
    
    if (videoParams.fps <= 0) {
        AV_LOGGER_ERROR("帧率无效");
        return false;
    }
    
    if (videoParams.bitRate <= 0) {
        AV_LOGGER_ERROR("比特率无效");
        return false;
    }
    
    if (videoParams.codecName.empty()) {
        AV_LOGGER_ERROR("编码器名称为空");
        return false;
    }
    
    return true;
}

ErrorCode VideoEncoder::initEncoder() {
    // 查找编码器
    codec_ = avcodec_find_encoder_by_name(videoParams_.codecName.c_str());
    if (!codec_) {
        AV_LOGGER_ERRORF("未找到编码器: {}", videoParams_.codecName);
        return ErrorCode::CODEC_NOT_FOUND;
    }
    
    if (codec_->type != AVMEDIA_TYPE_VIDEO) {
        AV_LOGGER_ERROR("编码器类型不是视频");
        return ErrorCode::INVALID_PARAMS;
    }
    
    // 创建编码上下文
    codecCtx_ = makeAVCodecContext(codec_);
    if (!codecCtx_) {
        AV_LOGGER_ERROR("分配编码上下文失败");
        return ErrorCode::MEMORY_ALLOC_FAILED;
    }
    
    // 设置硬件加速
    if (videoParams_.hardwareAccel && isHardwareEncoder(videoParams_.codecName)) {
        ErrorCode result = setupHardwareAcceleration();
        if (result != ErrorCode::SUCCESS) {
            AV_LOGGER_WARNING("硬件加速设置失败，回退到软件编码");
            isHardwareEncoder_ = false;
            
            // 清理硬件资源
            if (hwDeviceCtx_) {
                av_buffer_unref(&hwDeviceCtx_);
                hwDeviceCtx_ = nullptr;
            }
        }
    }
    
    // 设置编码器参数（在硬件加速设置之后）
    ErrorCode result = setupEncoderParams();
    if (result != ErrorCode::SUCCESS) {
        return result;
    }
    
    // 打开编码器前的详细日志
    AV_LOGGER_INFOF("准备打开编码器: {}", videoParams_.codecName);
    AV_LOGGER_INFOF("编码器参数: {}x{}, 比特率: {}, 帧率: {}, 像素格式: {}", 
                   codecCtx_->width, codecCtx_->height, codecCtx_->bit_rate, 
                   codecCtx_->framerate.num, static_cast<int>(codecCtx_->pix_fmt));
    
    if (isHardwareEncoder_) {
        AV_LOGGER_INFOF("硬件编码器状态: 设备上下文={}, 帧上下文={}", 
                       hwDeviceCtx_ ? "已创建" : "未创建",
                       codecCtx_->hw_frames_ctx ? "已设置" : "未设置");
    }
    
    // 验证编码器参数
    if (codecCtx_->width <= 0 || codecCtx_->height <= 0) {
        AV_LOGGER_ERROR("无效的视频尺寸参数");
        return ErrorCode::INVALID_PARAMS;
    }
    
    if (codecCtx_->bit_rate <= 0) {
        AV_LOGGER_ERROR("无效的比特率参数");
        return ErrorCode::INVALID_PARAMS;
    }
    
    // 打开编码器
    int ret = avcodec_open2(codecCtx_.get(), codec_, nullptr);
    if (ret < 0) {
        AV_LOGGER_ERRORF("打开编码器失败: {} (错误码: {})", ffmpeg_utils::errorToString(ret), ret);
        
        // 详细错误分析
        if (ret == AVERROR(EINVAL)) {
            AV_LOGGER_ERROR("编码器参数无效 - 可能的原因:");
            AV_LOGGER_ERROR("  1. 不支持的像素格式或分辨率组合");
            AV_LOGGER_ERROR("  2. 硬件编码器参数配置错误");
            AV_LOGGER_ERROR("  3. 硬件设备上下文与编码器不匹配");
        } else if (ret == AVERROR(EBUSY)) {
            AV_LOGGER_ERROR("硬件设备忙碌 - 可能被其他进程占用");
        } else if (ret == AVERROR(ENOMEM)) {
            AV_LOGGER_ERROR("内存不足 - 无法分配编码器资源");
        }
        
        return static_cast<ErrorCode>(ret);
    }
    
    AV_LOGGER_INFOF("编码器打开成功: {}", videoParams_.codecName);
    
    return ErrorCode::SUCCESS;
}

ErrorCode VideoEncoder::setupEncoderParams() {
    codecCtx_->bit_rate = videoParams_.bitRate;
    codecCtx_->width = videoParams_.width;
    codecCtx_->height = videoParams_.height;
    codecCtx_->time_base = {1, videoParams_.fps};
    codecCtx_->framerate = {videoParams_.fps, 1};
    codecCtx_->gop_size = videoParams_.gopSize;
    codecCtx_->max_b_frames = videoParams_.maxBFrames;
    
    // 设置像素格式
    if (isHardwareEncoder_) {
        AVPixelFormat hwPixFmt = getHardwarePixelFormat();
        if (hwPixFmt == AV_PIX_FMT_NONE) {
            AV_LOGGER_ERRORF("获取硬件像素格式失败，编码器: {}", videoParams_.codecName);
            return ErrorCode::NOT_SUPPORTED;
        }
        codecCtx_->pix_fmt = hwPixFmt;
        AV_LOGGER_INFOF("设置硬件编码器像素格式: {} ({})", 
                       static_cast<int>(hwPixFmt), av_get_pix_fmt_name(hwPixFmt));
    } else {
        codecCtx_->pix_fmt = videoParams_.pixelFormat;
        AV_LOGGER_INFOF("设置软件编码器像素格式: {} ({})", 
                       static_cast<int>(videoParams_.pixelFormat), 
                       av_get_pix_fmt_name(videoParams_.pixelFormat));
    }
    
    // 针对不同编码器设置特定参数
    if (videoParams_.codecName == "h264_nvenc") {
        AV_LOGGER_INFO("设置NVENC编码器参数...");
        
        // NVENC 特定参数 - 使用更保守的设置
        int ret;
        ret = av_opt_set(codecCtx_->priv_data, "preset", "medium", 0);
        AV_LOGGER_INFOF("Set preset=medium: {}", ret == 0 ? "success" : "failed");
        
        ret = av_opt_set(codecCtx_->priv_data, "profile", "main", 0);
        AV_LOGGER_INFOF("Set profile=main: {}", ret == 0 ? "success" : "failed");
        
        ret = av_opt_set(codecCtx_->priv_data, "rc", "vbr", 0);
        AV_LOGGER_INFOF("Set rc=vbr: {}", ret == 0 ? "success" : "failed");
        
        ret = av_opt_set_int(codecCtx_->priv_data, "surfaces", 16, 0);
        AV_LOGGER_INFOF("Set surfaces=16: {}", ret == 0 ? "success" : "failed");
        
        ret = av_opt_set_int(codecCtx_->priv_data, "delay", 0, 0);
        AV_LOGGER_INFOF("Set delay=0: {}", ret == 0 ? "success" : "failed");
        
        if (videoParams_.lowLatency) {
            AV_LOGGER_INFO("启用低延迟模式");
            ret = av_opt_set(codecCtx_->priv_data, "preset", "fast", 0);
            AV_LOGGER_INFOF("Set preset=fast: {}", ret == 0 ? "success" : "failed");
            
            ret = av_opt_set(codecCtx_->priv_data, "tune", "ll", 0);
            AV_LOGGER_INFOF("Set tune=ll: {}", ret == 0 ? "success" : "failed");
        }
    } else if (videoParams_.codecName == "h264_qsv") {
        // QSV 特定参数
        av_opt_set(codecCtx_->priv_data, "preset", "fast", 0);
        av_opt_set(codecCtx_->priv_data, "profile", "high", 0);
        
        if (videoParams_.lowLatency) {
            av_opt_set(codecCtx_->priv_data, "preset", "veryfast", 0);
        }
    } else if (videoParams_.codecName == "h264_amf") {
        // AMF 特定参数
        av_opt_set(codecCtx_->priv_data, "quality", "speed", 0);
        av_opt_set(codecCtx_->priv_data, "profile", "high", 0);
        
        if (videoParams_.lowLatency) {
            av_opt_set(codecCtx_->priv_data, "usage", "lowlatency", 0);
        }
    } else {
        // 软件编码器参数
        if (!videoParams_.preset.empty()) {
            av_opt_set(codecCtx_->priv_data, "preset", videoParams_.preset.c_str(), 0);
        }
        
        if (!videoParams_.tune.empty()) {
            av_opt_set(codecCtx_->priv_data, "tune", videoParams_.tune.c_str(), 0);
        }
        
        if (videoParams_.lowLatency) {
            av_opt_set(codecCtx_->priv_data, "preset", "ultrafast", 0);
            av_opt_set(codecCtx_->priv_data, "tune", "zerolatency", 0);
        }
    }
    
    return ErrorCode::SUCCESS;
}

ErrorCode VideoEncoder::setupHardwareAcceleration() {
    isHardwareEncoder_ = true;
    
    AVHWDeviceType hwType = getHardwareDeviceType();
    if (hwType == AV_HWDEVICE_TYPE_NONE) {
        AV_LOGGER_ERRORF("不支持的硬件编码器: {}", videoParams_.codecName);
        return ErrorCode::NOT_SUPPORTED;
    }
    
    AV_LOGGER_INFOF("开始设置硬件加速: 编码器={}, 设备类型={}", 
                   videoParams_.codecName, static_cast<int>(hwType));
    
    // 对于CUDA设备，检查可用性
    if (hwType == AV_HWDEVICE_TYPE_CUDA) {
        AV_LOGGER_INFO("检查CUDA设备可用性...");
        // 这里可以添加CUDA设备检查逻辑
    }
    
    // 创建硬件设备上下文
    AV_LOGGER_INFO("创建硬件设备上下文...");
    int ret = av_hwdevice_ctx_create(&hwDeviceCtx_, hwType, nullptr, nullptr, 0);
    if (ret < 0) {
        AV_LOGGER_ERRORF("创建硬件设备上下文失败: {} (编码器: {}, 错误码: {})", 
                        ffmpeg_utils::errorToString(ret), videoParams_.codecName, ret);
        
        // 特定错误处理
        if (ret == AVERROR(ENOENT)) {
            AV_LOGGER_ERROR("硬件设备不存在或驱动未安装");
            if (hwType == AV_HWDEVICE_TYPE_CUDA) {
                AV_LOGGER_ERROR("请检查NVIDIA驱动和CUDA是否正确安装");
            }
        } else if (ret == AVERROR(EBUSY)) {
            AV_LOGGER_ERROR("硬件设备正在被其他进程使用");
        } else if (ret == AVERROR(EINVAL)) {
            AV_LOGGER_ERROR("硬件设备参数无效");
        } else if (ret == AVERROR(ENOMEM)) {
            AV_LOGGER_ERROR("内存不足，无法创建硬件设备上下文");
        }
        
        return static_cast<ErrorCode>(ret);
    }
    
    AV_LOGGER_INFOF("硬件设备上下文创建成功: {}", videoParams_.codecName);
    
    // 设置硬件帧上下文
    return setupHardwareFrameContext();
}

ErrorCode VideoEncoder::setupHardwareFrameContext() {
    AVBufferRef* hwFramesRef = av_hwframe_ctx_alloc(hwDeviceCtx_);
    if (!hwFramesRef) {
        AV_LOGGER_ERROR("分配硬件帧上下文失败");
        return ErrorCode::MEMORY_ALLOC_FAILED;
    }
    
    AVHWFramesContext* framesCtx = reinterpret_cast<AVHWFramesContext*>(hwFramesRef->data);
    framesCtx->format = getHardwarePixelFormat();
    
    // 设置软件格式 - 统一使用NV12格式，这是大多数硬件编码器的首选格式
    framesCtx->sw_format = AV_PIX_FMT_NV12;
    
    framesCtx->width = videoParams_.width;
    framesCtx->height = videoParams_.height;
    framesCtx->initial_pool_size = 8;  // 增加池大小以提高稳定性
    
    AV_LOGGER_INFOF("设置硬件帧上下文: {}x{}, 硬件格式: {}, 软件格式: {}, 池大小: {}", 
                   framesCtx->width, framesCtx->height, 
                   static_cast<int>(framesCtx->format), 
                   static_cast<int>(framesCtx->sw_format),
                   framesCtx->initial_pool_size);
    
    int ret = av_hwframe_ctx_init(hwFramesRef);
    if (ret < 0) {
        AV_LOGGER_ERRORF("初始化硬件帧上下文失败: {}", ffmpeg_utils::errorToString(ret));
        av_buffer_unref(&hwFramesRef);
        return static_cast<ErrorCode>(ret);
    }
    
    codecCtx_->hw_frames_ctx = av_buffer_ref(hwFramesRef);
    av_buffer_unref(&hwFramesRef);
    
    AV_LOGGER_INFO("硬件帧上下文初始化成功");
    return ErrorCode::SUCCESS;
}

AVFramePtr VideoEncoder::convertFrame(const AVFramePtr& frame) {
    if (!frame) {
        AV_LOGGER_ERROR("输入帧为空");
        return nullptr;
    }
    
    // 对于YUV420P格式，直接使用软件编码，避免不必要的格式转换
    // 让OpenGL直接处理原始YUV数据进行显示
    if (frame->format == AV_PIX_FMT_YUV420P) {
        // AV_LOGGER_DEBUG("检测到YUV420P格式，直接使用软件编码，避免格式转换");

        // 创建一个新的独立帧副本
        AVFramePtr resultFrame = makeAVFrame();
        if (!resultFrame) {
            AV_LOGGER_ERROR("创建结果帧失败");
            return nullptr;
        }
        
        // 复制帧格式信息
        resultFrame->format = frame->format;
        resultFrame->width = frame->width;
        resultFrame->height = frame->height;
        resultFrame->pts = frame->pts;
        
        // 分配新的缓冲区
        if (av_frame_get_buffer(resultFrame.get(), 32) < 0) {
            AV_LOGGER_ERROR("分配帧缓冲区失败");
            return nullptr;
        }
        
        // 复制帧数据（避免引用计数问题）
        if (av_frame_copy(resultFrame.get(), frame.get()) < 0) {
            AV_LOGGER_ERROR("复制帧数据失败");
            return nullptr;
        }
        
        // 复制帧属性
        if (av_frame_copy_props(resultFrame.get(), frame.get()) < 0) {
            AV_LOGGER_ERROR("复制帧属性失败");
            return nullptr;
        }
        
        return resultFrame;
    }
    
    AVPixelFormat targetFormat;
    if (isHardwareEncoder_) {
        // 对于硬件编码器，暂时使用软件编码避免格式转换问题
        AV_LOGGER_WARNING("硬件编码器检测到，但为避免格式转换问题，使用软件编码");
        targetFormat = static_cast<AVPixelFormat>(frame->format); // 使用输入格式
    } else {
        targetFormat = videoParams_.pixelFormat;
    }
    
    AV_LOGGER_DEBUGF("帧格式转换: {}x{} format:{} -> {}", 
                     frame->width, frame->height,
                     static_cast<int>(frame->format),
                     static_cast<int>(targetFormat));
    
    // 如果格式已经匹配，创建新帧返回
    if (frame->format == targetFormat) {
        // 创建一个新的独立帧副本
        AVFramePtr resultFrame = makeAVFrame();
        if (!resultFrame) {
            AV_LOGGER_ERROR("创建结果帧失败");
            return nullptr;
        }
        
        // 复制帧格式信息
        resultFrame->format = frame->format;
        resultFrame->width = frame->width;
        resultFrame->height = frame->height;
        resultFrame->pts = frame->pts;
        
        // 分配新的缓冲区
        if (av_frame_get_buffer(resultFrame.get(), 32) < 0) {
            AV_LOGGER_ERROR("分配帧缓冲区失败");
            return nullptr;
        }
        
        // 复制帧数据（避免引用计数问题）
        if (av_frame_copy(resultFrame.get(), frame.get()) < 0) {
            AV_LOGGER_ERROR("复制帧数据失败");
            return nullptr;
        }
        
        // 复制帧属性
        if (av_frame_copy_props(resultFrame.get(), frame.get()) < 0) {
            AV_LOGGER_ERROR("复制帧属性失败");
            return nullptr;
        }
        
        return resultFrame;
    }
    
    // 对于其他格式转换需求，仅在必要时进行
    AV_LOGGER_WARNING("检测到格式转换需求，建议优化数据流避免不必要的转换");

    // 创建转换器
    if (!converter_ || 
        converter_->srcFormat_ != static_cast<AVPixelFormat>(frame->format) ||
        converter_->dstFormat_ != targetFormat) {
        AV_LOGGER_DEBUGF("创建新的像素格式转换器: {} -> {}",
                         static_cast<int>(frame->format),
                         static_cast<int>(targetFormat));
        converter_ = std::make_unique<PixelFormatConverter>(
            static_cast<AVPixelFormat>(frame->format), targetFormat);
    }
    
    auto result = converter_->convert(frame);
    if (!result) {
        AV_LOGGER_ERRORF("像素格式转换失败: {} -> {}",
                         static_cast<int>(frame->format),
                         static_cast<int>(targetFormat));
    }
    
    return result;
}

AVFramePtr VideoEncoder::transferToHardware(const AVFramePtr& frame) {
    if (!isHardwareEncoder_ || !frame) {
        // 创建一个新的独立帧副本
        if (frame) {
            AVFramePtr resultFrame = makeAVFrame();
            if (!resultFrame) {
                return nullptr;
            }
            
            // 复制帧格式信息
            resultFrame->format = frame->format;
            resultFrame->width = frame->width;
            resultFrame->height = frame->height;
            resultFrame->pts = frame->pts;
            
            // 分配新的缓冲区
            if (av_frame_get_buffer(resultFrame.get(), 32) < 0) {
                return nullptr;
            }
            
            // 复制帧数据（避免引用计数问题）
            if (av_frame_copy(resultFrame.get(), frame.get()) < 0) {
                return nullptr;
            }
            
            // 复制帧属性
            if (av_frame_copy_props(resultFrame.get(), frame.get()) < 0) {
                return nullptr;
            }
            
            return resultFrame;
        }
        return nullptr;
    }
    
    // 分配硬件帧
    hwFrame_ = makeAVFrame();
    if (!hwFrame_) {
        AV_LOGGER_ERROR("分配硬件帧失败");
        return nullptr;
    }
    
    int ret = av_hwframe_get_buffer(codecCtx_->hw_frames_ctx, hwFrame_.get(), 0);
    if (ret < 0) {
        AV_LOGGER_ERRORF("获取硬件帧缓冲区失败: {}", ffmpeg_utils::errorToString(ret));
        return nullptr;
    }
    
    // 传输数据到硬件
    ret = av_hwframe_transfer_data(hwFrame_.get(), frame.get(), 0);
    if (ret < 0) {
        AV_LOGGER_ERRORF("传输数据到硬件失败: {}", ffmpeg_utils::errorToString(ret));
        return nullptr;
    }
    
    // 复制时间戳等信息
    av_frame_copy_props(hwFrame_.get(), frame.get());
    
    return std::move(hwFrame_);
}

ErrorCode VideoEncoder::encodeFrame(const AVFramePtr& frame, std::vector<AVPacketPtr>& packets) {
    AVFramePtr processedFrame;
    
    if (frame) {
        // 格式转换
        auto convertedFrame = convertFrame(frame);
        if (!convertedFrame) {
            AV_LOGGER_ERROR("帧格式转换失败");
            return ErrorCode::CONVERSION_FAILED;
        }
        processedFrame = std::move(convertedFrame);
        
        // 硬件传输
        auto hwFrame = transferToHardware(processedFrame);
        if (!hwFrame) {
            AV_LOGGER_ERROR("硬件传输失败");
            return ErrorCode::HARDWARE_ERROR;
        }
        processedFrame = std::move(hwFrame);
    }
    
    // 发送帧到编码器
    int ret = avcodec_send_frame(codecCtx_.get(), processedFrame ? processedFrame.get() : nullptr);
    if (ret < 0) {
        AV_LOGGER_ERRORF("发送帧到编码器失败: {}", ffmpeg_utils::errorToString(ret));
        return static_cast<ErrorCode>(ret);
    }
    
    // 接收编码后的包
    return receivePackets(packets);
}

ErrorCode VideoEncoder::receivePackets(std::vector<AVPacketPtr>& packets) {
    while (true) {
        AVPacketPtr packet = makeAVPacket();
        if (!packet) {
            return ErrorCode::MEMORY_ALLOC_FAILED;
        }
        
        int ret = avcodec_receive_packet(codecCtx_.get(), packet.get());
        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
            break; // 需要更多输入或已结束
        }
        
        if (ret < 0) {
            AV_LOGGER_ERRORF("接收编码包失败: {}", ffmpeg_utils::errorToString(ret));
            return static_cast<ErrorCode>(ret);
        }
        
        packets.push_back(std::move(packet));
    }
    
    return ErrorCode::SUCCESS;
}

AVHWDeviceType VideoEncoder::getHardwareDeviceType() const {
    if (videoParams_.codecName == "h264_nvenc") {
        return AV_HWDEVICE_TYPE_CUDA;
    } else if (videoParams_.codecName == "h264_qsv") {
        return AV_HWDEVICE_TYPE_QSV;
    } else if (videoParams_.codecName == "h264_amf") {
        return AV_HWDEVICE_TYPE_D3D11VA;
    } else if (videoParams_.codecName == "h264_videotoolbox") {
        return AV_HWDEVICE_TYPE_VIDEOTOOLBOX;
    }
    
    return AV_HWDEVICE_TYPE_NONE;
}

AVPixelFormat VideoEncoder::getHardwarePixelFormat() const {
    if (videoParams_.codecName == "h264_nvenc") {
        return AV_PIX_FMT_CUDA;
    } else if (videoParams_.codecName == "h264_qsv") {
        return AV_PIX_FMT_QSV;
    } else if (videoParams_.codecName == "h264_amf") {
        return AV_PIX_FMT_D3D11;
    } else if (videoParams_.codecName == "h264_videotoolbox") {
        return AV_PIX_FMT_VIDEOTOOLBOX;
    }
    
    AV_LOGGER_ERRORF("未知的硬件编码器: {}", videoParams_.codecName);
    return AV_PIX_FMT_NONE;
}

std::vector<std::string> VideoEncoder::getSupportedEncoders() {
    std::call_once(encodersInitFlag_, findUsableEncoders);
    return supportedEncoders_;
}

bool VideoEncoder::isHardwareEncoder(const std::string& codecName) {
    for (const char* hwEncoder : HARDWARE_ENCODERS) {
        if (codecName == hwEncoder) {
            return true;
        }
    }
    return false;
}

std::string VideoEncoder::getRecommendedEncoder() {
    auto encoders = getSupportedEncoders();
    
    // 优先选择硬件编码器
    for (const char* hwEncoder : HARDWARE_ENCODERS) {
        if (std::find(encoders.begin(), encoders.end(), hwEncoder) != encoders.end()) {
            return hwEncoder;
        }
    }
    
    // 回退到软件编码器
    for (const char* swEncoder : SOFTWARE_ENCODERS) {
        if (std::find(encoders.begin(), encoders.end(), swEncoder) != encoders.end()) {
            return swEncoder;
        }
    }
    
    return encoders.empty() ? "" : encoders[0];
}

void VideoEncoder::findUsableEncoders() {
    AV_LOGGER_INFO("查找可用的视频编码器...");
    
    // 测试硬件编码器
    for (const char* encoder : HARDWARE_ENCODERS) {
        if (CodecFactory::isCodecSupported(encoder, CodecType::ENCODER, MediaType::VIDEO)) {
            supportedEncoders_.emplace_back(encoder);
            AV_LOGGER_INFOF("找到硬件编码器: {}", encoder);
        }
    }
    
    // 测试软件编码器
    for (const char* encoder : SOFTWARE_ENCODERS) {
        if (CodecFactory::isCodecSupported(encoder, CodecType::ENCODER, MediaType::VIDEO)) {
            supportedEncoders_.emplace_back(encoder);
            AV_LOGGER_INFOF("找到软件编码器: {}", encoder);
        }
    }
    
    AV_LOGGER_INFOF("总共找到 {} 个可用的视频编码器", supportedEncoders_.size());
}

// VideoEncoderFactory 实现
std::unique_ptr<VideoEncoder> VideoEncoderFactory::create(const std::string& codecName) {
    auto encoder = std::make_unique<VideoEncoder>();
    
    if (!codecName.empty()) {
        if (!CodecFactory::isCodecSupported(codecName, CodecType::ENCODER, MediaType::VIDEO)) {
            AV_LOGGER_ERRORF("不支持的编码器: {}", codecName);
            return nullptr;
        }
    }
    
    return encoder;
}

std::unique_ptr<VideoEncoder> VideoEncoderFactory::createBest(bool preferHardware) {
    std::string codecName;
    
    if (preferHardware) {
        codecName = VideoEncoder::getRecommendedEncoder();
    } else {
        // 优先选择软件编码器
        auto encoders = VideoEncoder::getSupportedEncoders();
        for (const char* swEncoder : VideoEncoder::SOFTWARE_ENCODERS) {
            if (std::find(encoders.begin(), encoders.end(), swEncoder) != encoders.end()) {
                codecName = swEncoder;
                break;
            }
        }
    }
    
    if (codecName.empty()) {
        AV_LOGGER_ERROR("未找到可用的视频编码器");
        return nullptr;
    }
    
    return create(codecName);
}

} // namespace codec
} // namespace av
