test_ffmpeg.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540
  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. using namespace std;
  6. namespace opencv_test { namespace {
  7. static inline long long getFileSize(const string &filename)
  8. {
  9. ifstream f(filename, ios_base::in | ios_base::binary);
  10. f.seekg(0, ios_base::end);
  11. return f.tellg();
  12. }
  13. typedef tuple<string, string, Size> FourCC_Ext_Size;
  14. typedef testing::TestWithParam< FourCC_Ext_Size > videoio_ffmpeg;
  15. TEST_P(videoio_ffmpeg, write_big)
  16. {
  17. if (!videoio_registry::hasBackend(CAP_FFMPEG))
  18. throw SkipTestException("FFmpeg backend was not found");
  19. const string fourcc = get<0>(GetParam());
  20. const string ext = get<1>(GetParam());
  21. const Size sz = get<2>(GetParam());
  22. const double time_sec = 1;
  23. const double fps = 25;
  24. ostringstream buf;
  25. buf << "write_big_" << fourcc << "." << ext;
  26. const string filename = tempfile(buf.str().c_str());
  27. VideoWriter writer(filename, CAP_FFMPEG, fourccFromString(fourcc), fps, sz);
  28. if (ext == "mp4" && fourcc == "H264" && !writer.isOpened())
  29. {
  30. throw cvtest::SkipTestException("H264/mp4 codec is not supported - SKIP");
  31. }
  32. ASSERT_TRUE(writer.isOpened());
  33. Mat img(sz, CV_8UC3, Scalar::all(0));
  34. const int coeff = cvRound(min(sz.width, sz.height)/(fps * time_sec));
  35. for (int i = 0 ; i < static_cast<int>(fps * time_sec); i++ )
  36. {
  37. rectangle(img,
  38. Point2i(coeff * i, coeff * i),
  39. Point2i(coeff * (i + 1), coeff * (i + 1)),
  40. Scalar::all(255 * (1.0 - static_cast<double>(i) / (fps * time_sec * 2))),
  41. -1);
  42. writer << img;
  43. }
  44. writer.release();
  45. EXPECT_GT(getFileSize(filename), 8192);
  46. remove(filename.c_str());
  47. }
  48. static const Size bigSize(4096, 4096);
  49. const FourCC_Ext_Size entries[] =
  50. {
  51. make_tuple("", "avi", bigSize),
  52. make_tuple("DX50", "avi", bigSize),
  53. make_tuple("FLV1", "avi", bigSize),
  54. make_tuple("H261", "avi", Size(352, 288)),
  55. make_tuple("H263", "avi", Size(704, 576)),
  56. make_tuple("I420", "avi", bigSize),
  57. make_tuple("MJPG", "avi", bigSize),
  58. make_tuple("mp4v", "avi", bigSize),
  59. make_tuple("MPEG", "avi", Size(720, 576)),
  60. make_tuple("XVID", "avi", bigSize),
  61. make_tuple("H264", "mp4", Size(4096, 2160))
  62. };
  63. INSTANTIATE_TEST_CASE_P(videoio, videoio_ffmpeg, testing::ValuesIn(entries));
  64. //==========================================================================
  65. TEST(videoio_ffmpeg, image)
  66. {
  67. if (!videoio_registry::hasBackend(CAP_FFMPEG))
  68. throw SkipTestException("FFmpeg backend was not found");
  69. const string filename = findDataFile("readwrite/ordinary.bmp");
  70. Mat image = imread(filename, IMREAD_COLOR);
  71. ASSERT_FALSE(image.empty());
  72. VideoCapture cap(filename, CAP_FFMPEG);
  73. ASSERT_TRUE(cap.isOpened());
  74. Mat frame1, frame2;
  75. cap >> frame1 >> frame2;
  76. ASSERT_FALSE(frame1.empty());
  77. ASSERT_TRUE(frame2.empty());
  78. ASSERT_EQ(0, cvtest::norm(image, frame1, NORM_INF));
  79. }
  80. //==========================================================================
  81. typedef tuple<VideoCaptureAPIs, string, string, string, string, string> videoio_container_params_t;
  82. typedef testing::TestWithParam< videoio_container_params_t > videoio_container;
  83. TEST_P(videoio_container, read)
  84. {
  85. const VideoCaptureAPIs api = get<0>(GetParam());
  86. if (!videoio_registry::hasBackend(api))
  87. throw SkipTestException("Backend was not found");
  88. const string path = get<1>(GetParam());
  89. const string ext = get<2>(GetParam());
  90. const string ext_raw = get<3>(GetParam());
  91. const string codec = get<4>(GetParam());
  92. const string pixelFormat = get<5>(GetParam());
  93. const string fileName = path + "." + ext;
  94. const string fileNameOut = tempfile(cv::format("test_container_stream.%s", ext_raw.c_str()).c_str());
  95. // Write encoded video read using VideoContainer to tmp file
  96. size_t totalBytes = 0;
  97. {
  98. VideoCapture container(findDataFile(fileName), api);
  99. if (!container.isOpened())
  100. throw SkipTestException("Video stream is not supported");
  101. if (!container.set(CAP_PROP_FORMAT, -1)) // turn off video decoder (extract stream)
  102. throw SkipTestException("Fetching of RAW video streams is not supported");
  103. ASSERT_EQ(-1.f, container.get(CAP_PROP_FORMAT)); // check
  104. EXPECT_EQ(codec, fourccToString((int)container.get(CAP_PROP_FOURCC)));
  105. EXPECT_EQ(pixelFormat, fourccToString((int)container.get(CAP_PROP_CODEC_PIXEL_FORMAT)));
  106. std::ofstream file(fileNameOut.c_str(), ios::out | ios::trunc | std::ios::binary);
  107. Mat raw_data;
  108. while (true)
  109. {
  110. container >> raw_data;
  111. size_t size = raw_data.total();
  112. if (raw_data.empty())
  113. break;
  114. ASSERT_EQ(CV_8UC1, raw_data.type());
  115. ASSERT_LE(raw_data.dims, 2);
  116. ASSERT_EQ(raw_data.rows, 1);
  117. ASSERT_EQ((size_t)raw_data.cols, raw_data.total());
  118. ASSERT_TRUE(raw_data.isContinuous());
  119. totalBytes += size;
  120. file.write(reinterpret_cast<char*>(raw_data.data), size);
  121. ASSERT_FALSE(file.fail());
  122. }
  123. ASSERT_GE(totalBytes, (size_t)65536) << "Encoded stream is too small";
  124. }
  125. std::cout << "Checking extracted video stream: " << fileNameOut << " (size: " << totalBytes << " bytes)" << std::endl;
  126. // Check decoded frames read from original media are equal to frames decoded from tmp file
  127. {
  128. VideoCapture capReference(findDataFile(fileName), api);
  129. ASSERT_TRUE(capReference.isOpened());
  130. VideoCapture capActual(fileNameOut.c_str(), api);
  131. ASSERT_TRUE(capActual.isOpened());
  132. Mat reference, actual;
  133. int nframes = 0, n_err = 0;
  134. while (capReference.read(reference) && n_err < 3)
  135. {
  136. nframes++;
  137. ASSERT_TRUE(capActual.read(actual)) << nframes;
  138. EXPECT_EQ(0, cvtest::norm(actual, reference, NORM_INF)) << "frame=" << nframes << " err=" << ++n_err;
  139. }
  140. ASSERT_GT(nframes, 0);
  141. }
  142. ASSERT_EQ(0, remove(fileNameOut.c_str()));
  143. }
  144. const videoio_container_params_t videoio_container_params[] =
  145. {
  146. videoio_container_params_t(CAP_FFMPEG, "video/big_buck_bunny", "h264", "h264", "h264", "I420"),
  147. videoio_container_params_t(CAP_FFMPEG, "video/big_buck_bunny", "h265", "h265", "hevc", "I420"),
  148. videoio_container_params_t(CAP_FFMPEG, "video/big_buck_bunny", "mjpg.avi", "mjpg", "MJPG", "I420"),
  149. //videoio_container_params_t(CAP_FFMPEG, "video/big_buck_bunny", "h264.mkv", "mkv.h264", "h264", "I420"),
  150. //videoio_container_params_t(CAP_FFMPEG, "video/big_buck_bunny", "h265.mkv", "mkv.h265", "hevc", "I420"),
  151. //videoio_container_params_t(CAP_FFMPEG, "video/big_buck_bunny", "h264.mp4", "mp4.avc1", "avc1", "I420"),
  152. //videoio_container_params_t(CAP_FFMPEG, "video/big_buck_bunny", "h265.mp4", "mp4.hev1", "hev1", "I420"),
  153. };
  154. INSTANTIATE_TEST_CASE_P(/**/, videoio_container, testing::ValuesIn(videoio_container_params));
  155. typedef tuple<string, string, int> videoio_skip_params_t;
  156. typedef testing::TestWithParam< videoio_skip_params_t > videoio_skip;
  157. TEST_P(videoio_skip, DISABLED_read) // optional test, may fail in some configurations
  158. {
  159. #if CV_VERSION_MAJOR >= 4
  160. if (!videoio_registry::hasBackend(CAP_FFMPEG))
  161. throw SkipTestException("Backend was not found");
  162. #endif
  163. const string path = get<0>(GetParam());
  164. const string env = get<1>(GetParam());
  165. const int expectedFrameNumber = get<2>(GetParam());
  166. #ifdef _WIN32
  167. _putenv_s("OPENCV_FFMPEG_CAPTURE_OPTIONS", env.c_str());
  168. #else
  169. setenv("OPENCV_FFMPEG_CAPTURE_OPTIONS", env.c_str(), 1);
  170. #endif
  171. VideoCapture container(findDataFile(path), CAP_FFMPEG);
  172. #ifdef _WIN32
  173. _putenv_s("OPENCV_FFMPEG_CAPTURE_OPTIONS", "");
  174. #else
  175. setenv("OPENCV_FFMPEG_CAPTURE_OPTIONS", "", 1);
  176. #endif
  177. ASSERT_TRUE(container.isOpened());
  178. Mat reference;
  179. int nframes = 0, n_err = 0;
  180. while (container.isOpened())
  181. {
  182. if (container.read(reference))
  183. nframes++;
  184. else if (++n_err > 3)
  185. break;
  186. }
  187. EXPECT_EQ(expectedFrameNumber, nframes);
  188. }
  189. const videoio_skip_params_t videoio_skip_params[] =
  190. {
  191. videoio_skip_params_t("video/big_buck_bunny.mp4", "", 125),
  192. videoio_skip_params_t("video/big_buck_bunny.mp4", "avdiscard;nonkey", 11)
  193. };
  194. INSTANTIATE_TEST_CASE_P(/**/, videoio_skip, testing::ValuesIn(videoio_skip_params));
  195. //==========================================================================
  196. static void generateFrame(Mat &frame, unsigned int i, const Point &center, const Scalar &color)
  197. {
  198. frame = Scalar::all(i % 255);
  199. stringstream buf(ios::out);
  200. buf << "frame #" << i;
  201. putText(frame, buf.str(), Point(50, center.y), FONT_HERSHEY_SIMPLEX, 5.0, color, 5, CV_AA);
  202. circle(frame, center, i + 2, color, 2, CV_AA);
  203. }
  204. TEST(videoio_ffmpeg, parallel)
  205. {
  206. if (!videoio_registry::hasBackend(CAP_FFMPEG))
  207. throw SkipTestException("FFmpeg backend was not found");
  208. const int NUM = 4;
  209. const int GRAN = 4;
  210. const Range R(0, NUM);
  211. const Size sz(1020, 900);
  212. const int frameNum = 300;
  213. const Scalar color(Scalar::all(0));
  214. const Point center(sz.height / 2, sz.width / 2);
  215. // Generate filenames
  216. vector<string> files;
  217. for (int i = 0; i < NUM; ++i)
  218. {
  219. ostringstream stream;
  220. stream << i << ".avi";
  221. files.push_back(tempfile(stream.str().c_str()));
  222. }
  223. // Write videos
  224. {
  225. vector< Ptr<VideoWriter> > writers(NUM);
  226. auto makeWriters = [&](const Range &r)
  227. {
  228. for (int i = r.start; i != r.end; ++i)
  229. writers[i] = makePtr<VideoWriter>(files[i],
  230. CAP_FFMPEG,
  231. VideoWriter::fourcc('X','V','I','D'),
  232. 25.0f,
  233. sz);
  234. };
  235. parallel_for_(R, makeWriters, GRAN);
  236. for(int i = 0; i < NUM; ++i)
  237. {
  238. ASSERT_TRUE(writers[i]);
  239. ASSERT_TRUE(writers[i]->isOpened());
  240. }
  241. auto writeFrames = [&](const Range &r)
  242. {
  243. for (int j = r.start; j < r.end; ++j)
  244. {
  245. Mat frame(sz, CV_8UC3);
  246. for (int i = 0; i < frameNum; ++i)
  247. {
  248. generateFrame(frame, i, center, color);
  249. writers[j]->write(frame);
  250. }
  251. }
  252. };
  253. parallel_for_(R, writeFrames, GRAN);
  254. }
  255. // Read videos
  256. {
  257. vector< Ptr<VideoCapture> > readers(NUM);
  258. auto makeCaptures = [&](const Range &r)
  259. {
  260. for (int i = r.start; i != r.end; ++i)
  261. readers[i] = makePtr<VideoCapture>(files[i], CAP_FFMPEG);
  262. };
  263. parallel_for_(R, makeCaptures, GRAN);
  264. for(int i = 0; i < NUM; ++i)
  265. {
  266. ASSERT_TRUE(readers[i]);
  267. ASSERT_TRUE(readers[i]->isOpened());
  268. }
  269. auto readFrames = [&](const Range &r)
  270. {
  271. for (int j = r.start; j < r.end; ++j)
  272. {
  273. Mat reference(sz, CV_8UC3);
  274. for (int i = 0; i < frameNum; ++i)
  275. {
  276. Mat actual;
  277. EXPECT_TRUE(readers[j]->read(actual));
  278. EXPECT_FALSE(actual.empty());
  279. generateFrame(reference, i, center, color);
  280. EXPECT_EQ(reference.size(), actual.size());
  281. EXPECT_EQ(reference.depth(), actual.depth());
  282. EXPECT_EQ(reference.channels(), actual.channels());
  283. EXPECT_GE(cvtest::PSNR(actual, reference), 35.0) << "cap" << j << ", frame " << i;
  284. }
  285. }
  286. };
  287. parallel_for_(R, readFrames, GRAN);
  288. }
  289. // Remove files
  290. for(int i = 0; i < NUM; ++i)
  291. {
  292. remove(files[i].c_str());
  293. }
  294. }
  295. typedef std::pair<VideoCaptureProperties, double> cap_property_t;
  296. typedef std::vector<cap_property_t> cap_properties_t;
  297. typedef std::pair<std::string, cap_properties_t> ffmpeg_cap_properties_param_t;
  298. typedef testing::TestWithParam<ffmpeg_cap_properties_param_t> ffmpeg_cap_properties;
  299. #ifdef _WIN32
  300. namespace {
  301. ::testing::AssertionResult IsOneOf(double value, double expected1, double expected2)
  302. {
  303. // internal floating point class is used to perform accurate floating point types comparison
  304. typedef ::testing::internal::FloatingPoint<double> FloatingPoint;
  305. FloatingPoint val(value);
  306. if (val.AlmostEquals(FloatingPoint(expected1)) || val.AlmostEquals(FloatingPoint(expected2)))
  307. {
  308. return ::testing::AssertionSuccess();
  309. }
  310. else
  311. {
  312. return ::testing::AssertionFailure()
  313. << value << " is neither equal to " << expected1 << " nor " << expected2;
  314. }
  315. }
  316. }
  317. #endif
  318. TEST_P(ffmpeg_cap_properties, can_read_property)
  319. {
  320. if (!videoio_registry::hasBackend(CAP_FFMPEG))
  321. throw SkipTestException("FFmpeg backend was not found");
  322. ffmpeg_cap_properties_param_t parameters = GetParam();
  323. const std::string path = parameters.first;
  324. const cap_properties_t properties = parameters.second;
  325. VideoCapture cap(findDataFile(path), CAP_FFMPEG);
  326. ASSERT_TRUE(cap.isOpened()) << "Can not open " << findDataFile(path);
  327. for (std::size_t i = 0; i < properties.size(); ++i)
  328. {
  329. const cap_property_t& prop = properties[i];
  330. const double actualValue = cap.get(static_cast<int>(prop.first));
  331. #ifndef _WIN32
  332. EXPECT_DOUBLE_EQ(actualValue, prop.second)
  333. << "Property " << static_cast<int>(prop.first) << " has wrong value";
  334. #else
  335. EXPECT_TRUE(IsOneOf(actualValue, prop.second, 0.0))
  336. << "Property " << static_cast<int>(prop.first) << " has wrong value";
  337. #endif
  338. }
  339. }
  340. cap_properties_t loadBigBuckBunnyFFProbeResults() {
  341. cap_property_t properties[] = { cap_property_t(CAP_PROP_BITRATE, 5851.),
  342. cap_property_t(CAP_PROP_FPS, 24.),
  343. cap_property_t(CAP_PROP_FRAME_HEIGHT, 384.),
  344. cap_property_t(CAP_PROP_FRAME_WIDTH, 672.) };
  345. return cap_properties_t(properties, properties + sizeof(properties) / sizeof(cap_property_t));
  346. }
  347. const ffmpeg_cap_properties_param_t videoio_ffmpeg_properties[] = {
  348. ffmpeg_cap_properties_param_t("video/big_buck_bunny.avi", loadBigBuckBunnyFFProbeResults())
  349. };
  350. INSTANTIATE_TEST_CASE_P(videoio, ffmpeg_cap_properties, testing::ValuesIn(videoio_ffmpeg_properties));
  351. // related issue: https://github.com/opencv/opencv/issues/15499
  352. TEST(videoio, mp4_orientation_meta_auto)
  353. {
  354. if (!videoio_registry::hasBackend(CAP_FFMPEG))
  355. throw SkipTestException("FFmpeg backend was not found");
  356. string video_file = string(cvtest::TS::ptr()->get_data_path()) + "video/big_buck_bunny_rotated.mp4";
  357. VideoCapture cap;
  358. EXPECT_NO_THROW(cap.open(video_file, CAP_FFMPEG));
  359. ASSERT_TRUE(cap.isOpened()) << "Can't open the video: " << video_file << " with backend " << CAP_FFMPEG << std::endl;
  360. cap.set(CAP_PROP_ORIENTATION_AUTO, true);
  361. if (cap.get(CAP_PROP_ORIENTATION_AUTO) == 0)
  362. throw SkipTestException("FFmpeg frame rotation metadata is not supported");
  363. Size actual;
  364. EXPECT_NO_THROW(actual = Size((int)cap.get(CAP_PROP_FRAME_WIDTH),
  365. (int)cap.get(CAP_PROP_FRAME_HEIGHT)));
  366. EXPECT_EQ(384, actual.width);
  367. EXPECT_EQ(672, actual.height);
  368. Mat frame;
  369. cap >> frame;
  370. ASSERT_EQ(384, frame.cols);
  371. ASSERT_EQ(672, frame.rows);
  372. }
  373. // related issue: https://github.com/opencv/opencv/issues/15499
  374. TEST(videoio, mp4_orientation_no_rotation)
  375. {
  376. if (!videoio_registry::hasBackend(CAP_FFMPEG))
  377. throw SkipTestException("FFmpeg backend was not found");
  378. string video_file = string(cvtest::TS::ptr()->get_data_path()) + "video/big_buck_bunny_rotated.mp4";
  379. VideoCapture cap;
  380. EXPECT_NO_THROW(cap.open(video_file, CAP_FFMPEG));
  381. cap.set(CAP_PROP_ORIENTATION_AUTO, 0);
  382. ASSERT_TRUE(cap.isOpened()) << "Can't open the video: " << video_file << " with backend " << CAP_FFMPEG << std::endl;
  383. ASSERT_FALSE(cap.get(CAP_PROP_ORIENTATION_AUTO));
  384. Size actual;
  385. EXPECT_NO_THROW(actual = Size((int)cap.get(CAP_PROP_FRAME_WIDTH),
  386. (int)cap.get(CAP_PROP_FRAME_HEIGHT)));
  387. EXPECT_EQ(672, actual.width);
  388. EXPECT_EQ(384, actual.height);
  389. Mat frame;
  390. cap >> frame;
  391. ASSERT_EQ(672, frame.cols);
  392. ASSERT_EQ(384, frame.rows);
  393. }
  394. static void ffmpeg_check_read_raw(VideoCapture& cap)
  395. {
  396. ASSERT_TRUE(cap.isOpened()) << "Can't open the video";
  397. Mat data;
  398. cap >> data;
  399. EXPECT_EQ(CV_8UC1, data.type()) << "CV_8UC1 != " << typeToString(data.type());
  400. EXPECT_TRUE(data.rows == 1 || data.cols == 1) << data.size;
  401. EXPECT_EQ((size_t)29729, data.total());
  402. cap >> data;
  403. EXPECT_EQ(CV_8UC1, data.type()) << "CV_8UC1 != " << typeToString(data.type());
  404. EXPECT_TRUE(data.rows == 1 || data.cols == 1) << data.size;
  405. EXPECT_EQ((size_t)37118, data.total());
  406. }
  407. TEST(videoio_ffmpeg, ffmpeg_check_extra_data)
  408. {
  409. if (!videoio_registry::hasBackend(CAP_FFMPEG))
  410. throw SkipTestException("FFmpeg backend was not found");
  411. string video_file = findDataFile("video/big_buck_bunny.mp4");
  412. VideoCapture cap;
  413. EXPECT_NO_THROW(cap.open(video_file, CAP_FFMPEG));
  414. ASSERT_TRUE(cap.isOpened()) << "Can't open the video";
  415. const int codecExtradataIdx = (int)cap.get(CAP_PROP_CODEC_EXTRADATA_INDEX);
  416. #ifdef _WIN32 // handle old FFmpeg backend
  417. if (codecExtradataIdx <= 0)
  418. throw SkipTestException("Codec extra data is not supported by backend or video stream");
  419. #endif
  420. Mat data;
  421. ASSERT_TRUE(cap.retrieve(data, codecExtradataIdx));
  422. EXPECT_EQ(CV_8UC1, data.type()) << "CV_8UC1 != " << typeToString(data.type());
  423. EXPECT_TRUE(data.rows == 1 || data.cols == 1) << data.size;
  424. EXPECT_EQ((size_t)45, data.total());
  425. }
  426. TEST(videoio_ffmpeg, open_with_property)
  427. {
  428. if (!videoio_registry::hasBackend(CAP_FFMPEG))
  429. throw SkipTestException("FFmpeg backend was not found");
  430. string video_file = findDataFile("video/big_buck_bunny.mp4");
  431. VideoCapture cap;
  432. EXPECT_NO_THROW(cap.open(video_file, CAP_FFMPEG, {
  433. CAP_PROP_FORMAT, -1 // demux only
  434. }));
  435. ffmpeg_check_read_raw(cap);
  436. }
  437. TEST(videoio_ffmpeg, create_with_property)
  438. {
  439. if (!videoio_registry::hasBackend(CAP_FFMPEG))
  440. throw SkipTestException("FFmpeg backend was not found");
  441. string video_file = findDataFile("video/big_buck_bunny.mp4");
  442. VideoCapture cap(video_file, CAP_FFMPEG, {
  443. CAP_PROP_FORMAT, -1 // demux only
  444. });
  445. ffmpeg_check_read_raw(cap);
  446. }
  447. TEST(videoio_ffmpeg, create_with_property_badarg)
  448. {
  449. if (!videoio_registry::hasBackend(CAP_FFMPEG))
  450. throw SkipTestException("FFmpeg backend was not found");
  451. string video_file = findDataFile("video/big_buck_bunny.mp4");
  452. VideoCapture cap(video_file, CAP_FFMPEG, {
  453. CAP_PROP_FORMAT, -2 // invalid
  454. });
  455. EXPECT_FALSE(cap.isOpened());
  456. }
  457. }} // namespace