- 创建基本项目结构和目录 - 添加CMake构建系统 - 实现基础的配置解析功能 - 添加YOLO推理框架支持 - 集成RTSP和视频流处理功能 - 添加性能监控和日志系统
171 lines
5.3 KiB
C++
171 lines
5.3 KiB
C++
#include <gtest/gtest.h>
|
||
#include <filesystem>
|
||
#include "../pipeline/output/video_writer.hpp"
|
||
#include "../pipeline/common/config_parser.hpp"
|
||
|
||
namespace pipeline {
|
||
namespace test {
|
||
|
||
class VideoWriterTest : public ::testing::Test {
|
||
protected:
|
||
void SetUp() override {
|
||
// 创建测试目录
|
||
test_dir_ = "/tmp/test_video_writer";
|
||
if (std::filesystem::exists(test_dir_)) {
|
||
std::filesystem::remove_all(test_dir_);
|
||
}
|
||
std::filesystem::create_directories(test_dir_);
|
||
|
||
// 创建测试帧
|
||
test_frame_ = cv::Mat(480, 640, CV_8UC3, cv::Scalar(0, 255, 0));
|
||
cv::putText(test_frame_, "Test Frame", cv::Point(50, 50),
|
||
cv::FONT_HERSHEY_SIMPLEX, 1.0, cv::Scalar(255, 255, 255), 2);
|
||
}
|
||
|
||
void TearDown() override {
|
||
// 清理测试目录
|
||
if (std::filesystem::exists(test_dir_)) {
|
||
std::filesystem::remove_all(test_dir_);
|
||
}
|
||
}
|
||
|
||
// 创建基本配置
|
||
OutputTargetConfig createConfig(const std::string& name,
|
||
const std::string& codec = "h264") {
|
||
OutputTargetConfig config;
|
||
config.type = "video";
|
||
config.name = name;
|
||
config.path = test_dir_ + "/" + name + ".mp4";
|
||
config.fps = 30;
|
||
config.codec = codec;
|
||
config.bitrate = 4000000;
|
||
return config;
|
||
}
|
||
|
||
std::string test_dir_;
|
||
cv::Mat test_frame_;
|
||
};
|
||
|
||
// 测试初始化
|
||
TEST_F(VideoWriterTest, Initialization) {
|
||
VideoWriter writer;
|
||
auto config = createConfig("test_init");
|
||
|
||
// 测试正常初始化
|
||
EXPECT_TRUE(writer.init(config)); // 应该成功,因为路径有效
|
||
EXPECT_TRUE(writer.isOpened()); // 应该已经打开,因为init时会尝试打开文件
|
||
EXPECT_EQ(writer.getName(), "test_init");
|
||
|
||
// 写入一帧
|
||
EXPECT_TRUE(writer.write(test_frame_));
|
||
EXPECT_TRUE(writer.isOpened());
|
||
|
||
// 测试重复初始化
|
||
EXPECT_TRUE(writer.init(config));
|
||
}
|
||
|
||
// 测试无效路径
|
||
TEST_F(VideoWriterTest, InvalidPath) {
|
||
VideoWriter writer;
|
||
auto config = createConfig("test_invalid");
|
||
config.path = "/invalid/path/test.mp4";
|
||
|
||
// 初始化应该失败,因为路径无效且会立即尝试打开文件
|
||
EXPECT_FALSE(writer.init(config));
|
||
EXPECT_FALSE(writer.isOpened());
|
||
|
||
// 检查错误信息
|
||
std::string error_msg;
|
||
EXPECT_FALSE(writer.getStatus(error_msg));
|
||
EXPECT_FALSE(error_msg.empty());
|
||
}
|
||
|
||
// 测试写入帧
|
||
TEST_F(VideoWriterTest, WriteFrame) {
|
||
VideoWriter writer;
|
||
auto config = createConfig("test_write");
|
||
ASSERT_TRUE(writer.init(config));
|
||
EXPECT_TRUE(writer.isOpened()); // 应该已经打开
|
||
|
||
// 测试写入有效帧
|
||
EXPECT_TRUE(writer.write(test_frame_));
|
||
EXPECT_TRUE(writer.isOpened());
|
||
|
||
// 测试写入空帧
|
||
cv::Mat empty_frame;
|
||
EXPECT_FALSE(writer.write(empty_frame));
|
||
|
||
// 测试写入多帧
|
||
for (int i = 0; i < 10; ++i) {
|
||
EXPECT_TRUE(writer.write(test_frame_));
|
||
}
|
||
|
||
writer.release();
|
||
|
||
// 验证文件是否创建
|
||
EXPECT_TRUE(std::filesystem::exists(config.path));
|
||
EXPECT_GT(std::filesystem::file_size(config.path), 0);
|
||
}
|
||
|
||
// 测试不同编码器
|
||
TEST_F(VideoWriterTest, DifferentCodecs) {
|
||
std::vector<std::string> codecs = {"h264", "mp4v", "mjpg", "xvid"};
|
||
|
||
for (const auto& codec : codecs) {
|
||
VideoWriter writer;
|
||
auto config = createConfig("test_codec_" + codec, codec);
|
||
|
||
ASSERT_TRUE(writer.init(config));
|
||
EXPECT_TRUE(writer.isOpened()); // 初始化后应该是true,因为init时会打开文件
|
||
EXPECT_TRUE(writer.write(test_frame_));
|
||
EXPECT_TRUE(writer.isOpened()); // 写入后仍然是true
|
||
writer.release();
|
||
|
||
EXPECT_TRUE(std::filesystem::exists(config.path));
|
||
EXPECT_GT(std::filesystem::file_size(config.path), 0);
|
||
}
|
||
}
|
||
|
||
// 测试错误处理
|
||
TEST_F(VideoWriterTest, ErrorHandling) {
|
||
VideoWriter writer;
|
||
|
||
// 测试未初始化写入
|
||
EXPECT_FALSE(writer.write(test_frame_));
|
||
|
||
// 测试状态获取
|
||
std::string error_msg;
|
||
EXPECT_FALSE(writer.getStatus(error_msg));
|
||
EXPECT_FALSE(error_msg.empty());
|
||
|
||
// 测试无效编码器
|
||
auto config = createConfig("test_error", "invalid_codec");
|
||
EXPECT_TRUE(writer.init(config)); // 应该成功但使用默认编码器
|
||
EXPECT_TRUE(writer.isOpened()); // 初始化后应该是true,因为init时会打开文件
|
||
}
|
||
|
||
// 测试资源释放
|
||
TEST_F(VideoWriterTest, ResourceCleanup) {
|
||
{
|
||
VideoWriter writer;
|
||
auto config = createConfig("test_cleanup");
|
||
ASSERT_TRUE(writer.init(config));
|
||
EXPECT_TRUE(writer.isOpened()); // 初始化后应该是true,因为init时会打开文件
|
||
EXPECT_TRUE(writer.write(test_frame_));
|
||
EXPECT_TRUE(writer.isOpened()); // 写入后仍然是true
|
||
// writer在这里会自动释放
|
||
}
|
||
|
||
// 测试手动释放
|
||
VideoWriter writer;
|
||
auto config = createConfig("test_manual_cleanup");
|
||
ASSERT_TRUE(writer.init(config));
|
||
EXPECT_TRUE(writer.isOpened()); // 初始化后应该是true,因为init时会打开文件
|
||
EXPECT_TRUE(writer.write(test_frame_));
|
||
EXPECT_TRUE(writer.isOpened()); // 写入后仍然是true
|
||
writer.release();
|
||
EXPECT_FALSE(writer.isOpened()); // 释放后应该是false
|
||
}
|
||
|
||
} // namespace test
|
||
} // namespace pipeline
|