Merge remote-tracking branch 'upstream/3.4' into merge-3.4
[platform/upstream/opencv.git] / modules / videoio / test / test_mfx.cpp
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
5 #include "test_precomp.hpp"
6
7 namespace opencv_test { namespace {
8
9 TEST(videoio_mfx, read_invalid)
10 {
11     if (!videoio_registry::hasBackend(CAP_INTEL_MFX))
12         throw SkipTestException("MediaSDK backend was not found");
13
14     VideoCapture cap;
15     ASSERT_NO_THROW(cap.open("nonexistent-file", CAP_INTEL_MFX));
16     ASSERT_FALSE(cap.isOpened());
17     Mat img;
18     ASSERT_NO_THROW(cap >> img);
19     ASSERT_TRUE(img.empty());
20 }
21
22 TEST(videoio_mfx, write_invalid)
23 {
24     if (!videoio_registry::hasBackend(CAP_INTEL_MFX))
25         throw SkipTestException("MediaSDK backend was not found");
26
27     const string filename = cv::tempfile(".264");
28     VideoWriter writer;
29     bool res = true;
30     ASSERT_NO_THROW(res = writer.open(filename, CAP_INTEL_MFX, VideoWriter::fourcc('H', '2', '6', '4'), 1, Size(641, 480), true));
31     EXPECT_FALSE(res);
32     EXPECT_FALSE(writer.isOpened());
33     ASSERT_NO_THROW(res = writer.open(filename, CAP_INTEL_MFX, VideoWriter::fourcc('H', '2', '6', '4'), 1, Size(640, 481), true));
34     EXPECT_FALSE(res);
35     EXPECT_FALSE(writer.isOpened());
36     ASSERT_NO_THROW(res = writer.open(filename, CAP_INTEL_MFX, VideoWriter::fourcc('A', 'B', 'C', 'D'), 1, Size(640, 480), true));
37     EXPECT_FALSE(res);
38     EXPECT_FALSE(writer.isOpened());
39     ASSERT_NO_THROW(res = writer.open(String(), CAP_INTEL_MFX, VideoWriter::fourcc('H', '2', '6', '4'), 1, Size(640, 480), true));
40     EXPECT_FALSE(res);
41     EXPECT_FALSE(writer.isOpened());
42     ASSERT_NO_THROW(res = writer.open(filename, CAP_INTEL_MFX, VideoWriter::fourcc('H', '2', '6', '4'), 0, Size(640, 480), true));
43     EXPECT_FALSE(res);
44     EXPECT_FALSE(writer.isOpened());
45
46     ASSERT_NO_THROW(res = writer.open(filename, CAP_INTEL_MFX, VideoWriter::fourcc('H', '2', '6', '4'), 30, Size(640, 480), true));
47     ASSERT_TRUE(res);
48     ASSERT_TRUE(writer.isOpened());
49     Mat t;
50     // write some bad frames
51     t = Mat(Size(1024, 768), CV_8UC3);
52     EXPECT_NO_THROW(writer << t);
53     t = Mat(Size(320, 240), CV_8UC3);
54     EXPECT_NO_THROW(writer << t);
55     t = Mat(Size(640, 480), CV_8UC2);
56     EXPECT_NO_THROW(writer << t);
57
58     // cleanup
59     ASSERT_NO_THROW(writer.release());
60     remove(filename.c_str());
61 }
62
63
64 //==================================================================================================
65
66 const int FRAME_COUNT = 20;
67
68 inline void generateFrame(int i, Mat & frame)
69 {
70     ::generateFrame(i, FRAME_COUNT, frame);
71 }
72
73 inline int fourccByExt(const String &ext)
74 {
75     if (ext == ".mpeg2")
76         return VideoWriter::fourcc('M', 'P', 'G', '2');
77     else if (ext == ".264")
78         return VideoWriter::fourcc('H', '2', '6', '4');
79     else if (ext == ".265")
80         return VideoWriter::fourcc('H', '2', '6', '5');
81     return -1;
82 }
83
84 //==================================================================================================
85
86 typedef tuple<Size, double, const char *> Size_FPS_Ext;
87 typedef testing::TestWithParam< Size_FPS_Ext > videoio_mfx;
88
89 TEST_P(videoio_mfx, read_write_raw)
90 {
91     if (!videoio_registry::hasBackend(CAP_INTEL_MFX))
92         throw SkipTestException("MediaSDK backend was not found");
93
94     const Size FRAME_SIZE = get<0>(GetParam());
95     const double FPS = get<1>(GetParam());
96     const char *ext = get<2>(GetParam());
97     const String filename = cv::tempfile(ext);
98     const int fourcc = fourccByExt(ext);
99
100     bool isColor = true;
101     std::queue<Mat> goodFrames;
102
103     // Write video
104     VideoWriter writer;
105     writer.open(filename, CAP_INTEL_MFX, fourcc, FPS, FRAME_SIZE, isColor);
106     ASSERT_TRUE(writer.isOpened());
107     Mat frame(FRAME_SIZE, CV_8UC3);
108     for (int i = 0; i < FRAME_COUNT; ++i)
109     {
110         generateFrame(i, frame);
111         goodFrames.push(frame.clone());
112         writer << frame;
113     }
114     writer.release();
115     EXPECT_FALSE(writer.isOpened());
116
117     // Read video
118     VideoCapture cap;
119     cap.open(filename, CAP_INTEL_MFX);
120     ASSERT_TRUE(cap.isOpened());
121     EXPECT_EQ(FRAME_SIZE.width, cap.get(CAP_PROP_FRAME_WIDTH));
122     EXPECT_EQ(FRAME_SIZE.height, cap.get(CAP_PROP_FRAME_HEIGHT));
123     for (int i = 0; i < FRAME_COUNT; ++i)
124     {
125         ASSERT_TRUE(cap.read(frame));
126         ASSERT_FALSE(frame.empty());
127         ASSERT_EQ(FRAME_SIZE.width, frame.cols);
128         ASSERT_EQ(FRAME_SIZE.height, frame.rows);
129         // verify
130         ASSERT_NE(goodFrames.size(), 0u);
131         const Mat &goodFrame = goodFrames.front();
132         EXPECT_EQ(goodFrame.depth(), frame.depth());
133         EXPECT_EQ(goodFrame.channels(), frame.channels());
134         EXPECT_EQ(goodFrame.type(), frame.type());
135         double psnr = cvtest::PSNR(goodFrame, frame);
136         if (fourcc == VideoWriter::fourcc('M', 'P', 'G', '2'))
137             EXPECT_GT(psnr, 31); // experimentally chosen value
138         else
139             EXPECT_GT(psnr, 33); // experimentally chosen value
140         goodFrames.pop();
141     }
142     EXPECT_FALSE(cap.read(frame));
143     EXPECT_TRUE(frame.empty());
144     cap.release();
145     EXPECT_FALSE(cap.isOpened());
146     remove(filename.c_str());
147 }
148
149 inline static std::string videoio_mfx_name_printer(const testing::TestParamInfo<videoio_mfx::ParamType>& info)
150 {
151     std::ostringstream out;
152     const Size sz = get<0>(info.param);
153     const std::string ext = get<2>(info.param);
154     out << sz.width << "x" << sz.height << "x" << get<1>(info.param) << "x" << ext.substr(1, ext.size() - 1);
155     return out.str();
156 }
157
158 INSTANTIATE_TEST_CASE_P(videoio, videoio_mfx,
159                         testing::Combine(
160                             testing::Values(Size(640, 480), Size(638, 478), Size(636, 476), Size(1920, 1080)),
161                             testing::Values(1, 30, 100),
162                             testing::Values(".mpeg2", ".264", ".265")),
163                         videoio_mfx_name_printer);
164
165 }} // namespace