From 76211709a3ee38a7212340fb17b8d12ffbaef506 Mon Sep 17 00:00:00 2001 From: Vladislav Vinogradov Date: Tue, 11 Jun 2013 13:05:02 +0400 Subject: [PATCH] refactored VideoReader (convert it to abstract interface) also refactored VideoSource interface (made it simplier, now it has only 2 abstract methods) --- modules/gpucodec/doc/videodec.rst | 195 +++------ modules/gpucodec/include/opencv2/gpucodec.hpp | 139 ++----- modules/gpucodec/perf/perf_video.cpp | 5 +- modules/gpucodec/src/cuda/nv12_to_rgb.cu | 7 +- modules/gpucodec/src/cuvid_video_source.cpp | 35 +- ..._video_source.h => cuvid_video_source.hpp} | 23 +- modules/gpucodec/src/ffmpeg_video_source.cpp | 77 +--- ...video_source.h => ffmpeg_video_source.hpp} | 37 +- modules/gpucodec/src/frame_queue.cpp | 13 +- .../src/{frame_queue.h => frame_queue.hpp} | 11 +- modules/gpucodec/src/precomp.hpp | 13 +- modules/gpucodec/src/thread.cpp | 17 +- modules/gpucodec/src/{thread.h => thread.hpp} | 13 +- modules/gpucodec/src/video_decoder.cpp | 7 +- .../{video_decoder.h => video_decoder.hpp} | 25 +- modules/gpucodec/src/video_parser.cpp | 21 +- .../src/{video_parser.h => video_parser.hpp} | 19 +- modules/gpucodec/src/video_reader.cpp | 392 ++++++------------ modules/gpucodec/src/video_source.cpp | 121 ++++++ modules/gpucodec/src/video_source.hpp | 99 +++++ modules/gpucodec/test/test_video.cpp | 8 +- modules/superres/src/frame_source.cpp | 10 +- samples/gpu/video_reader.cpp | 5 +- 23 files changed, 590 insertions(+), 702 deletions(-) rename modules/gpucodec/src/{cuvid_video_source.h => cuvid_video_source.hpp} (88%) rename modules/gpucodec/src/{ffmpeg_video_source.h => ffmpeg_video_source.hpp} (75%) rename modules/gpucodec/src/{frame_queue.h => frame_queue.hpp} (93%) rename modules/gpucodec/src/{thread.h => thread.hpp} (87%) rename modules/gpucodec/src/{video_decoder.h => video_decoder.hpp} (85%) rename modules/gpucodec/src/{video_parser.h => video_parser.hpp} (92%) create mode 100644 modules/gpucodec/src/video_source.cpp create mode 100644 modules/gpucodec/src/video_source.hpp diff --git a/modules/gpucodec/doc/videodec.rst b/modules/gpucodec/doc/videodec.rst index 342203223b..e2da305591 100644 --- a/modules/gpucodec/doc/videodec.rst +++ b/modules/gpucodec/doc/videodec.rst @@ -5,20 +5,37 @@ Video Decoding -gpu::VideoReader_GPU --------------------- -Video reader class. +gpucodec::VideoReader +--------------------- +Video reader interface. -.. ocv:class:: gpu::VideoReader_GPU +.. ocv:class:: gpucodec::VideoReader -gpu::VideoReader_GPU::Codec ---------------------------- +gpucodec::VideoReader::nextFrame +-------------------------------- +Grabs, decodes and returns the next video frame. + +.. ocv:function:: bool gpucodec::VideoReader::nextFrame(OutputArray frame) + +If no frames has been grabbed (there are no more frames in video file), the methods return ``false`` . The method throws :ocv:class:`Exception` if error occurs. + + + +gpucodec::VideoReader::format +----------------------------- +Returns information about video file format. + +.. ocv:function:: FormatInfo gpucodec::VideoReader::format() const + -Video codecs supported by :ocv:class:`gpu::VideoReader_GPU` . -.. ocv:enum:: gpu::VideoReader_GPU::Codec +gpucodec::Codec +--------------- +Video codecs supported by :ocv:class:`gpucodec::VideoReader` . + +.. ocv:enum:: gpucodec::Codec .. ocv:emember:: MPEG1 = 0 .. ocv:emember:: MPEG2 @@ -50,12 +67,12 @@ Video codecs supported by :ocv:class:`gpu::VideoReader_GPU` . UYVY (4:2:2) -gpu::VideoReader_GPU::ChromaFormat ----------------------------------- -Chroma formats supported by :ocv:class:`gpu::VideoReader_GPU` . +gpucodec::ChromaFormat +---------------------- +Chroma formats supported by :ocv:class:`gpucodec::VideoReader` . -.. ocv:enum:: gpu::VideoReader_GPU::ChromaFormat +.. ocv:enum:: gpucodec::ChromaFormat .. ocv:emember:: Monochrome = 0 .. ocv:emember:: YUV420 @@ -63,9 +80,10 @@ Chroma formats supported by :ocv:class:`gpu::VideoReader_GPU` . .. ocv:emember:: YUV444 -gpu::VideoReader_GPU::FormatInfo --------------------------------- -.. ocv:struct:: gpu::VideoReader_GPU::FormatInfo + +gpucodec::FormatInfo +-------------------- +.. ocv:struct:: gpucodec::FormatInfo Struct providing information about video file format. :: @@ -78,157 +96,58 @@ Struct providing information about video file format. :: }; -gpu::VideoReader_GPU::VideoReader_GPU -------------------------------------- -Constructors. - -.. ocv:function:: gpu::VideoReader_GPU::VideoReader_GPU() -.. ocv:function:: gpu::VideoReader_GPU::VideoReader_GPU(const String& filename) -.. ocv:function:: gpu::VideoReader_GPU::VideoReader_GPU(const cv::Ptr& source) - - :param filename: Name of the input video file. - :param source: Video file parser implemented by user. - -The constructors initialize video reader. FFMPEG is used to read videos. User can implement own demultiplexing with :ocv:class:`gpu::VideoReader_GPU::VideoSource` . - - - -gpu::VideoReader_GPU::open --------------------------- -Initializes or reinitializes video reader. - -.. ocv:function:: void gpu::VideoReader_GPU::open(const String& filename) -.. ocv:function:: void gpu::VideoReader_GPU::open(const cv::Ptr& source) - -The method opens video reader. Parameters are the same as in the constructor :ocv:func:`gpu::VideoReader_GPU::VideoReader_GPU` . The method throws :ocv:class:`Exception` if error occurs. - - - -gpu::VideoReader_GPU::isOpened ------------------------------- -Returns true if video reader has been successfully initialized. - -.. ocv:function:: bool gpu::VideoReader_GPU::isOpened() const - - - -gpu::VideoReader_GPU::close +gpucodec::createVideoReader --------------------------- -Releases the video reader. - -.. ocv:function:: void gpu::VideoReader_GPU::close() - +Creates video reader. +.. ocv:function:: Ptr gpucodec::createVideoReader(const String& filename) +.. ocv:function:: Ptr gpucodec::createVideoReader(const Ptr& source) -gpu::VideoReader_GPU::read --------------------------- -Grabs, decodes and returns the next video frame. - -.. ocv:function:: bool gpu::VideoReader_GPU::read(GpuMat& image) - -If no frames has been grabbed (there are no more frames in video file), the methods return ``false`` . The method throws :ocv:class:`Exception` if error occurs. - - - -gpu::VideoReader_GPU::format ----------------------------- -Returns information about video file format. - -.. ocv:function:: FormatInfo gpu::VideoReader_GPU::format() const - -The method throws :ocv:class:`Exception` if video reader wasn't initialized. - - - -gpu::VideoReader_GPU::dumpFormat --------------------------------- -Dump information about video file format to specified stream. - -.. ocv:function:: void gpu::VideoReader_GPU::dumpFormat(std::ostream& st) + :param filename: Name of the input video file. - :param st: Output stream. + :param source: RAW video source implemented by user. -The method throws :ocv:class:`Exception` if video reader wasn't initialized. +FFMPEG is used to read videos. User can implement own demultiplexing with :ocv:class:`gpucodec::RawVideoSource` . -gpu::VideoReader_GPU::VideoSource ------------------------------------ -.. ocv:class:: gpu::VideoReader_GPU::VideoSource +gpucodec::RawVideoSource +------------------------ +.. ocv:class:: gpucodec::RawVideoSource Interface for video demultiplexing. :: - class VideoSource + class RawVideoSource { public: - VideoSource(); - virtual ~VideoSource() {} + virtual ~RawVideoSource() {} - virtual FormatInfo format() const = 0; - virtual void start() = 0; - virtual void stop() = 0; - virtual bool isStarted() const = 0; - virtual bool hasError() const = 0; + virtual bool getNextPacket(unsigned char** data, int* size, bool* endOfFile) = 0; - protected: - bool parseVideoData(const unsigned char* data, size_t size, bool endOfStream = false); + virtual FormatInfo format() const = 0; }; User can implement own demultiplexing by implementing this interface. -gpu::VideoReader_GPU::VideoSource::format ------------------------------------------ -Returns information about video file format. - -.. ocv:function:: virtual FormatInfo gpu::VideoReader_GPU::VideoSource::format() const = 0 - - - -gpu::VideoReader_GPU::VideoSource::start ----------------------------------------- -Starts processing. - -.. ocv:function:: virtual void gpu::VideoReader_GPU::VideoSource::start() = 0 - -Implementation must create own thread with video processing and call periodic :ocv:func:`gpu::VideoReader_GPU::VideoSource::parseVideoData` . - - - -gpu::VideoReader_GPU::VideoSource::stop +gpucodec::RawVideoSource::getNextPacket --------------------------------------- -Stops processing. - -.. ocv:function:: virtual void gpu::VideoReader_GPU::VideoSource::stop() = 0 - - - -gpu::VideoReader_GPU::VideoSource::isStarted --------------------------------------------- -Returns ``true`` if processing was successfully started. - -.. ocv:function:: virtual bool gpu::VideoReader_GPU::VideoSource::isStarted() const = 0 +Returns next packet with RAW video frame. +.. ocv:function:: bool gpucodec::VideoSource::getNextPacket(unsigned char** data, int* size, bool* endOfFile) = 0 + :param data: Pointer to frame data. -gpu::VideoReader_GPU::VideoSource::hasError -------------------------------------------- -Returns ``true`` if error occured during processing. - -.. ocv:function:: virtual bool gpu::VideoReader_GPU::VideoSource::hasError() const = 0 - - + :param size: Size in bytes of current frame. -gpu::VideoReader_GPU::VideoSource::parseVideoData -------------------------------------------------- -Parse next video frame. Implementation must call this method after new frame was grabbed. + :param endOfStream: Indicates that it is end of stream. -.. ocv:function:: bool gpu::VideoReader_GPU::VideoSource::parseVideoData(const uchar* data, size_t size, bool endOfStream = false) - :param data: Pointer to frame data. Can be ``NULL`` if ``endOfStream`` if ``true`` . - :param size: Size in bytes of current frame. +gpucodec::RawVideoSource::format +-------------------------------- +Returns information about video file format. - :param endOfStream: Indicates that it is end of stream. +.. ocv:function:: virtual FormatInfo gpucodec::RawVideoSource::format() const = 0 diff --git a/modules/gpucodec/include/opencv2/gpucodec.hpp b/modules/gpucodec/include/opencv2/gpucodec.hpp index 8c3cd86c7b..f2e298fd70 100644 --- a/modules/gpucodec/include/opencv2/gpucodec.hpp +++ b/modules/gpucodec/include/opencv2/gpucodec.hpp @@ -48,8 +48,6 @@ # error gpucodec.hpp header must be compiled as C++ #endif -#include - #include "opencv2/core/gpu.hpp" namespace cv { namespace gpucodec { @@ -144,112 +142,65 @@ CV_EXPORTS Ptr createVideoWriter(const String& fileName, Size frame CV_EXPORTS Ptr createVideoWriter(const Ptr& encoderCallback, Size frameSize, double fps, SurfaceFormat format = SF_BGR); CV_EXPORTS Ptr createVideoWriter(const Ptr& encoderCallback, Size frameSize, double fps, const EncoderParams& params, SurfaceFormat format = SF_BGR); -}} // namespace cv { namespace gpucodec { - -namespace cv { namespace gpu { - ////////////////////////////////// Video Decoding ////////////////////////////////////////// -namespace detail +enum Codec { - class FrameQueue; - class VideoParser; -} + MPEG1 = 0, + MPEG2, + MPEG4, + VC1, + H264, + JPEG, + H264_SVC, + H264_MVC, + + Uncompressed_YUV420 = (('I'<<24)|('Y'<<16)|('U'<<8)|('V')), // Y,U,V (4:2:0) + Uncompressed_YV12 = (('Y'<<24)|('V'<<16)|('1'<<8)|('2')), // Y,V,U (4:2:0) + Uncompressed_NV12 = (('N'<<24)|('V'<<16)|('1'<<8)|('2')), // Y,UV (4:2:0) + Uncompressed_YUYV = (('Y'<<24)|('U'<<16)|('Y'<<8)|('V')), // YUYV/YUY2 (4:2:2) + Uncompressed_UYVY = (('U'<<24)|('Y'<<16)|('V'<<8)|('Y')) // UYVY (4:2:2) +}; -class CV_EXPORTS VideoReader_GPU +enum ChromaFormat { -public: - enum Codec - { - MPEG1 = 0, - MPEG2, - MPEG4, - VC1, - H264, - JPEG, - H264_SVC, - H264_MVC, - - Uncompressed_YUV420 = (('I'<<24)|('Y'<<16)|('U'<<8)|('V')), // Y,U,V (4:2:0) - Uncompressed_YV12 = (('Y'<<24)|('V'<<16)|('1'<<8)|('2')), // Y,V,U (4:2:0) - Uncompressed_NV12 = (('N'<<24)|('V'<<16)|('1'<<8)|('2')), // Y,UV (4:2:0) - Uncompressed_YUYV = (('Y'<<24)|('U'<<16)|('Y'<<8)|('V')), // YUYV/YUY2 (4:2:2) - Uncompressed_UYVY = (('U'<<24)|('Y'<<16)|('V'<<8)|('Y')), // UYVY (4:2:2) - }; - - enum ChromaFormat - { - Monochrome=0, - YUV420, - YUV422, - YUV444, - }; - - struct FormatInfo - { - Codec codec; - ChromaFormat chromaFormat; - int width; - int height; - }; - - class VideoSource; - - VideoReader_GPU(); - explicit VideoReader_GPU(const String& filename); - explicit VideoReader_GPU(const cv::Ptr& source); - - ~VideoReader_GPU(); - - void open(const String& filename); - void open(const cv::Ptr& source); - bool isOpened() const; - - void close(); - - bool read(GpuMat& image); - - FormatInfo format() const; - void dumpFormat(std::ostream& st); - - class CV_EXPORTS VideoSource - { - public: - VideoSource() : frameQueue_(0), videoParser_(0) {} - virtual ~VideoSource() {} + Monochrome = 0, + YUV420, + YUV422, + YUV444 +}; - virtual FormatInfo format() const = 0; - virtual void start() = 0; - virtual void stop() = 0; - virtual bool isStarted() const = 0; - virtual bool hasError() const = 0; +struct FormatInfo +{ + Codec codec; + ChromaFormat chromaFormat; + int width; + int height; +}; - void setFrameQueue(detail::FrameQueue* frameQueue) { frameQueue_ = frameQueue; } - void setVideoParser(detail::VideoParser* videoParser) { videoParser_ = videoParser; } +class CV_EXPORTS VideoReader +{ +public: + virtual ~VideoReader() {} - protected: - bool parseVideoData(const uchar* data, size_t size, bool endOfStream = false); + virtual bool nextFrame(OutputArray frame) = 0; - private: - VideoSource(const VideoSource&); - VideoSource& operator =(const VideoSource&); + virtual FormatInfo format() const = 0; +}; - detail::FrameQueue* frameQueue_; - detail::VideoParser* videoParser_; - }; +class CV_EXPORTS RawVideoSource +{ +public: + virtual ~RawVideoSource() {} - class Impl; + virtual bool getNextPacket(unsigned char** data, int* size, bool* endOfFile) = 0; -private: - cv::Ptr impl_; + virtual FormatInfo format() const = 0; }; -}} // namespace cv { namespace gpu { - -namespace cv { +CV_EXPORTS Ptr createVideoReader(const String& filename); +CV_EXPORTS Ptr createVideoReader(const Ptr& source); -template <> CV_EXPORTS void Ptr::delete_obj(); - -} +}} // namespace cv { namespace gpucodec { #endif /* __OPENCV_GPUCODEC_HPP__ */ diff --git a/modules/gpucodec/perf/perf_video.cpp b/modules/gpucodec/perf/perf_video.cpp index ec9237d37a..f389605d05 100644 --- a/modules/gpucodec/perf/perf_video.cpp +++ b/modules/gpucodec/perf/perf_video.cpp @@ -74,12 +74,11 @@ PERF_TEST_P(FileName, VideoReader, Values("gpu/video/768x576.avi", "gpu/video/19 if (PERF_RUN_GPU()) { - cv::gpu::VideoReader_GPU d_reader(inputFile); - ASSERT_TRUE( d_reader.isOpened() ); + cv::Ptr d_reader = cv::gpucodec::createVideoReader(inputFile); cv::gpu::GpuMat frame; - TEST_CYCLE_N(10) d_reader.read(frame); + TEST_CYCLE_N(10) d_reader->nextFrame(frame); GPU_SANITY_CHECK(frame); } diff --git a/modules/gpucodec/src/cuda/nv12_to_rgb.cu b/modules/gpucodec/src/cuda/nv12_to_rgb.cu index 536ba2715f..1de916e5a3 100644 --- a/modules/gpucodec/src/cuda/nv12_to_rgb.cu +++ b/modules/gpucodec/src/cuda/nv12_to_rgb.cu @@ -51,12 +51,7 @@ namespace cv { namespace gpu { namespace cudev { - __constant__ float constHueColorSpaceMat[9]; - - void loadHueCSC(float hueCSC[9]) - { - cudaSafeCall( cudaMemcpyToSymbol(constHueColorSpaceMat, hueCSC, 9 * sizeof(float)) ); - } + __constant__ float constHueColorSpaceMat[9] = {1.1644f, 0.0f, 1.596f, 1.1644f, -0.3918f, -0.813f, 1.1644f, 2.0172f, 0.0f}; __device__ void YUV2RGB(const uint* yuvi, float* red, float* green, float* blue) { diff --git a/modules/gpucodec/src/cuvid_video_source.cpp b/modules/gpucodec/src/cuvid_video_source.cpp index 73d6d24263..477951e931 100644 --- a/modules/gpucodec/src/cuvid_video_source.cpp +++ b/modules/gpucodec/src/cuvid_video_source.cpp @@ -7,11 +7,12 @@ // copy or use the software. // // -// License Agreement +// License Agreement // For Open Source Computer Vision Library // // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. // Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, @@ -44,7 +45,11 @@ #ifdef HAVE_NVCUVID -cv::gpu::detail::CuvidVideoSource::CuvidVideoSource(const String& fname) +using namespace cv; +using namespace cv::gpucodec; +using namespace cv::gpucodec::detail; + +cv::gpucodec::detail::CuvidVideoSource::CuvidVideoSource(const String& fname) { CUVIDSOURCEPARAMS params; std::memset(¶ms, 0, sizeof(CUVIDSOURCEPARAMS)); @@ -55,51 +60,51 @@ cv::gpu::detail::CuvidVideoSource::CuvidVideoSource(const String& fname) params.pfnAudioDataHandler = 0; // now create the actual source - CUresult res = cuvidCreateVideoSource(&videoSource_, fname.c_str(), ¶ms); - if (res == CUDA_ERROR_INVALID_SOURCE) - throw std::runtime_error("Unsupported video source"); - cuSafeCall( res ); + CUresult cuRes = cuvidCreateVideoSource(&videoSource_, fname.c_str(), ¶ms); + if (cuRes == CUDA_ERROR_INVALID_SOURCE) + throw std::runtime_error(""); + cuSafeCall( cuRes ); CUVIDEOFORMAT vidfmt; cuSafeCall( cuvidGetSourceVideoFormat(videoSource_, &vidfmt, 0) ); - format_.codec = static_cast(vidfmt.codec); - format_.chromaFormat = static_cast(vidfmt.chroma_format); + format_.codec = static_cast(vidfmt.codec); + format_.chromaFormat = static_cast(vidfmt.chroma_format); format_.width = vidfmt.coded_width; format_.height = vidfmt.coded_height; } -cv::gpu::detail::CuvidVideoSource::~CuvidVideoSource() +cv::gpucodec::detail::CuvidVideoSource::~CuvidVideoSource() { cuvidDestroyVideoSource(videoSource_); } -cv::gpu::VideoReader_GPU::FormatInfo cv::gpu::detail::CuvidVideoSource::format() const +FormatInfo cv::gpucodec::detail::CuvidVideoSource::format() const { return format_; } -void cv::gpu::detail::CuvidVideoSource::start() +void cv::gpucodec::detail::CuvidVideoSource::start() { cuSafeCall( cuvidSetVideoSourceState(videoSource_, cudaVideoState_Started) ); } -void cv::gpu::detail::CuvidVideoSource::stop() +void cv::gpucodec::detail::CuvidVideoSource::stop() { cuSafeCall( cuvidSetVideoSourceState(videoSource_, cudaVideoState_Stopped) ); } -bool cv::gpu::detail::CuvidVideoSource::isStarted() const +bool cv::gpucodec::detail::CuvidVideoSource::isStarted() const { return (cuvidGetVideoSourceState(videoSource_) == cudaVideoState_Started); } -bool cv::gpu::detail::CuvidVideoSource::hasError() const +bool cv::gpucodec::detail::CuvidVideoSource::hasError() const { return (cuvidGetVideoSourceState(videoSource_) == cudaVideoState_Error); } -int CUDAAPI cv::gpu::detail::CuvidVideoSource::HandleVideoData(void* userData, CUVIDSOURCEDATAPACKET* packet) +int CUDAAPI cv::gpucodec::detail::CuvidVideoSource::HandleVideoData(void* userData, CUVIDSOURCEDATAPACKET* packet) { CuvidVideoSource* thiz = static_cast(userData); diff --git a/modules/gpucodec/src/cuvid_video_source.h b/modules/gpucodec/src/cuvid_video_source.hpp similarity index 88% rename from modules/gpucodec/src/cuvid_video_source.h rename to modules/gpucodec/src/cuvid_video_source.hpp index a4a0e85211..c2f0e2f571 100644 --- a/modules/gpucodec/src/cuvid_video_source.h +++ b/modules/gpucodec/src/cuvid_video_source.hpp @@ -7,11 +7,12 @@ // copy or use the software. // // -// License Agreement +// License Agreement // For Open Source Computer Vision Library // // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. // Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, @@ -40,25 +41,25 @@ // //M*/ -#ifndef __CUVUD_VIDEO_SOURCE_H__ -#define __CUVUD_VIDEO_SOURCE_H__ +#ifndef __CUVID_VIDEO_SOURCE_HPP__ +#define __CUVID_VIDEO_SOURCE_HPP__ + +#include #include "opencv2/core/private.gpu.hpp" #include "opencv2/gpucodec.hpp" -#include "thread.h" - -#include +#include "video_source.hpp" -namespace cv { namespace gpu { namespace detail +namespace cv { namespace gpucodec { namespace detail { -class CuvidVideoSource : public VideoReader_GPU::VideoSource +class CuvidVideoSource : public VideoSource { public: explicit CuvidVideoSource(const String& fname); ~CuvidVideoSource(); - VideoReader_GPU::FormatInfo format() const; + FormatInfo format() const; void start(); void stop(); bool isStarted() const; @@ -78,9 +79,9 @@ private: static int CUDAAPI HandleVideoData(void* pUserData, CUVIDSOURCEDATAPACKET* pPacket); CUvideosource videoSource_; - VideoReader_GPU::FormatInfo format_; + FormatInfo format_; }; }}} -#endif // __CUVUD_VIDEO_SOURCE_H__ +#endif // __CUVID_VIDEO_SOURCE_HPP__ diff --git a/modules/gpucodec/src/ffmpeg_video_source.cpp b/modules/gpucodec/src/ffmpeg_video_source.cpp index 6ba09284dc..b5a73875bc 100644 --- a/modules/gpucodec/src/ffmpeg_video_source.cpp +++ b/modules/gpucodec/src/ffmpeg_video_source.cpp @@ -7,11 +7,12 @@ // copy or use the software. // // -// License Agreement +// License Agreement // For Open Source Computer Vision Library // // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. // Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, @@ -48,6 +49,10 @@ #include "../src/cap_ffmpeg_impl.hpp" #endif +using namespace cv; +using namespace cv::gpucodec; +using namespace cv::gpucodec::detail; + namespace { Create_InputMediaStream_FFMPEG_Plugin create_InputMediaStream_FFMPEG_p = 0; @@ -94,7 +99,7 @@ namespace } } -cv::gpu::detail::FFmpegVideoSource::FFmpegVideoSource(const String& fname) : +cv::gpucodec::detail::FFmpegVideoSource::FFmpegVideoSource(const String& fname) : stream_(0) { CV_Assert( init_MediaStream_FFMPEG() ); @@ -106,75 +111,33 @@ cv::gpu::detail::FFmpegVideoSource::FFmpegVideoSource(const String& fname) : stream_ = create_InputMediaStream_FFMPEG_p(fname.c_str(), &codec, &chroma_format, &width, &height); if (!stream_) - CV_Error(cv::Error::StsUnsupportedFormat, "Unsupported video source"); + CV_Error(Error::StsUnsupportedFormat, "Unsupported video source"); - format_.codec = static_cast(codec); - format_.chromaFormat = static_cast(chroma_format); + format_.codec = static_cast(codec); + format_.chromaFormat = static_cast(chroma_format); format_.width = width; format_.height = height; } -cv::gpu::VideoReader_GPU::FormatInfo cv::gpu::detail::FFmpegVideoSource::format() const -{ - return format_; -} - -void cv::gpu::detail::FFmpegVideoSource::start() -{ - stop_ = false; - hasError_ = false; - thread_ = new Thread(readLoop, this); -} - -void cv::gpu::detail::FFmpegVideoSource::stop() -{ - stop_ = true; - thread_->wait(); - thread_.release(); -} - -bool cv::gpu::detail::FFmpegVideoSource::isStarted() const +cv::gpucodec::detail::FFmpegVideoSource::~FFmpegVideoSource() { - return !stop_; + if (stream_) + release_InputMediaStream_FFMPEG_p(stream_); } -bool cv::gpu::detail::FFmpegVideoSource::hasError() const +FormatInfo cv::gpucodec::detail::FFmpegVideoSource::format() const { - return hasError_; + return format_; } -void cv::gpu::detail::FFmpegVideoSource::readLoop(void* userData) +bool cv::gpucodec::detail::FFmpegVideoSource::getNextPacket(unsigned char** data, int* size, bool* bEndOfFile) { - FFmpegVideoSource* thiz = static_cast(userData); + int endOfFile; - for (;;) - { - unsigned char* data; - int size; - int endOfFile; - - if (!read_InputMediaStream_FFMPEG_p(thiz->stream_, &data, &size, &endOfFile)) - { - thiz->hasError_ = !endOfFile; - break; - } - - if (!thiz->parseVideoData(data, size)) - { - thiz->hasError_ = true; - break; - } - - if (thiz->stop_) - break; - } + int res = read_InputMediaStream_FFMPEG_p(stream_, data, size, &endOfFile); - thiz->parseVideoData(0, 0, true); -} - -template <> void cv::Ptr::delete_obj() -{ - if (obj) release_InputMediaStream_FFMPEG_p(obj); + *bEndOfFile = (endOfFile != 0); + return res != 0; } #endif // HAVE_CUDA diff --git a/modules/gpucodec/src/ffmpeg_video_source.h b/modules/gpucodec/src/ffmpeg_video_source.hpp similarity index 75% rename from modules/gpucodec/src/ffmpeg_video_source.h rename to modules/gpucodec/src/ffmpeg_video_source.hpp index d097785d77..6ea59ddac1 100644 --- a/modules/gpucodec/src/ffmpeg_video_source.h +++ b/modules/gpucodec/src/ffmpeg_video_source.hpp @@ -7,11 +7,12 @@ // copy or use the software. // // -// License Agreement +// License Agreement // For Open Source Computer Vision Library // // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. // Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, @@ -40,43 +41,31 @@ // //M*/ -#ifndef __FFMPEG_VIDEO_SOURCE_H__ -#define __FFMPEG_VIDEO_SOURCE_H__ +#ifndef __FFMPEG_VIDEO_SOURCE_HPP__ +#define __FFMPEG_VIDEO_SOURCE_HPP__ #include "opencv2/gpucodec.hpp" -#include "thread.h" struct InputMediaStream_FFMPEG; -namespace cv { namespace gpu { namespace detail { +namespace cv { namespace gpucodec { namespace detail { -class FFmpegVideoSource : public VideoReader_GPU::VideoSource +class FFmpegVideoSource : public RawVideoSource { public: FFmpegVideoSource(const String& fname); + ~FFmpegVideoSource(); - VideoReader_GPU::FormatInfo format() const; - void start(); - void stop(); - bool isStarted() const; - bool hasError() const; + bool getNextPacket(unsigned char** data, int* size, bool* endOfFile); -private: - VideoReader_GPU::FormatInfo format_; - - cv::Ptr stream_; + FormatInfo format() const; - cv::Ptr thread_; - volatile bool stop_; - volatile bool hasError_; +private: + FormatInfo format_; - static void readLoop(void* userData); + InputMediaStream_FFMPEG* stream_; }; }}} -namespace cv { - template <> void Ptr::delete_obj(); -} - -#endif // __FFMPEG_VIDEO_SOURCE_H__ +#endif // __FFMPEG_VIDEO_SOURCE_HPP__ diff --git a/modules/gpucodec/src/frame_queue.cpp b/modules/gpucodec/src/frame_queue.cpp index 2c5045500d..f9141d84f5 100644 --- a/modules/gpucodec/src/frame_queue.cpp +++ b/modules/gpucodec/src/frame_queue.cpp @@ -7,11 +7,12 @@ // copy or use the software. // // -// License Agreement +// License Agreement // For Open Source Computer Vision Library // // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. // Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, @@ -44,16 +45,16 @@ #ifdef HAVE_NVCUVID -cv::gpu::detail::FrameQueue::FrameQueue() : +cv::gpucodec::detail::FrameQueue::FrameQueue() : endOfDecode_(0), framesInQueue_(0), readPosition_(0) { std::memset(displayQueue_, 0, sizeof(displayQueue_)); - std::memset((void*)isFrameInUse_, 0, sizeof(isFrameInUse_)); + std::memset((void*) isFrameInUse_, 0, sizeof(isFrameInUse_)); } -bool cv::gpu::detail::FrameQueue::waitUntilFrameAvailable(int pictureIndex) +bool cv::gpucodec::detail::FrameQueue::waitUntilFrameAvailable(int pictureIndex) { while (isInUse(pictureIndex)) { @@ -67,7 +68,7 @@ bool cv::gpu::detail::FrameQueue::waitUntilFrameAvailable(int pictureIndex) return true; } -void cv::gpu::detail::FrameQueue::enqueue(const CUVIDPARSERDISPINFO* picParams) +void cv::gpucodec::detail::FrameQueue::enqueue(const CUVIDPARSERDISPINFO* picParams) { // Mark the frame as 'in-use' so we don't re-use it for decoding until it is no longer needed // for display @@ -98,7 +99,7 @@ void cv::gpu::detail::FrameQueue::enqueue(const CUVIDPARSERDISPINFO* picParams) } while (!isEndOfDecode()); } -bool cv::gpu::detail::FrameQueue::dequeue(CUVIDPARSERDISPINFO& displayInfo) +bool cv::gpucodec::detail::FrameQueue::dequeue(CUVIDPARSERDISPINFO& displayInfo) { AutoLock autoLock(mtx_); diff --git a/modules/gpucodec/src/frame_queue.h b/modules/gpucodec/src/frame_queue.hpp similarity index 93% rename from modules/gpucodec/src/frame_queue.h rename to modules/gpucodec/src/frame_queue.hpp index d9a4433b3d..c3b427b74f 100644 --- a/modules/gpucodec/src/frame_queue.h +++ b/modules/gpucodec/src/frame_queue.hpp @@ -7,11 +7,12 @@ // copy or use the software. // // -// License Agreement +// License Agreement // For Open Source Computer Vision Library // // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. // Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, @@ -40,15 +41,15 @@ // //M*/ -#ifndef __FRAME_QUEUE_H__ -#define __FRAME_QUEUE_H__ +#ifndef __FRAME_QUEUE_HPP__ +#define __FRAME_QUEUE_HPP__ #include "opencv2/core/utility.hpp" #include "opencv2/core/private.gpu.hpp" #include -namespace cv { namespace gpu { namespace detail +namespace cv { namespace gpucodec { namespace detail { class FrameQueue @@ -94,4 +95,4 @@ private: }}} -#endif // __FRAME_QUEUE_H__ +#endif // __FRAME_QUEUE_HPP__ diff --git a/modules/gpucodec/src/precomp.hpp b/modules/gpucodec/src/precomp.hpp index 2afb0abb11..7cef1b7a94 100644 --- a/modules/gpucodec/src/precomp.hpp +++ b/modules/gpucodec/src/precomp.hpp @@ -67,12 +67,13 @@ #include #endif - #include "thread.h" - #include "ffmpeg_video_source.h" - #include "cuvid_video_source.h" - #include "frame_queue.h" - #include "video_decoder.h" - #include "video_parser.h" + #include "thread.hpp" + #include "video_source.hpp" + #include "ffmpeg_video_source.hpp" + #include "cuvid_video_source.hpp" + #include "frame_queue.hpp" + #include "video_decoder.hpp" + #include "video_parser.hpp" #include "../src/cap_ffmpeg_api.hpp" #endif diff --git a/modules/gpucodec/src/thread.cpp b/modules/gpucodec/src/thread.cpp index db9f3de39b..b936d8e21a 100644 --- a/modules/gpucodec/src/thread.cpp +++ b/modules/gpucodec/src/thread.cpp @@ -7,11 +7,12 @@ // copy or use the software. // // -// License Agreement +// License Agreement // For Open Source Computer Vision Library // // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. // Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, @@ -44,7 +45,7 @@ #ifdef HAVE_NVCUVID -using namespace cv::gpu::detail; +using namespace cv::gpucodec::detail; #ifdef WIN32 @@ -66,7 +67,7 @@ namespace } } -class cv::gpu::detail::Thread::Impl +class cv::gpucodec::detail::Thread::Impl { public: Impl(Thread::Func func, void* userData) @@ -119,7 +120,7 @@ namespace } } -class cv::gpu::detail::Thread::Impl +class cv::gpucodec::detail::Thread::Impl { public: Impl(Thread::Func func, void* userData) @@ -147,17 +148,17 @@ private: #endif -cv::gpu::detail::Thread::Thread(Func func, void* userData) : +cv::gpucodec::detail::Thread::Thread(Func func, void* userData) : impl_(new Impl(func, userData)) { } -void cv::gpu::detail::Thread::wait() +void cv::gpucodec::detail::Thread::wait() { impl_->wait(); } -void cv::gpu::detail::Thread::sleep(int ms) +void cv::gpucodec::detail::Thread::sleep(int ms) { #ifdef WIN32 ::Sleep(ms); @@ -166,7 +167,7 @@ void cv::gpu::detail::Thread::sleep(int ms) #endif } -template <> void cv::Ptr::delete_obj() +template <> void cv::Ptr::delete_obj() { if (obj) delete obj; } diff --git a/modules/gpucodec/src/thread.h b/modules/gpucodec/src/thread.hpp similarity index 87% rename from modules/gpucodec/src/thread.h rename to modules/gpucodec/src/thread.hpp index 1489f5830b..ccda5b5c7c 100644 --- a/modules/gpucodec/src/thread.h +++ b/modules/gpucodec/src/thread.hpp @@ -7,11 +7,12 @@ // copy or use the software. // // -// License Agreement +// License Agreement // For Open Source Computer Vision Library // // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. // Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, @@ -40,12 +41,12 @@ // //M*/ -#ifndef __THREAD_WRAPPERS_H__ -#define __THREAD_WRAPPERS_H__ +#ifndef __THREAD_WRAPPERS_HPP__ +#define __THREAD_WRAPPERS_HPP__ #include "opencv2/core.hpp" -namespace cv { namespace gpu { namespace detail { +namespace cv { namespace gpucodec { namespace detail { class Thread { @@ -67,7 +68,7 @@ private: }}} namespace cv { - template <> void Ptr::delete_obj(); + template <> void Ptr::delete_obj(); } -#endif // __THREAD_WRAPPERS_H__ +#endif // __THREAD_WRAPPERS_HPP__ diff --git a/modules/gpucodec/src/video_decoder.cpp b/modules/gpucodec/src/video_decoder.cpp index 7e28e872bb..d734ef363a 100644 --- a/modules/gpucodec/src/video_decoder.cpp +++ b/modules/gpucodec/src/video_decoder.cpp @@ -7,11 +7,12 @@ // copy or use the software. // // -// License Agreement +// License Agreement // For Open Source Computer Vision Library // // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. // Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, @@ -44,7 +45,7 @@ #ifdef HAVE_NVCUVID -void cv::gpu::detail::VideoDecoder::create(const VideoReader_GPU::FormatInfo& videoFormat) +void cv::gpucodec::detail::VideoDecoder::create(const FormatInfo& videoFormat) { release(); @@ -103,7 +104,7 @@ void cv::gpu::detail::VideoDecoder::create(const VideoReader_GPU::FormatInfo& vi cuSafeCall( cuvidCreateDecoder(&decoder_, &createInfo_) ); } -void cv::gpu::detail::VideoDecoder::release() +void cv::gpucodec::detail::VideoDecoder::release() { if (decoder_) { diff --git a/modules/gpucodec/src/video_decoder.h b/modules/gpucodec/src/video_decoder.hpp similarity index 85% rename from modules/gpucodec/src/video_decoder.h rename to modules/gpucodec/src/video_decoder.hpp index 7a36335cc3..05a92f2664 100644 --- a/modules/gpucodec/src/video_decoder.h +++ b/modules/gpucodec/src/video_decoder.hpp @@ -7,11 +7,12 @@ // copy or use the software. // // -// License Agreement +// License Agreement // For Open Source Computer Vision Library // // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. // Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, @@ -40,21 +41,21 @@ // //M*/ -#ifndef __VIDEO_DECODER_H__ -#define __VIDEO_DECODER_H__ +#ifndef __VIDEO_DECODER_HPP__ +#define __VIDEO_DECODER_HPP__ + +#include #include "opencv2/core/private.gpu.hpp" #include "opencv2/gpucodec.hpp" -#include - -namespace cv { namespace gpu { namespace detail +namespace cv { namespace gpucodec { namespace detail { class VideoDecoder { public: - VideoDecoder(const VideoReader_GPU::FormatInfo& videoFormat, CUvideoctxlock lock) : lock_(lock), decoder_(0) + VideoDecoder(const FormatInfo& videoFormat, CUvideoctxlock lock) : lock_(lock), decoder_(0) { create(videoFormat); } @@ -64,7 +65,7 @@ public: release(); } - void create(const VideoReader_GPU::FormatInfo& videoFormat); + void create(const FormatInfo& videoFormat); void release(); // Get the code-type currently used. @@ -84,17 +85,17 @@ public: return cuvidDecodePicture(decoder_, picParams) == CUDA_SUCCESS; } - cv::gpu::GpuMat mapFrame(int picIdx, CUVIDPROCPARAMS& videoProcParams) + gpu::GpuMat mapFrame(int picIdx, CUVIDPROCPARAMS& videoProcParams) { CUdeviceptr ptr; unsigned int pitch; cuSafeCall( cuvidMapVideoFrame(decoder_, picIdx, &ptr, &pitch, &videoProcParams) ); - return GpuMat(targetHeight() * 3 / 2, targetWidth(), CV_8UC1, (void*) ptr, pitch); + return gpu::GpuMat(targetHeight() * 3 / 2, targetWidth(), CV_8UC1, (void*) ptr, pitch); } - void unmapFrame(cv::gpu::GpuMat& frame) + void unmapFrame(gpu::GpuMat& frame) { cuSafeCall( cuvidUnmapVideoFrame(decoder_, (CUdeviceptr) frame.data) ); frame.release(); @@ -108,4 +109,4 @@ private: }}} -#endif // __VIDEO_DECODER_H__ +#endif // __VIDEO_DECODER_HPP__ diff --git a/modules/gpucodec/src/video_parser.cpp b/modules/gpucodec/src/video_parser.cpp index 620f85fe8f..66aab62ad1 100644 --- a/modules/gpucodec/src/video_parser.cpp +++ b/modules/gpucodec/src/video_parser.cpp @@ -7,11 +7,12 @@ // copy or use the software. // // -// License Agreement +// License Agreement // For Open Source Computer Vision Library // // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. // Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, @@ -44,11 +45,11 @@ #ifdef HAVE_NVCUVID -cv::gpu::detail::VideoParser::VideoParser(VideoDecoder* videoDecoder, FrameQueue* frameQueue) : +cv::gpucodec::detail::VideoParser::VideoParser(VideoDecoder* videoDecoder, FrameQueue* frameQueue) : videoDecoder_(videoDecoder), frameQueue_(frameQueue), unparsedPackets_(0), hasError_(false) { CUVIDPARSERPARAMS params; - memset(¶ms, 0, sizeof(CUVIDPARSERPARAMS)); + std::memset(¶ms, 0, sizeof(CUVIDPARSERPARAMS)); params.CodecType = videoDecoder->codec(); params.ulMaxNumDecodeSurfaces = videoDecoder->maxDecodeSurfaces(); @@ -61,7 +62,7 @@ cv::gpu::detail::VideoParser::VideoParser(VideoDecoder* videoDecoder, FrameQueue cuSafeCall( cuvidCreateVideoParser(&parser_, ¶ms) ); } -bool cv::gpu::detail::VideoParser::parseVideoData(const unsigned char* data, size_t size, bool endOfStream) +bool cv::gpucodec::detail::VideoParser::parseVideoData(const unsigned char* data, size_t size, bool endOfStream) { CUVIDSOURCEDATAPACKET packet; std::memset(&packet, 0, sizeof(CUVIDSOURCEDATAPACKET)); @@ -95,7 +96,7 @@ bool cv::gpu::detail::VideoParser::parseVideoData(const unsigned char* data, siz return !frameQueue_->isEndOfDecode(); } -int CUDAAPI cv::gpu::detail::VideoParser::HandleVideoSequence(void* userData, CUVIDEOFORMAT* format) +int CUDAAPI cv::gpucodec::detail::VideoParser::HandleVideoSequence(void* userData, CUVIDEOFORMAT* format) { VideoParser* thiz = static_cast(userData); @@ -106,10 +107,10 @@ int CUDAAPI cv::gpu::detail::VideoParser::HandleVideoSequence(void* userData, CU format->coded_height != thiz->videoDecoder_->frameHeight() || format->chroma_format != thiz->videoDecoder_->chromaFormat()) { - VideoReader_GPU::FormatInfo newFormat; + FormatInfo newFormat; - newFormat.codec = static_cast(format->codec); - newFormat.chromaFormat = static_cast(format->chroma_format); + newFormat.codec = static_cast(format->codec); + newFormat.chromaFormat = static_cast(format->chroma_format); newFormat.width = format->coded_width; newFormat.height = format->coded_height; @@ -127,7 +128,7 @@ int CUDAAPI cv::gpu::detail::VideoParser::HandleVideoSequence(void* userData, CU return true; } -int CUDAAPI cv::gpu::detail::VideoParser::HandlePictureDecode(void* userData, CUVIDPICPARAMS* picParams) +int CUDAAPI cv::gpucodec::detail::VideoParser::HandlePictureDecode(void* userData, CUVIDPICPARAMS* picParams) { VideoParser* thiz = static_cast(userData); @@ -147,7 +148,7 @@ int CUDAAPI cv::gpu::detail::VideoParser::HandlePictureDecode(void* userData, CU return true; } -int CUDAAPI cv::gpu::detail::VideoParser::HandlePictureDisplay(void* userData, CUVIDPARSERDISPINFO* picParams) +int CUDAAPI cv::gpucodec::detail::VideoParser::HandlePictureDisplay(void* userData, CUVIDPARSERDISPINFO* picParams) { VideoParser* thiz = static_cast(userData); diff --git a/modules/gpucodec/src/video_parser.h b/modules/gpucodec/src/video_parser.hpp similarity index 92% rename from modules/gpucodec/src/video_parser.h rename to modules/gpucodec/src/video_parser.hpp index e11b7eff6a..b4dddb3895 100644 --- a/modules/gpucodec/src/video_parser.h +++ b/modules/gpucodec/src/video_parser.hpp @@ -7,11 +7,12 @@ // copy or use the software. // // -// License Agreement +// License Agreement // For Open Source Computer Vision Library // // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. // Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, @@ -40,17 +41,17 @@ // //M*/ -#ifndef __VIDEO_PARSER_H__ -#define __VIDEO_PARSER_H__ +#ifndef __VIDEO_PARSER_HPP__ +#define __VIDEO_PARSER_HPP__ + +#include #include "opencv2/core/private.gpu.hpp" #include "opencv2/gpucodec.hpp" -#include "frame_queue.h" -#include "video_decoder.h" - -#include +#include "frame_queue.hpp" +#include "video_decoder.hpp" -namespace cv { namespace gpu { namespace detail +namespace cv { namespace gpucodec { namespace detail { class VideoParser @@ -91,4 +92,4 @@ private: }}} -#endif // __VIDEO_PARSER_H__ +#endif // __VIDEO_PARSER_HPP__ diff --git a/modules/gpucodec/src/video_reader.cpp b/modules/gpucodec/src/video_reader.cpp index dbb4bbcf2b..67e9cd1078 100644 --- a/modules/gpucodec/src/video_reader.cpp +++ b/modules/gpucodec/src/video_reader.cpp @@ -42,88 +42,77 @@ #include "precomp.hpp" +using namespace cv; +using namespace cv::gpu; +using namespace cv::gpucodec; + #ifndef HAVE_NVCUVID -class cv::gpu::VideoReader_GPU::Impl -{ -}; - -cv::gpu::VideoReader_GPU::VideoReader_GPU() { throw_no_cuda(); } -cv::gpu::VideoReader_GPU::VideoReader_GPU(const String&) { throw_no_cuda(); } -cv::gpu::VideoReader_GPU::VideoReader_GPU(const cv::Ptr&) { throw_no_cuda(); } -cv::gpu::VideoReader_GPU::~VideoReader_GPU() { } -void cv::gpu::VideoReader_GPU::open(const String&) { throw_no_cuda(); } -void cv::gpu::VideoReader_GPU::open(const cv::Ptr&) { throw_no_cuda(); } -bool cv::gpu::VideoReader_GPU::isOpened() const { return false; } -void cv::gpu::VideoReader_GPU::close() { } -bool cv::gpu::VideoReader_GPU::read(GpuMat&) { throw_no_cuda(); return false; } -cv::gpu::VideoReader_GPU::FormatInfo cv::gpu::VideoReader_GPU::format() const { throw_no_cuda(); FormatInfo format_ = {MPEG1,Monochrome,0,0}; return format_; } -bool cv::gpu::VideoReader_GPU::VideoSource::parseVideoData(const unsigned char*, size_t, bool) { throw_no_cuda(); return false; } -void cv::gpu::VideoReader_GPU::dumpFormat(std::ostream&) { throw_no_cuda(); } +Ptr cv::gpucodec::createVideoReader(const String&) { throw_no_cuda(); return Ptr(); } +Ptr cv::gpucodec::createVideoReader(const Ptr&) { throw_no_cuda(); return Ptr(); } #else // HAVE_NVCUVID -class cv::gpu::VideoReader_GPU::Impl +namespace cv { namespace gpu { namespace cudev { -public: - explicit Impl(const cv::Ptr& source); - ~Impl(); - - bool grab(cv::gpu::GpuMat& frame); + void NV12_to_RGB(const PtrStepb decodedFrame, PtrStepSz interopFrame, cudaStream_t stream = 0); +}}} - cv::gpu::VideoReader_GPU::FormatInfo format() const { return videoSource_->format(); } +namespace +{ + class VideoReaderImpl : public VideoReader + { + public: + explicit VideoReaderImpl(const Ptr& source); + ~VideoReaderImpl(); -private: - cv::Ptr videoSource_; + bool nextFrame(OutputArray frame); - cv::Ptr frameQueue_; - cv::Ptr videoDecoder_; - cv::Ptr videoParser_; + FormatInfo format() const; - CUvideoctxlock lock_; + private: + Ptr videoSource_; - std::deque< std::pair > frames_; -}; + Ptr frameQueue_; + Ptr videoDecoder_; + Ptr videoParser_; -cv::gpu::VideoReader_GPU::Impl::Impl(const cv::Ptr& source) : - videoSource_(source), - lock_(0) -{ - // init context - GpuMat temp(1, 1, CV_8UC1); - temp.release(); + CUvideoctxlock lock_; - DeviceInfo devInfo; - CV_Assert( devInfo.supports(FEATURE_SET_COMPUTE_11) ); + std::deque< std::pair > frames_; + }; - CUcontext ctx; - cuSafeCall( cuCtxGetCurrent(&ctx) ); - cuSafeCall( cuvidCtxLockCreate(&lock_, ctx) ); + FormatInfo VideoReaderImpl::format() const + { + return videoSource_->format(); + } - frameQueue_ = new detail::FrameQueue; - videoDecoder_ = new detail::VideoDecoder(videoSource_->format(), lock_); - videoParser_ = new detail::VideoParser(videoDecoder_, frameQueue_); + VideoReaderImpl::VideoReaderImpl(const Ptr& source) : + videoSource_(source), + lock_(0) + { + // init context + GpuMat temp(1, 1, CV_8UC1); + temp.release(); - videoSource_->setFrameQueue(frameQueue_); - videoSource_->setVideoParser(videoParser_); + CUcontext ctx; + cuSafeCall( cuCtxGetCurrent(&ctx) ); + cuSafeCall( cuvidCtxLockCreate(&lock_, ctx) ); - videoSource_->start(); -} + frameQueue_ = new detail::FrameQueue; + videoDecoder_ = new detail::VideoDecoder(videoSource_->format(), lock_); + videoParser_ = new detail::VideoParser(videoDecoder_, frameQueue_); -cv::gpu::VideoReader_GPU::Impl::~Impl() -{ - frameQueue_->endDecode(); - videoSource_->stop(); -} + videoSource_->setVideoParser(videoParser_); + videoSource_->start(); + } -namespace cv { namespace gpu { namespace cudev -{ - void loadHueCSC(float hueCSC[9]); - void NV12_to_RGB(const PtrStepb decodedFrame, PtrStepSz interopFrame, cudaStream_t stream = 0); -}}} + VideoReaderImpl::~VideoReaderImpl() + { + frameQueue_->endDecode(); + videoSource_->stop(); + } -namespace -{ class VideoCtxAutoLock { public: @@ -134,259 +123,114 @@ namespace CUvideoctxlock m_lock; }; - enum ColorSpace - { - ITU601 = 1, - ITU709 = 2 - }; - - void setColorSpaceMatrix(ColorSpace CSC, float hueCSC[9], float hue) - { - float hueSin = std::sin(hue); - float hueCos = std::cos(hue); - - if (CSC == ITU601) - { - //CCIR 601 - hueCSC[0] = 1.1644f; - hueCSC[1] = hueSin * 1.5960f; - hueCSC[2] = hueCos * 1.5960f; - hueCSC[3] = 1.1644f; - hueCSC[4] = (hueCos * -0.3918f) - (hueSin * 0.8130f); - hueCSC[5] = (hueSin * 0.3918f) - (hueCos * 0.8130f); - hueCSC[6] = 1.1644f; - hueCSC[7] = hueCos * 2.0172f; - hueCSC[8] = hueSin * -2.0172f; - } - else if (CSC == ITU709) - { - //CCIR 709 - hueCSC[0] = 1.0f; - hueCSC[1] = hueSin * 1.57480f; - hueCSC[2] = hueCos * 1.57480f; - hueCSC[3] = 1.0; - hueCSC[4] = (hueCos * -0.18732f) - (hueSin * 0.46812f); - hueCSC[5] = (hueSin * 0.18732f) - (hueCos * 0.46812f); - hueCSC[6] = 1.0f; - hueCSC[7] = hueCos * 1.85560f; - hueCSC[8] = hueSin * -1.85560f; - } - } - - void cudaPostProcessFrame(const cv::gpu::GpuMat& decodedFrame, cv::gpu::GpuMat& interopFrame, int width, int height) + void cudaPostProcessFrame(const GpuMat& decodedFrame, OutputArray _outFrame, int width, int height) { using namespace cv::gpu::cudev; - static bool updateCSC = true; - static float hueColorSpaceMat[9]; - - // Upload the Color Space Conversion Matrices - if (updateCSC) - { - const ColorSpace colorSpace = ITU601; - const float hue = 0.0f; - - // CCIR 601/709 - setColorSpaceMatrix(colorSpace, hueColorSpaceMat, hue); - - updateCSC = false; - } - // Final Stage: NV12toARGB color space conversion - interopFrame.create(height, width, CV_8UC4); - - loadHueCSC(hueColorSpaceMat); + _outFrame.create(height, width, CV_8UC4); + GpuMat outFrame = _outFrame.getGpuMat(); - NV12_to_RGB(decodedFrame, interopFrame); + NV12_to_RGB(decodedFrame, outFrame); } -} -bool cv::gpu::VideoReader_GPU::Impl::grab(GpuMat& frame) -{ - if (videoSource_->hasError() || videoParser_->hasError()) - CV_Error(cv::Error::StsUnsupportedFormat, "Unsupported video source"); - - if (!videoSource_->isStarted() || frameQueue_->isEndOfDecode()) - return false; - - if (frames_.empty()) + bool VideoReaderImpl::nextFrame(OutputArray frame) { - CUVIDPARSERDISPINFO displayInfo; - - for (;;) - { - if (frameQueue_->dequeue(displayInfo)) - break; - - if (videoSource_->hasError() || videoParser_->hasError()) - CV_Error(cv::Error::StsUnsupportedFormat, "Unsupported video source"); + if (videoSource_->hasError() || videoParser_->hasError()) + CV_Error(Error::StsUnsupportedFormat, "Unsupported video source"); - if (frameQueue_->isEndOfDecode()) - return false; + if (!videoSource_->isStarted() || frameQueue_->isEndOfDecode()) + return false; - // Wait a bit - detail::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) + if (frames_.empty()) { - CUVIDPROCPARAMS videoProcParams; - std::memset(&videoProcParams, 0, sizeof(CUVIDPROCPARAMS)); + CUVIDPARSERDISPINFO displayInfo; - 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); + for (;;) + { + if (frameQueue_->dequeue(displayInfo)) + break; - frames_.push_back(std::make_pair(displayInfo, videoProcParams)); - } - } + if (videoSource_->hasError() || videoParser_->hasError()) + CV_Error(Error::StsUnsupportedFormat, "Unsupported video source"); - if (frames_.empty()) - return false; + if (frameQueue_->isEndOfDecode()) + return false; - std::pair frameInfo = frames_.front(); - frames_.pop_front(); + // Wait a bit + detail::Thread::sleep(1); + } - { - VideoCtxAutoLock autoLock(lock_); + bool isProgressive = displayInfo.progressive_frame != 0; + const int num_fields = isProgressive ? 1 : 2 + displayInfo.repeat_first_field; - // map decoded video frame to CUDA surface - cv::gpu::GpuMat decodedFrame = videoDecoder_->mapFrame(frameInfo.first.picture_index, frameInfo.second); + for (int active_field = 0; active_field < num_fields; ++active_field) + { + CUVIDPROCPARAMS videoProcParams; + std::memset(&videoProcParams, 0, sizeof(CUVIDPROCPARAMS)); - // perform post processing on the CUDA surface (performs colors space conversion and post processing) - // comment this out if we inclue the line of code seen above - cudaPostProcessFrame(decodedFrame, frame, videoDecoder_->targetWidth(), videoDecoder_->targetHeight()); + 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); - // unmap video frame - // unmapFrame() synchronizes with the VideoDecode API (ensures the frame has finished decoding) - videoDecoder_->unmapFrame(decodedFrame); - } + frames_.push_back(std::make_pair(displayInfo, videoProcParams)); + } + } - // release the frame, so it can be re-used in decoder - if (frames_.empty()) - frameQueue_->releaseFrame(frameInfo.first); + if (frames_.empty()) + return false; - return true; -} + std::pair frameInfo = frames_.front(); + frames_.pop_front(); -//////////////////////////////////////////////////////////////////////////// + { + VideoCtxAutoLock autoLock(lock_); -cv::gpu::VideoReader_GPU::VideoReader_GPU() -{ -} + // map decoded video frame to CUDA surface + GpuMat decodedFrame = videoDecoder_->mapFrame(frameInfo.first.picture_index, frameInfo.second); -cv::gpu::VideoReader_GPU::VideoReader_GPU(const String& filename) -{ - open(filename); -} + // perform post processing on the CUDA surface (performs colors space conversion and post processing) + // comment this out if we inclue the line of code seen above + cudaPostProcessFrame(decodedFrame, frame, videoDecoder_->targetWidth(), videoDecoder_->targetHeight()); -cv::gpu::VideoReader_GPU::VideoReader_GPU(const cv::Ptr& source) -{ - open(source); -} + // unmap video frame + // unmapFrame() synchronizes with the VideoDecode API (ensures the frame has finished decoding) + videoDecoder_->unmapFrame(decodedFrame); + } -cv::gpu::VideoReader_GPU::~VideoReader_GPU() -{ - close(); + // release the frame, so it can be re-used in decoder + if (frames_.empty()) + frameQueue_->releaseFrame(frameInfo.first); + + return true; + } } -void cv::gpu::VideoReader_GPU::open(const String& filename) +Ptr cv::gpucodec::createVideoReader(const String& filename) { CV_Assert( !filename.empty() ); -#ifndef __APPLE__ + Ptr videoSource; + try { - cv::Ptr source(new detail::CuvidVideoSource(filename)); - open(source); - } - catch (const std::runtime_error&) -#endif - { - cv::Ptr source(new cv::gpu::detail::FFmpegVideoSource(filename)); - open(source); + videoSource = new detail::CuvidVideoSource(filename); } -} - -void cv::gpu::VideoReader_GPU::open(const cv::Ptr& source) -{ - CV_Assert( !source.empty() ); - close(); - impl_ = new Impl(source); -} - -bool cv::gpu::VideoReader_GPU::isOpened() const -{ - return !impl_.empty(); -} - -void cv::gpu::VideoReader_GPU::close() -{ - impl_.release(); -} - -bool cv::gpu::VideoReader_GPU::read(GpuMat& image) -{ - if (!isOpened()) - return false; - - if (!impl_->grab(image)) + catch (...) { - close(); - return false; + Ptr source(new detail::FFmpegVideoSource(filename)); + videoSource = new detail::RawVideoSourceWrapper(source); } - return true; -} - -cv::gpu::VideoReader_GPU::FormatInfo cv::gpu::VideoReader_GPU::format() const -{ - CV_Assert( isOpened() ); - return impl_->format(); -} - -bool cv::gpu::VideoReader_GPU::VideoSource::parseVideoData(const unsigned char* data, size_t size, bool endOfStream) -{ - return videoParser_->parseVideoData(data, size, endOfStream); + return new VideoReaderImpl(videoSource); } -void cv::gpu::VideoReader_GPU::dumpFormat(std::ostream& st) +Ptr cv::gpucodec::createVideoReader(const Ptr& source) { - static const char* codecs[] = - { - "MPEG1", - "MPEG2", - "MPEG4", - "VC1", - "H264", - "JPEG", - "H264_SVC", - "H264_MVC" - }; - - static const char* chromas[] = - { - "Monochrome", - "YUV420", - "YUV422", - "YUV444" - }; - - FormatInfo _format = this->format(); - - st << "Frame Size : " << _format.width << "x" << _format.height << std::endl; - st << "Codec : " << (_format.codec <= H264_MVC ? codecs[_format.codec] : "Uncompressed YUV") << std::endl; - st << "Chroma Format : " << chromas[_format.chromaFormat] << std::endl; + Ptr videoSource(new detail::RawVideoSourceWrapper(source)); + return new VideoReaderImpl(videoSource); } #endif // HAVE_NVCUVID - -template <> void cv::Ptr::delete_obj() -{ - if (obj) delete obj; -} diff --git a/modules/gpucodec/src/video_source.cpp b/modules/gpucodec/src/video_source.cpp new file mode 100644 index 0000000000..ce6a1bd8c0 --- /dev/null +++ b/modules/gpucodec/src/video_source.cpp @@ -0,0 +1,121 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +#ifdef HAVE_NVCUVID + +using namespace cv; +using namespace cv::gpucodec; +using namespace cv::gpucodec::detail; + +bool cv::gpucodec::detail::VideoSource::parseVideoData(const unsigned char* data, size_t size, bool endOfStream) +{ + return videoParser_->parseVideoData(data, size, endOfStream); +} + +cv::gpucodec::detail::RawVideoSourceWrapper::RawVideoSourceWrapper(const Ptr& source) : + source_(source) +{ + CV_Assert( !source_.empty() ); +} + +cv::gpucodec::FormatInfo cv::gpucodec::detail::RawVideoSourceWrapper::format() const +{ + return source_->format(); +} + +void cv::gpucodec::detail::RawVideoSourceWrapper::start() +{ + stop_ = false; + hasError_ = false; + thread_ = new Thread(readLoop, this); +} + +void cv::gpucodec::detail::RawVideoSourceWrapper::stop() +{ + stop_ = true; + thread_->wait(); + thread_.release(); +} + +bool cv::gpucodec::detail::RawVideoSourceWrapper::isStarted() const +{ + return !stop_; +} + +bool cv::gpucodec::detail::RawVideoSourceWrapper::hasError() const +{ + return hasError_; +} + +void cv::gpucodec::detail::RawVideoSourceWrapper::readLoop(void* userData) +{ + RawVideoSourceWrapper* thiz = static_cast(userData); + + for (;;) + { + unsigned char* data; + int size; + bool endOfFile; + + if (!thiz->source_->getNextPacket(&data, &size, &endOfFile)) + { + thiz->hasError_ = !endOfFile; + break; + } + + if (!thiz->parseVideoData(data, size)) + { + thiz->hasError_ = true; + break; + } + + if (thiz->stop_) + break; + } + + thiz->parseVideoData(0, 0, true); +} + +#endif // HAVE_NVCUVID diff --git a/modules/gpucodec/src/video_source.hpp b/modules/gpucodec/src/video_source.hpp new file mode 100644 index 0000000000..b4d930ee09 --- /dev/null +++ b/modules/gpucodec/src/video_source.hpp @@ -0,0 +1,99 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __GPUCODEC_VIDEO_SOURCE_H__ +#define __GPUCODEC_VIDEO_SOURCE_H__ + +#include "opencv2/core/private.gpu.hpp" +#include "opencv2/gpucodec.hpp" +#include "thread.hpp" + +namespace cv { namespace gpucodec { namespace detail +{ + +class VideoParser; + +class VideoSource +{ +public: + virtual ~VideoSource() {} + + virtual FormatInfo format() const = 0; + virtual void start() = 0; + virtual void stop() = 0; + virtual bool isStarted() const = 0; + virtual bool hasError() const = 0; + + void setVideoParser(detail::VideoParser* videoParser) { videoParser_ = videoParser; } + +protected: + bool parseVideoData(const uchar* data, size_t size, bool endOfStream = false); + +private: + detail::VideoParser* videoParser_; +}; + +class RawVideoSourceWrapper : public VideoSource +{ +public: + RawVideoSourceWrapper(const Ptr& source); + + FormatInfo format() const; + void start(); + void stop(); + bool isStarted() const; + bool hasError() const; + +private: + Ptr source_; + + Ptr thread_; + volatile bool stop_; + volatile bool hasError_; + + static void readLoop(void* userData); +}; + +}}} + +#endif // __GPUCODEC_VIDEO_SOURCE_H__ diff --git a/modules/gpucodec/test/test_video.cpp b/modules/gpucodec/test/test_video.cpp index a073a969af..26bcc02d58 100644 --- a/modules/gpucodec/test/test_video.cpp +++ b/modules/gpucodec/test/test_video.cpp @@ -57,19 +57,15 @@ GPU_TEST_P(Video, Reader) const std::string inputFile = std::string(cvtest::TS::ptr()->get_data_path()) + "video/" + GET_PARAM(1); - cv::gpu::VideoReader_GPU reader(inputFile); - ASSERT_TRUE(reader.isOpened()); + cv::Ptr reader = cv::gpucodec::createVideoReader(inputFile); cv::gpu::GpuMat frame; for (int i = 0; i < 10; ++i) { - ASSERT_TRUE(reader.read(frame)); + ASSERT_TRUE(reader->nextFrame(frame)); ASSERT_FALSE(frame.empty()); } - - reader.close(); - ASSERT_FALSE(reader.isOpened()); } ////////////////////////////////////////////////////// diff --git a/modules/superres/src/frame_source.cpp b/modules/superres/src/frame_source.cpp index cba2b14ea3..7da817cfac 100644 --- a/modules/superres/src/frame_source.cpp +++ b/modules/superres/src/frame_source.cpp @@ -210,7 +210,7 @@ namespace private: String fileName_; - VideoReader_GPU reader_; + Ptr reader_; GpuMat frame_; }; @@ -223,13 +223,13 @@ namespace { if (_frame.kind() == _InputArray::GPU_MAT) { - bool res = reader_.read(_frame.getGpuMatRef()); + bool res = reader_->nextFrame(_frame.getGpuMatRef()); if (!res) _frame.release(); } else { - bool res = reader_.read(frame_); + bool res = reader_->nextFrame(frame_); if (!res) _frame.release(); else @@ -239,9 +239,7 @@ namespace void VideoFrameSource_GPU::reset() { - reader_.close(); - reader_.open(fileName_); - CV_Assert( reader_.isOpened() ); + reader_ = gpucodec::createVideoReader(fileName_); } } diff --git a/samples/gpu/video_reader.cpp b/samples/gpu/video_reader.cpp index 7eea726399..42f6f91db4 100644 --- a/samples/gpu/video_reader.cpp +++ b/samples/gpu/video_reader.cpp @@ -30,8 +30,7 @@ int main(int argc, const char* argv[]) cv::VideoCapture reader(fname); cv::gpu::GpuMat d_frame; - cv::gpu::VideoReader_GPU d_reader(fname); - d_reader.dumpFormat(std::cout); + cv::Ptr d_reader = cv::gpucodec::createVideoReader(fname); cv::TickMeter tm; std::vector cpu_times; @@ -46,7 +45,7 @@ int main(int argc, const char* argv[]) cpu_times.push_back(tm.getTimeMilli()); tm.reset(); tm.start(); - if (!d_reader.read(d_frame)) + if (!d_reader->nextFrame(d_frame)) break; tm.stop(); gpu_times.push_back(tm.getTimeMilli());