// This file is part of OpenCV project. // It is subject to the license terms in the LICENSE file found in the top-level directory // of this distribution and at http://opencv.org/license.html. #ifndef CAP_INTERFACE_HPP #define CAP_INTERFACE_HPP #include "opencv2/core.hpp" #include "opencv2/core/core_c.h" #include "opencv2/videoio.hpp" #include "opencv2/videoio/videoio_c.h" //=================================================== // Legacy structs struct CvCapture { virtual ~CvCapture() {} virtual double getProperty(int) const { return 0; } virtual bool setProperty(int, double) { return 0; } virtual bool grabFrame() { return true; } virtual IplImage* retrieveFrame(int) { return 0; } virtual int getCaptureDomain() { return cv::CAP_ANY; } // Return the type of the capture object: CAP_DSHOW, etc... }; struct CvVideoWriter { virtual ~CvVideoWriter() {} virtual bool writeFrame(const IplImage*) { return false; } virtual int getCaptureDomain() const { return cv::CAP_ANY; } // Return the type of the capture object: CAP_FFMPEG, etc... virtual double getProperty(int) const { return 0; } }; //=================================================== // Modern classes namespace cv { namespace { template inline T castParameterTo(int paramValue) { return static_cast(paramValue); } template <> inline bool castParameterTo(int paramValue) { return paramValue != 0; } } class VideoParameters { public: struct VideoParameter { VideoParameter() = default; VideoParameter(int key_, int value_) : key(key_), value(value_) {} int key{-1}; int value{-1}; mutable bool isConsumed{false}; }; VideoParameters() = default; explicit VideoParameters(const std::vector& params) { const auto count = params.size(); if (count % 2 != 0) { CV_Error_(Error::StsVecLengthErr, ("Vector of VideoWriter parameters should have even length")); } params_.reserve(count / 2); for (std::size_t i = 0; i < count; i += 2) { add(params[i], params[i + 1]); } } VideoParameters(int* params, unsigned n_params) { params_.reserve(n_params); for (unsigned i = 0; i < n_params; ++i) { add(params[2*i], params[2*i + 1]); } } void add(int key, int value) { params_.emplace_back(key, value); } bool has(int key) const { auto it = std::find_if(params_.begin(), params_.end(), [key](const VideoParameter ¶m) { return param.key == key; } ); return it != params_.end(); } template ValueType get(int key) const { auto it = std::find_if(params_.begin(), params_.end(), [key](const VideoParameter ¶m) { return param.key == key; } ); if (it != params_.end()) { it->isConsumed = true; return castParameterTo(it->value); } else { CV_Error_(Error::StsBadArg, ("Missing value for parameter: [%d]", key)); } } template ValueType get(int key, ValueType defaultValue) const { auto it = std::find_if(params_.begin(), params_.end(), [key](const VideoParameter ¶m) { return param.key == key; } ); if (it != params_.end()) { it->isConsumed = true; return castParameterTo(it->value); } else { return defaultValue; } } std::vector getUnused() const { std::vector unusedParams; for (const auto ¶m : params_) { if (!param.isConsumed) { unusedParams.push_back(param.key); } } return unusedParams; } std::vector getIntVector() const { std::vector vint_params; for (const auto& param : params_) { vint_params.push_back(param.key); vint_params.push_back(param.value); } return vint_params; } bool empty() const { return params_.empty(); } bool warnUnusedParameters() const { bool found = false; for (const auto ¶m : params_) { if (!param.isConsumed) { found = true; CV_LOG_INFO(NULL, "VIDEOIO: unused parameter: [" << param.key << "]=" << cv::format("%lld / 0x%016llx", (long long)param.value, (long long)param.value)); } } return found; } private: std::vector params_; }; class VideoWriterParameters : public VideoParameters { public: using VideoParameters::VideoParameters; // reuse constructors }; class VideoCaptureParameters : public VideoParameters { public: using VideoParameters::VideoParameters; // reuse constructors }; class IVideoCapture { public: virtual ~IVideoCapture() {} virtual double getProperty(int) const { return 0; } virtual bool setProperty(int, double) { return false; } virtual bool grabFrame() = 0; virtual bool retrieveFrame(int, OutputArray) = 0; virtual bool isOpened() const = 0; virtual int getCaptureDomain() { return CAP_ANY; } // Return the type of the capture object: CAP_DSHOW, etc... }; class IVideoWriter { public: virtual ~IVideoWriter() {} virtual double getProperty(int) const { return 0; } virtual bool setProperty(int, double) { return false; } virtual bool isOpened() const = 0; virtual void write(InputArray) = 0; virtual int getCaptureDomain() const { return cv::CAP_ANY; } // Return the type of the capture object: CAP_FFMPEG, etc... }; namespace internal { class VideoCapturePrivateAccessor { public: static IVideoCapture* getIVideoCapture(const VideoCapture& cap) { return cap.icap.get(); } }; } // namespace //=================================================== // Wrapper class LegacyCapture : public IVideoCapture { private: CvCapture * cap; LegacyCapture(const LegacyCapture &); LegacyCapture& operator=(const LegacyCapture &); public: LegacyCapture(CvCapture * cap_) : cap(cap_) {} ~LegacyCapture() { cvReleaseCapture(&cap); } double getProperty(int propId) const CV_OVERRIDE { return cap ? cap->getProperty(propId) : 0; } bool setProperty(int propId, double value) CV_OVERRIDE { return cvSetCaptureProperty(cap, propId, value) != 0; } bool grabFrame() CV_OVERRIDE { return cap ? cvGrabFrame(cap) != 0 : false; } bool retrieveFrame(int channel, OutputArray image) CV_OVERRIDE { IplImage* _img = cvRetrieveFrame(cap, channel); if( !_img ) { image.release(); return false; } if(_img->origin == IPL_ORIGIN_TL) { cv::cvarrToMat(_img).copyTo(image); } else { Mat temp = cv::cvarrToMat(_img); flip(temp, image, 0); } return true; } bool isOpened() const CV_OVERRIDE { return cap != 0; // legacy interface doesn't support closed files } int getCaptureDomain() CV_OVERRIDE { return cap ? cap->getCaptureDomain() : 0; } CvCapture* getCvCapture() const { return cap; } }; class LegacyWriter : public IVideoWriter { private: CvVideoWriter * writer; LegacyWriter(const LegacyWriter &); LegacyWriter& operator=(const LegacyWriter &); public: LegacyWriter(CvVideoWriter * wri_) : writer(wri_) {} ~LegacyWriter() { cvReleaseVideoWriter(&writer); } double getProperty(int propId) const CV_OVERRIDE { if (writer) { return writer->getProperty(propId); } return 0.; } bool setProperty(int, double) CV_OVERRIDE { return false; } bool isOpened() const CV_OVERRIDE { return writer != NULL; } void write(InputArray image) CV_OVERRIDE { IplImage _img = cvIplImage(image.getMat()); cvWriteFrame(writer, &_img); } int getCaptureDomain() const CV_OVERRIDE { return writer ? writer->getCaptureDomain() : 0; } }; //================================================================================================== Ptr cvCreateFileCapture_FFMPEG_proxy(const std::string &filename, const VideoCaptureParameters& params); Ptr cvCreateVideoWriter_FFMPEG_proxy(const std::string& filename, int fourcc, double fps, const Size& frameSize, const VideoWriterParameters& params); Ptr createGStreamerCapture_file(const std::string& filename, const cv::VideoCaptureParameters& params); Ptr createGStreamerCapture_cam(int index, const cv::VideoCaptureParameters& params); Ptr create_GStreamer_writer(const std::string& filename, int fourcc, double fps, const Size& frameSize, const VideoWriterParameters& params); Ptr create_MFX_capture(const std::string &filename); Ptr create_MFX_writer(const std::string& filename, int _fourcc, double fps, const Size& frameSize, const VideoWriterParameters& params); Ptr create_AVFoundation_capture_file(const std::string &filename); Ptr create_AVFoundation_capture_cam(int index); Ptr create_AVFoundation_writer(const std::string& filename, int fourcc, double fps, const Size& frameSize, const VideoWriterParameters& params); Ptr create_WRT_capture(int device); Ptr cvCreateCapture_MSMF(int index, const VideoCaptureParameters& params); Ptr cvCreateCapture_MSMF(const std::string& filename, const VideoCaptureParameters& params); Ptr cvCreateVideoWriter_MSMF(const std::string& filename, int fourcc, double fps, const Size& frameSize, const VideoWriterParameters& params); Ptr create_DShow_capture(int index); Ptr create_V4L_capture_cam(int index); Ptr create_V4L_capture_file(const std::string &filename); Ptr create_OpenNI2_capture_cam( int index ); Ptr create_OpenNI2_capture_file( const std::string &filename ); Ptr create_Images_capture(const std::string &filename); Ptr create_Images_writer(const std::string& filename, int fourcc, double fps, const Size& frameSize, const VideoWriterParameters& params); Ptr create_DC1394_capture(int index); Ptr create_RealSense_capture(int index); Ptr create_PvAPI_capture( int index ); Ptr create_XIMEA_capture_cam( int index ); Ptr create_XIMEA_capture_file( const std::string &serialNumber ); Ptr create_ueye_camera(int camera); Ptr create_Aravis_capture( int index ); Ptr createMotionJpegCapture(const std::string& filename); Ptr createMotionJpegWriter(const std::string& filename, int fourcc, double fps, const Size& frameSize, const VideoWriterParameters& params); Ptr createGPhoto2Capture(int index); Ptr createGPhoto2Capture(const std::string& deviceName); Ptr createXINECapture(const std::string &filename); Ptr createAndroidCapture_cam( int index ); Ptr createAndroidCapture_file(const std::string &filename); bool VideoCapture_V4L_waitAny( const std::vector& streams, CV_OUT std::vector& ready, int64 timeoutNs); static inline std::ostream& operator<<(std::ostream& out, const VideoAccelerationType& va_type) { switch (va_type) { case VIDEO_ACCELERATION_NONE: out << "NONE"; return out; case VIDEO_ACCELERATION_ANY: out << "ANY"; return out; case VIDEO_ACCELERATION_D3D11: out << "D3D11"; return out; case VIDEO_ACCELERATION_VAAPI: out << "VAAPI"; return out; case VIDEO_ACCELERATION_MFX: out << "MFX"; return out; } out << cv::format("UNKNOWN(0x%ux)", static_cast(va_type)); return out; } } // cv:: #endif // CAP_INTERFACE_HPP