test_mfx.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. // This file is part of OpenCV project.
  2. // It is subject to the license terms in the LICENSE file found in the top-level directory
  3. // of this distribution and at http://opencv.org/license.html
  4. #include "test_precomp.hpp"
  5. namespace opencv_test { namespace {
  6. TEST(videoio_mfx, read_invalid)
  7. {
  8. if (!videoio_registry::hasBackend(CAP_INTEL_MFX))
  9. throw SkipTestException("MediaSDK backend was not found");
  10. VideoCapture cap;
  11. ASSERT_NO_THROW(cap.open("nonexistent-file", CAP_INTEL_MFX));
  12. ASSERT_FALSE(cap.isOpened());
  13. Mat img;
  14. ASSERT_NO_THROW(cap >> img);
  15. ASSERT_TRUE(img.empty());
  16. }
  17. TEST(videoio_mfx, write_invalid)
  18. {
  19. if (!videoio_registry::hasBackend(CAP_INTEL_MFX))
  20. throw SkipTestException("MediaSDK backend was not found");
  21. const string filename = cv::tempfile(".264");
  22. VideoWriter writer;
  23. bool res = true;
  24. ASSERT_NO_THROW(res = writer.open(filename, CAP_INTEL_MFX, VideoWriter::fourcc('H', '2', '6', '4'), 1, Size(641, 480), true));
  25. EXPECT_FALSE(res);
  26. EXPECT_FALSE(writer.isOpened());
  27. ASSERT_NO_THROW(res = writer.open(filename, CAP_INTEL_MFX, VideoWriter::fourcc('H', '2', '6', '4'), 1, Size(640, 481), true));
  28. EXPECT_FALSE(res);
  29. EXPECT_FALSE(writer.isOpened());
  30. ASSERT_NO_THROW(res = writer.open(filename, CAP_INTEL_MFX, VideoWriter::fourcc('A', 'B', 'C', 'D'), 1, Size(640, 480), true));
  31. EXPECT_FALSE(res);
  32. EXPECT_FALSE(writer.isOpened());
  33. ASSERT_NO_THROW(res = writer.open(String(), CAP_INTEL_MFX, VideoWriter::fourcc('H', '2', '6', '4'), 1, Size(640, 480), true));
  34. EXPECT_FALSE(res);
  35. EXPECT_FALSE(writer.isOpened());
  36. ASSERT_NO_THROW(res = writer.open(filename, CAP_INTEL_MFX, VideoWriter::fourcc('H', '2', '6', '4'), 0, Size(640, 480), true));
  37. EXPECT_FALSE(res);
  38. EXPECT_FALSE(writer.isOpened());
  39. ASSERT_NO_THROW(res = writer.open(filename, CAP_INTEL_MFX, VideoWriter::fourcc('H', '2', '6', '4'), 30, Size(640, 480), true));
  40. ASSERT_TRUE(res);
  41. ASSERT_TRUE(writer.isOpened());
  42. Mat t;
  43. // write some bad frames
  44. t = Mat(Size(1024, 768), CV_8UC3);
  45. EXPECT_NO_THROW(writer << t);
  46. t = Mat(Size(320, 240), CV_8UC3);
  47. EXPECT_NO_THROW(writer << t);
  48. t = Mat(Size(640, 480), CV_8UC2);
  49. EXPECT_NO_THROW(writer << t);
  50. // cleanup
  51. ASSERT_NO_THROW(writer.release());
  52. remove(filename.c_str());
  53. }
  54. //==================================================================================================
  55. const int FRAME_COUNT = 20;
  56. inline void generateFrame(int i, Mat & frame)
  57. {
  58. ::generateFrame(i, FRAME_COUNT, frame);
  59. }
  60. inline int fourccByExt(const String &ext)
  61. {
  62. if (ext == ".mpeg2")
  63. return VideoWriter::fourcc('M', 'P', 'G', '2');
  64. else if (ext == ".264")
  65. return VideoWriter::fourcc('H', '2', '6', '4');
  66. else if (ext == ".265")
  67. return VideoWriter::fourcc('H', '2', '6', '5');
  68. return -1;
  69. }
  70. //==================================================================================================
  71. typedef tuple<Size, double, const char *> Size_FPS_Ext;
  72. typedef testing::TestWithParam< Size_FPS_Ext > videoio_mfx;
  73. TEST_P(videoio_mfx, read_write_raw)
  74. {
  75. if (!videoio_registry::hasBackend(CAP_INTEL_MFX))
  76. throw SkipTestException("MediaSDK backend was not found");
  77. const Size FRAME_SIZE = get<0>(GetParam());
  78. const double FPS = get<1>(GetParam());
  79. const char *ext = get<2>(GetParam());
  80. const String filename = cv::tempfile(ext);
  81. const int fourcc = fourccByExt(ext);
  82. // For some reason MPEG2 codec does not work well with this particular videostream at 1 FPS
  83. // even with large bitrate values. Thus skipping this case.
  84. if (FPS == 1. && fourcc == VideoWriter::fourcc('M', 'P', 'G', '2'))
  85. throw SkipTestException("This configuration is not supported");
  86. bool isColor = true;
  87. std::queue<Mat> goodFrames;
  88. // Write video
  89. VideoWriter writer;
  90. writer.open(filename, CAP_INTEL_MFX, fourcc, FPS, FRAME_SIZE, isColor);
  91. ASSERT_TRUE(writer.isOpened());
  92. Mat frame(FRAME_SIZE, CV_8UC3);
  93. for (int i = 0; i < FRAME_COUNT; ++i)
  94. {
  95. generateFrame(i, frame);
  96. goodFrames.push(frame.clone());
  97. writer << frame;
  98. }
  99. writer.release();
  100. EXPECT_FALSE(writer.isOpened());
  101. // Read video
  102. VideoCapture cap;
  103. cap.open(filename, CAP_INTEL_MFX);
  104. ASSERT_TRUE(cap.isOpened());
  105. EXPECT_EQ(FRAME_SIZE.width, cap.get(CAP_PROP_FRAME_WIDTH));
  106. EXPECT_EQ(FRAME_SIZE.height, cap.get(CAP_PROP_FRAME_HEIGHT));
  107. double psnrThreshold = (fourcc == VideoWriter::fourcc('M', 'P', 'G', '2')) ? 27.0 : 29.5; // experimentally chosen value
  108. for (int i = 0; i < FRAME_COUNT; ++i)
  109. {
  110. SCOPED_TRACE(i);
  111. ASSERT_TRUE(cap.read(frame));
  112. ASSERT_FALSE(frame.empty());
  113. ASSERT_EQ(FRAME_SIZE.width, frame.cols);
  114. ASSERT_EQ(FRAME_SIZE.height, frame.rows);
  115. // verify
  116. ASSERT_NE(goodFrames.size(), 0u);
  117. const Mat goodFrame = goodFrames.front(); goodFrames.pop();
  118. EXPECT_EQ(goodFrame.depth(), frame.depth());
  119. EXPECT_EQ(goodFrame.channels(), frame.channels());
  120. EXPECT_EQ(goodFrame.type(), frame.type());
  121. double psnr = cvtest::PSNR(goodFrame, frame);
  122. if ((i == 1 || i == 4) && fourcc == VideoWriter::fourcc('H', '2', '6', '5'))
  123. {
  124. // ignore bugs of some HW/SW configurations:
  125. // - (added 2021-10) i7-11700K, Win10, oneVPL 2021.4.0 / 2021.6.0
  126. std::cout << "SKIP: bypass frame content check: i=" << i << " psnr=" << psnr << ", expected to be >= " << psnrThreshold << std::endl;
  127. continue;
  128. }
  129. EXPECT_GE(psnr, psnrThreshold);
  130. }
  131. EXPECT_FALSE(cap.read(frame));
  132. EXPECT_TRUE(frame.empty());
  133. cap.release();
  134. EXPECT_FALSE(cap.isOpened());
  135. remove(filename.c_str());
  136. }
  137. inline static std::string videoio_mfx_name_printer(const testing::TestParamInfo<videoio_mfx::ParamType>& info)
  138. {
  139. std::ostringstream out;
  140. const Size sz = get<0>(info.param);
  141. const std::string ext = get<2>(info.param);
  142. out << sz.width << "x" << sz.height << "x" << get<1>(info.param) << "x" << ext.substr(1, ext.size() - 1);
  143. return out.str();
  144. }
  145. INSTANTIATE_TEST_CASE_P(videoio, videoio_mfx,
  146. testing::Combine(
  147. testing::Values(Size(640, 480), Size(638, 478), Size(636, 476), Size(1920, 1080)),
  148. testing::Values(1, 30, 100),
  149. testing::Values(".mpeg2", ".264", ".265")),
  150. videoio_mfx_name_printer);
  151. }} // namespace