1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html.
4 
5 #ifndef CAP_INTERFACE_HPP
6 #define CAP_INTERFACE_HPP
7 
8 #include "opencv2/core.hpp"
9 #include "opencv2/core/core_c.h"
10 #include "opencv2/videoio.hpp"
11 #include "opencv2/videoio/videoio_c.h"
12 
13 //===================================================
14 
15 // Legacy structs
16 
17 struct CvCapture
18 {
~CvCaptureCvCapture19     virtual ~CvCapture() {}
getPropertyCvCapture20     virtual double getProperty(int) const { return 0; }
setPropertyCvCapture21     virtual bool setProperty(int, double) { return 0; }
grabFrameCvCapture22     virtual bool grabFrame() { return true; }
retrieveFrameCvCapture23     virtual IplImage* retrieveFrame(int) { return 0; }
getCaptureDomainCvCapture24     virtual int getCaptureDomain() { return cv::CAP_ANY; } // Return the type of the capture object: CAP_DSHOW, etc...
25 };
26 
27 struct CvVideoWriter
28 {
~CvVideoWriterCvVideoWriter29     virtual ~CvVideoWriter() {}
writeFrameCvVideoWriter30     virtual bool writeFrame(const IplImage*) { return false; }
getCaptureDomainCvVideoWriter31     virtual int getCaptureDomain() const { return cv::CAP_ANY; } // Return the type of the capture object: CAP_FFMPEG, etc...
getPropertyCvVideoWriter32     virtual double getProperty(int) const { return 0; }
33 };
34 
35 //===================================================
36 
37 // Modern classes
38 
39 namespace cv
40 {
41 namespace
42 {
43 template <class T>
castParameterTo(int paramValue)44 inline T castParameterTo(int paramValue)
45 {
46     return static_cast<T>(paramValue);
47 }
48 
49 template <>
castParameterTo(int paramValue)50 inline bool castParameterTo(int paramValue)
51 {
52     return paramValue != 0;
53 }
54 }
55 
56 class VideoParameters
57 {
58 public:
59     struct VideoParameter {
60         VideoParameter() = default;
61 
VideoParametercv::VideoParameters::VideoParameter62         VideoParameter(int key_, int value_) : key(key_), value(value_) {}
63 
64         int key{-1};
65         int value{-1};
66         mutable bool isConsumed{false};
67     };
68 
69     VideoParameters() = default;
70 
VideoParameters(const std::vector<int> & params)71     explicit VideoParameters(const std::vector<int>& params)
72     {
73         const auto count = params.size();
74         if (count % 2 != 0)
75         {
76             CV_Error_(Error::StsVecLengthErr,
77                       ("Vector of VideoWriter parameters should have even length"));
78         }
79         params_.reserve(count / 2);
80         for (std::size_t i = 0; i < count; i += 2)
81         {
82             add(params[i], params[i + 1]);
83         }
84     }
85 
VideoParameters(int * params,unsigned n_params)86     VideoParameters(int* params, unsigned n_params)
87     {
88         params_.reserve(n_params);
89         for (unsigned i = 0; i < n_params; ++i)
90         {
91             add(params[2*i], params[2*i + 1]);
92         }
93     }
94 
add(int key,int value)95     void add(int key, int value)
96     {
97         params_.emplace_back(key, value);
98     }
99 
has(int key) const100     bool has(int key) const
101     {
102         auto it = std::find_if(params_.begin(), params_.end(),
103             [key](const VideoParameter &param)
104             {
105                 return param.key == key;
106             }
107         );
108         return it != params_.end();
109     }
110 
111     template <class ValueType>
get(int key) const112     ValueType get(int key) const
113     {
114         auto it = std::find_if(params_.begin(), params_.end(),
115             [key](const VideoParameter &param)
116             {
117                 return param.key == key;
118             }
119         );
120         if (it != params_.end())
121         {
122             it->isConsumed = true;
123             return castParameterTo<ValueType>(it->value);
124         }
125         else
126         {
127             CV_Error_(Error::StsBadArg, ("Missing value for parameter: [%d]", key));
128         }
129     }
130 
131     template <class ValueType>
get(int key,ValueType defaultValue) const132     ValueType get(int key, ValueType defaultValue) const
133     {
134         auto it = std::find_if(params_.begin(), params_.end(),
135             [key](const VideoParameter &param)
136             {
137                 return param.key == key;
138             }
139         );
140         if (it != params_.end())
141         {
142             it->isConsumed = true;
143             return castParameterTo<ValueType>(it->value);
144         }
145         else
146         {
147             return defaultValue;
148         }
149     }
150 
getUnused() const151     std::vector<int> getUnused() const
152     {
153         std::vector<int> unusedParams;
154         for (const auto &param : params_)
155         {
156             if (!param.isConsumed)
157             {
158                 unusedParams.push_back(param.key);
159             }
160         }
161         return unusedParams;
162     }
163 
getIntVector() const164     std::vector<int> getIntVector() const
165     {
166         std::vector<int> vint_params;
167         for (const auto& param : params_)
168         {
169             vint_params.push_back(param.key);
170             vint_params.push_back(param.value);
171         }
172         return vint_params;
173     }
174 
empty() const175     bool empty() const
176     {
177         return params_.empty();
178     }
179 
warnUnusedParameters() const180     bool warnUnusedParameters() const
181     {
182         bool found = false;
183         for (const auto &param : params_)
184         {
185             if (!param.isConsumed)
186             {
187                 found = true;
188                 CV_LOG_INFO(NULL, "VIDEOIO: unused parameter: [" << param.key << "]=" <<
189                     cv::format("%lld / 0x%016llx", (long long)param.value, (long long)param.value));
190             }
191         }
192         return found;
193     }
194 
195 
196 private:
197     std::vector<VideoParameter> params_;
198 };
199 
200 class VideoWriterParameters : public VideoParameters
201 {
202 public:
203     using VideoParameters::VideoParameters;  // reuse constructors
204 };
205 
206 class VideoCaptureParameters : public VideoParameters
207 {
208 public:
209     using VideoParameters::VideoParameters;  // reuse constructors
210 };
211 
212 class IVideoCapture
213 {
214 public:
~IVideoCapture()215     virtual ~IVideoCapture() {}
getProperty(int) const216     virtual double getProperty(int) const { return 0; }
setProperty(int,double)217     virtual bool setProperty(int, double) { return false; }
218     virtual bool grabFrame() = 0;
219     virtual bool retrieveFrame(int, OutputArray) = 0;
220     virtual bool isOpened() const = 0;
getCaptureDomain()221     virtual int getCaptureDomain() { return CAP_ANY; } // Return the type of the capture object: CAP_DSHOW, etc...
222 };
223 
224 class IVideoWriter
225 {
226 public:
~IVideoWriter()227     virtual ~IVideoWriter() {}
getProperty(int) const228     virtual double getProperty(int) const { return 0; }
setProperty(int,double)229     virtual bool setProperty(int, double) { return false; }
230     virtual bool isOpened() const = 0;
231     virtual void write(InputArray) = 0;
getCaptureDomain() const232     virtual int getCaptureDomain() const { return cv::CAP_ANY; } // Return the type of the capture object: CAP_FFMPEG, etc...
233 };
234 
235 namespace internal {
236 class VideoCapturePrivateAccessor
237 {
238 public:
239     static
getIVideoCapture(const VideoCapture & cap)240     IVideoCapture* getIVideoCapture(const VideoCapture& cap) { return cap.icap.get(); }
241 };
242 } // namespace
243 
244 //===================================================
245 
246 // Wrapper
247 
248 class LegacyCapture : public IVideoCapture
249 {
250 private:
251     CvCapture * cap;
252     LegacyCapture(const LegacyCapture &);
253     LegacyCapture& operator=(const LegacyCapture &);
254 public:
LegacyCapture(CvCapture * cap_)255     LegacyCapture(CvCapture * cap_) : cap(cap_) {}
~LegacyCapture()256     ~LegacyCapture()
257     {
258         cvReleaseCapture(&cap);
259     }
getProperty(int propId) const260     double getProperty(int propId) const CV_OVERRIDE
261     {
262         return cap ? cap->getProperty(propId) : 0;
263     }
setProperty(int propId,double value)264     bool setProperty(int propId, double value) CV_OVERRIDE
265     {
266         return cvSetCaptureProperty(cap, propId, value) != 0;
267     }
grabFrame()268     bool grabFrame() CV_OVERRIDE
269     {
270         return cap ? cvGrabFrame(cap) != 0 : false;
271     }
retrieveFrame(int channel,OutputArray image)272     bool retrieveFrame(int channel, OutputArray image) CV_OVERRIDE
273     {
274         IplImage* _img = cvRetrieveFrame(cap, channel);
275         if( !_img )
276         {
277             image.release();
278             return false;
279         }
280         if(_img->origin == IPL_ORIGIN_TL)
281         {
282             cv::cvarrToMat(_img).copyTo(image);
283         }
284         else
285         {
286             Mat temp = cv::cvarrToMat(_img);
287             flip(temp, image, 0);
288         }
289         return true;
290     }
isOpened() const291     bool isOpened() const CV_OVERRIDE
292     {
293         return cap != 0;  // legacy interface doesn't support closed files
294     }
getCaptureDomain()295     int getCaptureDomain() CV_OVERRIDE
296     {
297         return cap ? cap->getCaptureDomain() : 0;
298     }
299 
getCvCapture() const300     CvCapture* getCvCapture() const { return cap; }
301 };
302 
303 class LegacyWriter : public IVideoWriter
304 {
305 private:
306     CvVideoWriter * writer;
307     LegacyWriter(const LegacyWriter &);
308     LegacyWriter& operator=(const LegacyWriter &);
309 public:
LegacyWriter(CvVideoWriter * wri_)310     LegacyWriter(CvVideoWriter * wri_) : writer(wri_)
311     {}
~LegacyWriter()312     ~LegacyWriter()
313     {
314         cvReleaseVideoWriter(&writer);
315     }
getProperty(int propId) const316     double getProperty(int propId) const CV_OVERRIDE
317     {
318         if (writer)
319         {
320             return writer->getProperty(propId);
321         }
322         return 0.;
323     }
setProperty(int,double)324     bool setProperty(int, double) CV_OVERRIDE
325     {
326         return false;
327     }
isOpened() const328     bool isOpened() const CV_OVERRIDE
329     {
330         return writer != NULL;
331     }
write(InputArray image)332     void write(InputArray image) CV_OVERRIDE
333     {
334         IplImage _img = cvIplImage(image.getMat());
335         cvWriteFrame(writer, &_img);
336     }
getCaptureDomain() const337     int getCaptureDomain() const CV_OVERRIDE
338     {
339         return writer ? writer->getCaptureDomain() : 0;
340     }
341 };
342 
343 //==================================================================================================
344 
345 Ptr<IVideoCapture> cvCreateFileCapture_FFMPEG_proxy(const std::string &filename, const VideoCaptureParameters& params);
346 Ptr<IVideoWriter> cvCreateVideoWriter_FFMPEG_proxy(const std::string& filename, int fourcc,
347                                                    double fps, const Size& frameSize,
348                                                    const VideoWriterParameters& params);
349 
350 Ptr<IVideoCapture> createGStreamerCapture_file(const std::string& filename, const cv::VideoCaptureParameters& params);
351 Ptr<IVideoCapture> createGStreamerCapture_cam(int index, const cv::VideoCaptureParameters& params);
352 Ptr<IVideoWriter> create_GStreamer_writer(const std::string& filename, int fourcc,
353                                           double fps, const Size& frameSize,
354                                           const VideoWriterParameters& params);
355 
356 Ptr<IVideoCapture> create_MFX_capture(const std::string &filename);
357 Ptr<IVideoWriter> create_MFX_writer(const std::string& filename, int _fourcc,
358                                     double fps, const Size& frameSize,
359                                     const VideoWriterParameters& params);
360 
361 Ptr<IVideoCapture> create_AVFoundation_capture_file(const std::string &filename);
362 Ptr<IVideoCapture> create_AVFoundation_capture_cam(int index);
363 Ptr<IVideoWriter> create_AVFoundation_writer(const std::string& filename, int fourcc,
364                                              double fps, const Size& frameSize,
365                                              const VideoWriterParameters& params);
366 
367 Ptr<IVideoCapture> create_WRT_capture(int device);
368 
369 Ptr<IVideoCapture> cvCreateCapture_MSMF(int index, const VideoCaptureParameters& params);
370 Ptr<IVideoCapture> cvCreateCapture_MSMF(const std::string& filename, const VideoCaptureParameters& params);
371 Ptr<IVideoWriter> cvCreateVideoWriter_MSMF(const std::string& filename, int fourcc,
372                                            double fps, const Size& frameSize,
373                                            const VideoWriterParameters& params);
374 
375 Ptr<IVideoCapture> create_DShow_capture(int index);
376 
377 Ptr<IVideoCapture> create_V4L_capture_cam(int index);
378 Ptr<IVideoCapture> create_V4L_capture_file(const std::string &filename);
379 
380 Ptr<IVideoCapture> create_OpenNI2_capture_cam( int index );
381 Ptr<IVideoCapture> create_OpenNI2_capture_file( const std::string &filename );
382 
383 Ptr<IVideoCapture> create_Images_capture(const std::string &filename);
384 Ptr<IVideoWriter> create_Images_writer(const std::string& filename, int fourcc,
385                                        double fps, const Size& frameSize,
386                                        const VideoWriterParameters& params);
387 
388 Ptr<IVideoCapture> create_DC1394_capture(int index);
389 
390 Ptr<IVideoCapture> create_RealSense_capture(int index);
391 
392 Ptr<IVideoCapture> create_PvAPI_capture( int index );
393 
394 Ptr<IVideoCapture> create_XIMEA_capture_cam( int index );
395 Ptr<IVideoCapture> create_XIMEA_capture_file( const std::string &serialNumber );
396 
397 Ptr<IVideoCapture> create_ueye_camera(int camera);
398 
399 Ptr<IVideoCapture> create_Aravis_capture( int index );
400 
401 Ptr<IVideoCapture> createMotionJpegCapture(const std::string& filename);
402 Ptr<IVideoWriter> createMotionJpegWriter(const std::string& filename, int fourcc,
403                                          double fps, const Size& frameSize,
404                                          const VideoWriterParameters& params);
405 
406 Ptr<IVideoCapture> createGPhoto2Capture(int index);
407 Ptr<IVideoCapture> createGPhoto2Capture(const std::string& deviceName);
408 
409 Ptr<IVideoCapture> createXINECapture(const std::string &filename);
410 
411 Ptr<IVideoCapture> createAndroidCapture_cam( int index );
412 Ptr<IVideoCapture> createAndroidCapture_file(const std::string &filename);
413 
414 bool VideoCapture_V4L_waitAny(
415         const std::vector<VideoCapture>& streams,
416         CV_OUT std::vector<int>& ready,
417         int64 timeoutNs);
418 
419 static inline
operator <<(std::ostream & out,const VideoAccelerationType & va_type)420 std::ostream& operator<<(std::ostream& out, const VideoAccelerationType& va_type)
421 {
422     switch (va_type)
423     {
424     case VIDEO_ACCELERATION_NONE: out << "NONE"; return out;
425     case VIDEO_ACCELERATION_ANY: out << "ANY"; return out;
426     case VIDEO_ACCELERATION_D3D11: out << "D3D11"; return out;
427     case VIDEO_ACCELERATION_VAAPI: out << "VAAPI"; return out;
428     case VIDEO_ACCELERATION_MFX: out << "MFX"; return out;
429     }
430     out << cv::format("UNKNOWN(0x%ux)", static_cast<unsigned int>(va_type));
431     return out;
432 }
433 
434 } // cv::
435 
436 #endif // CAP_INTERFACE_HPP
437