test_player_stress.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #include <QApplication>
  2. #include <QDebug>
  3. #include <QTimer>
  4. #include <QThread>
  5. #include <chrono>
  6. #include <thread>
  7. #include "AVPlayer2/PlayWidget.h"
  8. #include "AVPlayer2/playercontroller.h"
  9. /**
  10. * @brief 压力测试PlayerController的线程安全性
  11. *
  12. * 这个测试程序验证PlayerController在暴力调用startToPlay时的稳定性
  13. */
  14. class PlayerStressTest : public QObject
  15. {
  16. Q_OBJECT
  17. public:
  18. explicit PlayerStressTest(QObject* parent = nullptr)
  19. : QObject(parent)
  20. , m_playWidget(new PlayWidget)
  21. {
  22. m_playWidget->resize(960, 540);
  23. m_playWidget->show();
  24. }
  25. ~PlayerStressTest()
  26. {
  27. delete m_playWidget;
  28. }
  29. void runStressTest()
  30. {
  31. qDebug() << "开始PlayerController压力测试...";
  32. // 测试1: 快速连续调用
  33. qDebug() << "测试1: 快速连续调用startToPlay (20次)";
  34. for (int i = 0; i < 20; ++i) {
  35. m_playWidget->startToPlay("C:/Users/zhuizhu/Videos/2.mp4");
  36. qDebug() << "调用" << (i + 1) << "/20";
  37. }
  38. // 等待一段时间让请求处理完成
  39. QTimer::singleShot(2000, [this]() {
  40. // 测试2: 多线程并发调用
  41. qDebug() << "测试2: 多线程并发调用startToPlay";
  42. runConcurrentTest();
  43. });
  44. // 测试3: 交替播放和停止
  45. QTimer::singleShot(5000, [this]() {
  46. qDebug() << "测试3: 交替播放和停止";
  47. runAlternatingTest();
  48. });
  49. // 测试4: 不同文件的快速切换
  50. QTimer::singleShot(8000, [this]() {
  51. qDebug() << "测试4: 不同文件的快速切换";
  52. runFileSwitchTest();
  53. });
  54. // 测试完成
  55. QTimer::singleShot(12000, [this]() {
  56. qDebug() << "所有压力测试完成!";
  57. QApplication::quit();
  58. });
  59. }
  60. private:
  61. void runConcurrentTest()
  62. {
  63. // 创建多个线程同时调用startToPlay
  64. std::vector<std::thread> threads;
  65. for (int i = 0; i < 5; ++i) {
  66. threads.emplace_back([this, i]() {
  67. for (int j = 0; j < 10; ++j) {
  68. // 使用QMetaObject::invokeMethod确保在主线程中调用
  69. QMetaObject::invokeMethod(this, [this]() {
  70. m_playWidget->startToPlay("C:/Users/zhuizhu/Videos/2.mp4");
  71. }, Qt::QueuedConnection);
  72. std::this_thread::sleep_for(std::chrono::milliseconds(10));
  73. }
  74. });
  75. }
  76. // 等待所有线程完成
  77. for (auto& thread : threads) {
  78. thread.join();
  79. }
  80. qDebug() << "并发测试完成";
  81. }
  82. void runAlternatingTest()
  83. {
  84. // 交替调用播放和停止
  85. for (int i = 0; i < 10; ++i) {
  86. m_playWidget->startToPlay("C:/Users/zhuizhu/Videos/2.mp4");
  87. QTimer::singleShot(100, [this]() {
  88. // 假设PlayWidget有stopPlay方法,如果没有可以通过PlayerController调用
  89. // m_playWidget->stopPlay();
  90. });
  91. std::this_thread::sleep_for(std::chrono::milliseconds(200));
  92. }
  93. qDebug() << "交替测试完成";
  94. }
  95. void runFileSwitchTest()
  96. {
  97. // 快速切换不同文件(如果有多个测试文件的话)
  98. QStringList testFiles = {
  99. "C:/Users/zhuizhu/Videos/2.mp4",
  100. "C:/Users/zhuizhu/Videos/2.mp4", // 重复文件测试去重功能
  101. "C:/Users/zhuizhu/Videos/2.mp4"
  102. };
  103. for (int i = 0; i < 15; ++i) {
  104. QString file = testFiles[i % testFiles.size()];
  105. m_playWidget->startToPlay(file);
  106. qDebug() << "切换到文件:" << file;
  107. std::this_thread::sleep_for(std::chrono::milliseconds(50));
  108. }
  109. qDebug() << "文件切换测试完成";
  110. }
  111. private:
  112. PlayWidget* m_playWidget;
  113. };
  114. int main(int argc, char *argv[])
  115. {
  116. QApplication app(argc, argv);
  117. // 启用详细日志
  118. QLoggingCategory::setFilterRules("player.controller.debug=true");
  119. PlayerStressTest test;
  120. // 延迟启动测试,确保UI完全初始化
  121. QTimer::singleShot(1000, &test, &PlayerStressTest::runStressTest);
  122. return app.exec();
  123. }
  124. #include "test_player_stress.moc"