videoio: retrieve encoded frames through FFmpeg backend
- backport 15290 - add extra test case
This commit is contained in:
committed by
Alexander Alekhin
parent
f4d55d512f
commit
aff8c9bd28
@@ -218,6 +218,93 @@ TEST(Videoio_Video, ffmpeg_image) { CV_FFmpegReadImageTest test; test.safe_run()
|
||||
|
||||
#if defined(HAVE_FFMPEG)
|
||||
|
||||
typedef tuple<VideoCaptureAPIs, string, string, string, string, string> videoio_container_params_t;
|
||||
typedef testing::TestWithParam< videoio_container_params_t > videoio_container;
|
||||
|
||||
TEST_P(videoio_container, read)
|
||||
{
|
||||
const VideoCaptureAPIs api = get<0>(GetParam());
|
||||
|
||||
//if (!videoio_registry::hasBackend(api))
|
||||
// throw SkipTestException("Backend was not found");
|
||||
|
||||
const string path = get<1>(GetParam());
|
||||
const string ext = get<2>(GetParam());
|
||||
const string ext_raw = get<3>(GetParam());
|
||||
const string codec = get<4>(GetParam());
|
||||
const string pixelFormat = get<5>(GetParam());
|
||||
const string fileName = path + "." + ext;
|
||||
const string fileNameOut = tempfile(cv::format("test_container_stream.%s", ext_raw.c_str()).c_str());
|
||||
|
||||
// Write encoded video read using VideoContainer to tmp file
|
||||
size_t totalBytes = 0;
|
||||
{
|
||||
VideoCapture container(findDataFile(fileName), api);
|
||||
if (!container.isOpened())
|
||||
throw SkipTestException("Video stream is not supported");
|
||||
if (!container.set(CAP_PROP_FORMAT, -1)) // turn off video decoder (extract stream)
|
||||
throw SkipTestException("Fetching of RAW video streams is not supported");
|
||||
ASSERT_EQ(-1.f, container.get(CAP_PROP_FORMAT)); // check
|
||||
EXPECT_EQ(codec, fourccToString((int)container.get(CAP_PROP_FOURCC)));
|
||||
EXPECT_EQ(pixelFormat, fourccToString((int)container.get(CAP_PROP_CODEC_PIXEL_FORMAT)));
|
||||
|
||||
std::ofstream file(fileNameOut.c_str(), ios::out | ios::trunc | std::ios::binary);
|
||||
Mat raw_data;
|
||||
while (true)
|
||||
{
|
||||
container >> raw_data;
|
||||
size_t size = raw_data.total();
|
||||
if (raw_data.empty())
|
||||
break;
|
||||
ASSERT_EQ(CV_8UC1, raw_data.type());
|
||||
ASSERT_LE(raw_data.dims, 2);
|
||||
ASSERT_EQ(raw_data.rows, 1);
|
||||
ASSERT_EQ((size_t)raw_data.cols, raw_data.total());
|
||||
ASSERT_TRUE(raw_data.isContinuous());
|
||||
totalBytes += size;
|
||||
file.write(reinterpret_cast<char*>(raw_data.data), size);
|
||||
ASSERT_FALSE(file.fail());
|
||||
}
|
||||
ASSERT_GE(totalBytes, (size_t)65536) << "Encoded stream is too small";
|
||||
}
|
||||
|
||||
std::cout << "Checking extracted video stream: " << fileNameOut << " (size: " << totalBytes << " bytes)" << std::endl;
|
||||
|
||||
// Check decoded frames read from original media are equal to frames decoded from tmp file
|
||||
{
|
||||
VideoCapture capReference(findDataFile(fileName), api);
|
||||
ASSERT_TRUE(capReference.isOpened());
|
||||
VideoCapture capActual(fileNameOut.c_str(), api);
|
||||
ASSERT_TRUE(capActual.isOpened());
|
||||
Mat reference, actual;
|
||||
int nframes = 0, n_err = 0;
|
||||
while (capReference.read(reference) && n_err < 3)
|
||||
{
|
||||
nframes++;
|
||||
ASSERT_TRUE(capActual.read(actual)) << nframes;
|
||||
EXPECT_EQ(0, cvtest::norm(actual, reference, NORM_INF)) << "frame=" << nframes << " err=" << ++n_err;
|
||||
}
|
||||
ASSERT_GT(nframes, 0);
|
||||
}
|
||||
|
||||
ASSERT_EQ(0, remove(fileNameOut.c_str()));
|
||||
}
|
||||
|
||||
const videoio_container_params_t videoio_container_params[] =
|
||||
{
|
||||
videoio_container_params_t(CAP_FFMPEG, "video/big_buck_bunny", "h264", "h264", "h264", "I420"),
|
||||
videoio_container_params_t(CAP_FFMPEG, "video/big_buck_bunny", "h265", "h265", "hevc", "I420"),
|
||||
videoio_container_params_t(CAP_FFMPEG, "video/big_buck_bunny", "mjpg.avi", "mjpg", "MJPG", "I420"),
|
||||
//videoio_container_params_t(CAP_FFMPEG, "video/big_buck_bunny", "h264.mkv", "mkv.h264", "h264", "I420"),
|
||||
//videoio_container_params_t(CAP_FFMPEG, "video/big_buck_bunny", "h265.mkv", "mkv.h265", "hevc", "I420"),
|
||||
//videoio_container_params_t(CAP_FFMPEG, "video/big_buck_bunny", "h264.mp4", "mp4.avc1", "avc1", "I420"),
|
||||
//videoio_container_params_t(CAP_FFMPEG, "video/big_buck_bunny", "h265.mp4", "mp4.hev1", "hev1", "I420"),
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, videoio_container, testing::ValuesIn(videoio_container_params));
|
||||
|
||||
//==========================================================================
|
||||
|
||||
//////////////////////////////// Parallel VideoWriters and VideoCaptures ////////////////////////////////////
|
||||
|
||||
class CreateVideoWriterInvoker :
|
||||
|
||||
Reference in New Issue
Block a user