zhuizhu před 8 měsíci
rodič
revize
cdfdee2b30

+ 24 - 0
AV/AV.pri

@@ -0,0 +1,24 @@
+HEADERS += \
+    $$PWD/code/base/media_common.h \
+    $$PWD/code/base/logger.h \
+    $$PWD/code/base/media_thread_base.h \
+    $$PWD/code/base/types.h \
+    $$PWD/code/codec/codec_abstract_codec.h \
+    $$PWD/code/codec/codec_audio_encoder.h \
+    $$PWD/code/codec/codec_video_encoder.h
+
+SOURCES += \
+    $$PWD/code/base/media_common.cpp \
+    $$PWD/code/base/logger.cpp \
+    $$PWD/code/base/media_thread_base.cpp \
+    $$PWD/code/codec/codec_abstract_codec.cpp \
+    $$PWD/code/codec/codec_audio_encoder.cpp \
+    $$PWD/code/codec/codec_video_encoder.cpp
+
+
+# SOURCES += $$PWD/test_basic.cpp
+SOURCES += $$PWD/test_codec.cpp
+
+
+
+

+ 105 - 0
AV/CMakeLists.txt

@@ -0,0 +1,105 @@
+cmake_minimum_required(VERSION 3.16)
+project(AV_Framework)
+
+# 设置C++标准
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+# 设置编译选项
+if(MSVC)
+    add_compile_options(/W3)
+else()
+    add_compile_options(-Wall -Wextra)
+endif()
+
+# 查找线程库
+find_package(Threads REQUIRED)
+
+# 查找FFmpeg库
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(FFMPEG REQUIRED
+    libavcodec
+    libavformat
+    libavutil
+    libswscale
+    libswresample
+)
+
+# 基础库源文件
+set(BASE_SOURCES
+    code/base/logger.cpp
+    code/base/media_thread_base.cpp
+    code/base/media_common.cpp
+)
+
+# 基础库头文件
+set(BASE_HEADERS
+    code/base/types.h
+    code/base/logger.h
+    code/base/media_thread_base.h
+    code/base/media_common.h
+)
+
+# 编解码库源文件
+set(CODEC_SOURCES
+    code/codec/codec_abstract_codec.cpp
+    code/codec/codec_video_encoder.cpp
+    code/codec/codec_audio_encoder.cpp
+)
+
+# 编解码库头文件
+set(CODEC_HEADERS
+    code/codec/codec_abstract_codec.h
+    code/codec/codec_video_encoder.h
+    code/codec/codec_audio_encoder.h
+)
+
+# 创建基础库
+add_library(av_base STATIC ${BASE_SOURCES} ${BASE_HEADERS})
+target_include_directories(av_base PUBLIC .)
+target_link_libraries(av_base PUBLIC Threads::Threads)
+
+# 创建编解码库
+add_library(av_codec STATIC ${CODEC_SOURCES} ${CODEC_HEADERS})
+target_include_directories(av_codec PUBLIC . ${FFMPEG_INCLUDE_DIRS})
+target_link_libraries(av_codec PUBLIC av_base ${FFMPEG_LIBRARIES})
+target_compile_options(av_codec PRIVATE ${FFMPEG_CFLAGS_OTHER})
+
+# 创建完整的AV库
+add_library(av_framework STATIC)
+target_link_libraries(av_framework PUBLIC av_base av_codec)
+
+# 测试程序
+add_executable(test_basic test_basic.cpp)
+target_link_libraries(test_basic av_base)
+
+# 编解码测试程序
+add_executable(test_codec test_codec.cpp)
+target_link_libraries(test_codec av_framework)
+
+# 设置输出目录
+set_target_properties(test_basic test_codec PROPERTIES
+    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
+)
+
+# 如果是Windows,复制运行时库
+if(WIN32)
+    set_target_properties(test_basic test_codec PROPERTIES
+        VS_DEBUGGER_WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin
+    )
+endif()
+
+# 安装规则
+install(TARGETS av_framework av_base av_codec
+    ARCHIVE DESTINATION lib
+    LIBRARY DESTINATION lib
+    RUNTIME DESTINATION bin
+)
+
+install(FILES ${BASE_HEADERS}
+    DESTINATION include/av/base
+)
+
+install(FILES ${CODEC_HEADERS}
+    DESTINATION include/av/codec
+)

+ 214 - 0
AV/code/base/logger.cpp

@@ -0,0 +1,214 @@
+#include "logger.h"
+#include <iostream>
+#include <iomanip>
+
+// Qt头文件只在需要时包含
+#ifdef QT_CORE_LIB
+#include <QString>
+#include <QDebug>
+#include <QLoggingCategory>
+#endif
+
+namespace av {
+
+// ConsoleOutput实现
+void ConsoleOutput::write(LogLevel level, const std::string& message) {
+    std::ostream& stream = (level >= LogLevel::WARNING) ? std::cerr : std::cout;
+    stream << message << std::endl;
+    stream.flush();
+}
+
+// FileOutput实现
+FileOutput::FileOutput(const std::string& filename) {
+    m_file.open(filename, std::ios::app);
+    if (!m_file.is_open()) {
+        std::cerr << "Failed to open log file: " << filename << std::endl;
+    }
+}
+
+FileOutput::~FileOutput() {
+    if (m_file.is_open()) {
+        m_file.close();
+    }
+}
+
+void FileOutput::write(LogLevel level, const std::string& message) {
+    std::lock_guard<std::mutex> lock(m_mutex);
+    if (m_file.is_open()) {
+        m_file << message << std::endl;
+        m_file.flush();
+    }
+}
+
+// QtOutput实现
+void QtOutput::write(LogLevel level, const std::string& message) {
+#ifdef QT_CORE_LIB
+    QString qmsg = QString::fromUtf8(message.c_str());
+    switch (level) {
+    case LogLevel::DEBUG:
+        qDebug() << qmsg;
+        break;
+    case LogLevel::INFO:
+        qInfo() << qmsg;
+        break;
+    case LogLevel::WARNING:
+        qWarning() << qmsg;
+        break;
+    case LogLevel::ERROR:
+        qCritical() << qmsg;
+        break;
+    }
+#else
+    // 如果没有Qt,回退到控制台输出
+    ConsoleOutput console;
+    console.write(level, message);
+#endif
+}
+
+// Logger实现
+Logger& Logger::instance() {
+    static Logger instance;
+    return instance;
+}
+
+void Logger::setLevel(LogLevel level) {
+    std::lock_guard<std::mutex> lock(m_mutex);
+    m_level = level;
+}
+
+LogLevel Logger::getLevel() const {
+    std::lock_guard<std::mutex> lock(m_mutex);
+    return m_level;
+}
+
+void Logger::addOutput(std::unique_ptr<LogOutput> output) {
+    std::lock_guard<std::mutex> lock(m_mutex);
+    m_outputs.push_back(std::move(output));
+}
+
+void Logger::clearOutputs() {
+    std::lock_guard<std::mutex> lock(m_mutex);
+    m_outputs.clear();
+}
+
+void Logger::debug(const std::string& message) {
+    if (shouldLog(LogLevel::DEBUG)) {
+        log(LogLevel::DEBUG, message);
+    }
+}
+
+void Logger::info(const std::string& message) {
+    if (shouldLog(LogLevel::INFO)) {
+        log(LogLevel::INFO, message);
+    }
+}
+
+void Logger::warning(const std::string& message) {
+    if (shouldLog(LogLevel::WARNING)) {
+        log(LogLevel::WARNING, message);
+    }
+}
+
+void Logger::error(const std::string& message) {
+    if (shouldLog(LogLevel::ERROR)) {
+        log(LogLevel::ERROR, message);
+    }
+}
+
+void Logger::qtDebug(const QString& message) {
+#ifdef QT_CORE_LIB
+    debug(message.toUtf8().toStdString());
+#else
+    debug("[Qt Debug] " + std::string(message.toUtf8().constData()));
+#endif
+}
+
+void Logger::qtInfo(const QString& message) {
+#ifdef QT_CORE_LIB
+    info(message.toUtf8().toStdString());
+#else
+    info("[Qt Info] " + std::string(message.toUtf8().constData()));
+#endif
+}
+
+void Logger::qtWarning(const QString& message) {
+#ifdef QT_CORE_LIB
+    warning(message.toUtf8().toStdString());
+#else
+    warning("[Qt Warning] " + std::string(message.toUtf8().constData()));
+#endif
+}
+
+void Logger::qtError(const QString& message) {
+#ifdef QT_CORE_LIB
+    error(message.toUtf8().toStdString());
+#else
+    error("[Qt Error] " + std::string(message.toUtf8().constData()));
+#endif
+}
+
+void Logger::initialize(const std::string& logFile, 
+                       LogLevel level,
+                       bool enableConsole,
+                       bool enableQt) {
+    Logger& logger = instance();
+    logger.clearOutputs();
+    logger.setLevel(level);
+    
+    // 添加文件输出
+    if (!logFile.empty()) {
+        logger.addOutput(std::make_unique<FileOutput>(logFile));
+    }
+    
+    // 添加控制台输出
+    if (enableConsole) {
+        logger.addOutput(std::make_unique<ConsoleOutput>());
+    }
+    
+    // 添加Qt输出
+    if (enableQt) {
+        logger.addOutput(std::make_unique<QtOutput>());
+    }
+    
+    logger.info("AV Logger initialized");
+}
+
+void Logger::log(LogLevel level, const std::string& message) {
+    std::lock_guard<std::mutex> lock(m_mutex);
+    
+    std::string formattedMessage = getCurrentTime() + " [" + levelToString(level) + "] " + message;
+    
+    for (auto& output : m_outputs) {
+        if (output) {
+            output->write(level, formattedMessage);
+        }
+    }
+}
+
+bool Logger::shouldLog(LogLevel level) const {
+    return level >= m_level;
+}
+
+std::string Logger::getCurrentTime() const {
+    auto now = std::chrono::system_clock::now();
+    auto time_t = std::chrono::system_clock::to_time_t(now);
+    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
+        now.time_since_epoch()) % 1000;
+    
+    std::ostringstream oss;
+    oss << std::put_time(std::localtime(&time_t), "%Y-%m-%d %H:%M:%S");
+    oss << '.' << std::setfill('0') << std::setw(3) << ms.count();
+    return oss.str();
+}
+
+std::string Logger::levelToString(LogLevel level) const {
+    switch (level) {
+    case LogLevel::DEBUG:   return "DEBUG";
+    case LogLevel::INFO:    return "INFO";
+    case LogLevel::WARNING: return "WARN";
+    case LogLevel::ERROR:   return "ERROR";
+    default:                return "UNKNOWN";
+    }
+}
+
+} // namespace av

+ 185 - 0
AV/code/base/logger.h

@@ -0,0 +1,185 @@
+#ifndef AV_BASE_LOGGER_H
+#define AV_BASE_LOGGER_H
+
+#include <string>
+#include <memory>
+#include <mutex>
+#include <fstream>
+#include <sstream>
+#include <chrono>
+#include <iomanip>
+#include <vector>
+
+// 前向声明Qt类型,避免在头文件中包含Qt
+class QString;
+
+namespace av {
+
+// 日志级别枚举
+enum class LogLevel {
+    DEBUG = 0,
+    INFO = 1,
+    WARNING = 2,
+    ERROR = 3
+};
+
+// 日志输出接口
+class LogOutput {
+public:
+    virtual ~LogOutput() = default;
+    virtual void write(LogLevel level, const std::string& message) = 0;
+};
+
+// 控制台输出
+class ConsoleOutput : public LogOutput {
+public:
+    void write(LogLevel level, const std::string& message) override;
+};
+
+// 文件输出
+class FileOutput : public LogOutput {
+public:
+    explicit FileOutput(const std::string& filename);
+    ~FileOutput();
+    void write(LogLevel level, const std::string& message) override;
+    
+private:
+    std::ofstream m_file;
+    std::mutex m_mutex;
+};
+
+// Qt输出(用于兼容现有Qt日志系统)
+class QtOutput : public LogOutput {
+public:
+    void write(LogLevel level, const std::string& message) override;
+};
+
+// 主日志类
+class Logger {
+public:
+    static Logger& instance();
+    
+    // 设置日志级别
+    void setLevel(LogLevel level);
+    LogLevel getLevel() const;
+    
+    // 添加输出目标
+    void addOutput(std::unique_ptr<LogOutput> output);
+    void clearOutputs();
+    
+    // 日志记录方法
+    void debug(const std::string& message);
+    void info(const std::string& message);
+    void warning(const std::string& message);
+    void error(const std::string& message);
+    
+    // 格式化日志记录
+    template<typename... Args>
+    void debugf(const std::string& format, Args&&... args) {
+        if (shouldLog(LogLevel::DEBUG)) {
+            log(LogLevel::DEBUG, formatString(format, std::forward<Args>(args)...));
+        }
+    }
+    
+    template<typename... Args>
+    void infof(const std::string& format, Args&&... args) {
+        if (shouldLog(LogLevel::INFO)) {
+            log(LogLevel::INFO, formatString(format, std::forward<Args>(args)...));
+        }
+    }
+    
+    template<typename... Args>
+    void warningf(const std::string& format, Args&&... args) {
+        if (shouldLog(LogLevel::WARNING)) {
+            log(LogLevel::WARNING, formatString(format, std::forward<Args>(args)...));
+        }
+    }
+    
+    template<typename... Args>
+    void errorf(const std::string& format, Args&&... args) {
+        if (shouldLog(LogLevel::ERROR)) {
+            log(LogLevel::ERROR, formatString(format, std::forward<Args>(args)...));
+        }
+    }
+    
+    // Qt兼容接口
+    void qtDebug(const QString& message);
+    void qtInfo(const QString& message);
+    void qtWarning(const QString& message);
+    void qtError(const QString& message);
+    
+    // 初始化方法(全局初始化时调用)
+    static void initialize(const std::string& logFile = "av_log.txt", 
+                          LogLevel level = LogLevel::INFO,
+                          bool enableConsole = true,
+                          bool enableQt = true);
+    
+private:
+    Logger() = default;
+    ~Logger() = default;
+    Logger(const Logger&) = delete;
+    Logger& operator=(const Logger&) = delete;
+    
+    void log(LogLevel level, const std::string& message);
+    bool shouldLog(LogLevel level) const;
+    std::string getCurrentTime() const;
+    std::string levelToString(LogLevel level) const;
+    
+    template<typename... Args>
+    std::string formatString(const std::string& format, Args&&... args) {
+        std::ostringstream oss;
+        formatImpl(oss, format, std::forward<Args>(args)...);
+        return oss.str();
+    }
+    
+    // 处理无参数情况的formatImpl重载
+    void formatImpl(std::ostringstream& oss, const std::string& format) {
+        oss << format;
+    }
+    
+    template<typename T>
+    void formatImpl(std::ostringstream& oss, const std::string& format, T&& value) {
+        size_t pos = format.find("{}");
+        if (pos != std::string::npos) {
+            oss << format.substr(0, pos) << std::forward<T>(value) << format.substr(pos + 2);
+        } else {
+            oss << format;
+        }
+    }
+    
+    template<typename T, typename... Args>
+    void formatImpl(std::ostringstream& oss, const std::string& format, T&& value, Args&&... args) {
+        size_t pos = format.find("{}");
+        if (pos != std::string::npos) {
+            oss << format.substr(0, pos) << std::forward<T>(value);
+            formatImpl(oss, format.substr(pos + 2), std::forward<Args>(args)...);
+        } else {
+            oss << format;
+        }
+    }
+    
+    LogLevel m_level = LogLevel::INFO;
+    std::vector<std::unique_ptr<LogOutput>> m_outputs;
+    mutable std::mutex m_mutex;
+};
+
+} // namespace av
+
+// 便捷宏定义(重命名以避免与FFmpeg宏冲突)
+#define AV_LOGGER_DEBUG(msg) av::Logger::instance().debug(msg)
+#define AV_LOGGER_INFO(msg) av::Logger::instance().info(msg)
+#define AV_LOGGER_WARNING(msg) av::Logger::instance().warning(msg)
+#define AV_LOGGER_ERROR(msg) av::Logger::instance().error(msg)
+
+#define AV_LOGGER_DEBUGF(fmt, ...) av::Logger::instance().debugf(fmt, __VA_ARGS__)
+#define AV_LOGGER_INFOF(fmt, ...) av::Logger::instance().infof(fmt, __VA_ARGS__)
+#define AV_LOGGER_WARNINGF(fmt, ...) av::Logger::instance().warningf(fmt, __VA_ARGS__)
+#define AV_LOGGER_ERRORF(fmt, ...) av::Logger::instance().errorf(fmt, __VA_ARGS__)
+
+// Qt兼容宏(用于逐步替换现有代码)
+#define AV_QDEBUG(msg) av::Logger::instance().qtDebug(msg)
+#define AV_QINFO(msg) av::Logger::instance().qtInfo(msg)
+#define AV_QWARNING(msg) av::Logger::instance().qtWarning(msg)
+#define AV_QERROR(msg) av::Logger::instance().qtError(msg)
+
+#endif // AV_BASE_LOGGER_H

+ 492 - 0
AV/code/base/media_common.cpp

@@ -0,0 +1,492 @@
+#include "media_common.h"
+#include "logger.h"
+#include <algorithm>
+#include <sstream>
+#include <fstream>
+#include <filesystem>
+#include <cctype>
+#include <iomanip>
+#include <cstring>
+#include <limits>
+
+// FFmpeg头文件
+extern "C" {
+#include <libavutil/avutil.h>
+#include <libavcodec/avcodec.h>
+#include <libavformat/avformat.h>
+#include <libswscale/swscale.h>
+#include <libswresample/swresample.h>
+#include <libavutil/log.h>
+#include <libavutil/error.h>
+#include <libavutil/pixfmt.h>
+#include <libavutil/pixdesc.h>
+#include <libavutil/samplefmt.h>
+#include <libavutil/frame.h>
+#include <libavcodec/packet.h>
+}
+
+namespace av {
+
+// 字符串工具实现
+namespace string_utils {
+
+std::vector<std::string> split(const std::string& str, char delimiter) {
+    std::vector<std::string> result;
+    std::stringstream ss(str);
+    std::string item;
+    
+    while (std::getline(ss, item, delimiter)) {
+        result.push_back(item);
+    }
+    
+    return result;
+}
+
+std::vector<std::string> split(const std::string& str, const std::string& delimiter) {
+    std::vector<std::string> result;
+    size_t start = 0;
+    size_t end = str.find(delimiter);
+    
+    while (end != std::string::npos) {
+        result.push_back(str.substr(start, end - start));
+        start = end + delimiter.length();
+        end = str.find(delimiter, start);
+    }
+    
+    result.push_back(str.substr(start));
+    return result;
+}
+
+std::string trim(const std::string& str) {
+    return trimLeft(trimRight(str));
+}
+
+std::string trimLeft(const std::string& str) {
+    auto start = str.begin();
+    while (start != str.end() && std::isspace(*start)) {
+        start++;
+    }
+    return std::string(start, str.end());
+}
+
+std::string trimRight(const std::string& str) {
+    auto end = str.end();
+    while (end != str.begin() && std::isspace(*(end - 1))) {
+        end--;
+    }
+    return std::string(str.begin(), end);
+}
+
+std::string replace(const std::string& str, const std::string& from, const std::string& to) {
+    std::string result = str;
+    size_t pos = 0;
+    
+    while ((pos = result.find(from, pos)) != std::string::npos) {
+        result.replace(pos, from.length(), to);
+        pos += to.length();
+    }
+    
+    return result;
+}
+
+std::string toLower(const std::string& str) {
+    std::string result = str;
+    std::transform(result.begin(), result.end(), result.begin(), ::tolower);
+    return result;
+}
+
+std::string toUpper(const std::string& str) {
+    std::string result = str;
+    std::transform(result.begin(), result.end(), result.begin(), ::toupper);
+    return result;
+}
+
+bool startsWith(const std::string& str, const std::string& prefix) {
+    return str.length() >= prefix.length() && 
+           str.compare(0, prefix.length(), prefix) == 0;
+}
+
+bool endsWith(const std::string& str, const std::string& suffix) {
+    return str.length() >= suffix.length() && 
+           str.compare(str.length() - suffix.length(), suffix.length(), suffix) == 0;
+}
+
+bool contains(const std::string& str, const std::string& substr) {
+    return str.find(substr) != std::string::npos;
+}
+
+} // namespace string_utils
+
+// 文件路径工具实现
+namespace path_utils {
+
+std::string join(const std::string& path1, const std::string& path2) {
+    if (path1.empty()) return path2;
+    if (path2.empty()) return path1;
+    
+    std::filesystem::path p1(path1);
+    std::filesystem::path p2(path2);
+    return (p1 / p2).string();
+}
+
+std::string getDirectory(const std::string& path) {
+    std::filesystem::path p(path);
+    return p.parent_path().string();
+}
+
+std::string getFilename(const std::string& path) {
+    std::filesystem::path p(path);
+    return p.filename().string();
+}
+
+std::string getExtension(const std::string& path) {
+    std::filesystem::path p(path);
+    return p.extension().string();
+}
+
+std::string removeExtension(const std::string& path) {
+    std::filesystem::path p(path);
+    return p.replace_extension().string();
+}
+
+std::string normalize(const std::string& path) {
+    std::filesystem::path p(path);
+    return std::filesystem::weakly_canonical(p).string();
+}
+
+std::string toNative(const std::string& path) {
+    std::filesystem::path p(path);
+    return p.make_preferred().string();
+}
+
+bool exists(const std::string& path) {
+    return std::filesystem::exists(path);
+}
+
+bool isFile(const std::string& path) {
+    return std::filesystem::is_regular_file(path);
+}
+
+bool isDirectory(const std::string& path) {
+    return std::filesystem::is_directory(path);
+}
+
+bool isAbsolute(const std::string& path) {
+    std::filesystem::path p(path);
+    return p.is_absolute();
+}
+
+bool createDirectory(const std::string& path) {
+    try {
+        return std::filesystem::create_directories(path);
+    } catch (const std::exception& e) {
+        AV_LOGGER_ERRORF("Failed to create directory '{}': {}", path, e.what());
+        return false;
+    }
+}
+
+bool removeFile(const std::string& path) {
+    try {
+        return std::filesystem::remove(path);
+    } catch (const std::exception& e) {
+        AV_LOGGER_ERRORF("Failed to remove file '{}': {}", path, e.what());
+        return false;
+    }
+}
+
+} // namespace path_utils
+
+// 时间工具实现
+namespace time_utils {
+
+int64_t getCurrentTimeMs() {
+    return std::chrono::duration_cast<std::chrono::milliseconds>(
+        std::chrono::steady_clock::now().time_since_epoch()).count();
+}
+
+int64_t getCurrentTimeUs() {
+    return std::chrono::duration_cast<std::chrono::microseconds>(
+        std::chrono::steady_clock::now().time_since_epoch()).count();
+}
+
+std::string formatTime(int64_t timeMs, const std::string& format) {
+    auto time_t = std::chrono::system_clock::to_time_t(
+        std::chrono::system_clock::time_point(
+            std::chrono::milliseconds(timeMs)));
+    
+    std::ostringstream oss;
+    oss << std::put_time(std::localtime(&time_t), format.c_str());
+    return oss.str();
+}
+
+std::string formatDuration(int64_t durationMs) {
+    int64_t hours = durationMs / (1000 * 60 * 60);
+    int64_t minutes = (durationMs % (1000 * 60 * 60)) / (1000 * 60);
+    int64_t seconds = (durationMs % (1000 * 60)) / 1000;
+    int64_t ms = durationMs % 1000;
+    
+    std::ostringstream oss;
+    if (hours > 0) {
+        oss << hours << ":" << std::setfill('0') << std::setw(2) << minutes 
+            << ":" << std::setw(2) << seconds;
+    } else {
+        oss << minutes << ":" << std::setfill('0') << std::setw(2) << seconds;
+    }
+    
+    if (ms > 0) {
+        oss << "." << std::setw(3) << ms;
+    }
+    
+    return oss.str();
+}
+
+// Timer实现
+Timer::Timer() {
+    reset();
+}
+
+void Timer::start() {
+    m_startTime = std::chrono::high_resolution_clock::now();
+    m_running = true;
+}
+
+void Timer::stop() {
+    if (m_running) {
+        m_endTime = std::chrono::high_resolution_clock::now();
+        m_running = false;
+    }
+}
+
+void Timer::reset() {
+    m_startTime = std::chrono::high_resolution_clock::now();
+    m_endTime = m_startTime;
+    m_running = false;
+}
+
+int64_t Timer::elapsedMs() const {
+    auto endTime = m_running ? std::chrono::high_resolution_clock::now() : m_endTime;
+    return std::chrono::duration_cast<std::chrono::milliseconds>(endTime - m_startTime).count();
+}
+
+int64_t Timer::elapsedUs() const {
+    auto endTime = m_running ? std::chrono::high_resolution_clock::now() : m_endTime;
+    return std::chrono::duration_cast<std::chrono::microseconds>(endTime - m_startTime).count();
+}
+
+bool Timer::isRunning() const {
+    return m_running;
+}
+
+// ScopedTimer实现
+ScopedTimer::ScopedTimer(const std::string& name) : m_name(name) {
+    m_timer.start();
+}
+
+ScopedTimer::~ScopedTimer() {
+    m_timer.stop();
+    AV_LOGGER_INFOF("[Timer] {} took {} ms", m_name, m_timer.elapsedMs());
+}
+
+} // namespace time_utils
+
+// 内存工具实现
+namespace memory_utils {
+
+size_t alignSize(size_t size, size_t alignment) {
+    return (size + alignment - 1) & ~(alignment - 1);
+}
+
+void* alignedAlloc(size_t size, size_t alignment) {
+#ifdef _WIN32
+    return _aligned_malloc(size, alignment);
+#else
+    void* ptr = nullptr;
+    if (posix_memalign(&ptr, alignment, size) != 0) {
+        return nullptr;
+    }
+    return ptr;
+#endif
+}
+
+void alignedFree(void* ptr) {
+#ifdef _WIN32
+    _aligned_free(ptr);
+#else
+    free(ptr);
+#endif
+}
+
+// MemoryPool实现
+MemoryPool::MemoryPool(size_t blockSize, size_t blockCount) 
+    : m_blockSize(blockSize) {
+    size_t totalSize = blockSize * blockCount;
+    m_memory.resize(totalSize);
+    
+    // 初始化空闲块列表
+    for (size_t i = 0; i < blockCount; ++i) {
+        m_freeBlocks.push_back(m_memory.data() + i * blockSize);
+    }
+}
+
+MemoryPool::~MemoryPool() {
+    // 析构函数自动清理
+}
+
+void* MemoryPool::allocate() {
+    std::lock_guard<std::mutex> lock(m_mutex);
+    
+    if (m_freeBlocks.empty()) {
+        return nullptr;
+    }
+    
+    void* ptr = m_freeBlocks.back();
+    m_freeBlocks.pop_back();
+    return ptr;
+}
+
+void MemoryPool::deallocate(void* ptr) {
+    if (!ptr) return;
+    
+    std::lock_guard<std::mutex> lock(m_mutex);
+    
+    // 验证指针是否属于这个内存池
+    uint8_t* bytePtr = static_cast<uint8_t*>(ptr);
+    if (bytePtr >= m_memory.data() && 
+        bytePtr < m_memory.data() + m_memory.size()) {
+        m_freeBlocks.push_back(ptr);
+    }
+}
+
+size_t MemoryPool::getAvailableBlocks() const {
+    std::lock_guard<std::mutex> lock(m_mutex);
+    return m_freeBlocks.size();
+}
+
+} // namespace memory_utils
+
+// FFmpeg工具实现
+namespace ffmpeg_utils {
+
+std::string errorToString(int errorCode) {
+    char buffer[AV_ERROR_MAX_STRING_SIZE];
+    av_strerror(errorCode, buffer, sizeof(buffer));
+    return std::string(buffer);
+}
+
+bool checkError(int ret, const std::string& operation) {
+    if (ret < 0) {
+        AV_LOGGER_ERRORF("{} failed: {}", operation, errorToString(ret));
+        return false;
+    }
+    return true;
+}
+
+std::string pixelFormatToString(AVPixelFormat format) {
+    const char* name = av_get_pix_fmt_name(format);
+    return name ? std::string(name) : "unknown";
+}
+
+std::string sampleFormatToString(AVSampleFormat format) {
+    const char* name = av_get_sample_fmt_name(format);
+    return name ? std::string(name) : "unknown";
+}
+
+std::string codecTypeToString(AVMediaType type) {
+    const char* name = av_get_media_type_string(type);
+    return name ? std::string(name) : "unknown";
+}
+
+bool isValidPixelFormat(AVPixelFormat format) {
+    return format != AV_PIX_FMT_NONE && av_get_pix_fmt_name(format) != nullptr;
+}
+
+bool isValidSampleFormat(AVSampleFormat format) {
+    return format != AV_SAMPLE_FMT_NONE && av_get_sample_fmt_name(format) != nullptr;
+}
+
+bool isValidSampleRate(int sampleRate) {
+    return sampleRate > 0 && sampleRate <= 192000;
+}
+
+bool isValidChannels(int channels) {
+    return channels > 0 && channels <= 32;
+}
+
+AVFrame* allocateFrame(AVPixelFormat format, int width, int height) {
+    AVFrame* frame = av_frame_alloc();
+    if (!frame) {
+        return nullptr;
+    }
+    
+    frame->format = format;
+    frame->width = width;
+    frame->height = height;
+    
+    if (av_frame_get_buffer(frame, 32) < 0) {
+        av_frame_free(&frame);
+        return nullptr;
+    }
+    
+    return frame;
+}
+
+AVFrame* allocateAudioFrame(AVSampleFormat format, int sampleRate, int channels, int nbSamples) {
+    AVFrame* frame = av_frame_alloc();
+    if (!frame) {
+        return nullptr;
+    }
+    
+    frame->format = format;
+    frame->sample_rate = sampleRate;
+    frame->ch_layout.nb_channels = channels;
+    frame->nb_samples = nbSamples;
+    
+    if (av_frame_get_buffer(frame, 0) < 0) {
+        av_frame_free(&frame);
+        return nullptr;
+    }
+    
+    return frame;
+}
+
+void freeFrame(AVFrame** frame) {
+    if (frame && *frame) {
+        av_frame_free(frame);
+    }
+}
+
+AVPacket* allocatePacket() {
+    return av_packet_alloc();
+}
+
+void freePacket(AVPacket** packet) {
+    if (packet && *packet) {
+        av_packet_free(packet);
+    }
+}
+
+bool initializeFFmpeg() {
+    static bool initialized = false;
+    if (initialized) {
+        return true;
+    }
+    
+    try {
+        // FFmpeg 4.0+ 不需要显式注册
+        av_log_set_level(AV_LOG_QUIET);
+        initialized = true;
+        AV_LOGGER_INFO("FFmpeg initialized successfully");
+        return true;
+    } catch (const std::exception& e) {
+        AV_LOGGER_ERRORF("Failed to initialize FFmpeg: {}", e.what());
+        return false;
+    }
+}
+
+void cleanupFFmpeg() {
+    // FFmpeg 4.0+ 不需要显式清理
+    AV_LOGGER_INFO("FFmpeg cleanup completed");
+}
+
+} // namespace ffmpeg_utils
+} // namespace av

+ 278 - 0
AV/code/base/media_common.h

@@ -0,0 +1,278 @@
+#ifndef AV_BASE_MEDIA_COMMON_H
+#define AV_BASE_MEDIA_COMMON_H
+
+#include "types.h"
+#include <string>
+#include <vector>
+#include <memory>
+#include <functional>
+#include <chrono>
+
+namespace av {
+
+// 字符串工具
+namespace string_utils {
+    // 字符串分割
+    std::vector<std::string> split(const std::string& str, char delimiter);
+    std::vector<std::string> split(const std::string& str, const std::string& delimiter);
+    
+    // 字符串修剪
+    std::string trim(const std::string& str);
+    std::string trimLeft(const std::string& str);
+    std::string trimRight(const std::string& str);
+    
+    // 字符串替换
+    std::string replace(const std::string& str, const std::string& from, const std::string& to);
+    
+    // 大小写转换
+    std::string toLower(const std::string& str);
+    std::string toUpper(const std::string& str);
+    
+    // 字符串判断
+    bool startsWith(const std::string& str, const std::string& prefix);
+    bool endsWith(const std::string& str, const std::string& suffix);
+    bool contains(const std::string& str, const std::string& substr);
+    
+    // 格式化
+    template<typename... Args>
+    std::string format(const std::string& format, Args&&... args);
+}
+
+// 文件路径工具
+namespace path_utils {
+    // 路径操作
+    std::string join(const std::string& path1, const std::string& path2);
+    std::string getDirectory(const std::string& path);
+    std::string getFilename(const std::string& path);
+    std::string getExtension(const std::string& path);
+    std::string removeExtension(const std::string& path);
+    
+    // 路径规范化
+    std::string normalize(const std::string& path);
+    std::string toNative(const std::string& path);
+    
+    // 路径判断
+    bool exists(const std::string& path);
+    bool isFile(const std::string& path);
+    bool isDirectory(const std::string& path);
+    bool isAbsolute(const std::string& path);
+    
+    // 目录操作
+    bool createDirectory(const std::string& path);
+    bool removeFile(const std::string& path);
+}
+
+// 时间工具
+namespace time_utils {
+    // 获取当前时间戳
+    int64_t getCurrentTimeMs();
+    int64_t getCurrentTimeUs();
+    
+    // 时间格式化
+    std::string formatTime(int64_t timeMs, const std::string& format = "%Y-%m-%d %H:%M:%S");
+    std::string formatDuration(int64_t durationMs);
+    
+    // 性能计时器
+    class Timer {
+    public:
+        Timer();
+        void start();
+        void stop();
+        void reset();
+        int64_t elapsedMs() const;
+        int64_t elapsedUs() const;
+        bool isRunning() const;
+        
+    private:
+        std::chrono::high_resolution_clock::time_point m_startTime;
+        std::chrono::high_resolution_clock::time_point m_endTime;
+        bool m_running = false;
+    };
+    
+    // RAII计时器
+    class ScopedTimer {
+    public:
+        explicit ScopedTimer(const std::string& name);
+        ~ScopedTimer();
+        
+    private:
+        std::string m_name;
+        Timer m_timer;
+    };
+}
+
+// 内存工具
+namespace memory_utils {
+    // 内存对齐
+    size_t alignSize(size_t size, size_t alignment);
+    void* alignedAlloc(size_t size, size_t alignment);
+    void alignedFree(void* ptr);
+    
+    // 内存池(简单实现)
+    class MemoryPool {
+    public:
+        explicit MemoryPool(size_t blockSize, size_t blockCount = 100);
+        ~MemoryPool();
+        
+        void* allocate();
+        void deallocate(void* ptr);
+        
+        size_t getBlockSize() const { return m_blockSize; }
+        size_t getAvailableBlocks() const;
+        
+    private:
+        size_t m_blockSize;
+        std::vector<uint8_t> m_memory;
+        std::vector<void*> m_freeBlocks;
+        mutable std::mutex m_mutex;
+    };
+}
+
+// FFmpeg工具
+namespace ffmpeg_utils {
+    // 错误处理
+    std::string errorToString(int errorCode);
+    bool checkError(int ret, const std::string& operation);
+    
+    // 格式转换
+    std::string pixelFormatToString(AVPixelFormat format);
+    std::string sampleFormatToString(AVSampleFormat format);
+    std::string codecTypeToString(AVMediaType type);
+    
+    // 参数验证
+    bool isValidPixelFormat(AVPixelFormat format);
+    bool isValidSampleFormat(AVSampleFormat format);
+    bool isValidSampleRate(int sampleRate);
+    bool isValidChannels(int channels);
+    
+    // 帧工具
+    AVFrame* allocateFrame(AVPixelFormat format, int width, int height);
+    AVFrame* allocateAudioFrame(AVSampleFormat format, int sampleRate, int channels, int nbSamples);
+    void freeFrame(AVFrame** frame);
+    
+    // 包工具
+    AVPacket* allocatePacket();
+    void freePacket(AVPacket** packet);
+    
+    // 初始化
+    bool initializeFFmpeg();
+    void cleanupFFmpeg();
+}
+
+// 数学工具
+namespace math_utils {
+    // 数值限制
+    template<typename T>
+    T clamp(T value, T min, T max) {
+        return (value < min) ? min : (value > max) ? max : value;
+    }
+    
+    // 数值转换
+    template<typename T, typename U>
+    T safeCast(U value) {
+        return static_cast<T>(clamp<U>(value, 
+            static_cast<U>(std::numeric_limits<T>::min()),
+            static_cast<U>(std::numeric_limits<T>::max())));
+    }
+    
+    // 对齐
+    template<typename T>
+    T alignUp(T value, T alignment) {
+        return (value + alignment - 1) / alignment * alignment;
+    }
+    
+    template<typename T>
+    T alignDown(T value, T alignment) {
+        return value / alignment * alignment;
+    }
+}
+
+// 线程安全的单例模板
+template<typename T>
+class Singleton {
+public:
+    static T& instance() {
+        static T instance;
+        return instance;
+    }
+    
+protected:
+    Singleton() = default;
+    virtual ~Singleton() = default;
+    
+private:
+    Singleton(const Singleton&) = delete;
+    Singleton& operator=(const Singleton&) = delete;
+};
+
+// RAII资源管理器
+template<typename Resource, typename Deleter>
+class ResourceGuard {
+public:
+    explicit ResourceGuard(Resource resource, Deleter deleter)
+        : m_resource(resource), m_deleter(deleter), m_valid(true) {}
+    
+    ~ResourceGuard() {
+        if (m_valid && m_resource) {
+            m_deleter(m_resource);
+        }
+    }
+    
+    // 移动构造
+    ResourceGuard(ResourceGuard&& other) noexcept
+        : m_resource(other.m_resource), m_deleter(std::move(other.m_deleter)), m_valid(other.m_valid) {
+        other.m_valid = false;
+    }
+    
+    // 移动赋值
+    ResourceGuard& operator=(ResourceGuard&& other) noexcept {
+        if (this != &other) {
+            if (m_valid && m_resource) {
+                m_deleter(m_resource);
+            }
+            m_resource = other.m_resource;
+            m_deleter = std::move(other.m_deleter);
+            m_valid = other.m_valid;
+            other.m_valid = false;
+        }
+        return *this;
+    }
+    
+    // 禁止拷贝
+    ResourceGuard(const ResourceGuard&) = delete;
+    ResourceGuard& operator=(const ResourceGuard&) = delete;
+    
+    Resource get() const { return m_resource; }
+    Resource release() {
+        m_valid = false;
+        return m_resource;
+    }
+    
+    bool isValid() const { return m_valid; }
+    
+private:
+    Resource m_resource;
+    Deleter m_deleter;
+    bool m_valid;
+};
+
+// 便捷的资源管理器创建函数
+template<typename Resource, typename Deleter>
+ResourceGuard<Resource, Deleter> makeResourceGuard(Resource resource, Deleter deleter) {
+    return ResourceGuard<Resource, Deleter>(resource, deleter);
+}
+
+} // namespace av
+
+// 便捷宏定义
+#define AV_SCOPED_TIMER(name) av::time_utils::ScopedTimer _timer(name)
+#define AV_MEASURE_TIME(name, code) \
+    do { \
+        av::time_utils::Timer _timer; \
+        _timer.start(); \
+        code; \
+        _timer.stop(); \
+        AV_LOGGER_INFOF("{} took {} ms", name, _timer.elapsedMs()); \
+    } while(0)
+
+#endif // AV_BASE_COMMON_H

+ 290 - 0
AV/code/base/media_thread_base.cpp

@@ -0,0 +1,290 @@
+#include "media_thread_base.h"
+
+#include "../base/logger.h"
+
+#include <stdexcept>
+#include <sstream>
+
+namespace av {
+
+ThreadBase::ThreadBase() {
+    AV_LOGGER_DEBUG("ThreadBase created");
+}
+
+ThreadBase::~ThreadBase() {
+    if (isRunning()) {
+        AV_LOGGER_WARNING("ThreadBase destroyed while still running, forcing stop");
+        stop();
+        join();
+    }
+    AV_LOGGER_DEBUG("ThreadBase destroyed");
+}
+
+bool ThreadBase::start() {
+    std::unique_lock<std::mutex> lock(m_stateMutex);
+    
+    if (m_state != ThreadState::STOPPED) {
+        AV_LOGGER_WARNING("Thread already started or starting");
+        return false;
+    }
+    
+    try {
+        setState(ThreadState::STARTING);
+        m_exitRequested = false;
+        
+        m_thread = std::make_unique<std::thread>(&ThreadBase::threadEntry, this);
+        m_threadId = m_thread->get_id();
+        
+        // 等待线程真正开始运行
+        m_stateCondition.wait(lock, [this] {
+            return m_state == ThreadState::RUNNING || m_state == ThreadState::STOPPED;
+        });
+        
+        bool success = (m_state == ThreadState::RUNNING);
+        if (success) {
+            AV_LOGGER_INFOF("Thread '{}' started successfully", m_threadName.empty() ? "unnamed" : m_threadName);
+        } else {
+            AV_LOGGER_ERRORF("Thread '{}' failed to start", m_threadName.empty() ? "unnamed" : m_threadName);
+        }
+        
+        return success;
+    } catch (const std::exception& e) {
+        setState(ThreadState::STOPPED);
+        AV_LOGGER_ERRORF("Failed to start thread: {}", e.what());
+        return false;
+    }
+}
+
+void ThreadBase::stop() {
+    {
+        std::lock_guard<std::mutex> lock(m_stateMutex);
+        if (m_state == ThreadState::STOPPED || m_state == ThreadState::STOPPING) {
+            return;
+        }
+        setState(ThreadState::STOPPING);
+    }
+    
+    m_exitRequested = true;
+    m_condition.notify_all();
+    
+    AV_LOGGER_INFOF("Thread '{}' stop requested", m_threadName.empty() ? "unnamed" : m_threadName);
+}
+
+void ThreadBase::join() {
+    std::unique_ptr<std::thread> thread;
+    {
+        std::lock_guard<std::mutex> lock(m_stateMutex);
+        thread = std::move(m_thread);
+    }
+    
+    if (thread && thread->joinable()) {
+        // 检查是否在同一线程中调用join
+        if (std::this_thread::get_id() == thread->get_id()) {
+            AV_LOGGER_WARNING("Cannot join thread from itself, detaching instead");
+            thread->detach();
+            return;
+        }
+        
+        try {
+            // 使用超时等待
+            std::unique_lock<std::mutex> lock(m_stateMutex);
+            bool finished = m_stateCondition.wait_for(lock, 
+                std::chrono::milliseconds(DEFAULT_JOIN_TIMEOUT_MS),
+                [this] { return m_state == ThreadState::STOPPED; });
+            
+            if (finished) {
+                lock.unlock();
+                thread->join();
+                AV_LOGGER_INFOF("Thread '{}' joined successfully", m_threadName.empty() ? "unnamed" : m_threadName);
+            } else {
+                AV_LOGGER_WARNINGF("Thread '{}' join timeout, detaching", m_threadName.empty() ? "unnamed" : m_threadName);
+                thread->detach();
+            }
+        } catch (const std::exception& e) {
+            AV_LOGGER_ERRORF("Exception during thread join: {}", e.what());
+            if (thread->joinable()) {
+                thread->detach();
+            }
+        }
+    }
+}
+
+bool ThreadBase::isRunning() const {
+    return m_state == ThreadState::RUNNING;
+}
+
+bool ThreadBase::isStopping() const {
+    return m_state == ThreadState::STOPPING;
+}
+
+ThreadState ThreadBase::getState() const {
+    return m_state.load();
+}
+
+std::thread::id ThreadBase::getThreadId() const {
+    std::lock_guard<std::mutex> lock(m_stateMutex);
+    return m_threadId;
+}
+
+void ThreadBase::setThreadName(const std::string& name) {
+    std::lock_guard<std::mutex> lock(m_stateMutex);
+    m_threadName = name;
+}
+
+std::string ThreadBase::getThreadName() const {
+    std::lock_guard<std::mutex> lock(m_stateMutex);
+    return m_threadName;
+}
+
+void ThreadBase::setOnStarted(std::function<void()> callback) {
+    std::lock_guard<std::mutex> lock(m_stateMutex);
+    m_onStarted = std::move(callback);
+}
+
+void ThreadBase::setOnFinished(std::function<void()> callback) {
+    std::lock_guard<std::mutex> lock(m_stateMutex);
+    m_onFinished = std::move(callback);
+}
+
+void ThreadBase::setOnError(std::function<void(const std::string&)> callback) {
+    std::lock_guard<std::mutex> lock(m_stateMutex);
+    m_onError = std::move(callback);
+}
+
+void ThreadBase::waitForCondition(std::function<bool()> condition, int timeoutMs) {
+    std::unique_lock<std::mutex> lock(m_mutex);
+    
+    if (timeoutMs < 0) {
+        m_condition.wait(lock, [this, &condition] {
+            return shouldExit() || condition();
+        });
+    } else {
+        m_condition.wait_for(lock, std::chrono::milliseconds(timeoutMs), [this, &condition] {
+            return shouldExit() || condition();
+        });
+    }
+}
+
+void ThreadBase::notifyCondition() {
+    m_condition.notify_all();
+}
+
+bool ThreadBase::shouldExit() const {
+    return m_exitRequested.load();
+}
+
+void ThreadBase::sleepMs(int ms) {
+    std::this_thread::sleep_for(std::chrono::milliseconds(ms));
+}
+
+bool ThreadBase::waitForMs(int ms) {
+    std::unique_lock<std::mutex> lock(m_mutex);
+    return !m_condition.wait_for(lock, std::chrono::milliseconds(ms), [this] {
+        return shouldExit();
+    });
+}
+
+void ThreadBase::reportError(const std::string& error) {
+    AV_LOGGER_ERRORF("Thread '{}' error: {}", m_threadName.empty() ? "unnamed" : m_threadName, error);
+    
+    std::function<void(const std::string&)> errorCallback;
+    {
+        std::lock_guard<std::mutex> lock(m_stateMutex);
+        errorCallback = m_onError;
+    }
+    
+    if (errorCallback) {
+        try {
+            errorCallback(error);
+        } catch (const std::exception& e) {
+            AV_LOGGER_ERRORF("Exception in error callback: {}", e.what());
+        } catch (...) {
+            AV_LOGGER_ERROR("Unknown exception in error callback");
+        }
+    }
+}
+
+void ThreadBase::threadEntry() {
+    try {
+        // 设置线程状态为运行中
+        {
+            std::lock_guard<std::mutex> lock(m_stateMutex);
+            setState(ThreadState::RUNNING);
+            m_stateCondition.notify_all();
+        }
+        
+        // 调用启动回调
+        std::function<void()> startedCallback;
+        {
+            std::lock_guard<std::mutex> lock(m_stateMutex);
+            startedCallback = m_onStarted;
+        }
+        
+        if (startedCallback) {
+            try {
+                startedCallback();
+            } catch (const std::exception& e) {
+                AV_LOGGER_ERRORF("Exception in started callback: {}", e.what());
+            } catch (...) {
+                AV_LOGGER_ERROR("Unknown exception in started callback");
+            }
+        }
+        
+        AV_LOGGER_DEBUGF("Thread '{}' entering run loop", m_threadName.empty() ? "unnamed" : m_threadName);
+        
+        // 执行用户逻辑
+        run();
+        
+        AV_LOGGER_DEBUGF("Thread '{}' exiting run loop", m_threadName.empty() ? "unnamed" : m_threadName);
+        
+    } catch (const std::exception& e) {
+        AV_LOGGER_ERRORF("Unhandled exception in thread '{}': {}", m_threadName.empty()
+                             ? "unnamed"
+                             : m_threadName,
+                         e.what());
+        reportError("Unhandled exception: " + std::string(e.what()));
+    } catch (...) {
+        AV_LOGGER_ERRORF("Unknown unhandled exception in thread '{}'", 
+                     m_threadName.empty() ? "unnamed" : m_threadName);
+        reportError("Unknown unhandled exception");
+    }
+    
+    cleanup();
+}
+
+void ThreadBase::setState(ThreadState state) {
+    m_state = state;
+    AV_LOGGER_DEBUGF("Thread '{}' state changed to {}", 
+                 m_threadName.empty() ? "unnamed" : m_threadName, 
+                 static_cast<int>(state));
+}
+
+void ThreadBase::cleanup() {
+    // 调用完成回调
+    std::function<void()> finishedCallback;
+    {
+        std::lock_guard<std::mutex> lock(m_stateMutex);
+        finishedCallback = m_onFinished;
+    }
+    
+    if (finishedCallback) {
+        try {
+            finishedCallback();
+        } catch (const std::exception& e) {
+            AV_LOGGER_ERRORF("Exception in finished callback: {}", e.what());
+        } catch (...) {
+            AV_LOGGER_ERROR("Unknown exception in finished callback");
+        }
+    }
+    
+    // 设置最终状态
+    {
+        std::lock_guard<std::mutex> lock(m_stateMutex);
+        setState(ThreadState::STOPPED);
+        m_stateCondition.notify_all();
+    }
+    
+    AV_LOGGER_INFOF("Thread '{}' finished", m_threadName.empty() ? "unnamed" : m_threadName);
+}
+
+} // namespace av

+ 153 - 0
AV/code/base/media_thread_base.h

@@ -0,0 +1,153 @@
+#ifndef AV_BASE_MEDIA_THREAD_BASE_H
+#define AV_BASE_MEDIA_THREAD_BASE_H
+
+#include "types.h"
+#include <atomic>
+#include <thread>
+#include <mutex>
+#include <condition_variable>
+#include <functional>
+#include <memory>
+#include <chrono>
+
+namespace av {
+
+// 线程状态枚举
+enum class ThreadState {
+    STOPPED,
+    STARTING,
+    RUNNING,
+    STOPPING
+};
+
+// 线程基类
+class ThreadBase {
+public:
+    ThreadBase();
+    virtual ~ThreadBase();
+    
+    // 禁止拷贝和移动
+    ThreadBase(const ThreadBase&) = delete;
+    ThreadBase& operator=(const ThreadBase&) = delete;
+    ThreadBase(ThreadBase&&) = delete;
+    ThreadBase& operator=(ThreadBase&&) = delete;
+    
+    // 线程控制
+    bool start();
+    void stop();
+    void join();
+    
+    // 状态查询
+    bool isRunning() const;
+    bool isStopping() const;
+    ThreadState getState() const;
+    
+    // 线程ID
+    std::thread::id getThreadId() const;
+    
+    // 设置线程名称(用于调试)
+    void setThreadName(const std::string& name);
+    std::string getThreadName() const;
+    
+    // 回调设置
+    void setOnStarted(std::function<void()> callback);
+    void setOnFinished(std::function<void()> callback);
+    void setOnError(std::function<void(const std::string&)> callback);
+    
+    // 等待条件
+    void waitForCondition(std::function<bool()> condition, int timeoutMs = -1);
+    void notifyCondition();
+    
+protected:
+    // 子类需要实现的运行逻辑
+    virtual void run() = 0;
+    
+    // 辅助方法
+    bool shouldExit() const;
+    void sleepMs(int ms);
+    bool waitForMs(int ms); // 可中断的等待
+    
+    // 错误处理
+    void reportError(const std::string& error);
+    
+    // 线程同步
+    std::mutex m_mutex;
+    std::condition_variable m_condition;
+    
+private:
+    void threadEntry();
+    void setState(ThreadState state);
+    void cleanup();
+    
+    // 线程控制
+    std::atomic<bool> m_exitRequested{false};
+    std::atomic<ThreadState> m_state{ThreadState::STOPPED};
+    std::unique_ptr<std::thread> m_thread;
+    
+    // 线程信息
+    std::string m_threadName;
+    std::thread::id m_threadId;
+    
+    // 回调函数
+    std::function<void()> m_onStarted;
+    std::function<void()> m_onFinished;
+    std::function<void(const std::string&)> m_onError;
+    
+    // 同步控制
+    mutable std::mutex m_stateMutex;
+    std::condition_variable m_stateCondition;
+    
+    // 超时控制
+    static constexpr int DEFAULT_JOIN_TIMEOUT_MS = 5000;
+};
+
+// 工作线程模板类(用于简单的循环工作)
+template<typename WorkFunc>
+class WorkerThread : public ThreadBase {
+public:
+    explicit WorkerThread(WorkFunc workFunc, int intervalMs = 10)
+        : m_workFunc(std::move(workFunc))
+        , m_intervalMs(intervalMs) {
+    }
+    
+    void setInterval(int intervalMs) {
+        std::lock_guard<std::mutex> lock(m_mutex);
+        m_intervalMs = intervalMs;
+    }
+    
+    int getInterval() const {
+        std::lock_guard<std::mutex> lock(m_mutex);
+        return m_intervalMs;
+    }
+    
+protected:
+    void run() override {
+        while (!shouldExit()) {
+            try {
+                m_workFunc();
+            } catch (const std::exception& e) {
+                reportError("Work function exception: " + std::string(e.what()));
+            } catch (...) {
+                reportError("Unknown work function exception");
+            }
+            
+            if (!shouldExit()) {
+                waitForMs(m_intervalMs);
+            }
+        }
+    }
+    
+private:
+    WorkFunc m_workFunc;
+    int m_intervalMs;
+};
+
+// 便捷的工作线程创建函数
+template<typename WorkFunc>
+std::unique_ptr<WorkerThread<WorkFunc>> makeWorkerThread(WorkFunc workFunc, int intervalMs = 10) {
+    return std::make_unique<WorkerThread<WorkFunc>>(std::move(workFunc), intervalMs);
+}
+
+} // namespace av
+
+#endif // AV_BASE_THREAD_BASE_H

+ 182 - 0
AV/code/base/types.h

@@ -0,0 +1,182 @@
+#ifndef AV_BASE_TYPES_H
+#define AV_BASE_TYPES_H
+
+#include <memory>
+#include <string>
+#include <functional>
+#include <atomic>
+#include <mutex>
+#include <condition_variable>
+#include <thread>
+#include <chrono>
+
+extern "C" {
+#include <libavcodec/avcodec.h>
+#include <libavformat/avformat.h>
+#include <libavutil/avutil.h>
+#include <libswscale/swscale.h>
+#include <libswresample/swresample.h>
+}
+
+namespace av {
+
+// 媒体类型枚举
+enum class MediaType {
+    AUDIO,
+    VIDEO
+};
+
+// 编解码参数结构
+struct CodecParams {
+    // 通用参数
+    MediaType type;
+    std::string codecName;
+    int bitRate = 0;
+    
+    // 视频参数
+    int width = 0;
+    int height = 0;
+    int fps = 0;
+    AVPixelFormat pixelFormat = AV_PIX_FMT_NONE;
+    
+    // 音频参数
+    int sampleRate = 0;
+    int channels = 0;
+    AVSampleFormat sampleFormat = AV_SAMPLE_FMT_NONE;
+};
+
+// 音频数据结构
+struct AudioData {
+    uint8_t* data = nullptr;
+    int size = 0;
+    int sampleRate = 0;
+    int channels = 0;
+    AVSampleFormat format = AV_SAMPLE_FMT_NONE;
+    int64_t pts = 0;
+};
+
+// 视频帧数据结构
+struct VideoFrame {
+    uint8_t* data[4] = {nullptr};
+    int linesize[4] = {0};
+    int width = 0;
+    int height = 0;
+    AVPixelFormat format = AV_PIX_FMT_NONE;
+    int64_t pts = 0;
+};
+
+// 错误码定义
+enum class ErrorCode {
+    SUCCESS = 0,
+    OK = 0,  // 兼容别名
+    INVALID_PARAMS,
+    INVALID_ARGUMENT,  // 兼容别名
+    CODEC_NOT_FOUND,
+    CODEC_OPEN_FAILED,
+    ENCODE_FAILED,
+    DECODE_FAILED,
+    MEMORY_ALLOC_FAILED,
+    OUT_OF_MEMORY,  // 兼容别名
+    FILE_OPEN_FAILED,
+    INVALID_STATE,
+    CONVERSION_FAILED,
+    NOT_SUPPORTED,
+    HARDWARE_ERROR,
+    UNKNOWN_ERROR
+};
+
+// AVResult 类型别名(用于兼容)
+using AVResult = ErrorCode;
+
+// 常用结果常量
+const AVResult AV_OK = AVResult::SUCCESS;
+
+// 回调函数类型定义
+using FrameCallback = std::function<void(AVFrame*)>;
+using PacketCallback = std::function<void(AVPacket*)>;
+using ErrorCallback = std::function<void(ErrorCode, const std::string&)>;
+
+// 智能指针类型定义
+// 自定义删除器用于AVFrame
+struct AVFrameDeleter {
+    void operator()(AVFrame* frame) {
+        av_frame_free(&frame);
+    }
+};
+using AVFramePtr = std::unique_ptr<AVFrame, AVFrameDeleter>;
+
+// 自定义删除器用于AVPacket
+struct AVPacketDeleter {
+    void operator()(AVPacket* pkt) {
+        av_packet_free(&pkt);
+    }
+};
+using AVPacketPtr = std::unique_ptr<AVPacket, AVPacketDeleter>;
+
+// 自定义删除器用于AVCodecContext
+struct AVCodecContextDeleter {
+    void operator()(AVCodecContext* ctx) {
+        avcodec_free_context(&ctx);
+    }
+};
+using AVCodecContextPtr = std::unique_ptr<AVCodecContext, AVCodecContextDeleter>;
+
+// 自定义删除器用于AVFormatContext
+struct AVFormatContextDeleter {
+    void operator()(AVFormatContext* ctx) {
+        avformat_free_context(ctx);
+    }
+};
+using AVFormatContextPtr = std::unique_ptr<AVFormatContext, AVFormatContextDeleter>;
+
+// 智能指针创建函数
+inline AVFramePtr makeAVFrame() {
+    return AVFramePtr(av_frame_alloc());
+}
+
+inline AVPacketPtr makeAVPacket() {
+    return AVPacketPtr(av_packet_alloc());
+}
+
+inline AVCodecContextPtr makeAVCodecContext(const AVCodec* codec) {
+    return AVCodecContextPtr(avcodec_alloc_context3(codec));
+}
+
+// 内存管理辅助函数
+template<typename T, typename Func>
+void safeFree(T*& ptr, Func&& func) {
+    if (ptr != nullptr) {
+        func();
+        ptr = nullptr;
+    }
+}
+
+// 时间工具函数
+inline void sleepMs(int timeMs) {
+    std::this_thread::sleep_for(std::chrono::milliseconds(timeMs));
+}
+
+inline int64_t getCurrentTimeMs() {
+    return std::chrono::duration_cast<std::chrono::milliseconds>(
+        std::chrono::steady_clock::now().time_since_epoch()).count();
+}
+
+// 音频全局配置常量
+namespace audio {
+    constexpr int SAMPLE_RATE = 48000;
+    constexpr int CHANNELS = 1;
+    constexpr AVSampleFormat SAMPLE_FORMAT = AV_SAMPLE_FMT_FLTP;
+    constexpr int CAPTURE_BITS_PER_SAMPLE = 16;
+    constexpr int MICROPHONE_INDEX = 0;
+    constexpr int SPEAKER_INDEX = 1;
+}
+
+// 视频全局配置常量
+namespace video {
+    constexpr AVPixelFormat DEFAULT_PIXEL_FORMAT = AV_PIX_FMT_NV12;
+    constexpr int DEFAULT_FPS = 30;
+}
+
+} // namespace av
+
+#endif // AV_BASE_TYPES_H

+ 242 - 0
AV/code/codec/codec_abstract_codec.cpp

@@ -0,0 +1,242 @@
+#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::OK;
+    }
+    
+    // 先刷新缓冲区
+    ErrorCode result = flush();
+    if (result != ErrorCode::OK) {
+        AV_LOGGER_ERRORF("刷新编解码器失败: {}", static_cast<int>(result));
+        return result;
+    }
+    
+    // 重置统计信息
+    resetStatistics();
+    
+    setState(CodecState::OPENED);
+    return ErrorCode::OK;
+}
+
+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::OK;
+}
+
+} // namespace codec
+} // namespace av

+ 232 - 0
AV/code/codec/codec_abstract_codec.h

@@ -0,0 +1,232 @@
+#pragma once
+
+#include "../base/types.h"
+#include <memory>
+#include <functional>
+#include <vector>
+#include <string>
+
+namespace av {
+namespace codec {
+
+/**
+ * 编解码器状态
+ */
+enum class CodecState {
+    IDLE,       // 空闲
+    OPENED,     // 已打开
+    RUNNING,    // 运行中
+    FLUSHING,   // 刷新中
+    CLOSED,     // 已关闭
+    ERROR       // 错误
+};
+
+/**
+ * 编解码器类型
+ */
+enum class CodecType {
+    ENCODER,    // 编码器
+    DECODER     // 解码器
+};
+
+/**
+ * 抽象编解码器基类
+ * 提供编解码器的通用接口和状态管理
+ */
+class AbstractCodec {
+public:
+    AbstractCodec(MediaType mediaType, CodecType codecType);
+    virtual ~AbstractCodec();
+
+    // 禁止拷贝
+    AbstractCodec(const AbstractCodec&) = delete;
+    AbstractCodec& operator=(const AbstractCodec&) = delete;
+
+    /**
+     * 打开编解码器
+     * @param params 编解码参数
+     * @return 成功返回ErrorCode::OK
+     */
+    virtual ErrorCode open(const CodecParams& params) = 0;
+
+    /**
+     * 关闭编解码器
+     */
+    virtual void close() = 0;
+
+    /**
+     * 刷新编解码器缓冲区
+     * @return 成功返回ErrorCode::OK
+     */
+    virtual ErrorCode flush() = 0;
+
+    /**
+     * 重置编解码器
+     * @return 成功返回ErrorCode::OK
+     */
+    virtual ErrorCode reset();
+
+    // 状态查询
+    CodecState getState() const { return state_; }
+    MediaType getMediaType() const { return mediaType_; }
+    CodecType getCodecType() const { return codecType_; }
+    bool isOpened() const { return state_ == CodecState::OPENED || state_ == CodecState::RUNNING; }
+    bool isRunning() const { return state_ == CodecState::RUNNING; }
+    bool hasError() const { return state_ == CodecState::ERROR; }
+
+    // 参数获取
+    const CodecParams& getParams() const { return params_; }
+
+    // 统计信息
+    struct Statistics {
+        uint64_t processedFrames = 0;   // 处理的帧数
+        uint64_t droppedFrames = 0;     // 丢弃的帧数
+        uint64_t errorCount = 0;        // 错误次数
+        double avgProcessTime = 0.0;    // 平均处理时间(ms)
+        uint64_t totalBytes = 0;        // 总字节数
+    };
+    
+    const Statistics& getStatistics() const { return stats_; }
+    void resetStatistics();
+
+    // 回调函数设置
+    using ErrorCallback = std::function<void(ErrorCode error, const std::string& message)>;
+    void setErrorCallback(ErrorCallback callback) { errorCallback_ = std::move(callback); }
+
+protected:
+    /**
+     * 设置编解码器状态
+     */
+    void setState(CodecState state);
+
+    /**
+     * 报告错误
+     */
+    void reportError(ErrorCode error, const std::string& message = "");
+
+    /**
+     * 更新统计信息
+     */
+    void updateStats(bool success, double processTime, uint64_t bytes = 0);
+
+    /**
+     * 验证参数有效性
+     */
+    virtual bool validateParams(const CodecParams& params) = 0;
+
+protected:
+    MediaType mediaType_;           // 媒体类型
+    CodecType codecType_;           // 编解码器类型
+    CodecState state_;              // 当前状态
+    CodecParams params_;            // 编解码参数
+    Statistics stats_;              // 统计信息
+    ErrorCallback errorCallback_;   // 错误回调
+    
+    // FFmpeg相关
+    AVCodecContextPtr codecCtx_;    // 编解码上下文
+    const AVCodec* codec_;          // 编解码器
+};
+
+/**
+ * 抽象编码器基类
+ */
+class AbstractEncoder : public AbstractCodec {
+public:
+    AbstractEncoder(MediaType mediaType) : AbstractCodec(mediaType, CodecType::ENCODER) {}
+    virtual ~AbstractEncoder() = default;
+
+    /**
+     * 编码一帧数据
+     * @param frame 输入帧
+     * @param packets 输出包列表
+     * @return 成功返回ErrorCode::OK
+     */
+    virtual ErrorCode encode(const AVFramePtr& frame, std::vector<AVPacketPtr>& packets) = 0;
+
+    /**
+     * 结束编码(刷新缓冲区)
+     * @param packets 输出包列表
+     * @return 成功返回ErrorCode::OK
+     */
+    virtual ErrorCode finishEncode(std::vector<AVPacketPtr>& packets) = 0;
+
+    // 编码器特有的回调
+    using FrameCallback = std::function<void(const AVFramePtr& frame)>;
+    using PacketCallback = std::function<void(const AVPacketPtr& packet)>;
+    
+    void setFrameCallback(FrameCallback callback) { frameCallback_ = std::move(callback); }
+    void setPacketCallback(PacketCallback callback) { packetCallback_ = std::move(callback); }
+
+protected:
+    FrameCallback frameCallback_;   // 帧回调
+    PacketCallback packetCallback_; // 包回调
+};
+
+/**
+ * 抽象解码器基类
+ */
+class AbstractDecoder : public AbstractCodec {
+public:
+    AbstractDecoder(MediaType mediaType) : AbstractCodec(mediaType, CodecType::DECODER) {}
+    virtual ~AbstractDecoder() = default;
+
+    /**
+     * 解码一个包
+     * @param packet 输入包
+     * @param frames 输出帧列表
+     * @return 成功返回ErrorCode::OK
+     */
+    virtual ErrorCode decode(const AVPacketPtr& packet, std::vector<AVFramePtr>& frames) = 0;
+
+    /**
+     * 结束解码(刷新缓冲区)
+     * @param frames 输出帧列表
+     * @return 成功返回ErrorCode::OK
+     */
+    virtual ErrorCode finishDecode(std::vector<AVFramePtr>& frames) = 0;
+
+    // 解码器特有的回调
+    using PacketCallback = std::function<void(const AVPacketPtr& packet)>;
+    using FrameCallback = std::function<void(const AVFramePtr& frame)>;
+    
+    void setPacketCallback(PacketCallback callback) { packetCallback_ = std::move(callback); }
+    void setFrameCallback(FrameCallback callback) { frameCallback_ = std::move(callback); }
+
+protected:
+    PacketCallback packetCallback_; // 包回调
+    FrameCallback frameCallback_;   // 帧回调
+};
+
+/**
+ * 编解码器工厂类
+ */
+class CodecFactory {
+public:
+    /**
+     * 创建编码器
+     */
+    static std::unique_ptr<AbstractEncoder> createEncoder(MediaType mediaType, const std::string& codecName);
+
+    /**
+     * 创建解码器
+     */
+    static std::unique_ptr<AbstractDecoder> createDecoder(MediaType mediaType, const std::string& codecName);
+
+    /**
+     * 获取支持的编码器列表
+     */
+    static std::vector<std::string> getSupportedEncoders(MediaType mediaType);
+
+    /**
+     * 获取支持的解码器列表
+     */
+    static std::vector<std::string> getSupportedDecoders(MediaType mediaType);
+
+    /**
+     * 检查编解码器是否支持
+     */
+    static bool isCodecSupported(const std::string& codecName, CodecType type, MediaType mediaType);
+};
+
+} // namespace codec
+} // namespace av

+ 654 - 0
AV/code/codec/codec_audio_encoder.cpp

@@ -0,0 +1,654 @@
+#include "codec_audio_encoder.h"
+#include "../base/logger.h"
+#include <algorithm>
+#include <chrono>
+
+namespace av {
+namespace codec {
+
+// 静态成员初始化
+std::vector<std::string> AudioEncoder::supportedEncoders_;
+std::once_flag AudioEncoder::encodersInitFlag_;
+
+// AudioResampler 实现
+AudioResampler::AudioResampler()
+    : swrCtx_(nullptr)
+    , srcFormat_(AV_SAMPLE_FMT_NONE)
+    , dstFormat_(AV_SAMPLE_FMT_NONE)
+    , srcSampleRate_(0)
+    , dstSampleRate_(0)
+    , dstFrameSize_(0)
+    , initialized_(false) {
+    av_channel_layout_default(&srcLayout_, 0);
+    av_channel_layout_default(&dstLayout_, 0);
+}
+
+AudioResampler::~AudioResampler() {
+    if (swrCtx_) {
+        swr_free(&swrCtx_);
+    }
+    av_channel_layout_uninit(&srcLayout_);
+    av_channel_layout_uninit(&dstLayout_);
+}
+
+bool AudioResampler::init(const AVChannelLayout& srcLayout, AVSampleFormat srcFormat, int srcSampleRate,
+                         const AVChannelLayout& dstLayout, AVSampleFormat dstFormat, int dstSampleRate) {
+    if (swrCtx_) {
+        swr_free(&swrCtx_);
+    }
+    
+    av_channel_layout_uninit(&srcLayout_);
+    av_channel_layout_uninit(&dstLayout_);
+    
+    // 复制声道布局
+    if (av_channel_layout_copy(&srcLayout_, &srcLayout) < 0 ||
+        av_channel_layout_copy(&dstLayout_, &dstLayout) < 0) {
+        AV_LOGGER_ERROR("复制声道布局失败");
+        return false;
+    }
+    
+    srcFormat_ = srcFormat;
+    dstFormat_ = dstFormat;
+    srcSampleRate_ = srcSampleRate;
+    dstSampleRate_ = dstSampleRate;
+    
+    // 创建重采样上下文
+    int ret = swr_alloc_set_opts2(&swrCtx_,
+                                  &dstLayout_, dstFormat_, dstSampleRate_,
+                                  &srcLayout_, srcFormat_, srcSampleRate_,
+                                  0, nullptr);
+    if (ret < 0) {
+        AV_LOGGER_ERRORF("创建重采样上下文失败: {}", ffmpeg_utils::errorToString(ret));
+        return false;
+    }
+    
+    // 初始化重采样器
+    ret = swr_init(swrCtx_);
+    if (ret < 0) {
+        AV_LOGGER_ERRORF("初始化重采样器失败: {}", ffmpeg_utils::errorToString(ret));
+        swr_free(&swrCtx_);
+        return false;
+    }
+    
+    // 计算输出帧大小
+    dstFrameSize_ = av_rescale_rnd(1024, dstSampleRate_, srcSampleRate_, AV_ROUND_UP);
+    
+    // 创建输出帧
+    dstFrame_ = makeAVFrame();
+    if (!dstFrame_) {
+        AV_LOGGER_ERROR("分配输出帧失败");
+        return false;
+    }
+    
+    dstFrame_->format = dstFormat_;
+    dstFrame_->sample_rate = dstSampleRate_;
+    av_channel_layout_copy(&dstFrame_->ch_layout, &dstLayout_);
+    dstFrame_->nb_samples = dstFrameSize_;
+    
+    ret = av_frame_get_buffer(dstFrame_.get(), 0);
+    if (ret < 0) {
+        AV_LOGGER_ERRORF("分配帧缓冲区失败: {}", ffmpeg_utils::errorToString(ret));
+        return false;
+    }
+    
+    initialized_ = true;
+    return true;
+}
+
+AVFramePtr AudioResampler::resample(const AVFramePtr& srcFrame) {
+    if (!initialized_ || !srcFrame) {
+        return nullptr;
+    }
+    
+    // 计算输出样本数
+    int dstSamples = av_rescale_rnd(srcFrame->nb_samples, dstSampleRate_, srcSampleRate_, AV_ROUND_UP);
+    
+    // 确保输出帧有足够的空间
+    if (dstFrame_->nb_samples < dstSamples) {
+        av_frame_unref(dstFrame_.get());
+        dstFrame_->nb_samples = dstSamples;
+        
+        int ret = av_frame_get_buffer(dstFrame_.get(), 0);
+        if (ret < 0) {
+            AV_LOGGER_ERRORF("重新分配帧缓冲区失败: {}", ffmpeg_utils::errorToString(ret));
+            return nullptr;
+        }
+    }
+    
+    // 执行重采样
+    int convertedSamples = swr_convert(swrCtx_,
+                                       dstFrame_->data, dstSamples,
+                                       const_cast<const uint8_t**>(srcFrame->data), srcFrame->nb_samples);
+    
+    if (convertedSamples < 0) {
+        AV_LOGGER_ERRORF("音频重采样失败: {}", ffmpeg_utils::errorToString(convertedSamples));
+        return nullptr;
+    }
+    
+    dstFrame_->nb_samples = convertedSamples;
+    
+    // 复制时间戳等信息
+    av_frame_copy_props(dstFrame_.get(), srcFrame.get());
+    
+    // 调整时间戳
+    if (srcFrame->pts != AV_NOPTS_VALUE) {
+        dstFrame_->pts = av_rescale_q(srcFrame->pts, {1, srcSampleRate_}, {1, dstSampleRate_});
+    }
+    
+    return std::move(dstFrame_);
+}
+
+std::vector<AVFramePtr> AudioResampler::flush() {
+    std::vector<AVFramePtr> frames;
+    
+    if (!initialized_) {
+        return frames;
+    }
+    
+    while (true) {
+        AVFramePtr frame = makeAVFrame();
+        if (!frame) {
+            break;
+        }
+        
+        frame->format = dstFormat_;
+        frame->sample_rate = dstSampleRate_;
+        av_channel_layout_copy(&frame->ch_layout, &dstLayout_);
+        frame->nb_samples = dstFrameSize_;
+        
+        int ret = av_frame_get_buffer(frame.get(), 0);
+        if (ret < 0) {
+            break;
+        }
+        
+        int convertedSamples = swr_convert(swrCtx_,
+                                           frame->data, dstFrameSize_,
+                                           nullptr, 0);
+        
+        if (convertedSamples <= 0) {
+            break;
+        }
+        
+        frame->nb_samples = convertedSamples;
+        frames.push_back(std::move(frame));
+    }
+    
+    return frames;
+}
+
+// AudioEncoder 实现
+AudioEncoder::AudioEncoder()
+    : AbstractEncoder(MediaType::AUDIO) {
+    AV_LOGGER_DEBUG("创建音频编码器");
+}
+
+AudioEncoder::~AudioEncoder() {
+    close();
+    AV_LOGGER_DEBUG("音频编码器已销毁");
+}
+
+ErrorCode AudioEncoder::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_ARGUMENT;
+    }
+    
+    audioParams_ = static_cast<const AudioEncoderParams&>(params);
+    params_ = params;
+    
+    ErrorCode result = initEncoder();
+    if (result != ErrorCode::OK) {
+        close();
+        return result;
+    }
+    
+    setState(CodecState::OPENED);
+    AV_LOGGER_INFOF("音频编码器已打开: {} ({}Hz, {}ch, {}kbps)", 
+                 audioParams_.codecName, audioParams_.sampleRate, 
+                 audioParams_.channels, audioParams_.bitRate / 1000);
+    
+    return ErrorCode::OK;
+}
+
+void AudioEncoder::close() {
+    std::lock_guard<std::mutex> lock(encodeMutex_);
+    
+    if (state_ == CodecState::CLOSED || state_ == CodecState::IDLE) {
+        return;
+    }
+    
+    // 清理资源
+    resampler_.reset();
+    convertedFrame_.reset();
+    
+    // 清理编解码上下文
+    codecCtx_.reset();
+    codec_ = nullptr;
+    
+    setState(CodecState::CLOSED);
+    AV_LOGGER_DEBUG("音频编码器已关闭");
+}
+
+ErrorCode AudioEncoder::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::OK;
+}
+
+ErrorCode AudioEncoder::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::OK, processTime, 
+                frame ? frame->nb_samples * audioParams_.channels * av_get_bytes_per_sample(static_cast<AVSampleFormat>(frame->format)) : 0);
+    
+    if (frameCallback_ && frame) {
+        frameCallback_(frame);
+    }
+    
+    for (const auto& packet : packets) {
+        if (packetCallback_) {
+            packetCallback_(packet);
+        }
+    }
+    
+    return result;
+}
+
+ErrorCode AudioEncoder::finishEncode(std::vector<AVPacketPtr>& packets) {
+    return flush();
+}
+
+bool AudioEncoder::validateParams(const CodecParams& params) {
+    if (params.type != MediaType::AUDIO) {
+        AV_LOGGER_ERROR("参数媒体类型不是音频");
+        return false;
+    }
+    
+    const auto& audioParams = static_cast<const AudioEncoderParams&>(params);
+    
+    if (audioParams.sampleRate <= 0) {
+        AV_LOGGER_ERROR("采样率无效");
+        return false;
+    }
+    
+    if (audioParams.channels <= 0) {
+        AV_LOGGER_ERROR("声道数无效");
+        return false;
+    }
+    
+    if (audioParams.bitRate <= 0) {
+        AV_LOGGER_ERROR("比特率无效");
+        return false;
+    }
+    
+    if (audioParams.codecName.empty()) {
+        AV_LOGGER_ERROR("编码器名称为空");
+        return false;
+    }
+    
+    return true;
+}
+
+ErrorCode AudioEncoder::initEncoder() {
+    // 查找编码器
+    codec_ = avcodec_find_encoder_by_name(audioParams_.codecName.c_str());
+    if (!codec_) {
+        AV_LOGGER_ERRORF("未找到编码器: {}", audioParams_.codecName);
+        return ErrorCode::CODEC_NOT_FOUND;
+    }
+    
+    if (codec_->type != AVMEDIA_TYPE_AUDIO) {
+        AV_LOGGER_ERROR("编码器类型不是音频");
+        return ErrorCode::INVALID_ARGUMENT;
+    }
+    
+    // 创建编码上下文
+    codecCtx_ = makeAVCodecContext(codec_);
+    if (!codecCtx_) {
+        AV_LOGGER_ERROR("分配编码上下文失败");
+        return ErrorCode::OUT_OF_MEMORY;
+    }
+    
+    // 设置编码器参数
+    ErrorCode result = setupEncoderParams();
+    if (result != ErrorCode::OK) {
+        return result;
+    }
+    
+    // 打开编码器
+    int ret = avcodec_open2(codecCtx_.get(), codec_, nullptr);
+    if (ret < 0) {
+        AV_LOGGER_ERRORF("打开编码器失败: {}", ffmpeg_utils::errorToString(ret));
+        return static_cast<ErrorCode>(ret);
+    }
+    
+    return ErrorCode::OK;
+}
+
+ErrorCode AudioEncoder::setupEncoderParams() {
+    codecCtx_->bit_rate = audioParams_.bitRate;
+    codecCtx_->sample_rate = audioParams_.sampleRate;
+    
+    // 设置声道布局
+    ErrorCode result = setupChannelLayout();
+    if (result != ErrorCode::OK) {
+        return result;
+    }
+    
+    // 设置采样格式
+    codecCtx_->sample_fmt = getBestSampleFormat();
+    
+    // 设置帧大小
+    if (codec_->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE) {
+        codecCtx_->frame_size = audioParams_.frameSize;
+    }
+    
+    // 设置配置文件
+    if (!audioParams_.profile.empty()) {
+        av_opt_set(codecCtx_->priv_data, "profile", audioParams_.profile.c_str(), 0);
+    }
+    
+    return ErrorCode::OK;
+}
+
+ErrorCode AudioEncoder::setupChannelLayout() {
+    // 设置声道布局
+    if (audioParams_.channelLayout.nb_channels > 0) {
+        av_channel_layout_copy(&codecCtx_->ch_layout, &audioParams_.channelLayout);
+    } else {
+        // 根据声道数设置默认布局
+        av_channel_layout_default(&codecCtx_->ch_layout, audioParams_.channels);
+    }
+    
+    return ErrorCode::OK;
+}
+
+AVFramePtr AudioEncoder::convertFrame(const AVFramePtr& frame) {
+    if (!frame) {
+        return nullptr;
+    }
+    
+    // 检查是否需要转换
+    bool needConvert = false;
+    
+    if (frame->format != codecCtx_->sample_fmt) {
+        needConvert = true;
+    }
+    
+    if (frame->sample_rate != codecCtx_->sample_rate) {
+        needConvert = true;
+    }
+    
+    if (av_channel_layout_compare(&frame->ch_layout, &codecCtx_->ch_layout) != 0) {
+        needConvert = true;
+    }
+    
+    if (!needConvert) {
+        // 创建一个新的帧来返回,避免拷贝构造
+        AVFramePtr resultFrame = makeAVFrame();
+        if (!resultFrame) {
+            return nullptr;
+        }
+        
+        // 复制帧数据
+        if (av_frame_ref(resultFrame.get(), frame.get()) < 0) {
+            return nullptr;
+        }
+        
+        return resultFrame;
+    }
+    
+    // 创建重采样器
+    if (!resampler_) {
+        resampler_ = std::make_unique<AudioResampler>();
+        if (!resampler_->init(frame->ch_layout, static_cast<AVSampleFormat>(frame->format), frame->sample_rate,
+                             codecCtx_->ch_layout, codecCtx_->sample_fmt, codecCtx_->sample_rate)) {
+            AV_LOGGER_ERROR("初始化音频重采样器失败");
+            return nullptr;
+        }
+    }
+    
+    return resampler_->resample(frame);
+}
+
+ErrorCode AudioEncoder::encodeFrame(const AVFramePtr& frame, std::vector<AVPacketPtr>& packets) {
+    AVFramePtr processedFrame;
+    
+    if (frame) {
+        // 格式转换
+        processedFrame = convertFrame(frame);
+        if (!processedFrame) {
+            AV_LOGGER_ERROR("音频帧格式转换失败");
+            return ErrorCode::CONVERSION_FAILED;
+        }
+    }
+    
+    // 发送帧到编码器
+    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 AudioEncoder::receivePackets(std::vector<AVPacketPtr>& packets) {
+    while (true) {
+        AVPacketPtr packet = makeAVPacket();
+        if (!packet) {
+            return ErrorCode::OUT_OF_MEMORY;
+        }
+        
+        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::OK;
+}
+
+AVSampleFormat AudioEncoder::getBestSampleFormat() const {
+    if (!codec_->sample_fmts) {
+        return audioParams_.sampleFormat;
+    }
+    
+    // 首先尝试使用指定的格式
+    for (const AVSampleFormat* fmt = codec_->sample_fmts; *fmt != AV_SAMPLE_FMT_NONE; fmt++) {
+        if (*fmt == audioParams_.sampleFormat) {
+            return *fmt;
+        }
+    }
+    
+    // 返回第一个支持的格式
+    return codec_->sample_fmts[0];
+}
+
+int AudioEncoder::getBestSampleRate() const {
+    if (!codec_->supported_samplerates) {
+        return audioParams_.sampleRate;
+    }
+    
+    // 首先尝试使用指定的采样率
+    for (const int* rate = codec_->supported_samplerates; *rate != 0; rate++) {
+        if (*rate == audioParams_.sampleRate) {
+            return *rate;
+        }
+    }
+    
+    // 返回第一个支持的采样率
+    return codec_->supported_samplerates[0];
+}
+
+std::vector<std::string> AudioEncoder::getSupportedEncoders() {
+    std::call_once(encodersInitFlag_, findSupportedEncoders);
+    return supportedEncoders_;
+}
+
+std::string AudioEncoder::getRecommendedEncoder() {
+    auto encoders = getSupportedEncoders();
+    
+    // 优先选择高质量编码器
+    const char* preferredEncoders[] = {"libfdk_aac", "aac", "libopus", "opus", "libmp3lame", "mp3"};
+    
+    for (const char* encoder : preferredEncoders) {
+        if (std::find(encoders.begin(), encoders.end(), encoder) != encoders.end()) {
+            return encoder;
+        }
+    }
+    
+    return encoders.empty() ? "" : encoders[0];
+}
+
+bool AudioEncoder::isSampleFormatSupported(const std::string& codecName, AVSampleFormat format) {
+    const AVCodec* codec = avcodec_find_encoder_by_name(codecName.c_str());
+    if (!codec || !codec->sample_fmts) {
+        return false;
+    }
+    
+    for (const AVSampleFormat* fmt = codec->sample_fmts; *fmt != AV_SAMPLE_FMT_NONE; fmt++) {
+        if (*fmt == format) {
+            return true;
+        }
+    }
+    
+    return false;
+}
+
+bool AudioEncoder::isSampleRateSupported(const std::string& codecName, int sampleRate) {
+    const AVCodec* codec = avcodec_find_encoder_by_name(codecName.c_str());
+    if (!codec) {
+        return false;
+    }
+    
+    if (!codec->supported_samplerates) {
+        return true; // 支持所有采样率
+    }
+    
+    for (const int* rate = codec->supported_samplerates; *rate != 0; rate++) {
+        if (*rate == sampleRate) {
+            return true;
+        }
+    }
+    
+    return false;
+}
+
+bool AudioEncoder::isChannelLayoutSupported(const std::string& codecName, const AVChannelLayout& layout) {
+    const AVCodec* codec = avcodec_find_encoder_by_name(codecName.c_str());
+    if (!codec) {
+        return false;
+    }
+    
+    if (!codec->ch_layouts) {
+        return true; // 支持所有声道布局
+    }
+    
+    for (const AVChannelLayout* ch_layout = codec->ch_layouts; ch_layout->nb_channels != 0; ch_layout++) {
+        if (av_channel_layout_compare(ch_layout, &layout) == 0) {
+            return true;
+        }
+    }
+    
+    return false;
+}
+
+void AudioEncoder::findSupportedEncoders() {
+    AV_LOGGER_INFO("查找可用的音频编码器...");
+    
+    for (const char* encoder : AUDIO_ENCODERS) {
+        if (CodecFactory::isCodecSupported(encoder, CodecType::ENCODER, MediaType::AUDIO)) {
+            supportedEncoders_.emplace_back(encoder);
+            AV_LOGGER_INFOF("找到音频编码器: {}", encoder);
+        }
+    }
+    
+    AV_LOGGER_INFOF("总共找到 {} 个可用的音频编码器", supportedEncoders_.size());
+}
+
+// AudioEncoderFactory 实现
+std::unique_ptr<AudioEncoder> AudioEncoderFactory::create(const std::string& codecName) {
+    auto encoder = std::make_unique<AudioEncoder>();
+    
+    if (!codecName.empty()) {
+        if (!CodecFactory::isCodecSupported(codecName, CodecType::ENCODER, MediaType::AUDIO)) {
+            AV_LOGGER_ERRORF("不支持的编码器: {}", codecName);
+            return nullptr;
+        }
+    }
+    
+    return encoder;
+}
+
+std::unique_ptr<AudioEncoder> AudioEncoderFactory::createBest() {
+    std::string codecName = AudioEncoder::getRecommendedEncoder();
+    
+    if (codecName.empty()) {
+        AV_LOGGER_ERROR("未找到可用的音频编码器");
+        return nullptr;
+    }
+    
+    return create(codecName);
+}
+
+std::unique_ptr<AudioEncoder> AudioEncoderFactory::createLossless() {
+    auto encoders = AudioEncoder::getSupportedEncoders();
+    
+    // 优先选择无损编码器
+    const char* losslessEncoders[] = {"flac", "pcm_s24le", "pcm_s16le"};
+    
+    for (const char* encoder : losslessEncoders) {
+        if (std::find(encoders.begin(), encoders.end(), encoder) != encoders.end()) {
+            return create(encoder);
+        }
+    }
+    
+    AV_LOGGER_WARNING("未找到无损音频编码器,使用默认编码器");
+    return createBest();
+}
+
+} // namespace codec
+} // namespace av

+ 198 - 0
AV/code/codec/codec_audio_encoder.h

@@ -0,0 +1,198 @@
+#pragma once
+
+#include "codec_abstract_codec.h"
+#include "../base/media_common.h"
+#include <mutex>
+#include <memory>
+
+extern "C" {
+#include <libavcodec/avcodec.h>
+#include <libavutil/channel_layout.h>
+#include <libavutil/opt.h>
+#include <libavformat/avformat.h>
+#include <libswresample/swresample.h>
+}
+
+namespace av {
+namespace codec {
+
+/**
+ * 音频编码器参数
+ */
+struct AudioEncoderParams : public CodecParams {
+    int bitRate = 128000;                           // 比特率 (bps)
+    int sampleRate = 44100;                         // 采样率
+    int channels = 2;                               // 声道数
+    AVChannelLayout channelLayout = AV_CHANNEL_LAYOUT_STEREO; // 声道布局
+    AVSampleFormat sampleFormat = AV_SAMPLE_FMT_FLTP; // 采样格式
+    int frameSize = 1024;                           // 帧大小
+    std::string profile = "";                       // 编码配置文件
+    
+    AudioEncoderParams() {
+        type = MediaType::AUDIO;
+        codecName = "aac";  // 默认使用AAC编码器
+    }
+};
+
+/**
+ * 音频重采样器
+ */
+class AudioResampler {
+public:
+    AudioResampler();
+    ~AudioResampler();
+    
+    /**
+     * 初始化重采样器
+     */
+    bool init(const AVChannelLayout& srcLayout, AVSampleFormat srcFormat, int srcSampleRate,
+              const AVChannelLayout& dstLayout, AVSampleFormat dstFormat, int dstSampleRate);
+    
+    /**
+     * 重采样音频帧
+     */
+    AVFramePtr resample(const AVFramePtr& srcFrame);
+    
+    /**
+     * 刷新重采样器缓冲区
+     */
+    std::vector<AVFramePtr> flush();
+    
+    /**
+     * 获取输出帧大小
+     */
+    int getOutputFrameSize() const { return dstFrameSize_; }
+    
+private:
+    struct SwrContext* swrCtx_;
+    AVChannelLayout srcLayout_;
+    AVChannelLayout dstLayout_;
+    AVSampleFormat srcFormat_;
+    AVSampleFormat dstFormat_;
+    int srcSampleRate_;
+    int dstSampleRate_;
+    int dstFrameSize_;
+    AVFramePtr dstFrame_;
+    bool initialized_;
+};
+
+/**
+ * 音频编码器实现
+ */
+class AudioEncoder : public AbstractEncoder {
+public:
+    AudioEncoder();
+    ~AudioEncoder() override;
+
+    // AbstractCodec 接口实现
+    ErrorCode open(const CodecParams& params) override;
+    void close() override;
+    ErrorCode flush() override;
+
+    // AbstractEncoder 接口实现
+    ErrorCode encode(const AVFramePtr& frame, std::vector<AVPacketPtr>& packets) override;
+    ErrorCode finishEncode(std::vector<AVPacketPtr>& packets) override;
+
+    // 音频编码器特有功能
+    const AudioEncoderParams& getAudioParams() const { return audioParams_; }
+    
+    // 获取支持的编码器列表
+    static std::vector<std::string> getSupportedEncoders();
+    
+    // 获取推荐的编码器
+    static std::string getRecommendedEncoder();
+    
+    // 检查编码器是否支持指定的采样格式
+    static bool isSampleFormatSupported(const std::string& codecName, AVSampleFormat format);
+    
+    // 检查编码器是否支持指定的采样率
+    static bool isSampleRateSupported(const std::string& codecName, int sampleRate);
+    
+    // 检查编码器是否支持指定的声道布局
+    static bool isChannelLayoutSupported(const std::string& codecName, const AVChannelLayout& layout);
+
+protected:
+    bool validateParams(const CodecParams& params) override;
+
+private:
+    // 初始化编码器
+    ErrorCode initEncoder();
+    
+    // 设置编码器参数
+    ErrorCode setupEncoderParams();
+    
+    // 设置声道布局
+    ErrorCode setupChannelLayout();
+    
+    // 转换音频帧格式
+    AVFramePtr convertFrame(const AVFramePtr& frame);
+    
+    // 编码单个帧
+    ErrorCode encodeFrame(const AVFramePtr& frame, std::vector<AVPacketPtr>& packets);
+    
+    // 接收编码后的包
+    ErrorCode receivePackets(std::vector<AVPacketPtr>& packets);
+    
+    // 获取编码器支持的最佳采样格式
+    AVSampleFormat getBestSampleFormat() const;
+    
+    // 获取编码器支持的最佳采样率
+    int getBestSampleRate() const;
+    
+    // 查找可用的编码器
+    static void findSupportedEncoders();
+
+private:
+    AudioEncoderParams audioParams_;        // 音频编码参数
+    
+    // 音频重采样
+    std::unique_ptr<AudioResampler> resampler_;
+    AVFramePtr convertedFrame_;             // 转换后的帧
+    
+    // 线程安全
+    std::mutex encodeMutex_;
+    
+    // 支持的编码器列表
+    static std::vector<std::string> supportedEncoders_;
+    static std::once_flag encodersInitFlag_;
+    
+    // 常用音频编码器
+    static constexpr const char* AUDIO_ENCODERS[] = {
+        "aac",
+        "libfdk_aac",
+        "mp3",
+        "libmp3lame",
+        "opus",
+        "libopus",
+        "vorbis",
+        "libvorbis",
+        "flac",
+        "pcm_s16le",
+        "pcm_s24le",
+        "pcm_s32le",
+    };
+};
+
+/**
+ * 音频编码器工厂
+ */
+class AudioEncoderFactory {
+public:
+    /**
+     * 创建音频编码器
+     */
+    static std::unique_ptr<AudioEncoder> create(const std::string& codecName = "");
+    
+    /**
+     * 创建最佳音频编码器(自动选择)
+     */
+    static std::unique_ptr<AudioEncoder> createBest();
+    
+    /**
+     * 创建无损音频编码器
+     */
+    static std::unique_ptr<AudioEncoder> createLossless();
+};
+
+} // namespace codec
+} // namespace av

+ 797 - 0
AV/code/codec/codec_video_encoder.cpp

@@ -0,0 +1,797 @@
+#include "codec_video_encoder.h"
+#include "../base/logger.h"
+#include <algorithm>
+#include <chrono>
+
+extern "C" {
+#include <libswscale/swscale.h>
+#include <libavutil/imgutils.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_ERROR("创建像素格式转换器失败");
+        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;
+    }
+    
+    // 复制帧数据
+    if (av_frame_ref(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_ARGUMENT;
+    }
+    
+    videoParams_ = static_cast<const VideoEncoderParams&>(params);
+    params_ = params;
+    
+    ErrorCode result = initEncoder();
+    if (result != ErrorCode::OK) {
+        close();
+        return result;
+    }
+    
+    setState(CodecState::OPENED);
+    AV_LOGGER_INFOF("视频编码器已打开: {} ({}x{} @ {}fps)", 
+                 videoParams_.codecName, videoParams_.width, 
+                 videoParams_.height, videoParams_.fps);
+    
+    return ErrorCode::OK;
+}
+
+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::OK;
+}
+
+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::OK, 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_ARGUMENT;
+    }
+    
+    // 创建编码上下文
+    codecCtx_ = makeAVCodecContext(codec_);
+    if (!codecCtx_) {
+        AV_LOGGER_ERROR("分配编码上下文失败");
+        return ErrorCode::OUT_OF_MEMORY;
+    }
+    
+    // 设置硬件加速
+    if (videoParams_.hardwareAccel && isHardwareEncoder(videoParams_.codecName)) {
+        ErrorCode result = setupHardwareAcceleration();
+        if (result != ErrorCode::OK) {
+            AV_LOGGER_WARNING("硬件加速设置失败,回退到软件编码");
+            isHardwareEncoder_ = false;
+            
+            // 清理硬件资源
+            if (hwDeviceCtx_) {
+                av_buffer_unref(&hwDeviceCtx_);
+                hwDeviceCtx_ = nullptr;
+            }
+        }
+    }
+    
+    // 设置编码器参数(在硬件加速设置之后)
+    ErrorCode result = setupEncoderParams();
+    if (result != ErrorCode::OK) {
+        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::OK;
+}
+
+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("设置preset=medium: {}", ret == 0 ? "成功" : "失败");
+        
+        ret = av_opt_set(codecCtx_->priv_data, "profile", "main", 0);
+        AV_LOGGER_INFOF("设置profile=main: {}", ret == 0 ? "成功" : "失败");
+        
+        ret = av_opt_set(codecCtx_->priv_data, "rc", "vbr", 0);
+        AV_LOGGER_INFOF("设置rc=vbr: {}", ret == 0 ? "成功" : "失败");
+        
+        ret = av_opt_set_int(codecCtx_->priv_data, "surfaces", 16, 0);
+        AV_LOGGER_INFOF("设置surfaces=16: {}", ret == 0 ? "成功" : "失败");
+        
+        ret = av_opt_set_int(codecCtx_->priv_data, "delay", 0, 0);
+        AV_LOGGER_INFOF("设置delay=0: {}", ret == 0 ? "成功" : "失败");
+        
+        if (videoParams_.lowLatency) {
+            AV_LOGGER_INFO("启用低延迟模式");
+            ret = av_opt_set(codecCtx_->priv_data, "preset", "fast", 0);
+            AV_LOGGER_INFOF("设置preset=fast: {}", ret == 0 ? "成功" : "失败");
+            
+            ret = av_opt_set(codecCtx_->priv_data, "tune", "ll", 0);
+            AV_LOGGER_INFOF("设置tune=ll: {}", ret == 0 ? "成功" : "失败");
+        }
+    } 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::OK;
+}
+
+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::OUT_OF_MEMORY;
+    }
+    
+    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::OK;
+}
+
+AVFramePtr VideoEncoder::convertFrame(const AVFramePtr& frame) {
+    if (!frame) {
+        return nullptr;
+    }
+    
+    AVPixelFormat targetFormat;
+    if (isHardwareEncoder_) {
+        // 硬件编码器统一使用NV12格式,与硬件帧上下文保持一致
+        targetFormat = AV_PIX_FMT_NV12;
+    } else {
+        targetFormat = videoParams_.pixelFormat;
+    }
+    
+    // 如果格式已经匹配,创建新帧返回
+    if (frame->format == targetFormat) {
+        // 创建一个新的帧来返回,避免拷贝构造
+        AVFramePtr resultFrame = makeAVFrame();
+        if (!resultFrame) {
+            return nullptr;
+        }
+        
+        // 复制帧数据
+        if (av_frame_ref(resultFrame.get(), frame.get()) < 0) {
+            return nullptr;
+        }
+        
+        return resultFrame;
+    }
+    
+    // 创建转换器
+    if (!converter_ || 
+        converter_->srcFormat_ != static_cast<AVPixelFormat>(frame->format) ||
+        converter_->dstFormat_ != targetFormat) {
+        converter_ = std::make_unique<PixelFormatConverter>(
+            static_cast<AVPixelFormat>(frame->format), targetFormat);
+    }
+    
+    return converter_->convert(frame);
+}
+
+AVFramePtr VideoEncoder::transferToHardware(const AVFramePtr& frame) {
+    if (!isHardwareEncoder_ || !frame) {
+        // 创建一个新的帧来返回,避免拷贝构造
+        if (frame) {
+            AVFramePtr resultFrame = makeAVFrame();
+            if (!resultFrame) {
+                return nullptr;
+            }
+            
+            // 复制帧数据
+            if (av_frame_ref(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::OUT_OF_MEMORY;
+        }
+        
+        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::OK;
+}
+
+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

+ 178 - 0
AV/code/codec/codec_video_encoder.h

@@ -0,0 +1,178 @@
+#pragma once
+
+#include "codec_abstract_codec.h"
+#include "../base/media_common.h"
+#include <mutex>
+#include <memory>
+
+extern "C" {
+#include <libavcodec/avcodec.h>
+#include <libavutil/hwcontext.h>
+#include <libavutil/opt.h>
+#include <libavformat/avformat.h>
+}
+
+namespace av {
+namespace codec {
+
+/**
+ * 视频编码器参数
+ */
+struct VideoEncoderParams : public CodecParams {
+    int bitRate = 2000000;          // 比特率 (bps)
+    int width = 1920;               // 宽度
+    int height = 1080;              // 高度
+    int fps = 30;                   // 帧率
+    int gopSize = 30;               // GOP大小
+    int maxBFrames = 0;             // B帧数量
+    std::string preset = "medium";  // 编码预设
+    std::string tune = "";          // 调优参数
+    bool lowLatency = false;        // 低延迟模式
+    bool hardwareAccel = true;      // 硬件加速
+    AVPixelFormat pixelFormat = AV_PIX_FMT_YUV420P; // 像素格式
+    
+    VideoEncoderParams() {
+        type = MediaType::VIDEO;
+    }
+};
+
+/**
+ * 像素格式转换器
+ */
+class PixelFormatConverter {
+    friend class VideoEncoder;
+    
+public:
+    PixelFormatConverter(AVPixelFormat srcFormat, AVPixelFormat dstFormat);
+    ~PixelFormatConverter();
+    
+    bool setSize(int width, int height);
+    AVFramePtr convert(const AVFramePtr& srcFrame);
+    
+private:
+    struct SwsContext* swsCtx_;
+    AVPixelFormat srcFormat_;
+    AVPixelFormat dstFormat_;
+    int width_;
+    int height_;
+    AVFramePtr dstFrame_;
+};
+
+/**
+ * 视频编码器实现
+ */
+class VideoEncoder : public AbstractEncoder {
+public:
+    VideoEncoder();
+    ~VideoEncoder() override;
+
+    // AbstractCodec 接口实现
+    ErrorCode open(const CodecParams& params) override;
+    void close() override;
+    ErrorCode flush() override;
+
+    // AbstractEncoder 接口实现
+    ErrorCode encode(const AVFramePtr& frame, std::vector<AVPacketPtr>& packets) override;
+    ErrorCode finishEncode(std::vector<AVPacketPtr>& packets) override;
+
+    // 视频编码器特有功能
+    const VideoEncoderParams& getVideoParams() const { return videoParams_; }
+    
+    // 获取支持的编码器列表
+    static std::vector<std::string> getSupportedEncoders();
+    
+    // 检查编码器是否支持硬件加速
+    static bool isHardwareEncoder(const std::string& codecName);
+    
+    // 获取推荐的编码器
+    static std::string getRecommendedEncoder();
+    
+    // 硬件编码器名称
+    static constexpr const char* HARDWARE_ENCODERS[] = {
+        "h264_nvenc",   // NVIDIA
+        "h264_qsv",     // Intel Quick Sync
+        "h264_amf",     // AMD
+        "h264_videotoolbox", // Apple
+    };
+    
+    // 软件编码器名称
+    static constexpr const char* SOFTWARE_ENCODERS[] = {
+        "libx264",
+        "libx265",
+    };
+
+protected:
+    bool validateParams(const CodecParams& params) override;
+
+private:
+    // 初始化编码器
+    ErrorCode initEncoder();
+    
+    // 设置编码器参数
+    ErrorCode setupEncoderParams();
+    
+    // 设置硬件加速
+    ErrorCode setupHardwareAcceleration();
+    
+    // 设置硬件帧上下文
+    ErrorCode setupHardwareFrameContext();
+    
+    // 转换帧格式
+    AVFramePtr convertFrame(const AVFramePtr& frame);
+    
+    // 转换到硬件帧
+    AVFramePtr transferToHardware(const AVFramePtr& frame);
+    
+    // 编码单个帧
+    ErrorCode encodeFrame(const AVFramePtr& frame, std::vector<AVPacketPtr>& packets);
+    
+    // 接收编码后的包
+    ErrorCode receivePackets(std::vector<AVPacketPtr>& packets);
+    
+    // 获取硬件设备类型
+    AVHWDeviceType getHardwareDeviceType() const;
+    
+    // 获取硬件像素格式
+    AVPixelFormat getHardwarePixelFormat() const;
+    
+    // 查找可用的编码器
+    static void findUsableEncoders();
+
+private:
+    VideoEncoderParams videoParams_;        // 视频编码参数
+    
+    // 硬件加速相关
+    bool isHardwareEncoder_;                // 是否硬件编码器
+    AVBufferRef* hwDeviceCtx_;              // 硬件设备上下文
+    AVFramePtr hwFrame_;                    // 硬件帧缓冲
+    
+    // 格式转换
+    std::unique_ptr<PixelFormatConverter> converter_;
+    AVFramePtr convertedFrame_;             // 转换后的帧
+    
+    // 线程安全
+    std::mutex encodeMutex_;
+    
+    // 支持的编码器列表
+    static std::vector<std::string> supportedEncoders_;
+    static std::once_flag encodersInitFlag_;
+};
+
+/**
+ * 视频编码器工厂
+ */
+class VideoEncoderFactory {
+public:
+    /**
+     * 创建视频编码器
+     */
+    static std::unique_ptr<VideoEncoder> create(const std::string& codecName = "");
+    
+    /**
+     * 创建最佳视频编码器(自动选择硬件/软件)
+     */
+    static std::unique_ptr<VideoEncoder> createBest(bool preferHardware = true);
+};
+
+} // namespace codec
+} // namespace av

+ 156 - 0
AV/test_basic.cpp

@@ -0,0 +1,156 @@
+// 基础设施测试程序
+#include "code/base/logger.h"
+#include "code/base/media_thread_base.h"
+#include "code/base/media_common.h"
+#include <iostream>
+#include <thread>
+#include <chrono>
+
+using namespace av;
+
+// 测试线程类
+class TestThread : public ThreadBase {
+public:
+    TestThread() {
+        setThreadName("TestThread");
+    }
+    
+protected:
+    void run() override {
+        AV_LOGGER_INFO("Test thread started");
+        
+        for (int i = 0; i < 10 && !shouldExit(); ++i) {
+            AV_LOGGER_INFOF("Test thread iteration: {}", i);
+            
+            if (!waitForMs(100)) {
+                break; // 收到退出信号
+            }
+        }
+        
+        AV_LOGGER_INFO("Test thread finished");
+    }
+};
+
+int main() {
+    std::cout << "=== AV基础设施测试 ===" << std::endl;
+    
+    // 1. 测试日志系统
+    std::cout << "1. 测试日志系统..." << std::endl;
+    Logger::initialize("test_log.txt", LogLevel::DEBUG, false, true);
+
+    AV_LOGGER_DEBUG("这是一条调试信息");
+    AV_LOGGER_INFO("这是一条信息");
+    AV_LOGGER_WARNING("这是一条警告");
+    AV_LOGGER_ERROR("这是一条错误");
+    
+    AV_LOGGER_INFOF("格式化日志测试: {} + {} = {}", 1, 2, 3);
+    
+    // 2. 测试时间工具
+    std::cout << "2. 测试时间工具..." << std::endl;
+    {
+        AV_SCOPED_TIMER("测试代码块");
+        std::this_thread::sleep_for(std::chrono::milliseconds(50));
+    }
+    
+    time_utils::Timer timer;
+    timer.start();
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+    timer.stop();
+    AV_LOGGER_INFOF("计时器测试: {} ms", timer.elapsedMs());
+    
+    // 3. 测试字符串工具
+    std::cout << "3. 测试字符串工具..." << std::endl;
+    std::string testStr = "  Hello, World!  ";
+    AV_LOGGER_INFOF("原始字符串: '{}'", testStr);
+    AV_LOGGER_INFOF("修剪后: '{}'", string_utils::trim(testStr));
+    AV_LOGGER_INFOF("转大写: '{}'", string_utils::toUpper(testStr));
+    
+    auto parts = string_utils::split("a,b,c,d", ',');
+    AV_LOGGER_INFOF("分割结果数量: {}", parts.size());
+    
+    // 4. 测试路径工具
+    std::cout << "4. 测试路径工具..." << std::endl;
+    std::string path = "C:/test/file.txt";
+    AV_LOGGER_INFOF("路径: {}", path);
+    AV_LOGGER_INFOF("目录: {}", path_utils::getDirectory(path));
+    AV_LOGGER_INFOF("文件名: {}", path_utils::getFilename(path));
+    AV_LOGGER_INFOF("扩展名: {}", path_utils::getExtension(path));
+    
+    // 5. 测试线程基类
+    std::cout << "5. 测试线程基类..." << std::endl;
+    {
+        TestThread testThread;
+        
+        testThread.setOnStarted([]() {
+            AV_LOGGER_INFO("线程启动回调被调用");
+        });
+        
+        testThread.setOnFinished([]() {
+            AV_LOGGER_INFO("线程完成回调被调用");
+        });
+        
+        AV_LOGGER_INFO("启动测试线程...");
+        if (testThread.start()) {
+            AV_LOGGER_INFO("测试线程启动成功");
+            
+            // 让线程运行一段时间
+            std::this_thread::sleep_for(std::chrono::milliseconds(300));
+            
+            AV_LOGGER_INFO("停止测试线程...");
+            testThread.stop();
+            testThread.join();
+            
+            AV_LOGGER_INFO("测试线程已停止");
+        } else {
+            AV_LOGGER_ERROR("测试线程启动失败");
+        }
+    }
+    
+    // 6. 测试工作线程
+    std::cout << "6. 测试工作线程..." << std::endl;
+    {
+        int counter = 0;
+        auto worker = makeWorkerThread([&counter]() {
+            counter++;
+            AV_LOGGER_INFOF("工作线程计数: {}", counter);
+        }, 50);
+        
+        worker->setThreadName("WorkerThread");
+        worker->start();
+        
+        std::this_thread::sleep_for(std::chrono::milliseconds(200));
+        
+        worker->stop();
+        worker->join();
+        
+        AV_LOGGER_INFOF("工作线程最终计数: {}", counter);
+    }
+    
+    // 7. 测试内存池
+    std::cout << "7. 测试内存池..." << std::endl;
+    {
+        memory_utils::MemoryPool pool(64, 10);
+        
+        std::vector<void*> ptrs;
+        for (int i = 0; i < 5; ++i) {
+            void* ptr = pool.allocate();
+            if (ptr) {
+                ptrs.push_back(ptr);
+                AV_LOGGER_INFOF("分配内存块 {}", i);
+            }
+        }
+        
+        AV_LOGGER_INFOF("剩余可用块: {}", pool.getAvailableBlocks());
+        
+        for (void* ptr : ptrs) {
+            pool.deallocate(ptr);
+        }
+        
+        AV_LOGGER_INFOF("释放后可用块: {}", pool.getAvailableBlocks());
+    }
+    
+    AV_LOGGER_INFO("=== 所有测试完成 ===");
+    std::cout << "测试完成,请查看 test_log.txt 文件" << std::endl;
+    
+    return 0;
+}

+ 207 - 0
AV/test_codec.cpp

@@ -0,0 +1,207 @@
+// 编解码测试程序
+#include "code/base/logger.h"
+#include "code/codec/codec_video_encoder.h"
+#include "code/codec/codec_audio_encoder.h"
+#include <iostream>
+#include <chrono>
+#include <thread>
+
+using namespace av;
+using namespace av::codec;
+
+int main() {
+    AV_LOGGER_INFO("=== AV编解码测试 ===");
+    
+    // 初始化日志系统
+    Logger::initialize("codec_test_log.txt", LogLevel::DEBUG, false, true);
+
+    // 初始化FFmpeg
+    ffmpeg_utils::initializeFFmpeg();
+    
+    try {
+        // 1. 测试视频编码器支持
+        AV_LOGGER_INFO("1. 测试视频编码器支持...");
+        auto videoEncoders = VideoEncoder::getSupportedEncoders();
+        AV_LOGGER_INFOF("支持的视频编码器数量: {}", videoEncoders.size());
+        
+        for (const auto& encoder : videoEncoders) {
+            AV_LOGGER_INFOF("  - {} (硬件: {})", encoder, 
+                         VideoEncoder::isHardwareEncoder(encoder) ? "是" : "否");
+        }
+        
+        std::string recommendedVideo = VideoEncoder::getRecommendedEncoder();
+        AV_LOGGER_INFOF("推荐的视频编码器: {}", recommendedVideo);
+        
+        // 2. 测试音频编码器支持
+        AV_LOGGER_INFO("2. 测试音频编码器支持...");
+        auto audioEncoders = AudioEncoder::getSupportedEncoders();
+        AV_LOGGER_INFOF("支持的音频编码器数量: {}", audioEncoders.size());
+        
+        for (const auto& encoder : audioEncoders) {
+            AV_LOGGER_INFOF("  - {}", encoder);
+        }
+        
+        std::string recommendedAudio = AudioEncoder::getRecommendedEncoder();
+        AV_LOGGER_INFOF("推荐的音频编码器: {}", recommendedAudio);
+        
+        // 3. 测试视频编码器创建和配置
+        AV_LOGGER_INFO("3. 测试视频编码器创建...");
+        if (!recommendedVideo.empty()) {
+            auto videoEncoder = VideoEncoderFactory::create(recommendedVideo);
+            if (videoEncoder) {
+                AV_LOGGER_INFO("视频编码器创建成功");
+                
+                // 配置编码器参数
+                VideoEncoderParams videoParams;
+                videoParams.codecName = recommendedVideo;
+                videoParams.width = 1280;
+                videoParams.height = 720;
+                videoParams.fps = 30;
+                videoParams.bitRate = 2000000;
+                videoParams.lowLatency = true;
+                videoParams.hardwareAccel = true;  // 启用硬件加速
+                
+                AVResult result = videoEncoder->open(videoParams);
+                if (result == AVResult::OK) {
+                    AV_LOGGER_INFO("视频编码器打开成功");
+                    
+                    // 测试编码器状态
+                    AV_LOGGER_INFOF("编码器状态: {}", static_cast<int>(videoEncoder->getState()));
+                    AV_LOGGER_INFOF("是否已打开: {}", videoEncoder->isOpened() ? "是" : "否");
+                    
+                    videoEncoder->close();
+                    AV_LOGGER_INFO("视频编码器已关闭");
+                } else {
+                    AV_LOGGER_ERRORF("硬件视频编码器打开失败: {}", static_cast<int>(result));
+                    
+                    // 尝试软件编码器
+                    AV_LOGGER_INFO("尝试使用软件编码器...");
+                    videoParams.hardwareAccel = false;
+                    videoParams.codecName = "libx264";
+                    
+                    auto softwareEncoder = VideoEncoderFactory::create("libx264");
+                    if (softwareEncoder) {
+                        AVResult softResult = softwareEncoder->open(videoParams);
+                        if (softResult == AVResult::OK) {
+                            AV_LOGGER_INFO("软件视频编码器打开成功");
+                            softwareEncoder->close();
+                            AV_LOGGER_INFO("软件视频编码器已关闭");
+                        } else {
+                            AV_LOGGER_ERRORF("软件视频编码器打开失败: {}", static_cast<int>(softResult));
+                        }
+                    }
+                }
+            } else {
+                AV_LOGGER_ERROR("视频编码器创建失败");
+            }
+        } else {
+            AV_LOGGER_WARNING("没有可用的视频编码器");
+        }
+        
+        // 4. 测试音频编码器创建和配置
+        AV_LOGGER_INFO("4. 测试音频编码器创建...");
+        if (!recommendedAudio.empty()) {
+            auto audioEncoder = AudioEncoderFactory::create(recommendedAudio);
+            if (audioEncoder) {
+                AV_LOGGER_INFO("音频编码器创建成功");
+                
+                // 配置编码器参数
+                AudioEncoderParams audioParams;
+                audioParams.codecName = recommendedAudio;
+                audioParams.sampleRate = 44100;
+                audioParams.channels = 2;
+                audioParams.bitRate = 128000;
+                av_channel_layout_default(&audioParams.channelLayout, 2);
+                
+                AVResult result = audioEncoder->open(audioParams);
+                if (result == AVResult::OK) {
+                    AV_LOGGER_INFO("音频编码器打开成功");
+                    
+                    // 测试编码器状态
+                    AV_LOGGER_INFOF("编码器状态: {}", static_cast<int>(audioEncoder->getState()));
+                    AV_LOGGER_INFOF("是否已打开: {}", audioEncoder->isOpened() ? "是" : "否");
+                    
+                    audioEncoder->close();
+                    AV_LOGGER_INFO("音频编码器已关闭");
+                } else {
+                    AV_LOGGER_ERRORF("音频编码器打开失败: {}", static_cast<int>(result));
+                }
+            } else {
+                AV_LOGGER_ERROR("音频编码器创建失败");
+            }
+        } else {
+            AV_LOGGER_WARNING("没有可用的音频编码器");
+        }
+        
+        // 5. 测试编码器工厂
+        AV_LOGGER_INFO("5. 测试编码器工厂...");
+        
+        // 测试最佳视频编码器
+        auto bestVideoEncoder = VideoEncoderFactory::createBest(true);
+        if (bestVideoEncoder) {
+            AV_LOGGER_INFO("最佳视频编码器创建成功(硬件优先)");
+        }
+        
+        auto softwareVideoEncoder = VideoEncoderFactory::createBest(false);
+        if (softwareVideoEncoder) {
+            AV_LOGGER_INFO("最佳视频编码器创建成功(软件优先)");
+        }
+        
+        // 测试最佳音频编码器
+        auto bestAudioEncoder = AudioEncoderFactory::createBest();
+        if (bestAudioEncoder) {
+            AV_LOGGER_INFO("最佳音频编码器创建成功");
+        }
+        
+        // 测试无损音频编码器
+        auto losslessAudioEncoder = AudioEncoderFactory::createLossless();
+        if (losslessAudioEncoder) {
+            AV_LOGGER_INFO("无损音频编码器创建成功");
+        }
+        
+        // 6. 测试编码器能力查询
+        AV_LOGGER_INFO("6. 测试编码器能力查询...");
+        
+        // 测试音频编码器能力
+        if (!recommendedAudio.empty()) {
+            bool supportsFLTP = AudioEncoder::isSampleFormatSupported(recommendedAudio, AV_SAMPLE_FMT_FLTP);
+            bool supports44100 = AudioEncoder::isSampleRateSupported(recommendedAudio, 44100);
+            
+            AVChannelLayout stereoLayout = AV_CHANNEL_LAYOUT_STEREO;
+            bool supportsStereo = AudioEncoder::isChannelLayoutSupported(recommendedAudio, stereoLayout);
+            
+            AV_LOGGER_INFOF("编码器 {} 支持:", recommendedAudio);
+            AV_LOGGER_INFOF("  - FLTP格式: {}", supportsFLTP ? "是" : "否");
+            AV_LOGGER_INFOF("  - 44100Hz: {}", supports44100 ? "是" : "否");
+            AV_LOGGER_INFOF("  - 立体声: {}", supportsStereo ? "是" : "否");
+        }
+        
+        // 7. 测试编码器统计信息
+        AV_LOGGER_INFO("7. 测试编码器统计信息...");
+        if (!recommendedVideo.empty()) {
+            auto encoder = VideoEncoderFactory::create(recommendedVideo);
+            if (encoder) {
+                const auto& stats = encoder->getStatistics();
+                AV_LOGGER_INFOF("编码器统计信息:");
+                AV_LOGGER_INFOF("  - 处理帧数: {}", stats.processedFrames);
+                AV_LOGGER_INFOF("  - 丢弃帧数: {}", stats.droppedFrames);
+                AV_LOGGER_INFOF("  - 错误次数: {}", stats.errorCount);
+                AV_LOGGER_INFOF("  - 平均处理时间: {:.2f}ms", stats.avgProcessTime);
+                AV_LOGGER_INFOF("  - 总字节数: {}", stats.totalBytes);
+            }
+        }
+
+        AV_LOGGER_INFO("=== 所有编解码测试完成 ===");
+        AV_LOGGER_INFO("测试完成,请查看 codec_test_log.txt 文件");
+        
+    } catch (const std::exception& e) {
+        AV_LOGGER_ERRORF("测试过程中发生异常: {}", e.what());
+        AV_LOGGER_ERRORF("测试失败: {}", e.what());
+        return 1;
+    }
+    
+    // 清理FFmpeg
+    ffmpeg_utils::cleanupFFmpeg();
+    
+    return 0;
+}

+ 2 - 0
LearningSmartClient.pro

@@ -88,6 +88,8 @@ include($$PWD/fmt.pri)
 include($$PWD/qtpromise/qtpromise.pri)
 include($$PWD/jsonserializer/jsonserializer.pri)
 
+include($$PWD/AV/AV.pri)
+
 
 INCLUDEPATH+="E:/AAA/ffmpeg-7.0.2-full_build-shared/include"
 LIBS+="-LE:/AAA/ffmpeg-7.0.2-full_build-shared/lib"

+ 133 - 133
main.cpp

@@ -1,133 +1,133 @@
-#include "AVPlayer2/mainwindowa.h"
-#include "mainwindow.h"
-#include "thememanager.h"
-#include "themesettingswidget.h"
-
-#include <QApplication>
-#include <QAudioDeviceInfo>
-#include <QAudioOutput>
-#include <QDebug>
-#include <QVBoxLayout>
-#include <qendian.h>
-#include <qmath.h>
-#include <QFile>
-#include <QTextStream>
-#include <QDateTime>
-#include <QMutex>
-#include <QLoggingCategory>
-
-QFile g_logFile;
-QTextStream* g_logStream = nullptr;
-QMutex g_logMutex;
-
-void myMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
-{
-    QMutexLocker locker(&g_logMutex);
-    if (!g_logStream) return;
-
-    QString typeStr;
-    switch (type) {
-    case QtDebugMsg:    typeStr = "DEBUG"; break;
-    case QtWarningMsg:  typeStr = "WARN "; break;
-    case QtCriticalMsg: typeStr = "ERROR"; break;
-    case QtFatalMsg:    typeStr = "FATAL"; break;
-    case QtInfoMsg:
-        break;
-    }
-
-    QString logMsg = QString("%1 [%2] %3 (%4:%5)\n")
-        .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz"))
-        .arg(typeStr)
-        .arg(msg)
-        .arg(QString(context.file ? context.file : ""))
-        .arg(context.line);
-
-    (*g_logStream) << logMsg;
-    g_logStream->flush();
-
-    if (type == QtFatalMsg)
-        abort();
-}
-namespace avrecorder::video { void InitWinRTCapture(); }
-int main(int argc, char* argv[])
-{
-    QLoggingCategory::setFilterRules(QStringLiteral("player.controller.ReadThread=false\n"
-                                                    "player.controller.AudioPlayThread=false\n"));
-    // QLoggingCategory::setFilterRules("*.debug=false\n"
-    //                                  "*.info=false\n"
-    //                                  "*.warning=false\n"
-    //                                  "*.critical=false\n"
-    //                                  "player.controller.*.debug=true\n"
-    //                                  "player.controller.*.info=true\n");
-
-    // 打开日志文件(覆盖模式)
-    g_logFile.setFileName("log.txt");
-    g_logFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate);
-    g_logStream = new QTextStream(&g_logFile);
-
-    // 安装日志处理器
-    //qInstallMessageHandler(myMessageHandler);
-
-    // std::freopen(nullptr, "w", stdout);
-    setvbuf(stdout, nullptr, _IONBF, 0);
-
-#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
-    QGuiApplication::setHighDpiScaleFactorRoundingPolicy(
-        Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
-#endif
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
-    QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
-#endif
-
-    QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
-
-    QApplication a(argc, argv);
-
-    ThemeManager::instance().setThemeMode(ThemeManager::Light);
-
-    // 注册Room 相关的类型 方便 序列化
-    void initRoomType();
-    initRoomType();
-
-    // 初始化wgc
-
-    avrecorder::video::InitWinRTCapture();
-
-    /*
-docker run -itd  --name zlmediakit --restart=always
--p 1935:1935 -p 8080:80 -p 8443:443
--p 8554:554 -p 10000:10000
--p 10000:10000/udp -p 8000:8000/udp
--p 9000:9000/udp
--v /data/zlmediakit/media/bin:/opt/media/bin
--v /data/zlmediakit/media/conf:/opt/media/conf
-zlmediakit/zlmediakit:master
-*/
-    // MainWindow w;
-    // w.show();
-
-    // 视频播放测试
-    MainWindowA aa;
-    aa.show();
-
-    // ThemeSettingsWidget ThemeSettingsWidget;
-    // ThemeSettingsWidget.show();
-
-    // PlayerWindow w;
-    // w.resize(960, 540);
-    // w.show();
-
-    // // 这里填你的流地址
-    // // w.startPlay("http://vd3.bdstatic.com/mda-jennyc5ci1ugrxzi/mda-jennyc5ci1ugrxzi.mp4");
-
-    // w.open("C:/Users/zhuizhu/Videos/1.mp4");
-    // // w.startPlay("rtmp://192.168.3.76:1935/stream/V1/stream");
-
-    int ret = a.exec();
-
-    delete g_logStream;
-    g_logFile.close();
-
-    return ret;
-}
+// #include "AVPlayer2/mainwindowa.h"
+// #include "mainwindow.h"
+// #include "thememanager.h"
+// #include "themesettingswidget.h"
+
+// #include <QApplication>
+// #include <QAudioDeviceInfo>
+// #include <QAudioOutput>
+// #include <QDebug>
+// #include <QVBoxLayout>
+// #include <qendian.h>
+// #include <qmath.h>
+// #include <QFile>
+// #include <QTextStream>
+// #include <QDateTime>
+// #include <QMutex>
+// #include <QLoggingCategory>
+
+// QFile g_logFile;
+// QTextStream* g_logStream = nullptr;
+// QMutex g_logMutex;
+
+// void myMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
+// {
+//     QMutexLocker locker(&g_logMutex);
+//     if (!g_logStream) return;
+
+//     QString typeStr;
+//     switch (type) {
+//     case QtDebugMsg:    typeStr = "DEBUG"; break;
+//     case QtWarningMsg:  typeStr = "WARN "; break;
+//     case QtCriticalMsg: typeStr = "ERROR"; break;
+//     case QtFatalMsg:    typeStr = "FATAL"; break;
+//     case QtInfoMsg:
+//         break;
+//     }
+
+//     QString logMsg = QString("%1 [%2] %3 (%4:%5)\n")
+//         .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz"))
+//         .arg(typeStr)
+//         .arg(msg)
+//         .arg(QString(context.file ? context.file : ""))
+//         .arg(context.line);
+
+//     (*g_logStream) << logMsg;
+//     g_logStream->flush();
+
+//     if (type == QtFatalMsg)
+//         abort();
+// }
+// namespace avrecorder::video { void InitWinRTCapture(); }
+// int main(int argc, char* argv[])
+// {
+//     QLoggingCategory::setFilterRules(QStringLiteral("player.controller.ReadThread=false\n"
+//                                                     "player.controller.AudioPlayThread=false\n"));
+//     // QLoggingCategory::setFilterRules("*.debug=false\n"
+//     //                                  "*.info=false\n"
+//     //                                  "*.warning=false\n"
+//     //                                  "*.critical=false\n"
+//     //                                  "player.controller.*.debug=true\n"
+//     //                                  "player.controller.*.info=true\n");
+
+//     // 打开日志文件(覆盖模式)
+//     g_logFile.setFileName("log.txt");
+//     g_logFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate);
+//     g_logStream = new QTextStream(&g_logFile);
+
+//     // 安装日志处理器
+//     //qInstallMessageHandler(myMessageHandler);
+
+//     // std::freopen(nullptr, "w", stdout);
+//     setvbuf(stdout, nullptr, _IONBF, 0);
+
+// #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
+//     QGuiApplication::setHighDpiScaleFactorRoundingPolicy(
+//         Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
+// #endif
+// #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+//     QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+//     QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
+// #endif
+
+//     QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
+
+//     QApplication a(argc, argv);
+
+//     ThemeManager::instance().setThemeMode(ThemeManager::Light);
+
+//     // 注册Room 相关的类型 方便 序列化
+//     void initRoomType();
+//     initRoomType();
+
+//     // 初始化wgc
+
+//     avrecorder::video::InitWinRTCapture();
+
+//     /*
+// docker run -itd  --name zlmediakit --restart=always
+// -p 1935:1935 -p 8080:80 -p 8443:443
+// -p 8554:554 -p 10000:10000
+// -p 10000:10000/udp -p 8000:8000/udp
+// -p 9000:9000/udp
+// -v /data/zlmediakit/media/bin:/opt/media/bin
+// -v /data/zlmediakit/media/conf:/opt/media/conf
+// zlmediakit/zlmediakit:master
+// */
+//     // MainWindow w;
+//     // w.show();
+
+//     // 视频播放测试
+//     MainWindowA aa;
+//     aa.show();
+
+//     // ThemeSettingsWidget ThemeSettingsWidget;
+//     // ThemeSettingsWidget.show();
+
+//     // PlayerWindow w;
+//     // w.resize(960, 540);
+//     // w.show();
+
+//     // // 这里填你的流地址
+//     // // w.startPlay("http://vd3.bdstatic.com/mda-jennyc5ci1ugrxzi/mda-jennyc5ci1ugrxzi.mp4");
+
+//     // w.open("C:/Users/zhuizhu/Videos/1.mp4");
+//     // // w.startPlay("rtmp://192.168.3.76:1935/stream/V1/stream");
+
+//     int ret = a.exec();
+
+//     delete g_logStream;
+//     g_logFile.close();
+
+//     return ret;
+// }