#include "code/codec/codec_audio_encoder.h" #include "code/base/logger.h" #include "code/base/media_common.h" #include #include #include #include #include #include #include using namespace av; using namespace av::codec; /** * 音频编码器测试类 */ class AudioEncoderTester { public: AudioEncoderTester() { Logger::instance().setLevel(LogLevel::DEBUG); Logger::instance().info("=== 音频编码器测试套件 ==="); } /** * 测试基本音频编码功能 */ bool testBasicAudioEncoding() { Logger::instance().info("[测试] 基本音频编码功能..."); try { // 创建音频编码器 auto encoder = AudioEncoderFactory::create("aac"); if (!encoder) { Logger::instance().error("[失败] 无法创建AAC编码器"); return false; } // 设置编码参数 AudioEncoderParams params; params.codecName = "aac"; params.bitRate = 128000; params.sampleRate = 44100; params.channels = 2; params.channelLayout = AV_CHANNEL_LAYOUT_STEREO; params.sampleFormat = AV_SAMPLE_FMT_FLTP; params.frameSize = 1024; // 打开编码器 ErrorCode result = encoder->open(params); if (result != ErrorCode::SUCCESS) { Logger::instance().errorf("[失败] 打开编码器失败: {}", static_cast(result)); return false; } // 创建测试音频帧 AVFramePtr frame = createTestAudioFrame(params); if (!frame) { Logger::instance().error("[失败] 创建测试音频帧失败"); return false; } // 编码音频帧 std::vector packets; result = encoder->encode(frame, packets); if (result != ErrorCode::SUCCESS) { Logger::instance().errorf("[失败] 编码音频帧失败: {}", static_cast(result)); return false; } Logger::instance().infof("[成功] 编码产生了 {} 个数据包", packets.size()); // 关闭编码器 encoder->close(); Logger::instance().info("[成功] 基本音频编码测试通过"); return true; } catch (const std::exception& e) { Logger::instance().errorf("[异常] {}", e.what()); return false; } } /** * 测试多种音频编码器 */ bool testMultipleEncoders() { Logger::instance().info("[测试] 多种音频编码器支持..."); auto supportedEncoders = AudioEncoder::getSupportedEncoders(); Logger::instance().infof("支持的编码器数量: {}", supportedEncoders.size()); if (supportedEncoders.empty()) { Logger::instance().warning("[警告] 没有找到支持的音频编码器"); return false; } int successCount = 0; // 只测试几个主要的编码器,避免实验性编码器导致的问题 std::vector testEncoders = {"aac", "libmp3lame", "libopus", "flac"}; for (const auto& codecName : testEncoders) { // 检查编码器是否在支持列表中 if (std::find(supportedEncoders.begin(), supportedEncoders.end(), codecName) == supportedEncoders.end()) { Logger::instance().infof("跳过不支持的编码器: {}", codecName); continue; } Logger::instance().infof("测试编码器: {}", codecName); try { auto encoder = AudioEncoderFactory::create(codecName); if (!encoder) { Logger::instance().errorf(" [失败] 无法创建编码器: {}", codecName); continue; } AudioEncoderParams params; params.codecName = codecName; params.bitRate = 128000; params.sampleRate = 44100; params.channels = 2; params.channelLayout = AV_CHANNEL_LAYOUT_STEREO; params.sampleFormat = AV_SAMPLE_FMT_FLTP; ErrorCode result = encoder->open(params); if (result == ErrorCode::SUCCESS) { Logger::instance().infof(" [成功] {} 编码器打开成功", codecName); successCount++; } else { Logger::instance().errorf(" [失败] {} 编码器打开失败: {}", codecName, static_cast(result)); } // 确保编码器正确关闭 encoder->close(); encoder.reset(); // 释放编码器资源 } catch (const std::exception& e) { Logger::instance().errorf(" [异常] 测试编码器 {} 时发生异常: {}", codecName, e.what()); } } Logger::instance().infof("成功测试的编码器: {}/{}", successCount, testEncoders.size()); return successCount > 0; } /** * 测试音频重采样功能 */ bool testAudioResampling() { Logger::instance().info("[测试] 音频重采样功能..."); try { AudioResampler resampler; // 设置重采样参数:从48kHz立体声转换为44.1kHz立体声 AVChannelLayout srcLayout = AV_CHANNEL_LAYOUT_STEREO; AVChannelLayout dstLayout = AV_CHANNEL_LAYOUT_STEREO; bool result = resampler.init(srcLayout, AV_SAMPLE_FMT_FLTP, 48000, dstLayout, AV_SAMPLE_FMT_FLTP, 44100); if (!result) { Logger::instance().error("[失败] 初始化重采样器失败"); return false; } // 创建测试音频帧 AudioEncoderParams params; params.sampleRate = 48000; params.channels = 2; params.sampleFormat = AV_SAMPLE_FMT_FLTP; AVFramePtr srcFrame = createTestAudioFrame(params); if (!srcFrame) { Logger::instance().error("[失败] 创建源音频帧失败"); return false; } // 执行重采样 AVFramePtr dstFrame = resampler.resample(srcFrame); if (!dstFrame) { Logger::instance().error("[失败] 音频重采样失败"); return false; } Logger::instance().infof("[成功] 重采样: {}Hz -> {}Hz", srcFrame->sample_rate, dstFrame->sample_rate); Logger::instance().infof("[成功] 样本数: {} -> {}", srcFrame->nb_samples, dstFrame->nb_samples); return true; } catch (const std::exception& e) { Logger::instance().errorf("[异常] {}", e.what()); return false; } } /** * 测试编码器工厂 */ bool testEncoderFactory() { Logger::instance().info("[测试] 编码器工厂功能..."); // 测试创建最佳编码器 auto bestEncoder = AudioEncoderFactory::createBest(); if (!bestEncoder) { Logger::instance().error("[失败] 无法创建最佳编码器"); return false; } Logger::instance().info("[成功] 创建最佳编码器"); // 测试创建无损编码器 auto losslessEncoder = AudioEncoderFactory::createLossless(); if (!losslessEncoder) { Logger::instance().error("[失败] 无法创建无损编码器"); return false; } Logger::instance().info("[成功] 创建无损编码器"); // 测试推荐编码器 std::string recommended = AudioEncoder::getRecommendedEncoder(); if (recommended.empty()) { Logger::instance().error("[失败] 无法获取推荐编码器"); return false; } Logger::instance().infof("[成功] 推荐编码器: {}", recommended); return true; } /** * 测试编码器状态管理 */ bool testEncoderStateManagement() { Logger::instance().info("[测试] 编码器状态管理..."); try { auto encoder = AudioEncoderFactory::create("aac"); if (!encoder) { Logger::instance().error("[失败] 无法创建编码器"); return false; } // 测试初始状态 if (encoder->getState() != CodecState::IDLE) { Logger::instance().error("[失败] 初始状态不正确"); return false; } // 测试打开编码器 AudioEncoderParams params; params.codecName = "aac"; params.bitRate = 128000; params.sampleRate = 44100; params.channels = 2; ErrorCode result = encoder->open(params); if (result != ErrorCode::SUCCESS) { Logger::instance().error("[失败] 打开编码器失败"); return false; } if (encoder->getState() != CodecState::OPENED) { Logger::instance().error("[失败] 打开后状态不正确"); return false; } // 测试关闭编码器 encoder->close(); if (encoder->getState() != CodecState::CLOSED) { Logger::instance().error("[失败] 关闭后状态不正确"); return false; } Logger::instance().info("[成功] 编码器状态管理测试通过"); return true; } catch (const std::exception& e) { Logger::instance().errorf("[异常] {}", e.what()); return false; } } /** * 测试错误处理 */ bool testErrorHandling() { Logger::instance().info("[测试] 错误处理..."); try { // 测试无效编码器名称 auto encoder = AudioEncoderFactory::create("invalid_codec"); if (encoder) { AudioEncoderParams params; params.codecName = "invalid_codec"; ErrorCode result = encoder->open(params); if (result == ErrorCode::SUCCESS) { Logger::instance().error("[失败] 应该拒绝无效编码器"); return false; } } // 测试无效参数 encoder = AudioEncoderFactory::create("aac"); if (encoder) { AudioEncoderParams params; params.codecName = "aac"; params.sampleRate = -1; // 无效采样率 params.channels = 0; // 无效声道数 ErrorCode result = encoder->open(params); if (result == ErrorCode::SUCCESS) { Logger::instance().error("[失败] 应该拒绝无效参数"); return false; } } Logger::instance().info("[成功] 错误处理测试通过"); return true; } catch (const std::exception& e) { Logger::instance().errorf("[异常] {}", e.what()); return false; } } /** * 运行所有测试 */ bool runAllTests() { Logger::instance().info("开始运行音频编码器测试套件..."); bool allPassed = true; allPassed &= testBasicAudioEncoding(); allPassed &= testMultipleEncoders(); allPassed &= testAudioResampling(); allPassed &= testEncoderFactory(); allPassed &= testEncoderStateManagement(); allPassed &= testErrorHandling(); Logger::instance().info("=== 测试结果 ==="); if (allPassed) { Logger::instance().info("[成功] 所有音频编码器测试通过!"); } else { Logger::instance().error("[失败] 部分测试失败!"); } return allPassed; } private: /** * 创建测试音频帧 */ AVFramePtr createTestAudioFrame(const AudioEncoderParams& params) { AVFramePtr frame = makeAVFrame(); if (!frame) { return nullptr; } frame->format = params.sampleFormat; frame->sample_rate = params.sampleRate; frame->nb_samples = params.frameSize > 0 ? params.frameSize : 1024; // 设置声道布局 if (params.channelLayout.nb_channels > 0) { av_channel_layout_copy(&frame->ch_layout, ¶ms.channelLayout); } else { av_channel_layout_default(&frame->ch_layout, params.channels); } // 分配音频缓冲区 int ret = av_frame_get_buffer(frame.get(), 0); if (ret < 0) { return nullptr; } // 填充测试数据(简单的正弦波) fillTestAudioData(frame.get()); return frame; } /** * 填充测试音频数据 */ void fillTestAudioData(AVFrame* frame) { if (frame->format == AV_SAMPLE_FMT_FLTP) { // 浮点平面格式 for (int ch = 0; ch < frame->ch_layout.nb_channels; ch++) { float* data = reinterpret_cast(frame->data[ch]); for (int i = 0; i < frame->nb_samples; i++) { // 生成440Hz正弦波 double t = static_cast(i) / frame->sample_rate; data[i] = static_cast(0.5 * sin(2.0 * M_PI * 440.0 * t)); } } } else if (frame->format == AV_SAMPLE_FMT_S16) { // 16位整数格式 int16_t* data = reinterpret_cast(frame->data[0]); for (int i = 0; i < frame->nb_samples * frame->ch_layout.nb_channels; i++) { double t = static_cast(i / frame->ch_layout.nb_channels) / frame->sample_rate; data[i] = static_cast(16384 * sin(2.0 * M_PI * 440.0 * t)); } } } }; int main() { try { AudioEncoderTester tester; bool success = tester.runAllTests(); return success ? 0 : 1; } catch (const std::exception& e) { Logger::instance().errorf("测试程序异常: {}", e.what()); return 1; } }