From 0853085ec629cdd819f8ad08dcd8b322be20642d Mon Sep 17 00:00:00 2001 From: Pierre Letessier Date: Sun, 26 Jan 2020 08:19:09 +0100 Subject: [PATCH] Merge pull request #16190 from pletessier:videocapture_skip_frames Videocapture skip frames * enable skipping frames * update videoio_skip test --- modules/videoio/src/cap_ffmpeg_impl.hpp | 23 ++++++++++++ modules/videoio/test/test_ffmpeg.cpp | 48 +++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/modules/videoio/src/cap_ffmpeg_impl.hpp b/modules/videoio/src/cap_ffmpeg_impl.hpp index fdc6b31b19..c69cd74509 100644 --- a/modules/videoio/src/cap_ffmpeg_impl.hpp +++ b/modules/videoio/src/cap_ffmpeg_impl.hpp @@ -966,6 +966,29 @@ bool CvCapture_FFMPEG::open( const char* _filename ) enc->thread_count = get_number_of_cpus(); //#endif +#if LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(52, 123, 0) + AVDictionaryEntry* avdiscard_entry = av_dict_get(dict, "avdiscard", NULL, 0); + + if (avdiscard_entry != 0) { + if(strcmp(avdiscard_entry->value, "all") == 0) + enc->skip_frame = AVDISCARD_ALL; + else if (strcmp(avdiscard_entry->value, "bidir") == 0) + enc->skip_frame = AVDISCARD_BIDIR; + else if (strcmp(avdiscard_entry->value, "default") == 0) + enc->skip_frame = AVDISCARD_DEFAULT; + else if (strcmp(avdiscard_entry->value, "none") == 0) + enc->skip_frame = AVDISCARD_NONE; +#if LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(54, 59, 100) + else if (strcmp(avdiscard_entry->value, "nonintra") == 0) + enc->skip_frame = AVDISCARD_NONINTRA; +#endif + else if (strcmp(avdiscard_entry->value, "nonkey") == 0) + enc->skip_frame = AVDISCARD_NONKEY; + else if (strcmp(avdiscard_entry->value, "nonref") == 0) + enc->skip_frame = AVDISCARD_NONREF; + } +#endif + #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0) #define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO #endif diff --git a/modules/videoio/test/test_ffmpeg.cpp b/modules/videoio/test/test_ffmpeg.cpp index 6519c57751..10f41daf7a 100644 --- a/modules/videoio/test/test_ffmpeg.cpp +++ b/modules/videoio/test/test_ffmpeg.cpp @@ -303,6 +303,54 @@ const videoio_container_params_t videoio_container_params[] = INSTANTIATE_TEST_CASE_P(/**/, videoio_container, testing::ValuesIn(videoio_container_params)); +typedef tuple videoio_skip_params_t; +typedef testing::TestWithParam< videoio_skip_params_t > videoio_skip; + +TEST_P(videoio_skip, DISABLED_read) // optional test, may fail in some configurations +{ +#if CV_VERSION_MAJOR >= 4 + if (!videoio_registry::hasBackend(CAP_FFMPEG)) + throw SkipTestException("Backend was not found"); +#endif + + const string path = get<0>(GetParam()); + const string env = get<1>(GetParam()); + const int expectedFrameNumber = get<2>(GetParam()); + + #ifdef _WIN32 + _putenv_s("OPENCV_FFMPEG_CAPTURE_OPTIONS", env.c_str()); + #else + setenv("OPENCV_FFMPEG_CAPTURE_OPTIONS", env.c_str(), 1); + #endif + VideoCapture container(findDataFile(path), CAP_FFMPEG); + #ifdef _WIN32 + _putenv_s("OPENCV_FFMPEG_CAPTURE_OPTIONS", ""); + #else + setenv("OPENCV_FFMPEG_CAPTURE_OPTIONS", "", 1); + #endif + + ASSERT_TRUE(container.isOpened()); + + Mat reference; + int nframes = 0, n_err = 0; + while (container.isOpened()) + { + if (container.read(reference)) + nframes++; + else if (++n_err > 3) + break; + } + EXPECT_EQ(expectedFrameNumber, nframes); +} + +const videoio_skip_params_t videoio_skip_params[] = +{ + videoio_skip_params_t("video/big_buck_bunny.mp4", "", 125), + videoio_skip_params_t("video/big_buck_bunny.mp4", "avdiscard;nonkey", 11) +}; + +INSTANTIATE_TEST_CASE_P(/**/, videoio_skip, testing::ValuesIn(videoio_skip_params)); + //========================================================================== //////////////////////////////// Parallel VideoWriters and VideoCaptures ////////////////////////////////////