Skip to content

Commit 4678704

Browse files
MaximMilashchenkoMilashchenkoalalek
authored
Merge pull request opencv#19394 from MaximMilashchenko:params
add video capture parameters * add parameters * videoio: revert unnecessary massive changes * videoio: support capture parameters in backends API - add tests - FFmpeg backend sample code - StaticBackend API is done - support through PluginBackend API will be added later Co-authored-by: Milashchenko <maksim.milashchenko@intel.com> Co-authored-by: Alexander Alekhin <alexander.a.alekhin@gmail.com>
1 parent 37c12db commit 4678704

File tree

10 files changed

+427
-29
lines changed

10 files changed

+427
-29
lines changed

modules/videoio/include/opencv2/videoio.hpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,14 @@ class CV_EXPORTS_W VideoCapture
651651
*/
652652
CV_WRAP explicit VideoCapture(const String& filename, int apiPreference = CAP_ANY);
653653

654+
/** @overload
655+
@brief Opens a video file or a capturing device or an IP video stream for video capturing with API Preference and parameters
656+
657+
The `params` parameter allows to specify extra parameters encoded as pairs `(paramId_1, paramValue_1, paramId_2, paramValue_2, ...)`.
658+
See cv::VideoCaptureProperties
659+
*/
660+
CV_WRAP explicit VideoCapture(const String& filename, int apiPreference, const std::vector<int>& params);
661+
654662
/** @overload
655663
@brief Opens a camera for video capturing
656664
@@ -663,6 +671,14 @@ class CV_EXPORTS_W VideoCapture
663671
*/
664672
CV_WRAP explicit VideoCapture(int index, int apiPreference = CAP_ANY);
665673

674+
/** @overload
675+
@brief Opens a camera for video capturing with API Preference and parameters
676+
677+
The `params` parameter allows to specify extra parameters encoded as pairs `(paramId_1, paramValue_1, paramId_2, paramValue_2, ...)`.
678+
See cv::VideoCaptureProperties
679+
*/
680+
CV_WRAP explicit VideoCapture(int index, int apiPreference, const std::vector<int>& params);
681+
666682
/** @brief Default destructor
667683
668684
The method first calls VideoCapture::release to close the already opened file or camera.
@@ -684,6 +700,19 @@ class CV_EXPORTS_W VideoCapture
684700
685701
@overload
686702
703+
The `params` parameter allows to specify extra parameters encoded as pairs `(paramId_1, paramValue_1, paramId_2, paramValue_2, ...)`.
704+
See cv::VideoCaptureProperties
705+
706+
@return `true` if the file has been successfully opened
707+
708+
The method first calls VideoCapture::release to close the already opened file or camera.
709+
*/
710+
CV_WRAP virtual bool open(const String& filename, int apiPreference, const std::vector<int>& params);
711+
712+
/** @brief Opens a camera for video capturing
713+
714+
@overload
715+
687716
Parameters are same as the constructor VideoCapture(int index, int apiPreference = CAP_ANY)
688717
@return `true` if the camera has been successfully opened.
689718
@@ -693,6 +722,19 @@ class CV_EXPORTS_W VideoCapture
693722

694723
/** @brief Returns true if video capturing has been initialized already.
695724
725+
@overload
726+
727+
The `params` parameter allows to specify extra parameters encoded as pairs `(paramId_1, paramValue_1, paramId_2, paramValue_2, ...)`.
728+
See cv::VideoCaptureProperties
729+
730+
@return `true` if the camera has been successfully opened.
731+
732+
The method first calls VideoCapture::release to close the already opened file or camera.
733+
*/
734+
CV_WRAP virtual bool open(int index, int apiPreference, const std::vector<int>& params);
735+
736+
/** @brief Returns true if video capturing has been initialized already.
737+
696738
If the previous call to VideoCapture constructor or VideoCapture::open() succeeded, the method returns
697739
true.
698740
*/

modules/videoio/misc/objc/gen_dict.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
},
1414
"func_arg_fix" : {
1515
"VideoCapture" : {
16-
"(BOOL)open:(int)index apiPreference:(int)apiPreference" : { "open" : {"name" : "openWithIndex"} }
16+
"(BOOL)open:(int)index apiPreference:(int)apiPreference" : { "open" : {"name" : "openWithIndex"} },
17+
"(BOOL)open:(int)index apiPreference:(int)apiPreference params:(IntVector*)params" : { "open" : {"name" : "openWithIndexAndParameters"} }
1718
}
1819
}
1920
}

modules/videoio/src/backend.hpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ class IBackend
1616
{
1717
public:
1818
virtual ~IBackend() {}
19-
virtual Ptr<IVideoCapture> createCapture(int camera) const = 0;
20-
virtual Ptr<IVideoCapture> createCapture(const std::string &filename) const = 0;
19+
virtual Ptr<IVideoCapture> createCapture(int camera, const VideoCaptureParameters& params) const = 0;
20+
virtual Ptr<IVideoCapture> createCapture(const std::string &filename, const VideoCaptureParameters& params) const = 0;
2121
virtual Ptr<IVideoWriter> createWriter(const std::string& filename, int fourcc, double fps, const cv::Size& sz,
2222
const VideoWriterParameters& params) const = 0;
2323
};
@@ -33,14 +33,21 @@ class IBackendFactory
3333

3434
typedef Ptr<IVideoCapture> (*FN_createCaptureFile)(const std::string & filename);
3535
typedef Ptr<IVideoCapture> (*FN_createCaptureCamera)(int camera);
36+
typedef Ptr<IVideoCapture> (*FN_createCaptureFileWithParams)(const std::string & filename, const VideoCaptureParameters& params);
37+
typedef Ptr<IVideoCapture> (*FN_createCaptureCameraWithParams)(int camera, const VideoCaptureParameters& params);
3638
typedef Ptr<IVideoWriter> (*FN_createWriter)(const std::string& filename, int fourcc, double fps, const Size& sz,
3739
const VideoWriterParameters& params);
3840
Ptr<IBackendFactory> createBackendFactory(FN_createCaptureFile createCaptureFile,
3941
FN_createCaptureCamera createCaptureCamera,
4042
FN_createWriter createWriter);
43+
Ptr<IBackendFactory> createBackendFactory(FN_createCaptureFileWithParams createCaptureFile,
44+
FN_createCaptureCameraWithParams createCaptureCamera,
45+
FN_createWriter createWriter);
4146

4247
Ptr<IBackendFactory> createPluginBackendFactory(VideoCaptureAPIs id, const char* baseName);
4348

49+
void applyParametersFallback(const Ptr<IVideoCapture>& cap, const VideoCaptureParameters& params);
50+
4451
} // namespace cv::
4552

4653
#endif // BACKEND_HPP_DEFINED

modules/videoio/src/backend_plugin.cpp

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,8 +363,10 @@ class PluginBackend: public IBackend
363363
}
364364
}
365365

366-
Ptr<IVideoCapture> createCapture(int camera) const CV_OVERRIDE;
367-
Ptr<IVideoCapture> createCapture(const std::string &filename) const CV_OVERRIDE;
366+
Ptr<IVideoCapture> createCapture(int camera) const;
367+
Ptr<IVideoCapture> createCapture(int camera, const VideoCaptureParameters& params) const CV_OVERRIDE;
368+
Ptr<IVideoCapture> createCapture(const std::string &filename) const;
369+
Ptr<IVideoCapture> createCapture(const std::string &filename, const VideoCaptureParameters& params) const CV_OVERRIDE;
368370
Ptr<IVideoWriter> createWriter(const std::string& filename, int fourcc, double fps,
369371
const cv::Size& sz, const VideoWriterParameters& params) const CV_OVERRIDE;
370372
};
@@ -753,10 +755,22 @@ Ptr<IVideoCapture> PluginBackend::createCapture(int camera) const
753755
catch (...)
754756
{
755757
CV_LOG_DEBUG(NULL, "Video I/O: can't create camera capture: " << camera);
758+
throw;
756759
}
757760
return Ptr<IVideoCapture>();
758761
}
759762

763+
Ptr<IVideoCapture> PluginBackend::createCapture(int camera, const VideoCaptureParameters& params) const
764+
{
765+
// TODO Update plugins API to support parameters
766+
Ptr<IVideoCapture> cap = createCapture(camera);
767+
if (cap && !params.empty())
768+
{
769+
applyParametersFallback(cap, params);
770+
}
771+
return cap;
772+
}
773+
760774
Ptr<IVideoCapture> PluginBackend::createCapture(const std::string &filename) const
761775
{
762776
try
@@ -769,10 +783,22 @@ Ptr<IVideoCapture> PluginBackend::createCapture(const std::string &filename) con
769783
catch (...)
770784
{
771785
CV_LOG_DEBUG(NULL, "Video I/O: can't open file capture: " << filename);
786+
throw;
772787
}
773788
return Ptr<IVideoCapture>();
774789
}
775790

791+
Ptr<IVideoCapture> PluginBackend::createCapture(const std::string &filename, const VideoCaptureParameters& params) const
792+
{
793+
// TODO Update plugins API to support parameters
794+
Ptr<IVideoCapture> cap = createCapture(filename);
795+
if (cap && !params.empty())
796+
{
797+
applyParametersFallback(cap, params);
798+
}
799+
return cap;
800+
}
801+
776802
Ptr<IVideoWriter> PluginBackend::createWriter(const std::string& filename, int fourcc, double fps,
777803
const cv::Size& sz, const VideoWriterParameters& params) const
778804
{

modules/videoio/src/backend_static.cpp

Lines changed: 109 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,28 @@
88

99
namespace cv {
1010

11+
12+
void applyParametersFallback(const Ptr<IVideoCapture>& cap, const VideoCaptureParameters& params)
13+
{
14+
std::vector<int> props = params.getUnused();
15+
CV_LOG_INFO(NULL, "VIDEOIO: Backend '" << videoio_registry::getBackendName((VideoCaptureAPIs)cap->getCaptureDomain()) <<
16+
"' implementation doesn't support parameters in .open(). Applying " <<
17+
props.size() << " properties through .setProperty()");
18+
for (int prop : props)
19+
{
20+
double value = params.get<double>(prop, -1);
21+
CV_LOG_INFO(NULL, "VIDEOIO: apply parameter: [" << prop << "]=" <<
22+
cv::format("%g / %lld / 0x%16llx", value, (long long)value, (long long)value));
23+
if (!cap->setProperty(prop, value))
24+
{
25+
CV_Error_(cv::Error::StsNotImplemented, ("VIDEOIO: Failed to apply invalid or unsupported parameter: [%d]=%g / %lld / 0x%08llx", prop, value, (long long)value, (long long)value));
26+
}
27+
}
28+
// NB: there is no dedicated "commit" parameters event, implementations should commit after each property automatically
29+
}
30+
31+
32+
// Legacy API. Modern API with parameters is below
1133
class StaticBackend: public IBackend
1234
{
1335
public:
@@ -20,18 +42,33 @@ class StaticBackend: public IBackend
2042
{
2143
// nothing
2244
}
45+
2346
~StaticBackend() CV_OVERRIDE {}
2447

25-
Ptr<IVideoCapture> createCapture(int camera) const CV_OVERRIDE
48+
Ptr<IVideoCapture> createCapture(int camera, const VideoCaptureParameters& params) const CV_OVERRIDE
2649
{
2750
if (fn_createCaptureCamera_)
28-
return fn_createCaptureCamera_(camera);
51+
{
52+
Ptr<IVideoCapture> cap = fn_createCaptureCamera_(camera);
53+
if (cap && !params.empty())
54+
{
55+
applyParametersFallback(cap, params);
56+
}
57+
return cap;
58+
}
2959
return Ptr<IVideoCapture>();
3060
}
31-
Ptr<IVideoCapture> createCapture(const std::string &filename) const CV_OVERRIDE
61+
Ptr<IVideoCapture> createCapture(const std::string &filename, const VideoCaptureParameters& params) const CV_OVERRIDE
3262
{
3363
if (fn_createCaptureFile_)
34-
return fn_createCaptureFile_(filename);
64+
{
65+
Ptr<IVideoCapture> cap = fn_createCaptureFile_(filename);
66+
if (cap && !params.empty())
67+
{
68+
applyParametersFallback(cap, params);
69+
}
70+
return cap;
71+
}
3572
return Ptr<IVideoCapture>();
3673
}
3774
Ptr<IVideoWriter> createWriter(const std::string& filename, int fourcc, double fps,
@@ -63,11 +100,79 @@ class StaticBackendFactory : public IBackendFactory
63100
}
64101
};
65102

103+
66104
Ptr<IBackendFactory> createBackendFactory(FN_createCaptureFile createCaptureFile,
67105
FN_createCaptureCamera createCaptureCamera,
68106
FN_createWriter createWriter)
69107
{
70108
return makePtr<StaticBackendFactory>(createCaptureFile, createCaptureCamera, createWriter).staticCast<IBackendFactory>();
71109
}
72110

111+
112+
113+
class StaticBackendWithParams: public IBackend
114+
{
115+
public:
116+
FN_createCaptureFileWithParams fn_createCaptureFile_;
117+
FN_createCaptureCameraWithParams fn_createCaptureCamera_;
118+
FN_createWriter fn_createWriter_;
119+
120+
StaticBackendWithParams(FN_createCaptureFileWithParams fn_createCaptureFile, FN_createCaptureCameraWithParams fn_createCaptureCamera, FN_createWriter fn_createWriter)
121+
: fn_createCaptureFile_(fn_createCaptureFile), fn_createCaptureCamera_(fn_createCaptureCamera), fn_createWriter_(fn_createWriter)
122+
{
123+
// nothing
124+
}
125+
126+
~StaticBackendWithParams() CV_OVERRIDE {}
127+
128+
Ptr<IVideoCapture> createCapture(int camera, const VideoCaptureParameters& params) const CV_OVERRIDE
129+
{
130+
if (fn_createCaptureCamera_)
131+
return fn_createCaptureCamera_(camera, params);
132+
return Ptr<IVideoCapture>();
133+
}
134+
Ptr<IVideoCapture> createCapture(const std::string &filename, const VideoCaptureParameters& params) const CV_OVERRIDE
135+
{
136+
if (fn_createCaptureFile_)
137+
return fn_createCaptureFile_(filename, params);
138+
return Ptr<IVideoCapture>();
139+
}
140+
Ptr<IVideoWriter> createWriter(const std::string& filename, int fourcc, double fps,
141+
const cv::Size& sz, const VideoWriterParameters& params) const CV_OVERRIDE
142+
{
143+
if (fn_createWriter_)
144+
return fn_createWriter_(filename, fourcc, fps, sz, params);
145+
return Ptr<IVideoWriter>();
146+
}
147+
}; // StaticBackendWithParams
148+
149+
class StaticBackendWithParamsFactory : public IBackendFactory
150+
{
151+
protected:
152+
Ptr<StaticBackendWithParams> backend;
153+
154+
public:
155+
StaticBackendWithParamsFactory(FN_createCaptureFileWithParams createCaptureFile, FN_createCaptureCameraWithParams createCaptureCamera, FN_createWriter createWriter)
156+
: backend(makePtr<StaticBackendWithParams>(createCaptureFile, createCaptureCamera, createWriter))
157+
{
158+
// nothing
159+
}
160+
161+
~StaticBackendWithParamsFactory() CV_OVERRIDE {}
162+
163+
Ptr<IBackend> getBackend() const CV_OVERRIDE
164+
{
165+
return backend.staticCast<IBackend>();
166+
}
167+
};
168+
169+
170+
Ptr<IBackendFactory> createBackendFactory(FN_createCaptureFileWithParams createCaptureFile,
171+
FN_createCaptureCameraWithParams createCaptureCamera,
172+
FN_createWriter createWriter)
173+
{
174+
return makePtr<StaticBackendWithParamsFactory>(createCaptureFile, createCaptureCamera, createWriter).staticCast<IBackendFactory>();
175+
}
176+
177+
73178
} // namespace

0 commit comments

Comments
 (0)