This source file includes following definitions.
- createVideoReader
- createVideoReader
- format
- lock_
- nextFrame
- createVideoReader
- createVideoReader
#include "precomp.hpp"
using namespace cv;
using namespace cv::cuda;
using namespace cv::cudacodec;
#ifndef HAVE_NVCUVID
Ptr<VideoReader> cv::cudacodec::createVideoReader(const String&) { throw_no_cuda(); return Ptr<VideoReader>(); }
Ptr<VideoReader> cv::cudacodec::createVideoReader(const Ptr<RawVideoSource>&) { throw_no_cuda(); return Ptr<VideoReader>(); }
#else
void videoDecPostProcessFrame(const GpuMat& decodedFrame, OutputArray _outFrame, int width, int height);
using namespace cv::cudacodec::detail;
namespace
{
class VideoReaderImpl : public VideoReader
{
public:
explicit VideoReaderImpl(const Ptr<VideoSource>& source);
~VideoReaderImpl();
bool nextFrame(OutputArray frame);
FormatInfo format() const;
private:
Ptr<VideoSource> videoSource_;
Ptr<FrameQueue> frameQueue_;
Ptr<VideoDecoder> videoDecoder_;
Ptr<VideoParser> videoParser_;
CUvideoctxlock lock_;
std::deque< std::pair<CUVIDPARSERDISPINFO, CUVIDPROCPARAMS> > frames_;
};
FormatInfo VideoReaderImpl::format() const
{
return videoSource_->format();
}
VideoReaderImpl::VideoReaderImpl(const Ptr<VideoSource>& source) :
videoSource_(source),
lock_(0)
{
GpuMat temp(1, 1, CV_8UC1);
temp.release();
CUcontext ctx;
cuSafeCall( cuCtxGetCurrent(&ctx) );
cuSafeCall( cuvidCtxLockCreate(&lock_, ctx) );
frameQueue_.reset(new FrameQueue);
videoDecoder_.reset(new VideoDecoder(videoSource_->format(), lock_));
videoParser_.reset(new VideoParser(videoDecoder_, frameQueue_));
videoSource_->setVideoParser(videoParser_);
videoSource_->start();
}
VideoReaderImpl::~VideoReaderImpl()
{
frameQueue_->endDecode();
videoSource_->stop();
}
class VideoCtxAutoLock
{
public:
VideoCtxAutoLock(CUvideoctxlock lock) : m_lock(lock) { cuSafeCall( cuvidCtxLock(m_lock, 0) ); }
~VideoCtxAutoLock() { cuvidCtxUnlock(m_lock, 0); }
private:
CUvideoctxlock m_lock;
};
bool VideoReaderImpl::nextFrame(OutputArray frame)
{
if (videoSource_->hasError() || videoParser_->hasError())
CV_Error(Error::StsUnsupportedFormat, "Unsupported video source");
if (!videoSource_->isStarted() || frameQueue_->isEndOfDecode())
return false;
if (frames_.empty())
{
CUVIDPARSERDISPINFO displayInfo;
for (;;)
{
if (frameQueue_->dequeue(displayInfo))
break;
if (videoSource_->hasError() || videoParser_->hasError())
CV_Error(Error::StsUnsupportedFormat, "Unsupported video source");
if (frameQueue_->isEndOfDecode())
return false;
Thread::sleep(1);
}
bool isProgressive = displayInfo.progressive_frame != 0;
const int num_fields = isProgressive ? 1 : 2 + displayInfo.repeat_first_field;
for (int active_field = 0; active_field < num_fields; ++active_field)
{
CUVIDPROCPARAMS videoProcParams;
std::memset(&videoProcParams, 0, sizeof(CUVIDPROCPARAMS));
videoProcParams.progressive_frame = displayInfo.progressive_frame;
videoProcParams.second_field = active_field;
videoProcParams.top_field_first = displayInfo.top_field_first;
videoProcParams.unpaired_field = (num_fields == 1);
frames_.push_back(std::make_pair(displayInfo, videoProcParams));
}
}
if (frames_.empty())
return false;
std::pair<CUVIDPARSERDISPINFO, CUVIDPROCPARAMS> frameInfo = frames_.front();
frames_.pop_front();
{
VideoCtxAutoLock autoLock(lock_);
GpuMat decodedFrame = videoDecoder_->mapFrame(frameInfo.first.picture_index, frameInfo.second);
videoDecPostProcessFrame(decodedFrame, frame, videoDecoder_->targetWidth(), videoDecoder_->targetHeight());
videoDecoder_->unmapFrame(decodedFrame);
}
if (frames_.empty())
frameQueue_->releaseFrame(frameInfo.first);
return true;
}
}
Ptr<VideoReader> cv::cudacodec::createVideoReader(const String& filename)
{
CV_Assert( !filename.empty() );
Ptr<VideoSource> videoSource;
try
{
videoSource.reset(new CuvidVideoSource(filename));
}
catch (...)
{
Ptr<RawVideoSource> source(new FFmpegVideoSource(filename));
videoSource.reset(new RawVideoSourceWrapper(source));
}
return makePtr<VideoReaderImpl>(videoSource);
}
Ptr<VideoReader> cv::cudacodec::createVideoReader(const Ptr<RawVideoSource>& source)
{
Ptr<VideoSource> videoSource(new RawVideoSourceWrapper(source));
return makePtr<VideoReaderImpl>(videoSource);
}
#endif