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