Skip to content

Commit e705414

Browse files
committed
videoio(plugins): support VideoCaptureParameters, CAPTURE_API_VERSION=1
- example: ffmpeg
1 parent 4678704 commit e705414

File tree

8 files changed

+154
-92
lines changed

8 files changed

+154
-92
lines changed

modules/videoio/src/backend_plugin.cpp

Lines changed: 54 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -564,20 +564,40 @@ class PluginCapture : public cv::IVideoCapture
564564
public:
565565
static
566566
Ptr<PluginCapture> create(const OpenCV_VideoIO_Capture_Plugin_API* plugin_api,
567-
const std::string &filename, int camera)
567+
const std::string &filename, int camera, const VideoCaptureParameters& params)
568568
{
569569
CV_Assert(plugin_api);
570+
CV_Assert(plugin_api->v0.Capture_release);
571+
570572
CvPluginCapture capture = NULL;
571573

572-
if (plugin_api->v0.Capture_open)
574+
if (plugin_api->api_header.api_version >= 1 && plugin_api->v1.Capture_open_with_params)
573575
{
574-
CV_Assert(plugin_api->v0.Capture_release);
575-
if (CV_ERROR_OK == plugin_api->v0.Capture_open(filename.empty() ? 0 : filename.c_str(), camera, &capture))
576+
std::vector<int> vint_params = params.getIntVector();
577+
int* c_params = &vint_params[0];
578+
unsigned n_params = (unsigned)(vint_params.size() / 2);
579+
580+
if (CV_ERROR_OK == plugin_api->v1.Capture_open_with_params(
581+
filename.empty() ? 0 : filename.c_str(), camera, c_params, n_params, &capture))
576582
{
577583
CV_Assert(capture);
578584
return makePtr<PluginCapture>(plugin_api, capture);
579585
}
580586
}
587+
else if (plugin_api->v0.Capture_open)
588+
{
589+
if (CV_ERROR_OK == plugin_api->v0.Capture_open(filename.empty() ? 0 : filename.c_str(), camera, &capture))
590+
{
591+
CV_Assert(capture);
592+
Ptr<PluginCapture> cap = makePtr<PluginCapture>(plugin_api, capture);
593+
if (cap && !params.empty())
594+
{
595+
applyParametersFallback(cap, params);
596+
}
597+
return cap;
598+
}
599+
}
600+
581601
return Ptr<PluginCapture>();
582602
}
583603

@@ -658,11 +678,13 @@ class PluginWriter : public cv::IVideoWriter
658678
const VideoWriterParameters& params)
659679
{
660680
CV_Assert(plugin_api);
681+
CV_Assert(plugin_api->v0.Writer_release);
682+
CV_Assert(!filename.empty());
683+
661684
CvPluginWriter writer = NULL;
685+
662686
if (plugin_api->api_header.api_version >= 1 && plugin_api->v1.Writer_open_with_params)
663687
{
664-
CV_Assert(plugin_api->v0.Writer_release);
665-
CV_Assert(!filename.empty());
666688
std::vector<int> vint_params = params.getIntVector();
667689
int* c_params = &vint_params[0];
668690
unsigned n_params = (unsigned)(vint_params.size() / 2);
@@ -675,21 +697,25 @@ class PluginWriter : public cv::IVideoWriter
675697
}
676698
else if (plugin_api->v0.Writer_open)
677699
{
678-
CV_Assert(plugin_api->v0.Writer_release);
679-
CV_Assert(!filename.empty());
680700
const bool isColor = params.get(VIDEOWRITER_PROP_IS_COLOR, true);
681701
const int depth = params.get(VIDEOWRITER_PROP_DEPTH, CV_8U);
682702
if (depth != CV_8U)
683703
{
684704
CV_LOG_WARNING(NULL, "Video I/O plugin doesn't support (due to lower API level) creation of VideoWriter with depth != CV_8U");
685705
return Ptr<PluginWriter>();
686706
}
707+
if (params.warnUnusedParameters())
708+
{
709+
CV_LOG_ERROR(NULL, "VIDEOIO/FFMPEG: unsupported parameters in VideoWriter, see logger INFO channel for details");
710+
return Ptr<PluginWriter>();
711+
}
687712
if (CV_ERROR_OK == plugin_api->v0.Writer_open(filename.c_str(), fourcc, fps, sz.width, sz.height, isColor, &writer))
688713
{
689714
CV_Assert(writer);
690715
return makePtr<PluginWriter>(plugin_api, writer);
691716
}
692717
}
718+
693719
return Ptr<PluginWriter>();
694720
}
695721

@@ -743,14 +769,21 @@ class PluginWriter : public cv::IVideoWriter
743769
};
744770

745771

746-
Ptr<IVideoCapture> PluginBackend::createCapture(int camera) const
772+
Ptr<IVideoCapture> PluginBackend::createCapture(int camera, const VideoCaptureParameters& params) const
747773
{
748774
try
749775
{
750776
if (capture_api_)
751-
return PluginCapture::create(capture_api_, std::string(), camera); //.staticCast<IVideoCapture>();
777+
return PluginCapture::create(capture_api_, std::string(), camera, params); //.staticCast<IVideoCapture>();
752778
if (plugin_api_)
753-
return legacy::PluginCapture::create(plugin_api_, std::string(), camera); //.staticCast<IVideoCapture>();
779+
{
780+
Ptr<IVideoCapture> cap = legacy::PluginCapture::create(plugin_api_, std::string(), camera); //.staticCast<IVideoCapture>();
781+
if (cap && !params.empty())
782+
{
783+
applyParametersFallback(cap, params);
784+
}
785+
return cap;
786+
}
754787
}
755788
catch (...)
756789
{
@@ -760,25 +793,21 @@ Ptr<IVideoCapture> PluginBackend::createCapture(int camera) const
760793
return Ptr<IVideoCapture>();
761794
}
762795

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-
774-
Ptr<IVideoCapture> PluginBackend::createCapture(const std::string &filename) const
796+
Ptr<IVideoCapture> PluginBackend::createCapture(const std::string &filename, const VideoCaptureParameters& params) const
775797
{
776798
try
777799
{
778800
if (capture_api_)
779-
return PluginCapture::create(capture_api_, filename, 0); //.staticCast<IVideoCapture>();
801+
return PluginCapture::create(capture_api_, filename, 0, params); //.staticCast<IVideoCapture>();
780802
if (plugin_api_)
781-
return legacy::PluginCapture::create(plugin_api_, filename, 0); //.staticCast<IVideoCapture>();
803+
{
804+
Ptr<IVideoCapture> cap = legacy::PluginCapture::create(plugin_api_, filename, 0); //.staticCast<IVideoCapture>();
805+
if (cap && !params.empty())
806+
{
807+
applyParametersFallback(cap, params);
808+
}
809+
return cap;
810+
}
782811
}
783812
catch (...)
784813
{
@@ -788,17 +817,6 @@ Ptr<IVideoCapture> PluginBackend::createCapture(const std::string &filename) con
788817
return Ptr<IVideoCapture>();
789818
}
790819

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-
802820
Ptr<IVideoWriter> PluginBackend::createWriter(const std::string& filename, int fourcc, double fps,
803821
const cv::Size& sz, const VideoWriterParameters& params) const
804822
{

modules/videoio/src/cap.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ VideoCapture::VideoCapture(const String& filename, int apiPreference) : throwOnF
7676
}
7777

7878
VideoCapture::VideoCapture(const String& filename, int apiPreference, const std::vector<int>& params)
79-
: throwOnFail(true)
79+
: throwOnFail(false)
8080
{
8181
CV_TRACE_FUNCTION();
8282
open(filename, apiPreference, params);
@@ -89,7 +89,7 @@ VideoCapture::VideoCapture(int index, int apiPreference) : throwOnFail(false)
8989
}
9090

9191
VideoCapture::VideoCapture(int index, int apiPreference, const std::vector<int>& params)
92-
: throwOnFail(true)
92+
: throwOnFail(false)
9393
{
9494
CV_TRACE_FUNCTION();
9595
open(index, apiPreference, params);

modules/videoio/src/cap_ffmpeg.cpp

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@
4949

5050
#include "cap_ffmpeg_impl.hpp"
5151

52-
#define icvCreateFileCapture_FFMPEG_p cvCreateFileCapture_FFMPEG
52+
// TODO drop legacy code
53+
//#define icvCreateFileCapture_FFMPEG_p cvCreateFileCapture_FFMPEG
5354
#define icvReleaseCapture_FFMPEG_p cvReleaseCapture_FFMPEG
5455
#define icvGrabFrame_FFMPEG_p cvGrabFrame_FFMPEG
5556
#define icvRetrieveFrame_FFMPEG_p cvRetrieveFrame_FFMPEG
@@ -101,36 +102,14 @@ class CvCapture_FFMPEG_proxy CV_FINAL : public cv::IVideoCapture
101102

102103
return true;
103104
}
104-
virtual bool open( const cv::String& filename )
105-
{
106-
close();
107-
108-
ffmpegCapture = icvCreateFileCapture_FFMPEG_p( filename.c_str() );
109-
return ffmpegCapture != 0;
110-
}
111105
bool open(const cv::String& filename, const cv::VideoCaptureParameters& params)
112106
{
113107
close();
114108

115-
ffmpegCapture = icvCreateFileCapture_FFMPEG_p(filename.c_str());
116-
if (ffmpegCapture && !params.empty())
117-
{
118-
if (params.has(CAP_PROP_FORMAT)) // just a sample code
119-
{
120-
int value = params.get<int>(CAP_PROP_FORMAT);
121-
if (!setProperty(CAP_PROP_FORMAT, value))
122-
{
123-
CV_Error_(Error::StsBadArg, ("VIDEOIO/FFMPEG: CAP_PROP_FORMAT parameter value is invalid/unsupported: %d", value));
124-
}
125-
}
126-
if (params.warnUnusedParameters())
127-
{
128-
CV_Error(Error::StsBadArg, "VIDEOIO/FFMPEG: unsupported parameters in .open(), see logger INFO channel for details");
129-
}
130-
}
109+
ffmpegCapture = cvCreateFileCaptureWithParams_FFMPEG(filename.c_str(), params);
131110
return ffmpegCapture != 0;
132111
}
133-
virtual void close()
112+
void close()
134113
{
135114
if (ffmpegCapture)
136115
icvReleaseCapture_FFMPEG_p( &ffmpegCapture );
@@ -251,7 +230,7 @@ cv::Ptr<cv::IVideoWriter> cvCreateVideoWriter_FFMPEG_proxy(const std::string& fi
251230
#include "plugin_api.hpp"
252231
#else
253232
#define CAPTURE_ABI_VERSION 1
254-
#define CAPTURE_API_VERSION 0
233+
#define CAPTURE_API_VERSION 1
255234
#include "plugin_capture_api.hpp"
256235
#define WRITER_ABI_VERSION 1
257236
#define WRITER_API_VERSION 0
@@ -287,6 +266,38 @@ CvResult CV_API_CALL cv_capture_open(const char* filename, int camera_index, CV_
287266
return CV_ERROR_FAIL;
288267
}
289268

269+
static
270+
CvResult CV_API_CALL cv_capture_open_with_params(
271+
const char* filename, int camera_index,
272+
int* params, unsigned n_params,
273+
CV_OUT CvPluginCapture* handle
274+
)
275+
{
276+
if (!handle)
277+
return CV_ERROR_FAIL;
278+
*handle = NULL;
279+
if (!filename)
280+
return CV_ERROR_FAIL;
281+
CV_UNUSED(camera_index);
282+
CvCapture_FFMPEG_proxy *cap = 0;
283+
try
284+
{
285+
cv::VideoCaptureParameters parameters(params, n_params);
286+
cap = new CvCapture_FFMPEG_proxy(filename, parameters);
287+
if (cap->isOpened())
288+
{
289+
*handle = (CvPluginCapture)cap;
290+
return CV_ERROR_OK;
291+
}
292+
}
293+
catch (...)
294+
{
295+
}
296+
if (cap)
297+
delete cap;
298+
return CV_ERROR_FAIL;
299+
}
300+
290301
static
291302
CvResult CV_API_CALL cv_capture_release(CvPluginCapture handle)
292303
{
@@ -505,6 +516,9 @@ static const OpenCV_VideoIO_Capture_Plugin_API capture_plugin_api =
505516
/* 5*/cv_capture_set_prop,
506517
/* 6*/cv_capture_grab,
507518
/* 7*/cv_capture_retrieve,
519+
},
520+
{
521+
/* 8*/cv_capture_open_with_params,
508522
}
509523
};
510524

modules/videoio/src/cap_ffmpeg_impl.hpp

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ static AVRational _opencv_ffmpeg_get_sample_aspect_ratio(AVStream *stream)
456456

457457
struct CvCapture_FFMPEG
458458
{
459-
bool open( const char* filename );
459+
bool open(const char* filename, const VideoCaptureParameters& params);
460460
void close();
461461

462462
double getProperty(int) const;
@@ -857,7 +857,7 @@ class InternalFFMpegRegister
857857
}
858858
};
859859

860-
bool CvCapture_FFMPEG::open( const char* _filename )
860+
bool CvCapture_FFMPEG::open(const char* _filename, const VideoCaptureParameters& params)
861861
{
862862
InternalFFMpegRegister::init();
863863
AutoLock lock(_mutex);
@@ -866,6 +866,29 @@ bool CvCapture_FFMPEG::open( const char* _filename )
866866

867867
close();
868868

869+
if (!params.empty())
870+
{
871+
if (params.has(CAP_PROP_FORMAT))
872+
{
873+
int value = params.get<int>(CAP_PROP_FORMAT);
874+
if (value == -1)
875+
{
876+
CV_LOG_INFO(NULL, "VIDEOIO/FFMPEG: enabled demuxer only mode: '" << (_filename ? _filename : "<NULL>") << "'");
877+
rawMode = true;
878+
}
879+
else
880+
{
881+
CV_LOG_ERROR(NULL, "VIDEOIO/FFMPEG: CAP_PROP_FORMAT parameter value is invalid/unsupported: " << value);
882+
return false;
883+
}
884+
}
885+
if (params.warnUnusedParameters())
886+
{
887+
CV_LOG_ERROR(NULL, "VIDEOIO/FFMPEG: unsupported parameters in .open(), see logger INFO channel for details");
888+
return false;
889+
}
890+
}
891+
869892
#if USE_AV_INTERRUPT_CALLBACK
870893
/* interrupt callback */
871894
interrupt_metadata.timeout_after_ms = LIBAVFORMAT_INTERRUPT_OPEN_TIMEOUT_MS;
@@ -2424,21 +2447,22 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
24242447

24252448

24262449

2427-
CvCapture_FFMPEG* cvCreateFileCapture_FFMPEG( const char* filename )
2450+
static
2451+
CvCapture_FFMPEG* cvCreateFileCaptureWithParams_FFMPEG(const char* filename, const VideoCaptureParameters& params)
24282452
{
2453+
// FIXIT: remove unsafe malloc() approach
24292454
CvCapture_FFMPEG* capture = (CvCapture_FFMPEG*)malloc(sizeof(*capture));
24302455
if (!capture)
24312456
return 0;
24322457
capture->init();
2433-
if( capture->open( filename ))
2458+
if (capture->open(filename, params))
24342459
return capture;
24352460

24362461
capture->close();
24372462
free(capture);
24382463
return 0;
24392464
}
24402465

2441-
24422466
void cvReleaseCapture_FFMPEG(CvCapture_FFMPEG** capture)
24432467
{
24442468
if( capture && *capture )

modules/videoio/src/cap_ffmpeg_legacy_api.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ extern "C"
2424
typedef struct CvCapture_FFMPEG CvCapture_FFMPEG;
2525
typedef struct CvVideoWriter_FFMPEG CvVideoWriter_FFMPEG;
2626

27-
OPENCV_FFMPEG_API struct CvCapture_FFMPEG* cvCreateFileCapture_FFMPEG(const char* filename);
27+
//OPENCV_FFMPEG_API struct CvCapture_FFMPEG* cvCreateFileCapture_FFMPEG(const char* filename);
2828
OPENCV_FFMPEG_API int cvSetCaptureProperty_FFMPEG(struct CvCapture_FFMPEG* cap,
2929
int prop, double value);
3030
OPENCV_FFMPEG_API double cvGetCaptureProperty_FFMPEG(struct CvCapture_FFMPEG* cap, int prop);

0 commit comments

Comments
 (0)