VideoIO classes refactoring
authorVadim Levin <vadim.levin@xperience.ai>
Fri, 27 Dec 2019 09:42:09 +0000 (12:42 +0300)
committerVadim Levin <vadim.levin@xperience.ai>
Wed, 22 Jan 2020 09:05:10 +0000 (12:05 +0300)
  - Added `explicit` to `VideoCapture` constructors with 2
    arguments, 1 of them has default value
  - Applied library code style
  - Introduced 2 debug macros to improve readability of the code

modules/videoio/include/opencv2/videoio.hpp
modules/videoio/src/cap.cpp

index 999643d..1e262bb 100644 (file)
@@ -628,7 +628,7 @@ public:
     implementation if multiple are available: e.g. cv::CAP_FFMPEG or cv::CAP_IMAGES or cv::CAP_DSHOW.
     @sa The list of supported API backends cv::VideoCaptureAPIs
     */
-    CV_WRAP VideoCapture(const String& filename, int apiPreference = CAP_ANY);
+    CV_WRAP explicit VideoCapture(const String& filename, int apiPreference = CAP_ANY);
 
     /** @overload
     @brief  Opens a camera for video capturing
@@ -640,7 +640,7 @@ public:
 
     @sa The list of supported API backends cv::VideoCaptureAPIs
     */
-    CV_WRAP VideoCapture(int index, int apiPreference = CAP_ANY);
+    CV_WRAP explicit VideoCapture(int index, int apiPreference = CAP_ANY);
 
     /** @brief Default destructor
 
index 6ae9ac7..c4206fb 100644 (file)
@@ -50,6 +50,17 @@ static bool param_VIDEOIO_DEBUG = utils::getConfigurationParameterBool("OPENCV_V
 static bool param_VIDEOCAPTURE_DEBUG = utils::getConfigurationParameterBool("OPENCV_VIDEOCAPTURE_DEBUG", false);
 static bool param_VIDEOWRITER_DEBUG = utils::getConfigurationParameterBool("OPENCV_VIDEOWRITER_DEBUG", false);
 
+#define CV_CAPTURE_LOG_DEBUG(tag, ...)                   \
+    if (param_VIDEOIO_DEBUG || param_VIDEOCAPTURE_DEBUG) \
+    {                                                    \
+        CV_LOG_WARNING(nullptr, __VA_ARGS__);            \
+    }
+
+#define CV_WRITER_LOG_DEBUG(tag, ...)                   \
+    if (param_VIDEOIO_DEBUG || param_VIDEOWRITER_DEBUG) \
+    {                                                   \
+        CV_LOG_WARNING(nullptr, __VA_ARGS__)            \
+    }
 
 void DefaultDeleter<CvCapture>::operator ()(CvCapture* obj) const { cvReleaseCapture(&obj); }
 void DefaultDeleter<CvVideoWriter>::operator ()(CvVideoWriter* obj) const { cvReleaseVideoWriter(&obj); }
@@ -80,7 +91,10 @@ bool VideoCapture::open(const String& filename, int apiPreference)
 {
     CV_TRACE_FUNCTION();
 
-    if (isOpened()) release();
+    if (isOpened())
+    {
+        release();
+    }
 
     const std::vector<VideoBackendInfo> backends = cv::videoio_registry::getAvailableBackends_CaptureByFilename();
     for (size_t i = 0; i < backends.size(); i++)
@@ -88,8 +102,10 @@ bool VideoCapture::open(const String& filename, int apiPreference)
         const VideoBackendInfo& info = backends[i];
         if (apiPreference == CAP_ANY || apiPreference == info.id)
         {
-            if (param_VIDEOIO_DEBUG || param_VIDEOCAPTURE_DEBUG)
-                CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): trying capture filename='%s' ...", info.name, filename.c_str()));
+
+            CV_CAPTURE_LOG_DEBUG(NULL,
+                                 cv::format("VIDEOIO(%s): trying capture filename='%s' ...",
+                                            info.name, filename.c_str()));
             CV_Assert(!info.backendFactory.empty());
             const Ptr<IBackend> backend = info.backendFactory->getBackend();
             if (!backend.empty())
@@ -99,48 +115,79 @@ bool VideoCapture::open(const String& filename, int apiPreference)
                     icap = backend->createCapture(filename);
                     if (!icap.empty())
                     {
-                        if (param_VIDEOIO_DEBUG || param_VIDEOCAPTURE_DEBUG)
-                            CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): created, isOpened=%d",
-                                                            info.name, icap->isOpened()));
+                        CV_CAPTURE_LOG_DEBUG(NULL,
+                                             cv::format("VIDEOIO(%s): created, isOpened=%d",
+                                                        info.name, icap->isOpened()));
                         if (icap->isOpened())
+                        {
                             return true;
+                        }
                         icap.release();
                     }
                     else
                     {
-                        if (param_VIDEOIO_DEBUG || param_VIDEOCAPTURE_DEBUG)
-                            CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): can't create capture", info.name));
+                        CV_CAPTURE_LOG_DEBUG(NULL,
+                                             cv::format("VIDEOIO(%s): can't create capture",
+                                                        info.name));
+                    }
+                }
+                catch (const cv::Exception& e)
+                {
+                    if (throwOnFail && apiPreference != CAP_ANY)
+                    {
+                        throw;
                     }
-                } catch(const cv::Exception& e) {
-                    if(throwOnFail && apiPreference != CAP_ANY) throw;
-                    CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised OpenCV exception:\n\n%s\n", info.name, e.what()));
-                } catch (const std::exception& e) {
-                    if(throwOnFail && apiPreference != CAP_ANY) throw;
-                    CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised C++ exception:\n\n%s\n", info.name, e.what()));
-                } catch(...) {
-                    if(throwOnFail && apiPreference != CAP_ANY) throw;
-                    CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised unknown C++ exception!\n\n", info.name));
+                    CV_LOG_ERROR(NULL,
+                                 cv::format("VIDEOIO(%s): raised OpenCV exception:\n\n%s\n",
+                                            info.name, e.what()));
+                }
+                catch (const std::exception& e)
+                {
+                    if (throwOnFail && apiPreference != CAP_ANY)
+                    {
+                        throw;
+                    }
+                    CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised C++ exception:\n\n%s\n",
+                                                  info.name, e.what()));
+                }
+                catch (...)
+                {
+                    if (throwOnFail && apiPreference != CAP_ANY)
+                    {
+                        throw;
+                    }
+                    CV_LOG_ERROR(NULL,
+                                 cv::format("VIDEOIO(%s): raised unknown C++ exception!\n\n",
+                                            info.name));
                 }
             }
             else
             {
-                if (param_VIDEOIO_DEBUG || param_VIDEOCAPTURE_DEBUG) \
-                    CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): backend is not available (plugin is missing, or can't be loaded due dependencies or it is not compatible)", info.name));
+                CV_CAPTURE_LOG_DEBUG(NULL,
+                                     cv::format("VIDEOIO(%s): backend is not available "
+                                                "(plugin is missing, or can't be loaded due "
+                                                "dependencies or it is not compatible)",
+                                                 info.name));
             }
         }
     }
 
     if (throwOnFail)
+    {
         CV_Error_(Error::StsError, ("could not open '%s'", filename.c_str()));
+    }
 
     return false;
 }
 
-bool  VideoCapture::open(int cameraNum, int apiPreference)
+bool VideoCapture::open(int cameraNum, int apiPreference)
 {
     CV_TRACE_FUNCTION();
 
-    if (isOpened()) release();
+    if (isOpened())
+    {
+        release();
+    }
 
     if (apiPreference == CAP_ANY)
     {
@@ -159,8 +206,10 @@ bool  VideoCapture::open(int cameraNum, int apiPreference)
         const VideoBackendInfo& info = backends[i];
         if (apiPreference == CAP_ANY || apiPreference == info.id)
         {
-            if (param_VIDEOIO_DEBUG || param_VIDEOCAPTURE_DEBUG)
-                CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): trying capture cameraNum=%d ...", info.name, cameraNum));
+            CV_CAPTURE_LOG_DEBUG(NULL,
+                                 cv::format("VIDEOIO(%s): trying capture cameraNum=%d ...",
+                                            info.name, cameraNum));
+
             CV_Assert(!info.backendFactory.empty());
             const Ptr<IBackend> backend = info.backendFactory->getBackend();
             if (!backend.empty())
@@ -170,39 +219,67 @@ bool  VideoCapture::open(int cameraNum, int apiPreference)
                     icap = backend->createCapture(cameraNum);
                     if (!icap.empty())
                     {
-                        if (param_VIDEOIO_DEBUG || param_VIDEOCAPTURE_DEBUG)
-                            CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): created, isOpened=%d",
-                                                            info.name, icap->isOpened()));
+                        CV_CAPTURE_LOG_DEBUG(NULL,
+                                             cv::format("VIDEOIO(%s): created, isOpened=%d",
+                                                        info.name, icap->isOpened()));
                         if (icap->isOpened())
+                        {
                             return true;
+                        }
                         icap.release();
                     }
                     else
                     {
-                        if (param_VIDEOIO_DEBUG || param_VIDEOCAPTURE_DEBUG)
-                            CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): can't create capture", info.name));
+                        CV_CAPTURE_LOG_DEBUG(NULL,
+                                             cv::format("VIDEOIO(%s): can't create capture",
+                                                        info.name));
+                    }
+                }
+                catch (const cv::Exception& e)
+                {
+                    if (throwOnFail && apiPreference != CAP_ANY)
+                    {
+                        throw;
+                    }
+                    CV_LOG_ERROR(NULL,
+                                 cv::format("VIDEOIO(%s): raised OpenCV exception:\n\n%s\n",
+                                            info.name, e.what()));
+                }
+                catch (const std::exception& e)
+                {
+                    if (throwOnFail && apiPreference != CAP_ANY)
+                    {
+                        throw;
+                    }
+                    CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised C++ exception:\n\n%s\n",
+                                                  info.name, e.what()));
+                }
+                catch (...)
+                {
+                    if (throwOnFail && apiPreference != CAP_ANY)
+                    {
+                        throw;
                     }
-                } catch(const cv::Exception& e) {
-                    if(throwOnFail && apiPreference != CAP_ANY) throw;
-                    CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised OpenCV exception:\n\n%s\n", info.name, e.what()));
-                } catch (const std::exception& e) {
-                    if(throwOnFail && apiPreference != CAP_ANY) throw;
-                    CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised C++ exception:\n\n%s\n", info.name, e.what()));
-                } catch(...) {
-                    if(throwOnFail && apiPreference != CAP_ANY) throw;
-                    CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised unknown C++ exception!\n\n", info.name));
+                    CV_LOG_ERROR(NULL,
+                                 cv::format("VIDEOIO(%s): raised unknown C++ exception!\n\n",
+                                            info.name));
                 }
             }
             else
             {
-                if (param_VIDEOIO_DEBUG || param_VIDEOCAPTURE_DEBUG) \
-                    CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): backend is not available (plugin is missing, or can't be loaded due dependencies or it is not compatible)", info.name));
+                CV_CAPTURE_LOG_DEBUG(NULL,
+                                     cv::format("VIDEOIO(%s): backend is not available "
+                                                "(plugin is missing, or can't be loaded due "
+                                                "dependencies or it is not compatible)",
+                                                 info.name));
             }
         }
     }
 
-    if(throwOnFail)
+    if (throwOnFail)
+    {
         CV_Error_(Error::StsError, ("could not open camera %d", cameraNum));
+    }
 
     return false;
 }
@@ -216,9 +293,11 @@ String VideoCapture::getBackendName() const
 {
     int api = 0;
     if (icap)
+    {
         api = icap->isOpened() ? icap->getCaptureDomain() : 0;
+    }
     CV_Assert(api != 0);
-    return cv::videoio_registry::getBackendName((VideoCaptureAPIs)api);
+    return cv::videoio_registry::getBackendName(static_cast<VideoCaptureAPIs>(api));
 }
 
 void VideoCapture::release()
@@ -232,7 +311,9 @@ bool VideoCapture::grab()
     CV_INSTRUMENT_REGION();
     bool ret = !icap.empty() ? icap->grabFrame() : false;
     if (!ret && throwOnFail)
+    {
         CV_Error(Error::StsError, "");
+    }
     return ret;
 }
 
@@ -242,9 +323,13 @@ bool VideoCapture::retrieve(OutputArray image, int channel)
 
     bool ret = false;
     if (!icap.empty())
+    {
         ret = icap->retrieveFrame(channel, image);
+    }
     if (!ret && throwOnFail)
+    {
         CV_Error_(Error::StsError, ("could not retrieve channel %d", channel));
+    }
     return ret;
 }
 
@@ -252,10 +337,12 @@ bool VideoCapture::read(OutputArray image)
 {
     CV_INSTRUMENT_REGION();
 
-    if(grab())
+    if (grab())
+    {
         retrieve(image);
-    else
+    } else {
         image.release();
+    }
     return !image.empty();
 }
 
@@ -300,7 +387,9 @@ bool VideoCapture::set(int propId, double value)
     CV_CheckNE(propId, (int)CAP_PROP_BACKEND, "Can't set read-only property");
     bool ret = !icap.empty() ? icap->setProperty(propId, value) : false;
     if (!ret && throwOnFail)
+    {
         CV_Error_(Error::StsError, ("could not set prop %d = %f", propId, value));
+    }
     return ret;
 }
 
@@ -309,17 +398,22 @@ double VideoCapture::get(int propId) const
     if (propId == CAP_PROP_BACKEND)
     {
         int api = 0;
-        if (icap)
-            api = icap->isOpened() ? icap->getCaptureDomain() : 0;
+        if (icap && icap->isOpened())
+        {
+            api = icap->getCaptureDomain();
+        }
         if (api <= 0)
+        {
             return -1.0;
-        return (double)api;
+        }
+        return static_cast<double>(api);
     }
     return !icap.empty() ? icap->getProperty(propId) : 0;
 }
 
 
-bool VideoCapture::waitAny(const std::vector<VideoCapture>& streams, CV_OUT std::vector<int>& readyIndex, int64 timeoutNs)
+bool VideoCapture::waitAny(const std::vector<VideoCapture>& streams,
+                           CV_OUT std::vector<int>& readyIndex, int64 timeoutNs)
 {
     CV_Assert(!streams.empty());
 
@@ -331,17 +425,19 @@ bool VideoCapture::waitAny(const std::vector<VideoCapture>& streams, CV_OUT std:
         CV_CheckEQ((int)backend, (int)backend_i, "All captures must have the same backend");
     }
 
-#if (defined HAVE_CAMV4L2 || defined HAVE_VIDEOIO)  // see cap_v4l.cpp guard
+#if (defined HAVE_CAMV4L2 || defined HAVE_VIDEOIO) // see cap_v4l.cpp guard
     if (backend == CAP_V4L2)
+    {
         return VideoCapture_V4L_waitAny(streams, readyIndex, timeoutNs);
+    }
 #else
-    CV_UNUSED(readyIndex); CV_UNUSED(timeoutNs);
+    CV_UNUSED(readyIndex);
+    CV_UNUSED(timeoutNs);
 #endif
     CV_Error(Error::StsNotImplemented, "VideoCapture::waitAny() is supported by V4L backend only");
 }
 
 
-
 //=================================================================================================
 
 
@@ -349,13 +445,15 @@ bool VideoCapture::waitAny(const std::vector<VideoCapture>& streams, CV_OUT std:
 VideoWriter::VideoWriter()
 {}
 
-VideoWriter::VideoWriter(const String& filename, int _fourcc, double fps, Size frameSize, bool isColor)
+VideoWriter::VideoWriter(const String& filename, int _fourcc, double fps, Size frameSize,
+                         bool isColor)
 {
     open(filename, _fourcc, fps, frameSize, isColor);
 }
 
 
-VideoWriter::VideoWriter(const String& filename, int apiPreference, int _fourcc, double fps, Size frameSize, bool isColor)
+VideoWriter::VideoWriter(const String& filename, int apiPreference, int _fourcc, double fps,
+                         Size frameSize, bool isColor)
 {
     open(filename, apiPreference, _fourcc, fps, frameSize, isColor);
 }
@@ -370,16 +468,21 @@ VideoWriter::~VideoWriter()
     release();
 }
 
-bool VideoWriter::open(const String& filename, int _fourcc, double fps, Size frameSize, bool isColor)
+bool VideoWriter::open(const String& filename, int _fourcc, double fps, Size frameSize,
+                       bool isColor)
 {
     return open(filename, CAP_ANY, _fourcc, fps, frameSize, isColor);
 }
 
-bool VideoWriter::open(const String& filename, int apiPreference, int _fourcc, double fps, Size frameSize, bool isColor)
+bool VideoWriter::open(const String& filename, int apiPreference, int _fourcc, double fps,
+                       Size frameSize, bool isColor)
 {
     CV_INSTRUMENT_REGION();
 
-    if (isOpened()) release();
+    if (isOpened())
+    {
+        release();
+    }
 
     const std::vector<VideoBackendInfo> backends = cv::videoio_registry::getAvailableBackends_Writer();
     for (size_t i = 0; i < backends.size(); i++)
@@ -387,9 +490,11 @@ bool VideoWriter::open(const String& filename, int apiPreference, int _fourcc, d
         const VideoBackendInfo& info = backends[i];
         if (apiPreference == CAP_ANY || apiPreference == info.id)
         {
-            if (param_VIDEOIO_DEBUG || param_VIDEOWRITER_DEBUG)
-                CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): trying writer with filename='%s' fourcc=0x%08x fps=%g sz=%dx%d isColor=%d...",
-                                                info.name, filename.c_str(), (unsigned)_fourcc, fps, frameSize.width, frameSize.height, (int)isColor));
+            CV_WRITER_LOG_DEBUG(NULL,
+                                cv::format("VIDEOIO(%s): trying writer with filename='%s' "
+                                           "fourcc=0x%08x fps=%g sz=%dx%d isColor=%d...",
+                                           info.name, filename.c_str(), (unsigned)_fourcc, fps,
+                                           frameSize.width, frameSize.height, (int)isColor));
             CV_Assert(!info.backendFactory.empty());
             const Ptr<IBackend> backend = info.backendFactory->getBackend();
             if (!backend.empty())
@@ -399,30 +504,47 @@ bool VideoWriter::open(const String& filename, int apiPreference, int _fourcc, d
                     iwriter = backend->createWriter(filename, _fourcc, fps, frameSize, isColor);
                     if (!iwriter.empty())
                     {
-                        if (param_VIDEOIO_DEBUG || param_VIDEOWRITER_DEBUG)
-                            CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): created, isOpened=%d",
-                                                            info.name, iwriter->isOpened()));
+
+                        CV_WRITER_LOG_DEBUG(NULL,
+                                            cv::format("VIDEOIO(%s): created, isOpened=%d",
+                                                       info.name, iwriter->isOpened()));
                         if (iwriter->isOpened())
+                        {
                             return true;
+                        }
                         iwriter.release();
                     }
                     else
                     {
-                        if (param_VIDEOIO_DEBUG || param_VIDEOWRITER_DEBUG)
-                            CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): can't create writer", info.name));
+                        CV_WRITER_LOG_DEBUG(NULL, cv::format("VIDEOIO(%s): can't create writer",
+                                                             info.name));
                     }
-                } catch(const cv::Exception& e) {
-                    CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised OpenCV exception:\n\n%s\n", info.name, e.what()));
-                } catch (const std::exception& e) {
-                    CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised C++ exception:\n\n%s\n", info.name, e.what()));
-                } catch(...) {
-                    CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised unknown C++ exception!\n\n", info.name));
+                }
+                catch (const cv::Exception& e)
+                {
+                    CV_LOG_ERROR(NULL,
+                                 cv::format("VIDEOIO(%s): raised OpenCV exception:\n\n%s\n",
+                                            info.name, e.what()));
+                }
+                catch (const std::exception& e)
+                {
+                    CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised C++ exception:\n\n%s\n",
+                                                     info.name, e.what()));
+                }
+                catch (...)
+                {
+                    CV_LOG_ERROR(NULL,
+                                 cv::format("VIDEOIO(%s): raised unknown C++ exception!\n\n",
+                                            info.name));
                 }
             }
             else
             {
-                if (param_VIDEOIO_DEBUG || param_VIDEOWRITER_DEBUG) \
-                    CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): backend is not available (plugin is missing, or can't be loaded due dependencies or it is not compatible)", info.name));
+                CV_WRITER_LOG_DEBUG(NULL,
+                                    cv::format("VIDEOIO(%s): backend is not available "
+                                               "(plugin is missing, or can't be loaded due "
+                                               "dependencies or it is not compatible)",
+                                               info.name));
             }
         }
     }
@@ -440,7 +562,9 @@ bool VideoWriter::set(int propId, double value)
     CV_CheckNE(propId, (int)CAP_PROP_BACKEND, "Can't set read-only property");
 
     if (!iwriter.empty())
+    {
         return iwriter->setProperty(propId, value);
+    }
     return false;
 }
 
@@ -450,13 +574,15 @@ double VideoWriter::get(int propId) const
     {
         int api = 0;
         if (iwriter)
+        {
             api = iwriter->getCaptureDomain();
-        if (api <= 0)
-            return -1.0;
-        return (double)api;
+        }
+        return (api <= 0) ?  -1. : static_cast<double>(api);
     }
     if (!iwriter.empty())
+    {
         return iwriter->getProperty(propId);
+    }
     return 0.;
 }
 
@@ -464,17 +590,21 @@ String VideoWriter::getBackendName() const
 {
     int api = 0;
     if (iwriter)
+    {
         api = iwriter->getCaptureDomain();
+    }
     CV_Assert(api != 0);
-    return cv::videoio_registry::getBackendName((VideoCaptureAPIs)api);
+    return cv::videoio_registry::getBackendName(static_cast<VideoCaptureAPIs>(api));
 }
 
 void VideoWriter::write(InputArray image)
 {
     CV_INSTRUMENT_REGION();
 
-    if( iwriter )
+    if (iwriter)
+    {
         iwriter->write(image);
+    }
 }
 
 VideoWriter& VideoWriter::operator << (const Mat& image)
@@ -498,4 +628,4 @@ int VideoWriter::fourcc(char c1, char c2, char c3, char c4)
     return (c1 & 255) + ((c2 & 255) << 8) + ((c3 & 255) << 16) + ((c4 & 255) << 24);
 }
 
-} // namespace
+} // namespace cv