diff --git a/modules/cudacodec/include/opencv2/cudacodec.hpp b/modules/cudacodec/include/opencv2/cudacodec.hpp index 7b8678df81c..e76d3cfb8b1 100644 --- a/modules/cudacodec/include/opencv2/cudacodec.hpp +++ b/modules/cudacodec/include/opencv2/cudacodec.hpp @@ -316,7 +316,10 @@ enum class VideoReaderProps { PROP_RAW_PACKAGES_BASE_INDEX = 2, //!< Base index for retrieving raw encoded data using retrieve(). PROP_NUMBER_OF_RAW_PACKAGES_SINCE_LAST_GRAB = 3, //!< Number of raw packages recieved since the last call to grab(). PROP_RAW_MODE = 4, //!< Status of raw mode. - PROP_LRF_HAS_KEY_FRAME = 5 //!< FFmpeg source only - Indicates whether the Last Raw Frame (LRF), output from VideoReader::retrieve() when VideoReader is initialized in raw mode, contains encoded data for a key frame. + PROP_LRF_HAS_KEY_FRAME = 5, //!< FFmpeg source only - Indicates whether the Last Raw Frame (LRF), output from VideoReader::retrieve() when VideoReader is initialized in raw mode, contains encoded data for a key frame. +#ifndef CV_DOXYGEN + PROP_NOT_SUPPORTED +#endif }; /** @brief Video reader interface. @@ -369,19 +372,33 @@ class CV_EXPORTS_W VideoReader /** @brief Sets a property in the VideoReader. - @param property Property identifier from cv::cudacodec::VideoReaderProps (eg. cv::cudacodec::PROP_DECODED_FRAME_IDX, cv::cudacodec::PROP_EXTRA_DATA_INDEX, ...) + @param propertyId Property identifier from cv::cudacodec::VideoReaderProps (eg. cv::cudacodec::VideoReaderProps::PROP_DECODED_FRAME_IDX, + cv::cudacodec::VideoReaderProps::PROP_EXTRA_DATA_INDEX, ...). @param propertyVal Value of the property. @return `true` if the property has been set. */ - CV_WRAP virtual bool set(const VideoReaderProps property, const double propertyVal) = 0; + CV_WRAP virtual bool set(const VideoReaderProps propertyId, const double propertyVal) = 0; /** @brief Returns the specified VideoReader property - @param property Property identifier from cv::cudacodec::VideoReaderProps (eg. cv::cudacodec::PROP_DECODED_FRAME_IDX, cv::cudacodec::PROP_EXTRA_DATA_INDEX, ...) - @param propertyVal Optional value for the property. - @return Value for the specified property. Value -1 is returned when querying a property that is not supported. + @param propertyId Property identifier from cv::cudacodec::VideoReaderProps (eg. cv::cudacodec::VideoReaderProps::PROP_DECODED_FRAME_IDX, + cv::cudacodec::VideoReaderProps::PROP_EXTRA_DATA_INDEX, ...). + @param propertyVal + In - Optional value required for querying specific propertyId's, e.g. the index of the raw package to be checked for a key frame (cv::cudacodec::VideoReaderProps::PROP_LRF_HAS_KEY_FRAME). + Out - Value of the property. + @return `true` unless the property is not supported. */ - CV_WRAP virtual int get(const VideoReaderProps property, const int propertyVal = -1) const = 0; + CV_WRAP virtual bool get(const VideoReaderProps propertyId, CV_IN_OUT double& propertyVal) const = 0; + + /** @brief Retrieves the specified property used by the VideoSource. + + @param propertyId Property identifier from cv::VideoCaptureProperties (eg. cv::CAP_PROP_POS_MSEC, cv::CAP_PROP_POS_FRAMES, ...) + or one from @ref videoio_flags_others. + @param propertyVal Value for the specified property. + + @return `true` unless the property is unset set or not supported. + */ + CV_WRAP virtual bool get(const int propertyId, CV_OUT double& propertyVal) const = 0; }; /** @brief Interface for video demultiplexing. : @@ -417,16 +434,30 @@ class CV_EXPORTS_W RawVideoSource @param extraData 1D cv::Mat containing the extra data if it exists. */ virtual void getExtraData(cv::Mat& extraData) const = 0; + + /** @brief Retrieves the specified property used by the VideoSource. + + @param propertyId Property identifier from cv::VideoCaptureProperties (eg. cv::CAP_PROP_POS_MSEC, cv::CAP_PROP_POS_FRAMES, ...) + or one from @ref videoio_flags_others. + @param propertyVal Value for the specified property. + + @return `true` unless the property is unset set or not supported. + */ + virtual bool get(const int propertyId, double& propertyVal) const = 0; }; /** @brief Creates video reader. @param filename Name of the input video file. +@param params Pass through parameters for VideoCapure. VideoCapture with the FFMpeg back end (CAP_FFMPEG) is used to parse the video input. +The `params` parameter allows to specify extra parameters encoded as pairs `(paramId_1, paramValue_1, paramId_2, paramValue_2, ...)`. + See cv::VideoCaptureProperties +e.g. when streaming from an RTSP source CAP_PROP_OPEN_TIMEOUT_MSEC may need to be set. @param rawMode Allow the raw encoded data which has been read up until the last call to grab() to be retrieved by calling retrieve(rawData,RAW_DATA_IDX). FFMPEG is used to read videos. User can implement own demultiplexing with cudacodec::RawVideoSource */ -CV_EXPORTS_W Ptr createVideoReader(const String& filename, const bool rawMode = false); +CV_EXPORTS_W Ptr createVideoReader(const String& filename, const std::vector& params = {}, const bool rawMode = false); /** @overload @param source RAW video source implemented by user. diff --git a/modules/cudacodec/src/ffmpeg_video_source.cpp b/modules/cudacodec/src/ffmpeg_video_source.cpp index 4efbe775a02..436a18eb395 100644 --- a/modules/cudacodec/src/ffmpeg_video_source.cpp +++ b/modules/cudacodec/src/ffmpeg_video_source.cpp @@ -113,6 +113,7 @@ void FourccToChromaFormat(const int pixelFormat, ChromaFormat &chromaFormat, int } } +static int StartCodeLen(unsigned char* data, const int sz) { if (sz >= 3 && data[0] == 0 && data[1] == 0 && data[2] == 1) return 3; @@ -129,12 +130,13 @@ bool ParamSetsExist(unsigned char* parameterSets, const int szParameterSets, uns return paramSetStartCodeLen != 0 && packetStartCodeLen != 0 && parameterSets[paramSetStartCodeLen] == data[packetStartCodeLen]; } -cv::cudacodec::detail::FFmpegVideoSource::FFmpegVideoSource(const String& fname) +cv::cudacodec::detail::FFmpegVideoSource::FFmpegVideoSource(const String& fname, const std::vector& _videoCaptureParams) + : videoCaptureParams(_videoCaptureParams) { if (!videoio_registry::hasBackend(CAP_FFMPEG)) CV_Error(Error::StsNotImplemented, "FFmpeg backend not found"); - cap.open(fname, CAP_FFMPEG); + cap.open(fname, CAP_FFMPEG, videoCaptureParams); if (!cap.isOpened()) CV_Error(Error::StsUnsupportedFormat, "Unsupported video source"); @@ -176,6 +178,18 @@ void cv::cudacodec::detail::FFmpegVideoSource::updateFormat(const FormatInfo& vi format_.valid = true; } +bool cv::cudacodec::detail::FFmpegVideoSource::get(const int propertyId, double& propertyVal) const +{ + CV_Assert(videoCaptureParams.size() % 2 == 0); + for (std::size_t i = 0; i < videoCaptureParams.size(); i += 2) { + if (videoCaptureParams.at(i) == propertyId) { + propertyVal = videoCaptureParams.at(i + 1); + return true; + } + } + return false; +} + bool cv::cudacodec::detail::FFmpegVideoSource::getNextPacket(unsigned char** data, size_t* size) { cap >> rawFrame; diff --git a/modules/cudacodec/src/ffmpeg_video_source.hpp b/modules/cudacodec/src/ffmpeg_video_source.hpp index e8346331e48..ce8582f6503 100644 --- a/modules/cudacodec/src/ffmpeg_video_source.hpp +++ b/modules/cudacodec/src/ffmpeg_video_source.hpp @@ -51,7 +51,7 @@ namespace cv { namespace cudacodec { namespace detail { class FFmpegVideoSource : public RawVideoSource { public: - FFmpegVideoSource(const String& fname); + FFmpegVideoSource(const String& fname, const std::vector& params); ~FFmpegVideoSource(); bool getNextPacket(unsigned char** data, size_t* size) CV_OVERRIDE; @@ -64,11 +64,14 @@ class FFmpegVideoSource : public RawVideoSource void getExtraData(cv::Mat& _extraData) const CV_OVERRIDE { _extraData = extraData; } + bool get(const int propertyId, double& propertyVal) const; + private: FormatInfo format_; VideoCapture cap; Mat rawFrame, extraData, dataWithHeader; int iFrame = 0; + std::vector videoCaptureParams; }; }}} diff --git a/modules/cudacodec/src/video_reader.cpp b/modules/cudacodec/src/video_reader.cpp index 49884f17b20..b1cbe70f4ce 100644 --- a/modules/cudacodec/src/video_reader.cpp +++ b/modules/cudacodec/src/video_reader.cpp @@ -48,7 +48,7 @@ using namespace cv::cudacodec; #ifndef HAVE_NVCUVID -Ptr cv::cudacodec::createVideoReader(const String&, const bool) { throw_no_cuda(); return Ptr(); } +Ptr cv::cudacodec::createVideoReader(const String&, const std::vector&, const bool) { throw_no_cuda(); return Ptr(); } Ptr cv::cudacodec::createVideoReader(const Ptr&, const bool) { throw_no_cuda(); return Ptr(); } #else // HAVE_NVCUVID @@ -73,9 +73,11 @@ namespace bool retrieve(OutputArray frame, const size_t idx) const CV_OVERRIDE; - bool set(const VideoReaderProps property, const double propertyVal) CV_OVERRIDE; + bool set(const VideoReaderProps propertyId, const double propertyVal) CV_OVERRIDE; - int get(const VideoReaderProps property, const int propertyVal) const CV_OVERRIDE; + bool get(const VideoReaderProps propertyId, double& propertyVal) const CV_OVERRIDE; + + bool get(const int propertyId, double& propertyVal) const CV_OVERRIDE; private: bool internalGrab(GpuMat& frame, Stream& stream); @@ -136,8 +138,8 @@ namespace }; bool VideoReaderImpl::internalGrab(GpuMat& frame, Stream& stream) { - if (videoSource_->hasError() || videoParser_->hasError()) - CV_Error(Error::StsUnsupportedFormat, "Unsupported video source"); + if (videoParser_->hasError()) + CV_Error(Error::StsError, "Parsing/Decoding video source failed, check GPU memory is available and GPU supports hardware decoding."); if (frames_.empty()) { @@ -148,8 +150,8 @@ namespace if (frameQueue_->dequeue(displayInfo, rawPackets)) break; - if (videoSource_->hasError() || videoParser_->hasError()) - CV_Error(Error::StsUnsupportedFormat, "Unsupported video source"); + if (videoParser_->hasError()) + CV_Error(Error::StsError, "Parsing/Decoding video source failed, check GPU memory is available and GPU supports hardware decoding."); if (frameQueue_->isEndOfDecode()) return false; @@ -231,8 +233,8 @@ namespace return !frame.empty(); } - bool VideoReaderImpl::set(const VideoReaderProps property, const double propertyVal) { - switch (property) { + bool VideoReaderImpl::set(const VideoReaderProps propertyId, const double propertyVal) { + switch (propertyId) { case VideoReaderProps::PROP_RAW_MODE : videoSource_->SetRawMode(static_cast(propertyVal)); break; @@ -240,33 +242,45 @@ namespace return true; } - int VideoReaderImpl::get(const VideoReaderProps property, const int propertyVal) const { - switch (property) + bool VideoReaderImpl::get(const VideoReaderProps propertyId, double& propertyVal) const { + switch (propertyId) { case VideoReaderProps::PROP_DECODED_FRAME_IDX: - return decodedFrameIdx; + propertyVal = decodedFrameIdx; + return true; case VideoReaderProps::PROP_EXTRA_DATA_INDEX: - return extraDataIdx; + propertyVal = extraDataIdx; + return true; case VideoReaderProps::PROP_RAW_PACKAGES_BASE_INDEX: - if (videoSource_->RawModeEnabled()) - return rawPacketsBaseIdx; + if (videoSource_->RawModeEnabled()) { + propertyVal = rawPacketsBaseIdx; + return true; + } else break; case VideoReaderProps::PROP_NUMBER_OF_RAW_PACKAGES_SINCE_LAST_GRAB: - return rawPackets.size(); + propertyVal = rawPackets.size(); + return true; case::VideoReaderProps::PROP_RAW_MODE: - return videoSource_->RawModeEnabled(); + propertyVal = videoSource_->RawModeEnabled(); + return true; case::VideoReaderProps::PROP_LRF_HAS_KEY_FRAME: { const int iPacket = propertyVal - rawPacketsBaseIdx; - if (videoSource_->RawModeEnabled() && iPacket >= 0 && iPacket < rawPackets.size()) - return rawPackets.at(iPacket).containsKeyFrame; + if (videoSource_->RawModeEnabled() && iPacket >= 0 && iPacket < rawPackets.size()) { + propertyVal = rawPackets.at(iPacket).containsKeyFrame; + return true; + } else break; } default: break; } - return -1; + return false; + } + + bool VideoReaderImpl::get(const int propertyId, double& propertyVal) const { + return videoSource_->get(propertyId, propertyVal); } bool VideoReaderImpl::nextFrame(GpuMat& frame, Stream& stream) @@ -277,7 +291,7 @@ namespace } } -Ptr cv::cudacodec::createVideoReader(const String& filename, const bool rawMode) +Ptr cv::cudacodec::createVideoReader(const String& filename, const std::vector& params, const bool rawMode) { CV_Assert(!filename.empty()); @@ -286,11 +300,12 @@ Ptr cv::cudacodec::createVideoReader(const String& filename, const try { // prefer ffmpeg to cuvidGetSourceVideoFormat() which doesn't always return the corrct raw pixel format - Ptr source(new FFmpegVideoSource(filename)); + Ptr source(new FFmpegVideoSource(filename, params)); videoSource.reset(new RawVideoSourceWrapper(source, rawMode)); } catch (...) { + if (params.size()) throw; videoSource.reset(new CuvidVideoSource(filename)); } diff --git a/modules/cudacodec/src/video_source.cpp b/modules/cudacodec/src/video_source.cpp index ab549fbd8e2..b58d753f74d 100644 --- a/modules/cudacodec/src/video_source.cpp +++ b/modules/cudacodec/src/video_source.cpp @@ -71,6 +71,11 @@ void cv::cudacodec::detail::RawVideoSourceWrapper::updateFormat(const FormatInfo source_->updateFormat(videoFormat); } +bool cv::cudacodec::detail::RawVideoSourceWrapper::get(const int propertyId, double& propertyVal) const +{ + return source_->get(propertyId, propertyVal); +} + void cv::cudacodec::detail::RawVideoSourceWrapper::start() { stop_ = false; diff --git a/modules/cudacodec/src/video_source.hpp b/modules/cudacodec/src/video_source.hpp index ebaa3ba301f..8c96a34f2d5 100644 --- a/modules/cudacodec/src/video_source.hpp +++ b/modules/cudacodec/src/video_source.hpp @@ -57,6 +57,7 @@ class VideoSource virtual FormatInfo format() const = 0; virtual void updateFormat(const FormatInfo& videoFormat) = 0; + virtual bool get(const int propertyId, double& propertyVal) const { return false; } virtual void start() = 0; virtual void stop() = 0; virtual bool isStarted() const = 0; @@ -89,6 +90,7 @@ class RawVideoSourceWrapper : public VideoSource FormatInfo format() const CV_OVERRIDE; void updateFormat(const FormatInfo& videoFormat) CV_OVERRIDE; + bool get(const int propertyId, double& propertyVal) const CV_OVERRIDE; void start() CV_OVERRIDE; void stop() CV_OVERRIDE; bool isStarted() const CV_OVERRIDE; diff --git a/modules/cudacodec/test/test_video.cpp b/modules/cudacodec/test/test_video.cpp index f23360dcebb..8dca0841255 100644 --- a/modules/cudacodec/test/test_video.cpp +++ b/modules/cudacodec/test/test_video.cpp @@ -49,6 +49,11 @@ PARAM_TEST_CASE(CheckSet, cv::cuda::DeviceInfo, std::string) { }; +typedef tuple check_extra_data_params_t; +PARAM_TEST_CASE(CheckExtraData, cv::cuda::DeviceInfo, check_extra_data_params_t) +{ +}; + PARAM_TEST_CASE(Video, cv::cuda::DeviceInfo, std::string) { }; @@ -61,6 +66,18 @@ PARAM_TEST_CASE(CheckKeyFrame, cv::cuda::DeviceInfo, std::string) { }; +struct CheckParams : testing::TestWithParam +{ + cv::cuda::DeviceInfo devInfo; + + virtual void SetUp() + { + devInfo = GetParam(); + + cv::cuda::setDevice(devInfo.deviceID()); + } +}; + #if defined(HAVE_NVCUVID) ////////////////////////////////////////////////////// // VideoReader @@ -76,12 +93,19 @@ CUDA_TEST_P(CheckSet, Reader) std::string inputFile = std::string(cvtest::TS::ptr()->get_data_path()) + +"../" + GET_PARAM(1); cv::Ptr reader = cv::cudacodec::createVideoReader(inputFile); - ASSERT_FALSE(reader->get(cv::cudacodec::VideoReaderProps::PROP_RAW_MODE)); + double unsupportedVal = -1; + ASSERT_FALSE(reader->get(cv::cudacodec::VideoReaderProps::PROP_NOT_SUPPORTED, unsupportedVal)); + double rawModeVal = -1; + ASSERT_TRUE(reader->get(cv::cudacodec::VideoReaderProps::PROP_RAW_MODE, rawModeVal)); + ASSERT_FALSE(rawModeVal); ASSERT_TRUE(reader->set(cv::cudacodec::VideoReaderProps::PROP_RAW_MODE,true)); - ASSERT_TRUE(reader->get(cv::cudacodec::VideoReaderProps::PROP_RAW_MODE)); + ASSERT_TRUE(reader->get(cv::cudacodec::VideoReaderProps::PROP_RAW_MODE, rawModeVal)); + ASSERT_TRUE(rawModeVal); bool rawPacketsAvailable = false; while (reader->grab()) { - if (reader->get(cv::cudacodec::VideoReaderProps::PROP_NUMBER_OF_RAW_PACKAGES_SINCE_LAST_GRAB) > 0) { + double nRawPackages = -1; + ASSERT_TRUE(reader->get(cv::cudacodec::VideoReaderProps::PROP_NUMBER_OF_RAW_PACKAGES_SINCE_LAST_GRAB, nRawPackages)); + if (nRawPackages > 0) { rawPacketsAvailable = true; break; } @@ -89,31 +113,28 @@ CUDA_TEST_P(CheckSet, Reader) ASSERT_TRUE(rawPacketsAvailable); } -typedef tuple check_extra_data_params_t; -typedef testing::TestWithParam< check_extra_data_params_t > CheckExtraData; - CUDA_TEST_P(CheckExtraData, Reader) { // RTSP streaming is only supported by the FFmpeg back end if (!videoio_registry::hasBackend(CAP_FFMPEG)) throw SkipTestException("FFmpeg backend not found"); - const std::vector devices = cvtest::DeviceManager::instance().values(); - for (const auto& device : devices) { - cv::cuda::setDevice(device.deviceID()); - const string path = GET_PARAM(0); - const int sz = GET_PARAM(1); - std::string inputFile = std::string(cvtest::TS::ptr()->get_data_path()) + "../" + path; - cv::Ptr reader = cv::cudacodec::createVideoReader(inputFile, true); - ASSERT_TRUE(reader->get(cv::cudacodec::VideoReaderProps::PROP_RAW_MODE)); - const int extraDataIdx = reader->get(cv::cudacodec::VideoReaderProps::PROP_EXTRA_DATA_INDEX); - ASSERT_EQ(extraDataIdx, 1 ); - ASSERT_TRUE(reader->grab()); - cv::Mat extraData; - const bool newData = reader->retrieve(extraData, extraDataIdx); - ASSERT_TRUE(newData && sz || !newData && !sz); - ASSERT_EQ(extraData.total(), sz); - } + cv::cuda::setDevice(GET_PARAM(0).deviceID()); + const string path = get<0>(GET_PARAM(1)); + const int sz = get<1>(GET_PARAM(1)); + std::string inputFile = std::string(cvtest::TS::ptr()->get_data_path()) + "../" + path; + cv::Ptr reader = cv::cudacodec::createVideoReader(inputFile, {}, true); + double rawModeVal = -1; + ASSERT_TRUE(reader->get(cv::cudacodec::VideoReaderProps::PROP_RAW_MODE, rawModeVal)); + ASSERT_TRUE(rawModeVal); + double extraDataIdx = -1; + ASSERT_TRUE(reader->get(cv::cudacodec::VideoReaderProps::PROP_EXTRA_DATA_INDEX, extraDataIdx)); + ASSERT_EQ(extraDataIdx, 1 ); + ASSERT_TRUE(reader->grab()); + cv::Mat extraData; + const bool newData = reader->retrieve(extraData, extraDataIdx); + ASSERT_TRUE(newData && sz || !newData && !sz); + ASSERT_EQ(extraData.total(), sz); } CUDA_TEST_P(CheckKeyFrame, Reader) @@ -126,18 +147,23 @@ CUDA_TEST_P(CheckKeyFrame, Reader) const string path = GET_PARAM(1); std::string inputFile = std::string(cvtest::TS::ptr()->get_data_path()) + "../" + path; - cv::Ptr reader = cv::cudacodec::createVideoReader(inputFile, true); - ASSERT_TRUE(reader->get(cv::cudacodec::VideoReaderProps::PROP_RAW_MODE)); - const int rawIdxBase = reader->get(cv::cudacodec::VideoReaderProps::PROP_RAW_PACKAGES_BASE_INDEX); + cv::Ptr reader = cv::cudacodec::createVideoReader(inputFile, {}, true); + double rawModeVal = -1; + ASSERT_TRUE(reader->get(cv::cudacodec::VideoReaderProps::PROP_RAW_MODE, rawModeVal)); + ASSERT_TRUE(rawModeVal); + double rawIdxBase = -1; + ASSERT_TRUE(reader->get(cv::cudacodec::VideoReaderProps::PROP_RAW_PACKAGES_BASE_INDEX, rawIdxBase)); ASSERT_EQ(rawIdxBase, 2); constexpr int maxNPackagesToCheck = 2; int nPackages = 0; while (nPackages < maxNPackagesToCheck) { ASSERT_TRUE(reader->grab()); - const int N = reader->get(cv::cudacodec::VideoReaderProps::PROP_NUMBER_OF_RAW_PACKAGES_SINCE_LAST_GRAB); + double N = -1; + ASSERT_TRUE(reader->get(cv::cudacodec::VideoReaderProps::PROP_NUMBER_OF_RAW_PACKAGES_SINCE_LAST_GRAB,N)); for (int i = rawIdxBase; i < N + rawIdxBase; i++) { nPackages++; - const bool containsKeyFrame = reader->get(cv::cudacodec::VideoReaderProps::PROP_LRF_HAS_KEY_FRAME, i); + double containsKeyFrame = i; + ASSERT_TRUE(reader->get(cv::cudacodec::VideoReaderProps::PROP_LRF_HAS_KEY_FRAME, containsKeyFrame)); ASSERT_TRUE(nPackages == 1 && containsKeyFrame || nPackages == 2 && !containsKeyFrame) << "nPackage: " << i; if (nPackages >= maxNPackagesToCheck) break; @@ -180,9 +206,12 @@ CUDA_TEST_P(VideoReadRaw, Reader) { std::ofstream file(fileNameOut, std::ios::binary); ASSERT_TRUE(file.is_open()); - cv::Ptr reader = cv::cudacodec::createVideoReader(inputFile,true); - ASSERT_TRUE(reader->get(cv::cudacodec::VideoReaderProps::PROP_RAW_MODE)); - const int rawIdxBase = reader->get(cv::cudacodec::VideoReaderProps::PROP_RAW_PACKAGES_BASE_INDEX); + cv::Ptr reader = cv::cudacodec::createVideoReader(inputFile, {}, true); + double rawModeVal = -1; + ASSERT_TRUE(reader->get(cv::cudacodec::VideoReaderProps::PROP_RAW_MODE, rawModeVal)); + ASSERT_TRUE(rawModeVal); + double rawIdxBase = -1; + ASSERT_TRUE(reader->get(cv::cudacodec::VideoReaderProps::PROP_RAW_PACKAGES_BASE_INDEX, rawIdxBase)); ASSERT_EQ(rawIdxBase, 2); cv::cuda::GpuMat frame; for (int i = 0; i < 100; i++) @@ -190,7 +219,8 @@ CUDA_TEST_P(VideoReadRaw, Reader) ASSERT_TRUE(reader->grab()); ASSERT_TRUE(reader->retrieve(frame)); ASSERT_FALSE(frame.empty()); - const int N = reader->get(cv::cudacodec::VideoReaderProps::PROP_NUMBER_OF_RAW_PACKAGES_SINCE_LAST_GRAB); + double N = -1; + ASSERT_TRUE(reader->get(cv::cudacodec::VideoReaderProps::PROP_NUMBER_OF_RAW_PACKAGES_SINCE_LAST_GRAB,N)); ASSERT_TRUE(N >= 0) << N << " < 0"; for (int i = rawIdxBase; i <= N + rawIdxBase; i++) { Mat rawPackets; @@ -204,8 +234,9 @@ CUDA_TEST_P(VideoReadRaw, Reader) { cv::Ptr readerReference = cv::cudacodec::createVideoReader(inputFile); - cv::Ptr readerActual = cv::cudacodec::createVideoReader(fileNameOut,true); - const int decodedFrameIdx = readerActual->get(cv::cudacodec::VideoReaderProps::PROP_DECODED_FRAME_IDX); + cv::Ptr readerActual = cv::cudacodec::createVideoReader(fileNameOut, {}, true); + double decodedFrameIdx = -1; + ASSERT_TRUE(readerActual->get(cv::cudacodec::VideoReaderProps::PROP_DECODED_FRAME_IDX, decodedFrameIdx)); ASSERT_EQ(decodedFrameIdx, 0); cv::cuda::GpuMat reference, actual; cv::Mat referenceHost, actualHost; @@ -222,6 +253,42 @@ CUDA_TEST_P(VideoReadRaw, Reader) ASSERT_EQ(0, remove(fileNameOut.c_str())); } + +CUDA_TEST_P(CheckParams, Reader) +{ + std::string inputFile = std::string(cvtest::TS::ptr()->get_data_path()) + "../highgui/video/big_buck_bunny.mp4"; + { + cv::Ptr reader = cv::cudacodec::createVideoReader(inputFile); + double msActual = -1; + ASSERT_FALSE(reader->get(cv::VideoCaptureProperties::CAP_PROP_OPEN_TIMEOUT_MSEC, msActual)); + } + + { + constexpr int msReference = 3333; + cv::Ptr reader = cv::cudacodec::createVideoReader(inputFile, { + cv::VideoCaptureProperties::CAP_PROP_OPEN_TIMEOUT_MSEC, msReference }); + double msActual = -1; + ASSERT_TRUE(reader->get(cv::VideoCaptureProperties::CAP_PROP_OPEN_TIMEOUT_MSEC, msActual)); + ASSERT_EQ(msActual, msReference); + } + + { + std::vector exceptionsThrown = { false,true }; + std::vector capPropFormats = { -1,0 }; + for (int i = 0; i < capPropFormats.size(); i++) { + bool exceptionThrown = false; + try { + cv::Ptr reader = cv::cudacodec::createVideoReader(inputFile, { + cv::VideoCaptureProperties::CAP_PROP_FORMAT, capPropFormats.at(i) }); + } + catch (cv::Exception ex) { + if (ex.code == Error::StsUnsupportedFormat) + exceptionThrown = true; + } + ASSERT_EQ(exceptionThrown, exceptionsThrown.at(i)); + } + } +} #endif // HAVE_NVCUVID #if defined(_WIN32) && defined(HAVE_NVCUVENC) @@ -290,23 +357,20 @@ INSTANTIATE_TEST_CASE_P(CUDA_Codec, VideoReadRaw, testing::Combine( const check_extra_data_params_t check_extra_data_params[] = { - check_extra_data_params_t("cv/video/768x576.avi", 44), - check_extra_data_params_t("cv/video/1920x1080.avi", 47), - check_extra_data_params_t("highgui/video/big_buck_bunny.h264", 38), - check_extra_data_params_t("highgui/video/big_buck_bunny.h265", 84), check_extra_data_params_t("highgui/video/big_buck_bunny.mp4", 45), - check_extra_data_params_t("highgui/video/big_buck_bunny.avi", 58), - check_extra_data_params_t("highgui/video/big_buck_bunny.mpg", 12), check_extra_data_params_t("highgui/video/big_buck_bunny.mov", 45), check_extra_data_params_t("highgui/video/big_buck_bunny.mjpg.avi", 0) }; -INSTANTIATE_TEST_CASE_P(CUDA_Codec, CheckExtraData, testing::ValuesIn(check_extra_data_params)); +INSTANTIATE_TEST_CASE_P(CUDA_Codec, CheckExtraData, testing::Combine( + ALL_DEVICES, + testing::ValuesIn(check_extra_data_params))); INSTANTIATE_TEST_CASE_P(CUDA_Codec, CheckKeyFrame, testing::Combine( ALL_DEVICES, testing::Values(VIDEO_SRC_R))); +INSTANTIATE_TEST_CASE_P(CUDA_Codec, CheckParams, ALL_DEVICES); #endif // HAVE_NVCUVID || HAVE_NVCUVENC }} // namespace