Skip to content

Commit b2904b9

Browse files
authored
Merge pull request #3247 from cudawarped:videoreader_add_rtsp_feature
Add RTSP features to cudacodec::VideoReader * Add live video source enhancements, e.g. rtsp from ip camera's Add error logs. * Fix type. * Change badly named flag. * Alter live source flag everywhere to indicate what it does not what it is for, which should be left up to the documentation. * Prevent frame que object from being reinitialized which could be unsafe if another thread and/or object is using it.
1 parent 84f8ea8 commit b2904b9

File tree

8 files changed

+155
-63
lines changed

8 files changed

+155
-63
lines changed

modules/cudacodec/include/opencv2/cudacodec.hpp

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,8 @@ enum class VideoReaderProps {
321321
PROP_RAW_MODE = 4, //!< Status of raw mode.
322322
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.
323323
PROP_COLOR_FORMAT = 6, //!< Set the ColorFormat of the decoded frame. This can be changed before every call to nextFrame() and retrieve().
324+
PROP_UDP_SOURCE = 7, //!< Status of VideoReaderInitParams::udpSource initialization.
325+
PROP_ALLOW_FRAME_DROP = 8, //!< Status of VideoReaderInitParams::allowFrameDrop initialization.
324326
#ifndef CV_DOXYGEN
325327
PROP_NOT_SUPPORTED
326328
#endif
@@ -468,32 +470,43 @@ class CV_EXPORTS_W RawVideoSource
468470
virtual bool get(const int propertyId, double& propertyVal) const = 0;
469471
};
470472

473+
/** @brief VideoReader initialization parameters
474+
@param udpSource Remove validation which can cause VideoReader() to throw exceptions when reading from a UDP source.
475+
@param allowFrameDrop Allow frames to be dropped when ingesting from a live capture source to prevent delay and eventual disconnection
476+
when calls to nextFrame()/grab() cannot keep up with the source's fps. Only use if delay and disconnection are a problem, i.e. not when decoding from
477+
video files where setting this flag will cause frames to be unnecessarily discarded.
478+
@param minNumDecodeSurfaces Minimum number of internal decode surfaces used by the hardware decoder. NVDEC will automatically determine the minimum number of
479+
surfaces it requires for correct functionality and optimal video memory usage but not necessarily for best performance, which depends on the design of the
480+
overall application. The optimal number of decode surfaces (in terms of performance and memory utilization) should be decided by experimentation for each application,
481+
but it cannot go below the number determined by NVDEC.
482+
@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).
483+
*/
484+
struct CV_EXPORTS_W_SIMPLE VideoReaderInitParams {
485+
CV_WRAP VideoReaderInitParams() : udpSource(false), allowFrameDrop(false), minNumDecodeSurfaces(0), rawMode(0) {};
486+
CV_PROP_RW bool udpSource;
487+
CV_PROP_RW bool allowFrameDrop;
488+
CV_PROP_RW int minNumDecodeSurfaces;
489+
CV_PROP_RW bool rawMode;
490+
};
491+
471492
/** @brief Creates video reader.
472493
473494
@param filename Name of the input video file.
474-
@param params Pass through parameters for VideoCapure. VideoCapture with the FFMpeg back end (CAP_FFMPEG) is used to parse the video input.
475-
The `params` parameter allows to specify extra parameters encoded as pairs `(paramId_1, paramValue_1, paramId_2, paramValue_2, ...)`.
495+
@param sourceParams Pass through parameters for VideoCapure. VideoCapture with the FFMpeg back end (CAP_FFMPEG) is used to parse the video input.
496+
The `sourceParams` parameter allows to specify extra parameters encoded as pairs `(paramId_1, paramValue_1, paramId_2, paramValue_2, ...)`.
476497
See cv::VideoCaptureProperties
477498
e.g. when streaming from an RTSP source CAP_PROP_OPEN_TIMEOUT_MSEC may need to be set.
478-
@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).
479-
@param minNumDecodeSurfaces Minimum number of internal decode surfaces used by the hardware decoder. NVDEC will automatically determine the minimum number of
480-
surfaces it requires for correct functionality and optimal video memory usage but not necessarily for best performance, which depends on the design of the
481-
overall application. The optimal number of decode surfaces (in terms of performance and memory utilization) should be decided by experimentation for each application,
482-
but it cannot go below the number determined by NVDEC.
499+
@param params Initializaton parameters. See cv::cudacodec::VideoReaderInitParams.
483500
484501
FFMPEG is used to read videos. User can implement own demultiplexing with cudacodec::RawVideoSource
485502
*/
486-
CV_EXPORTS_W Ptr<VideoReader> createVideoReader(const String& filename, const std::vector<int>& params = {}, const bool rawMode = false, const int minNumDecodeSurfaces = 0);
503+
CV_EXPORTS_W Ptr<VideoReader> createVideoReader(const String& filename, const std::vector<int>& sourceParams = {}, const VideoReaderInitParams params = VideoReaderInitParams());
487504

488505
/** @overload
489506
@param source RAW video source implemented by user.
490-
@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).
491-
@param minNumDecodeSurfaces Minimum number of internal decode surfaces used by the hardware decoder. NVDEC will automatically determine the minimum number of
492-
surfaces it requires for correct functionality and optimal video memory usage but not necessarily for best performance, which depends on the design of the
493-
overall application. The optimal number of decode surfaces (in terms of performance and memory utilization) should be decided by experimentation for each application,
494-
but it cannot go below the number determined by NVDEC.
507+
@param params Initializaton parameters. See cv::cudacodec::VideoReaderInitParams.
495508
*/
496-
CV_EXPORTS_W Ptr<VideoReader> createVideoReader(const Ptr<RawVideoSource>& source, const bool rawMode = false, const int minNumDecodeSurfaces = 0);
509+
CV_EXPORTS_W Ptr<VideoReader> createVideoReader(const Ptr<RawVideoSource>& source, const VideoReaderInitParams params = VideoReaderInitParams());
497510

498511
//! @}
499512

modules/cudacodec/src/frame_queue.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,20 @@ cv::cudacodec::detail::FrameQueue::~FrameQueue() {
5757

5858
void cv::cudacodec::detail::FrameQueue::init(const int _maxSz) {
5959
AutoLock autoLock(mtx_);
60+
if (isFrameInUse_)
61+
return;
6062
maxSz = _maxSz;
6163
displayQueue_ = std::vector<CUVIDPARSERDISPINFO>(maxSz, CUVIDPARSERDISPINFO());
6264
isFrameInUse_ = new volatile int[maxSz];
6365
std::memset((void*)isFrameInUse_, 0, sizeof(*isFrameInUse_) * maxSz);
6466
}
6567

66-
bool cv::cudacodec::detail::FrameQueue::waitUntilFrameAvailable(int pictureIndex)
68+
bool cv::cudacodec::detail::FrameQueue::waitUntilFrameAvailable(int pictureIndex, const bool allowFrameDrop)
6769
{
6870
while (isInUse(pictureIndex))
6971
{
72+
if (allowFrameDrop && dequeueUntil(pictureIndex))
73+
break;
7074
// Decoder is getting too far ahead from display
7175
Thread::sleep(1);
7276

@@ -110,6 +114,20 @@ void cv::cudacodec::detail::FrameQueue::enqueue(const CUVIDPARSERDISPINFO* picPa
110114
} while (!isEndOfDecode());
111115
}
112116

117+
bool cv::cudacodec::detail::FrameQueue::dequeueUntil(const int pictureIndex) {
118+
AutoLock autoLock(mtx_);
119+
if (isFrameInUse_[pictureIndex] != 1)
120+
return false;
121+
for (int i = 0; i < framesInQueue_; i++) {
122+
const bool found = displayQueue_.at(readPosition_).picture_index == pictureIndex;
123+
isFrameInUse_[displayQueue_.at(readPosition_).picture_index] = 0;
124+
framesInQueue_--;
125+
readPosition_ = (readPosition_ + 1) % maxSz;
126+
if (found) return true;
127+
}
128+
return false;
129+
}
130+
113131
bool cv::cudacodec::detail::FrameQueue::dequeue(CUVIDPARSERDISPINFO& displayInfo, std::vector<RawPacket>& rawPackets)
114132
{
115133
AutoLock autoLock(mtx_);
@@ -124,6 +142,7 @@ bool cv::cudacodec::detail::FrameQueue::dequeue(CUVIDPARSERDISPINFO& displayInfo
124142
}
125143
readPosition_ = (entry + 1) % maxSz;
126144
framesInQueue_--;
145+
isFrameInUse_[displayInfo.picture_index] = 2;
127146
return true;
128147
}
129148

modules/cudacodec/src/frame_queue.hpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ class FrameQueue
7272
// If the requested frame is available the method returns true.
7373
// If decoding was interrupted before the requested frame becomes
7474
// available, the method returns false.
75-
bool waitUntilFrameAvailable(int pictureIndex);
75+
// If allowFrameDrop == true, spin is disabled and n > 0 frames are discarded
76+
// to ensure a frame is available.
77+
bool waitUntilFrameAvailable(int pictureIndex, const bool allowFrameDrop = false);
7678

7779
void enqueue(const CUVIDPARSERDISPINFO* picParams, const std::vector<RawPacket> rawPackets);
7880

@@ -84,8 +86,16 @@ class FrameQueue
8486
// false, if the queue was empty and no new frame could be returned.
8587
bool dequeue(CUVIDPARSERDISPINFO& displayInfo, std::vector<RawPacket>& rawPackets);
8688

87-
void releaseFrame(const CUVIDPARSERDISPINFO& picParams) { isFrameInUse_[picParams.picture_index] = false; }
89+
// Deque all frames up to and including the frame with index pictureIndex - must only
90+
// be called in the same thread as enqueue.
91+
// Parameters:
92+
// pictureIndex - Display index of the frame.
93+
// Returns:
94+
// true, if successful,
95+
// false, if no frames are dequed.
96+
bool dequeueUntil(const int pictureIndex);
8897

98+
void releaseFrame(const CUVIDPARSERDISPINFO& picParams) { isFrameInUse_[picParams.picture_index] = 0; }
8999
private:
90100
bool isInUse(int pictureIndex) const { return isFrameInUse_[pictureIndex] != 0; }
91101

modules/cudacodec/src/video_decoder.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,10 @@ static const char* GetVideoChromaFormatString(cudaVideoChromaFormat eChromaForma
6464

6565
void cv::cudacodec::detail::VideoDecoder::create(const FormatInfo& videoFormat)
6666
{
67-
videoFormat_ = videoFormat;
67+
{
68+
AutoLock autoLock(mtx_);
69+
videoFormat_ = videoFormat;
70+
}
6871
const cudaVideoCodec _codec = static_cast<cudaVideoCodec>(videoFormat.codec);
6972
const cudaVideoChromaFormat _chromaFormat = static_cast<cudaVideoChromaFormat>(videoFormat.chromaFormat);
7073
if (videoFormat.nBitDepthMinus8 > 0) {
@@ -120,9 +123,10 @@ void cv::cudacodec::detail::VideoDecoder::create(const FormatInfo& videoFormat)
120123
cuSafeCall(cuCtxPushCurrent(ctx_));
121124
cuSafeCall(cuvidGetDecoderCaps(&decodeCaps));
122125
cuSafeCall(cuCtxPopCurrent(NULL));
123-
if (!(decodeCaps.bIsSupported && (decodeCaps.nOutputFormatMask & (1 << cudaVideoSurfaceFormat_NV12))))
126+
if (!(decodeCaps.bIsSupported && (decodeCaps.nOutputFormatMask & (1 << cudaVideoSurfaceFormat_NV12)))){
124127
CV_Error(Error::StsUnsupportedFormat, "Video source is not supported by hardware video decoder");
125-
128+
CV_LOG_ERROR(NULL, "Video source is not supported by hardware video decoder.");
129+
}
126130
CV_Assert(videoFormat.ulWidth >= decodeCaps.nMinWidth &&
127131
videoFormat.ulHeight >= decodeCaps.nMinHeight &&
128132
videoFormat.ulWidth <= decodeCaps.nMaxWidth &&

modules/cudacodec/src/video_parser.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,10 @@
4545

4646
#ifdef HAVE_NVCUVID
4747

48-
cv::cudacodec::detail::VideoParser::VideoParser(VideoDecoder* videoDecoder, FrameQueue* frameQueue) :
49-
videoDecoder_(videoDecoder), frameQueue_(frameQueue), unparsedPackets_(0), hasError_(false)
48+
cv::cudacodec::detail::VideoParser::VideoParser(VideoDecoder* videoDecoder, FrameQueue* frameQueue, const bool allowFrameDrop, const bool udpSource) :
49+
videoDecoder_(videoDecoder), frameQueue_(frameQueue), allowFrameDrop_(allowFrameDrop)
5050
{
51+
if (udpSource) maxUnparsedPackets_ = 0;
5152
CUVIDPARSERPARAMS params;
5253
std::memset(&params, 0, sizeof(CUVIDPARSERPARAMS));
5354

@@ -78,16 +79,17 @@ bool cv::cudacodec::detail::VideoParser::parseVideoData(const unsigned char* dat
7879

7980
if (cuvidParseVideoData(parser_, &packet) != CUDA_SUCCESS)
8081
{
82+
CV_LOG_ERROR(NULL, "Call to cuvidParseVideoData failed!");
8183
hasError_ = true;
8284
frameQueue_->endDecode();
8385
return false;
8486
}
8587

86-
constexpr int maxUnparsedPackets = 20;
87-
8888
++unparsedPackets_;
89-
if (unparsedPackets_ > maxUnparsedPackets)
89+
if (maxUnparsedPackets_ && unparsedPackets_ > maxUnparsedPackets_)
9090
{
91+
CV_LOG_ERROR(NULL, "Maxium number of packets (" << maxUnparsedPackets_ << ") parsed without decoding a frame or reconfiguring the decoder, if reading from \
92+
a live source consider initializing with VideoReaderInitParams::udpSource == true.");
9193
hasError_ = true;
9294
frameQueue_->endDecode();
9395
return false;
@@ -122,7 +124,8 @@ int CUDAAPI cv::cudacodec::detail::VideoParser::HandleVideoSequence(void* userDa
122124
newFormat.height = format->coded_height;
123125
newFormat.displayArea = Rect(Point(format->display_area.left, format->display_area.top), Point(format->display_area.right, format->display_area.bottom));
124126
newFormat.fps = format->frame_rate.numerator / static_cast<float>(format->frame_rate.denominator);
125-
newFormat.ulNumDecodeSurfaces = max(thiz->videoDecoder_->nDecodeSurfaces(), static_cast<int>(format->min_num_decode_surfaces));
127+
newFormat.ulNumDecodeSurfaces = min(!thiz->allowFrameDrop_ ? max(thiz->videoDecoder_->nDecodeSurfaces(), static_cast<int>(format->min_num_decode_surfaces)) :
128+
format->min_num_decode_surfaces * 2, 32);
126129
if (format->progressive_sequence)
127130
newFormat.deinterlaceMode = Weave;
128131
else
@@ -149,6 +152,7 @@ int CUDAAPI cv::cudacodec::detail::VideoParser::HandleVideoSequence(void* userDa
149152
}
150153
catch (const cv::Exception&)
151154
{
155+
CV_LOG_ERROR(NULL, "Attempt to reconfigure Nvidia decoder failed!");
152156
thiz->hasError_ = true;
153157
return false;
154158
}
@@ -163,13 +167,13 @@ int CUDAAPI cv::cudacodec::detail::VideoParser::HandlePictureDecode(void* userDa
163167

164168
thiz->unparsedPackets_ = 0;
165169

166-
bool isFrameAvailable = thiz->frameQueue_->waitUntilFrameAvailable(picParams->CurrPicIdx);
167-
170+
bool isFrameAvailable = thiz->frameQueue_->waitUntilFrameAvailable(picParams->CurrPicIdx, thiz->allowFrameDrop_);
168171
if (!isFrameAvailable)
169172
return false;
170173

171174
if (!thiz->videoDecoder_->decodePicture(picParams))
172175
{
176+
CV_LOG_ERROR(NULL, "Decoding failed!");
173177
thiz->hasError_ = true;
174178
return false;
175179
}

modules/cudacodec/src/video_parser.hpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ namespace cv { namespace cudacodec { namespace detail {
5252
class VideoParser
5353
{
5454
public:
55-
VideoParser(VideoDecoder* videoDecoder, FrameQueue* frameQueue);
55+
VideoParser(VideoDecoder* videoDecoder, FrameQueue* frameQueue, const bool allowFrameDrop = false, const bool udpSource = false);
5656

5757
~VideoParser()
5858
{
@@ -63,13 +63,19 @@ class VideoParser
6363

6464
bool hasError() const { return hasError_; }
6565

66+
bool udpSource() const { return maxUnparsedPackets_ == 0; }
67+
68+
bool allowFrameDrops() const { return allowFrameDrop_; }
69+
6670
private:
67-
VideoDecoder* videoDecoder_;
68-
FrameQueue* frameQueue_;
71+
VideoDecoder* videoDecoder_ = 0;
72+
FrameQueue* frameQueue_ = 0;
6973
CUvideoparser parser_;
70-
int unparsedPackets_;
74+
int unparsedPackets_ = 0;
75+
int maxUnparsedPackets_ = 20;
7176
std::vector<RawPacket> currentFramePackets;
72-
volatile bool hasError_;
77+
volatile bool hasError_ = false;
78+
bool allowFrameDrop_ = false;
7379

7480
// Called when the decoder encounters a video format change (or initial sequence header)
7581
// This particular implementation of the callback returns 0 in case the video format changes

modules/cudacodec/src/video_reader.cpp

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ using namespace cv::cudacodec;
4848

4949
#ifndef HAVE_NVCUVID
5050

51-
Ptr<VideoReader> cv::cudacodec::createVideoReader(const String&, const std::vector<int>&, const bool, const int) { throw_no_cuda(); return Ptr<VideoReader>(); }
52-
Ptr<VideoReader> cv::cudacodec::createVideoReader(const Ptr<RawVideoSource>&, const bool, const int) { throw_no_cuda(); return Ptr<VideoReader>(); }
51+
Ptr<VideoReader> cv::cudacodec::createVideoReader(const String&, const std::vector<int>&, const VideoReaderInitParams) { throw_no_cuda(); return Ptr<VideoReader>(); }
52+
Ptr<VideoReader> cv::cudacodec::createVideoReader(const Ptr<RawVideoSource>&, const VideoReaderInitParams) { throw_no_cuda(); return Ptr<VideoReader>(); }
5353

5454
#else // HAVE_NVCUVID
5555

@@ -86,7 +86,7 @@ namespace
8686
class VideoReaderImpl : public VideoReader
8787
{
8888
public:
89-
explicit VideoReaderImpl(const Ptr<VideoSource>& source, const int minNumDecodeSurfaces);
89+
explicit VideoReaderImpl(const Ptr<VideoSource>& source, const int minNumDecodeSurfaces, const bool allowFrameDrop = false , const bool udpSource = false);
9090
~VideoReaderImpl();
9191

9292
bool nextFrame(GpuMat& frame, Stream& stream) CV_OVERRIDE;
@@ -130,7 +130,7 @@ namespace
130130
return videoSource_->format();
131131
}
132132

133-
VideoReaderImpl::VideoReaderImpl(const Ptr<VideoSource>& source, const int minNumDecodeSurfaces) :
133+
VideoReaderImpl::VideoReaderImpl(const Ptr<VideoSource>& source, const int minNumDecodeSurfaces, const bool allowFrameDrop, const bool udpSource) :
134134
videoSource_(source),
135135
lock_(0)
136136
{
@@ -143,7 +143,7 @@ namespace
143143
cuSafeCall( cuvidCtxLockCreate(&lock_, ctx) );
144144
frameQueue_.reset(new FrameQueue());
145145
videoDecoder_.reset(new VideoDecoder(videoSource_->format().codec, minNumDecodeSurfaces, ctx, lock_));
146-
videoParser_.reset(new VideoParser(videoDecoder_, frameQueue_));
146+
videoParser_.reset(new VideoParser(videoDecoder_, frameQueue_, allowFrameDrop, udpSource));
147147
videoSource_->setVideoParser(videoParser_);
148148
videoSource_->start();
149149
}
@@ -291,10 +291,10 @@ namespace
291291
case VideoReaderProps::PROP_NUMBER_OF_RAW_PACKAGES_SINCE_LAST_GRAB:
292292
propertyVal = rawPackets.size();
293293
return true;
294-
case::VideoReaderProps::PROP_RAW_MODE:
294+
case VideoReaderProps::PROP_RAW_MODE:
295295
propertyVal = videoSource_->RawModeEnabled();
296296
return true;
297-
case::VideoReaderProps::PROP_LRF_HAS_KEY_FRAME: {
297+
case VideoReaderProps::PROP_LRF_HAS_KEY_FRAME: {
298298
const int iPacket = propertyVal - rawPacketsBaseIdx;
299299
if (videoSource_->RawModeEnabled() && iPacket >= 0 && iPacket < rawPackets.size()) {
300300
propertyVal = rawPackets.at(iPacket).containsKeyFrame;
@@ -303,6 +303,14 @@ namespace
303303
else
304304
break;
305305
}
306+
case VideoReaderProps::PROP_ALLOW_FRAME_DROP: {
307+
propertyVal = videoParser_->allowFrameDrops();
308+
return true;
309+
}
310+
case VideoReaderProps::PROP_UDP_SOURCE: {
311+
propertyVal = videoParser_->udpSource();
312+
return true;
313+
}
306314
default:
307315
break;
308316
}
@@ -321,7 +329,7 @@ namespace
321329
}
322330
}
323331

324-
Ptr<VideoReader> cv::cudacodec::createVideoReader(const String& filename, const std::vector<int>& params, const bool rawMode, const int minNumDecodeSurfaces)
332+
Ptr<VideoReader> cv::cudacodec::createVideoReader(const String& filename, const std::vector<int>& sourceParams, const VideoReaderInitParams params)
325333
{
326334
CV_Assert(!filename.empty());
327335

@@ -330,22 +338,22 @@ Ptr<VideoReader> cv::cudacodec::createVideoReader(const String& filename, const
330338
try
331339
{
332340
// prefer ffmpeg to cuvidGetSourceVideoFormat() which doesn't always return the corrct raw pixel format
333-
Ptr<RawVideoSource> source(new FFmpegVideoSource(filename, params));
334-
videoSource.reset(new RawVideoSourceWrapper(source, rawMode));
341+
Ptr<RawVideoSource> source(new FFmpegVideoSource(filename, sourceParams));
342+
videoSource.reset(new RawVideoSourceWrapper(source, params.rawMode));
335343
}
336344
catch (...)
337345
{
338-
if (params.size()) throw;
346+
if (sourceParams.size()) throw;
339347
videoSource.reset(new CuvidVideoSource(filename));
340348
}
341349

342-
return makePtr<VideoReaderImpl>(videoSource, minNumDecodeSurfaces);
350+
return makePtr<VideoReaderImpl>(videoSource, params.minNumDecodeSurfaces, params.allowFrameDrop, params.udpSource);
343351
}
344352

345-
Ptr<VideoReader> cv::cudacodec::createVideoReader(const Ptr<RawVideoSource>& source, const bool rawMode, const int minNumDecodeSurfaces)
353+
Ptr<VideoReader> cv::cudacodec::createVideoReader(const Ptr<RawVideoSource>& source, const VideoReaderInitParams params)
346354
{
347-
Ptr<VideoSource> videoSource(new RawVideoSourceWrapper(source, rawMode));
348-
return makePtr<VideoReaderImpl>(videoSource, minNumDecodeSurfaces);
355+
Ptr<VideoSource> videoSource(new RawVideoSourceWrapper(source, params.rawMode));
356+
return makePtr<VideoReaderImpl>(videoSource, params.minNumDecodeSurfaces);
349357
}
350358

351359
#endif // HAVE_NVCUVID

0 commit comments

Comments
 (0)