Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
5ae550c6
Commit
5ae550c6
authored
Apr 24, 2018
by
Maksim Shabunin
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #11320 from mshabunin:gstreamer-cpp
parents
e82af627
53098323
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
446 additions
and
435 deletions
+446
-435
cap.cpp
modules/videoio/src/cap.cpp
+20
-18
cap_gstreamer.cpp
modules/videoio/src/cap_gstreamer.cpp
+272
-317
precomp.hpp
modules/videoio/src/precomp.hpp
+4
-1
test_gstreamer.cpp
modules/videoio/test/test_gstreamer.cpp
+4
-2
test_video_io.cpp
modules/videoio/test/test_video_io.cpp
+146
-97
No files found.
modules/videoio/src/cap.cpp
View file @
5ae550c6
...
@@ -40,6 +40,8 @@
...
@@ -40,6 +40,8 @@
//M*/
//M*/
#include "precomp.hpp"
#include "precomp.hpp"
#include <iostream>
using
namespace
std
;
#include "cap_intelperc.hpp"
#include "cap_intelperc.hpp"
#include "cap_dshow.hpp"
#include "cap_dshow.hpp"
...
@@ -200,12 +202,6 @@ CV_IMPL CvCapture * cvCreateCameraCapture (int index)
...
@@ -200,12 +202,6 @@ CV_IMPL CvCapture * cvCreateCameraCapture (int index)
TRY_OPEN
(
capture
,
cvCreateCameraCapture_V4L
(
index
))
TRY_OPEN
(
capture
,
cvCreateCameraCapture_V4L
(
index
))
#endif
#endif
#ifdef HAVE_GSTREAMER
TRY_OPEN
(
capture
,
cvCreateCapture_GStreamer
(
CV_CAP_GSTREAMER_V4L2
,
reinterpret_cast
<
char
*>
(
index
)))
TRY_OPEN
(
capture
,
cvCreateCapture_GStreamer
(
CV_CAP_GSTREAMER_V4L
,
reinterpret_cast
<
char
*>
(
index
)))
#endif
if
(
pref
)
break
;
// CAP_VFW or CAP_V4L or CAP_V4L2
if
(
pref
)
break
;
// CAP_VFW or CAP_V4L or CAP_V4L2
case
CAP_FIREWIRE
:
case
CAP_FIREWIRE
:
...
@@ -221,11 +217,6 @@ CV_IMPL CvCapture * cvCreateCameraCapture (int index)
...
@@ -221,11 +217,6 @@ CV_IMPL CvCapture * cvCreateCameraCapture (int index)
TRY_OPEN
(
capture
,
cvCreateCameraCapture_CMU
(
index
))
TRY_OPEN
(
capture
,
cvCreateCameraCapture_CMU
(
index
))
#endif
#endif
#if defined(HAVE_GSTREAMER) && 0
// Re-enable again when gstreamer 1394 support will land in the backend code
TRY_OPEN
(
capture
,
cvCreateCapture_GStreamer
(
CV_CAP_GSTREAMER_1394
,
0
))
#endif
if
(
pref
)
break
;
// CAP_FIREWIRE
if
(
pref
)
break
;
// CAP_FIREWIRE
#ifdef HAVE_MIL
#ifdef HAVE_MIL
...
@@ -330,12 +321,6 @@ CV_IMPL CvCapture * cvCreateFileCaptureWithPreference (const char * filename, in
...
@@ -330,12 +321,6 @@ CV_IMPL CvCapture * cvCreateFileCaptureWithPreference (const char * filename, in
if
(
apiPreference
)
break
;
if
(
apiPreference
)
break
;
#endif
#endif
#ifdef HAVE_GSTREAMER
case
CAP_GSTREAMER
:
TRY_OPEN
(
result
,
cvCreateCapture_GStreamer
(
CV_CAP_GSTREAMER_FILE
,
filename
))
if
(
apiPreference
)
break
;
#endif
#if defined(HAVE_QUICKTIME) || defined(HAVE_QTKIT)
#if defined(HAVE_QUICKTIME) || defined(HAVE_QTKIT)
case
CAP_QT
:
case
CAP_QT
:
TRY_OPEN
(
result
,
cvCreateFileCapture_QT
(
filename
))
TRY_OPEN
(
result
,
cvCreateFileCapture_QT
(
filename
))
...
@@ -463,6 +448,9 @@ static Ptr<IVideoCapture> IVideoCapture_create(int index)
...
@@ -463,6 +448,9 @@ static Ptr<IVideoCapture> IVideoCapture_create(int index)
{
{
int
domains
[]
=
int
domains
[]
=
{
{
#ifdef HAVE_GSTREAMER
CAP_GSTREAMER
,
#endif
#ifdef HAVE_DSHOW
#ifdef HAVE_DSHOW
CAP_DSHOW
,
CAP_DSHOW
,
#endif
#endif
...
@@ -490,7 +478,8 @@ static Ptr<IVideoCapture> IVideoCapture_create(int index)
...
@@ -490,7 +478,8 @@ static Ptr<IVideoCapture> IVideoCapture_create(int index)
// try every possibly installed camera API
// try every possibly installed camera API
for
(
int
i
=
0
;
domains
[
i
]
>=
0
;
i
++
)
for
(
int
i
=
0
;
domains
[
i
]
>=
0
;
i
++
)
{
{
#if defined(HAVE_DSHOW) || \
#if defined(HAVE_GSTREAMER) || \
defined(HAVE_DSHOW) || \
defined(HAVE_INTELPERC) || \
defined(HAVE_INTELPERC) || \
defined(WINRT_VIDEO) || \
defined(WINRT_VIDEO) || \
defined(HAVE_GPHOTO2) || \
defined(HAVE_GPHOTO2) || \
...
@@ -499,6 +488,11 @@ static Ptr<IVideoCapture> IVideoCapture_create(int index)
...
@@ -499,6 +488,11 @@ static Ptr<IVideoCapture> IVideoCapture_create(int index)
switch
(
domains
[
i
])
switch
(
domains
[
i
])
{
{
#ifdef HAVE_GSTREAMER
case
CAP_GSTREAMER
:
capture
=
createGStreamerCapture
(
index
);
break
;
#endif
#ifdef HAVE_DSHOW
#ifdef HAVE_DSHOW
case
CAP_DSHOW
:
case
CAP_DSHOW
:
capture
=
makePtr
<
VideoCapture_DShow
>
(
index
);
capture
=
makePtr
<
VideoCapture_DShow
>
(
index
);
...
@@ -536,6 +530,14 @@ static Ptr<IVideoCapture> IVideoCapture_create(const String& filename, int apiPr
...
@@ -536,6 +530,14 @@ static Ptr<IVideoCapture> IVideoCapture_create(const String& filename, int apiPr
{
{
bool
useAny
=
(
apiPreference
==
CAP_ANY
);
bool
useAny
=
(
apiPreference
==
CAP_ANY
);
Ptr
<
IVideoCapture
>
capture
;
Ptr
<
IVideoCapture
>
capture
;
#ifdef HAVE_GSTREAMER
if
(
useAny
||
apiPreference
==
CAP_GSTREAMER
)
{
capture
=
createGStreamerCapture
(
filename
);
if
(
capture
&&
capture
->
isOpened
())
return
capture
;
}
#endif
#ifdef HAVE_XINE
#ifdef HAVE_XINE
if
(
useAny
||
apiPreference
==
CAP_XINE
)
if
(
useAny
||
apiPreference
==
CAP_XINE
)
{
{
...
...
modules/videoio/src/cap_gstreamer.cpp
View file @
5ae550c6
...
@@ -48,6 +48,8 @@
...
@@ -48,6 +48,8 @@
* \brief Use GStreamer to read/write video
* \brief Use GStreamer to read/write video
*/
*/
#include "precomp.hpp"
#include "precomp.hpp"
#include <iostream>
using
namespace
std
;
#ifndef _MSC_VER
#ifndef _MSC_VER
#include <unistd.h>
#include <unistd.h>
#endif
#endif
...
@@ -72,7 +74,7 @@
...
@@ -72,7 +74,7 @@
#ifdef NDEBUG
#ifdef NDEBUG
#define CV_WARN(message)
#define CV_WARN(message)
#else
#else
#define CV_WARN(message) fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__)
#define CV_WARN(message) fprintf(stderr, "
OpenCV | GStreamer
warning: %s (%s:%d)\n", message, __FILE__, __LINE__)
#endif
#endif
#if GST_VERSION_MAJOR == 0
#if GST_VERSION_MAJOR == 0
...
@@ -100,6 +102,7 @@ inline char *realpath(const char *path, char *resolved_path)
...
@@ -100,6 +102,7 @@ inline char *realpath(const char *path, char *resolved_path)
void
toFraction
(
double
decimal
,
double
&
numerator
,
double
&
denominator
);
void
toFraction
(
double
decimal
,
double
&
numerator
,
double
&
denominator
);
void
handleMessage
(
GstElement
*
pipeline
);
void
handleMessage
(
GstElement
*
pipeline
);
using
namespace
cv
;
static
cv
::
Mutex
gst_initializer_mutex
;
static
cv
::
Mutex
gst_initializer_mutex
;
...
@@ -120,116 +123,118 @@ private:
...
@@ -120,116 +123,118 @@ private:
gst_initializer
()
gst_initializer
()
{
{
gst_init
(
NULL
,
NULL
);
gst_init
(
NULL
,
NULL
);
guint
major
,
minor
,
micro
,
nano
;
gst_version
(
&
major
,
&
minor
,
&
micro
,
&
nano
);
if
(
GST_VERSION_MAJOR
==
major
)
{
CV_WARN
(
"incompatible gstreamer version"
);
}
// gst_debug_set_active(1);
// gst_debug_set_active(1);
// gst_debug_set_colored(1);
// gst_debug_set_colored(1);
// gst_debug_set_default_threshold(GST_LEVEL_INFO);
// gst_debug_set_default_threshold(GST_LEVEL_INFO);
}
}
};
};
/*!
inline
static
string
get_gst_propname
(
int
propId
)
* \brief The CvCapture_GStreamer class
* Use GStreamer to capture video
*/
class
CvCapture_GStreamer
CV_FINAL
:
public
CvCapture
{
{
public
:
switch
(
propId
)
CvCapture_GStreamer
()
{
init
();
}
{
virtual
~
CvCapture_GStreamer
()
{
close
();
}
case
CV_CAP_PROP_BRIGHTNESS
:
return
"brightness"
;
case
CV_CAP_PROP_CONTRAST
:
return
"contrast"
;
case
CV_CAP_PROP_SATURATION
:
return
"saturation"
;
case
CV_CAP_PROP_HUE
:
return
"hue"
;
default:
return
string
();
}
}
virtual
bool
open
(
int
type
,
const
char
*
filename
);
inline
static
bool
is_gst_element_exists
(
const
std
::
string
&
name
)
virtual
void
close
();
{
GstElementFactory
*
testfac
=
gst_element_factory_find
(
name
.
c_str
());
if
(
!
testfac
)
return
false
;
g_object_unref
(
G_OBJECT
(
testfac
));
return
true
;
}
virtual
double
getProperty
(
int
)
const
CV_OVERRIDE
;
//==================================================================================================
virtual
bool
setProperty
(
int
,
double
)
CV_OVERRIDE
;
virtual
bool
grabFrame
()
CV_OVERRIDE
;
virtual
IplImage
*
retrieveFrame
(
int
)
CV_OVERRIDE
;
protected
:
class
GStreamerCapture
:
public
IVideoCapture
void
init
();
{
bool
reopen
();
private
:
bool
isPipelinePlaying
();
void
startPipeline
();
void
stopPipeline
();
void
restartPipeline
();
void
setFilter
(
const
char
*
prop
,
int
type
,
int
v1
,
int
v2
=
0
);
void
removeFilter
(
const
char
*
filter
);
static
void
newPad
(
GstElement
*
myelement
,
GstPad
*
pad
,
gpointer
data
);
GstElement
*
pipeline
;
GstElement
*
pipeline
;
GstElement
*
uridecodebin
;
GstElement
*
v4l2src
;
GstElement
*
v4l2src
;
GstElement
*
color
;
GstElement
*
sink
;
GstElement
*
sink
;
#if GST_VERSION_MAJOR > 0
#if GST_VERSION_MAJOR > 0
GstSample
*
sample
;
GstSample
*
sample
;
#endif
#else
void
*
sample
;
// unused
GstBuffer
*
buffer
;
GstBuffer
*
buffer
;
#endif
GstCaps
*
caps
;
GstCaps
*
caps
;
IplImage
*
frame
;
gint64
duration
;
gint64
duration
;
gint
width
;
gint
width
;
gint
height
;
gint
height
;
gint
channels
;
double
fps
;
double
fps
;
bool
isPosFramesSupported
;
bool
isPosFramesSupported
;
bool
isPosFramesEmulated
;
bool
isPosFramesEmulated
;
gint64
emulatedFrameNumber
;
gint64
emulatedFrameNumber
;
bool
isOutputByteBuffer
;
bool
isOutputByteBuffer
;
public
:
GStreamerCapture
();
~
GStreamerCapture
();
virtual
bool
grabFrame
();
virtual
bool
retrieveFrame
(
int
/*unused*/
,
OutputArray
dst
);
virtual
double
getProperty
(
int
propId
)
const
;
virtual
bool
setProperty
(
int
propId
,
double
value
);
virtual
bool
isOpened
()
const
;
virtual
int
getCaptureDomain
();
// Return the type of the capture object: CAP_VFW, etc...
bool
open
(
int
id
);
bool
open
(
const
String
&
filename_
);
static
void
newPad
(
GstElement
*
/*elem*/
,
GstPad
*
pad
,
gpointer
data
);
protected
:
bool
determineFrameDims
(
Size
&
sz
);
bool
isPipelinePlaying
();
void
startPipeline
();
void
stopPipeline
();
void
restartPipeline
();
void
setFilter
(
const
char
*
prop
,
int
type
,
int
v1
,
int
v2
);
void
removeFilter
(
const
char
*
filter
);
};
};
/*!
/*!
* \brief CvCapture_GStreamer::init
* \brief CvCapture_GStreamer::init
* inits the class
* inits the class
*/
*/
void
CvCapture_GStreamer
::
init
()
GStreamerCapture
::
GStreamerCapture
()
:
{
pipeline
(
NULL
),
v4l2src
(
NULL
),
sink
(
NULL
),
sample
(
NULL
),
pipeline
=
NULL
;
#if GST_VERSION_MAJOR == 0
uridecodebin
=
NULL
;
buffer
(
NULL
),
v4l2src
=
NULL
;
color
=
NULL
;
sink
=
NULL
;
#if GST_VERSION_MAJOR > 0
sample
=
NULL
;
#endif
#endif
buffer
=
NULL
;
caps
(
NULL
),
caps
=
NULL
;
duration
(
-
1
),
width
(
-
1
),
height
(
-
1
),
channels
(
0
),
fps
(
-
1
),
frame
=
NULL
;
isPosFramesSupported
(
false
),
duration
=
-
1
;
isPosFramesEmulated
(
false
),
width
=
-
1
;
emulatedFrameNumber
(
-
1
),
height
=
-
1
;
isOutputByteBuffer
(
false
)
fps
=
-
1
;
{
isPosFramesSupported
=
false
;
isPosFramesEmulated
=
false
;
emulatedFrameNumber
=
-
1
;
isOutputByteBuffer
=
false
;
}
}
/*!
/*!
* \brief CvCapture_GStreamer::close
* \brief CvCapture_GStreamer::close
* Closes the pipeline and destroys all instances
* Closes the pipeline and destroys all instances
*/
*/
void
CvCapture_GStreamer
::
clos
e
()
GStreamerCapture
::~
GStreamerCaptur
e
()
{
{
if
(
isPipelinePlaying
())
if
(
isPipelinePlaying
())
this
->
stopPipeline
();
stopPipeline
();
if
(
pipeline
&&
GST_IS_ELEMENT
(
pipeline
))
if
(
pipeline
)
{
{
gst_element_set_state
(
GST_ELEMENT
(
pipeline
),
GST_STATE_NULL
);
gst_element_set_state
(
GST_ELEMENT
(
pipeline
),
GST_STATE_NULL
);
gst_object_unref
(
GST_OBJECT
(
pipeline
));
gst_object_unref
(
GST_OBJECT
(
pipeline
));
pipeline
=
NULL
;
}
}
duration
=
-
1
;
width
=
-
1
;
height
=
-
1
;
fps
=
-
1
;
isPosFramesSupported
=
false
;
isPosFramesEmulated
=
false
;
emulatedFrameNumber
=
-
1
;
}
}
/*!
/*!
...
@@ -238,7 +243,7 @@ void CvCapture_GStreamer::close()
...
@@ -238,7 +243,7 @@ void CvCapture_GStreamer::close()
* Grabs a sample from the pipeline, awaiting consumation by retreiveFrame.
* Grabs a sample from the pipeline, awaiting consumation by retreiveFrame.
* The pipeline is started if it was not running yet
* The pipeline is started if it was not running yet
*/
*/
bool
CvCapture_GStreamer
::
grabFrame
()
bool
GStreamerCapture
::
grabFrame
()
{
{
if
(
!
pipeline
)
if
(
!
pipeline
)
return
false
;
return
false
;
...
@@ -254,23 +259,18 @@ bool CvCapture_GStreamer::grabFrame()
...
@@ -254,23 +259,18 @@ bool CvCapture_GStreamer::grabFrame()
#if GST_VERSION_MAJOR == 0
#if GST_VERSION_MAJOR == 0
if
(
buffer
)
if
(
buffer
)
gst_buffer_unref
(
buffer
);
gst_buffer_unref
(
buffer
);
buffer
=
gst_app_sink_pull_buffer
(
GST_APP_SINK
(
sink
));
buffer
=
gst_app_sink_pull_buffer
(
GST_APP_SINK
(
sink
));
if
(
!
buffer
)
return
false
;
#else
#else
if
(
sample
)
if
(
sample
)
gst_sample_unref
(
sample
);
gst_sample_unref
(
sample
);
sample
=
gst_app_sink_pull_sample
(
GST_APP_SINK
(
sink
));
sample
=
gst_app_sink_pull_sample
(
GST_APP_SINK
(
sink
));
if
(
!
sample
)
if
(
!
sample
)
return
false
;
return
false
;
gst_sample_ref
(
sample
);
buffer
=
gst_sample_get_buffer
(
sample
);
#endif
#endif
if
(
!
buffer
)
return
false
;
if
(
isPosFramesEmulated
)
if
(
isPosFramesEmulated
)
emulatedFrameNumber
++
;
emulatedFrameNumber
++
;
...
@@ -282,41 +282,76 @@ bool CvCapture_GStreamer::grabFrame()
...
@@ -282,41 +282,76 @@ bool CvCapture_GStreamer::grabFrame()
* \return IplImage pointer. [Transfer Full]
* \return IplImage pointer. [Transfer Full]
* Retrieve the previously grabbed buffer, and wrap it in an IPLImage structure
* Retrieve the previously grabbed buffer, and wrap it in an IPLImage structure
*/
*/
IplImage
*
CvCapture_GStreamer
::
retrieveFrame
(
in
t
)
bool
GStreamerCapture
::
retrieveFrame
(
int
,
OutputArray
ds
t
)
{
{
if
(
!
buffer
)
#if GST_VERSION_MAJOR == 0
return
0
;
if
(
!
buffer
)
return
false
;
#else
if
(
!
sample
)
return
false
;
#endif
Size
sz
;
if
(
!
determineFrameDims
(
sz
))
return
false
;
// gstreamer expects us to handle the memory at this point
// so we can just wrap the raw buffer and be done with it
#if GST_VERSION_MAJOR == 0
Mat
src
(
sz
,
CV_8UC1
,
(
uchar
*
)
GST_BUFFER_DATA
(
buffer
));
src
.
copyTo
(
dst
);
#else
GstBuffer
*
buf
=
gst_sample_get_buffer
(
sample
);
if
(
!
buf
)
return
false
;
GstMapInfo
info
;
if
(
!
gst_buffer_map
(
buf
,
&
info
,
GST_MAP_READ
))
{
//something weird went wrong here. abort. abort.
CV_WARN
(
"Failed to map GStreamerbuffer to system memory"
);
return
false
;
}
//construct a frame header if we did not have any yet
if
(
!
frame
)
{
{
Mat
src
;
if
(
isOutputByteBuffer
)
src
=
Mat
(
Size
(
info
.
size
,
1
),
CV_8UC1
,
info
.
data
);
else
src
=
Mat
(
sz
,
CV_MAKETYPE
(
CV_8U
,
channels
),
info
.
data
);
CV_Assert
(
src
.
isContinuous
());
src
.
copyTo
(
dst
);
}
gst_buffer_unmap
(
buf
,
&
info
);
#endif
return
true
;
}
bool
GStreamerCapture
::
determineFrameDims
(
Size
&
sz
)
{
#if GST_VERSION_MAJOR == 0
#if GST_VERSION_MAJOR == 0
GstCaps
*
buffer
_caps
=
gst_buffer_get_caps
(
buffer
);
GstCaps
*
frame
_caps
=
gst_buffer_get_caps
(
buffer
);
#else
#else
GstCaps
*
buffer
_caps
=
gst_sample_get_caps
(
sample
);
GstCaps
*
frame
_caps
=
gst_sample_get_caps
(
sample
);
#endif
#endif
// bail out in no caps
// bail out in no caps
assert
(
gst_caps_get_size
(
buffer_caps
)
==
1
);
if
(
!
GST_CAPS_IS_SIMPLE
(
frame_caps
))
GstStructure
*
structure
=
gst_caps_get_structure
(
buffer_caps
,
0
);
return
false
;
GstStructure
*
structure
=
gst_caps_get_structure
(
frame_caps
,
0
);
// bail out if width or height are 0
// bail out if width or height are 0
if
(
!
gst_structure_get_int
(
structure
,
"width"
,
&
width
)
||
if
(
!
gst_structure_get_int
(
structure
,
"width"
,
&
width
)
!
gst_structure_get_int
(
structure
,
"height"
,
&
height
))
||
!
gst_structure_get_int
(
structure
,
"height"
,
&
height
))
{
return
false
;
gst_caps_unref
(
buffer_caps
);
return
0
;
}
int
depth
=
3
;
sz
=
Size
(
width
,
height
);
bool
height_extend
=
false
;
#if GST_VERSION_MAJOR > 0
#if GST_VERSION_MAJOR > 0
depth
=
0
;
const
gchar
*
name
=
gst_structure_get_name
(
structure
);
const
gchar
*
name
=
gst_structure_get_name
(
structure
);
const
gchar
*
format
=
gst_structure_get_string
(
structure
,
"format"
);
if
(
!
name
)
if
(
!
name
)
return
0
;
return
false
;
// we support 11 types of data:
// we support 11 types of data:
// video/x-raw, format=BGR -> 8bit, 3 channels
// video/x-raw, format=BGR -> 8bit, 3 channels
...
@@ -332,96 +367,60 @@ IplImage * CvCapture_GStreamer::retrieveFrame(int)
...
@@ -332,96 +367,60 @@ IplImage * CvCapture_GStreamer::retrieveFrame(int)
// image/jpeg -> 8bit, mjpeg: buffer_size x 1 x 1
// image/jpeg -> 8bit, mjpeg: buffer_size x 1 x 1
// bayer data is never decoded, the user is responsible for that
// bayer data is never decoded, the user is responsible for that
// everything is 8 bit, so we just test the caps for bit depth
// everything is 8 bit, so we just test the caps for bit depth
if
(
strcasecmp
(
name
,
"video/x-raw"
)
==
0
)
if
(
strcasecmp
(
name
,
"video/x-raw"
)
==
0
)
{
{
const
gchar
*
format
=
gst_structure_get_string
(
structure
,
"format"
);
if
(
!
format
)
if
(
!
format
)
return
0
;
return
false
;
if
(
strcasecmp
(
format
,
"BGR"
)
==
0
)
if
(
strcasecmp
(
format
,
"BGR"
)
==
0
)
{
{
depth
=
3
;
channels
=
3
;
}
}
else
if
(
(
strcasecmp
(
format
,
"UYVY"
)
==
0
)
||
(
strcasecmp
(
format
,
"YUY2"
)
==
0
)
||
(
strcasecmp
(
format
,
"YVYU"
)
==
0
)
){
else
if
(
(
strcasecmp
(
format
,
"UYVY"
)
==
0
)
||
(
strcasecmp
(
format
,
"YUY2"
)
==
0
)
||
(
strcasecmp
(
format
,
"YVYU"
)
==
0
)
)
depth
=
2
;
{
channels
=
2
;
}
}
else
if
(
(
strcasecmp
(
format
,
"NV12"
)
==
0
)
||
(
strcasecmp
(
format
,
"NV21"
)
==
0
)
||
(
strcasecmp
(
format
,
"YV12"
)
==
0
)
||
(
strcasecmp
(
format
,
"I420"
)
==
0
)
){
else
if
(
(
strcasecmp
(
format
,
"NV12"
)
==
0
)
||
(
strcasecmp
(
format
,
"NV21"
)
==
0
)
||
(
strcasecmp
(
format
,
"YV12"
)
==
0
)
||
(
strcasecmp
(
format
,
"I420"
)
==
0
)
)
depth
=
1
;
{
height_extend
=
true
;
channels
=
1
;
sz
.
height
=
sz
.
height
*
3
/
2
;
}
}
else
if
(
strcasecmp
(
format
,
"GRAY8"
)
==
0
){
else
if
(
strcasecmp
(
format
,
"GRAY8"
)
==
0
)
depth
=
1
;
{
channels
=
1
;
}
}
}
}
else
if
(
strcasecmp
(
name
,
"video/x-bayer"
)
==
0
)
else
if
(
strcasecmp
(
name
,
"video/x-bayer"
)
==
0
)
{
{
depth
=
1
;
channels
=
1
;
}
else
if
(
strcasecmp
(
name
,
"image/jpeg"
)
==
0
)
{
}
depth
=
1
;
else
if
(
strcasecmp
(
name
,
"image/jpeg"
)
==
0
)
{
// the correct size will be set once the first frame arrives
// the correct size will be set once the first frame arrives
channels
=
1
;
isOutputByteBuffer
=
true
;
isOutputByteBuffer
=
true
;
}
}
#endif
if
(
depth
>
0
)
{
if
(
height_extend
){
frame
=
cvCreateImageHeader
(
cvSize
(
width
,
height
*
3
/
2
),
IPL_DEPTH_8U
,
depth
);
}
else
{
frame
=
cvCreateImageHeader
(
cvSize
(
width
,
height
),
IPL_DEPTH_8U
,
depth
);
}
}
else
{
gst_caps_unref
(
buffer_caps
);
return
0
;
}
gst_caps_unref
(
buffer_caps
);
}
// gstreamer expects us to handle the memory at this point
// so we can just wrap the raw buffer and be done with it
#if GST_VERSION_MAJOR == 0
frame
->
imageData
=
(
char
*
)
GST_BUFFER_DATA
(
buffer
);
#else
#else
// info.data ptr is valid until next grabFrame where the associated sample is unref'd
// we support only video/x-raw, format=BGR -> 8bit, 3 channels
GstMapInfo
info
=
GstMapInfo
();
channels
=
3
;
gboolean
success
=
gst_buffer_map
(
buffer
,
&
info
,
(
GstMapFlags
)
GST_MAP_READ
);
// with MJPEG streams frame size can change arbitrarily
if
(
isOutputByteBuffer
&&
(
size_t
)
info
.
size
!=
(
size_t
)
frame
->
imageSize
)
{
cvReleaseImageHeader
(
&
frame
);
frame
=
cvCreateImageHeader
(
cvSize
(
info
.
size
,
1
),
IPL_DEPTH_8U
,
1
);
}
if
(
!
success
){
//something weird went wrong here. abort. abort.
//fprintf(stderr,"GStreamer: unable to map buffer");
return
0
;
}
frame
->
imageData
=
(
char
*
)
info
.
data
;
gst_buffer_unmap
(
buffer
,
&
info
);
#endif
#endif
return
true
;
return
frame
;
}
}
/*!
/*!
* \brief CvCapture_GStreamer::isPipelinePlaying
* \brief CvCapture_GStreamer::isPipelinePlaying
* \return if the pipeline is currently playing.
* \return if the pipeline is currently playing.
*/
*/
bool
CvCapture_GStreamer
::
isPipelinePlaying
()
bool
GStreamerCapture
::
isPipelinePlaying
()
{
{
GstState
current
,
pending
;
GstState
current
,
pending
;
GstClockTime
timeout
=
5
*
GST_SECOND
;
GstClockTime
timeout
=
5
*
GST_SECOND
;
if
(
!
GST_IS_ELEMENT
(
pipeline
)){
GstStateChangeReturn
ret
=
gst_element_get_state
(
pipeline
,
&
current
,
&
pending
,
timeout
);
return
false
;
if
(
!
ret
)
}
{
CV_WARN
(
"GStreamer: unable to query pipeline state"
);
GstStateChangeReturn
ret
=
gst_element_get_state
(
GST_ELEMENT
(
pipeline
),
&
current
,
&
pending
,
timeout
);
if
(
!
ret
){
//fprintf(stderr, "GStreamer: unable to query pipeline state\n");
return
false
;
return
false
;
}
}
return
current
==
GST_STATE_PLAYING
;
return
current
==
GST_STATE_PLAYING
;
}
}
...
@@ -429,12 +428,8 @@ bool CvCapture_GStreamer::isPipelinePlaying()
...
@@ -429,12 +428,8 @@ bool CvCapture_GStreamer::isPipelinePlaying()
* \brief CvCapture_GStreamer::startPipeline
* \brief CvCapture_GStreamer::startPipeline
* Start the pipeline by setting it to the playing state
* Start the pipeline by setting it to the playing state
*/
*/
void
CvCapture_GStreamer
::
startPipeline
()
void
GStreamerCapture
::
startPipeline
()
{
{
CV_FUNCNAME
(
"icvStartPipeline"
);
__BEGIN__
;
//fprintf(stderr, "relinked, pausing\n");
//fprintf(stderr, "relinked, pausing\n");
GstStateChangeReturn
status
=
gst_element_set_state
(
GST_ELEMENT
(
pipeline
),
GST_STATE_PLAYING
);
GstStateChangeReturn
status
=
gst_element_set_state
(
GST_ELEMENT
(
pipeline
),
GST_STATE_PLAYING
);
if
(
status
==
GST_STATE_CHANGE_ASYNC
)
if
(
status
==
GST_STATE_CHANGE_ASYNC
)
...
@@ -447,7 +442,7 @@ void CvCapture_GStreamer::startPipeline()
...
@@ -447,7 +442,7 @@ void CvCapture_GStreamer::startPipeline()
handleMessage
(
pipeline
);
handleMessage
(
pipeline
);
gst_object_unref
(
pipeline
);
gst_object_unref
(
pipeline
);
pipeline
=
NULL
;
pipeline
=
NULL
;
CV_
ERROR
(
CV_StsError
,
"GStreamer: unable to start pipeline
\n
"
);
CV_
WARN
(
"GStreamer: unable to start pipeline
"
);
return
;
return
;
}
}
...
@@ -456,36 +451,28 @@ void CvCapture_GStreamer::startPipeline()
...
@@ -456,36 +451,28 @@ void CvCapture_GStreamer::startPipeline()
//printf("state now playing\n");
//printf("state now playing\n");
handleMessage
(
pipeline
);
handleMessage
(
pipeline
);
__END__
;
}
}
/*!
/*!
* \brief CvCapture_GStreamer::stopPipeline
* \brief CvCapture_GStreamer::stopPipeline
* Stop the pipeline by setting it to NULL
* Stop the pipeline by setting it to NULL
*/
*/
void
CvCapture_GStreamer
::
stopPipeline
()
void
GStreamerCapture
::
stopPipeline
()
{
{
CV_FUNCNAME
(
"icvStopPipeline"
);
__BEGIN__
;
//fprintf(stderr, "restarting pipeline, going to ready\n");
//fprintf(stderr, "restarting pipeline, going to ready\n");
if
(
gst_element_set_state
(
GST_ELEMENT
(
pipeline
),
GST_STATE_NULL
)
==
if
(
gst_element_set_state
(
GST_ELEMENT
(
pipeline
),
GST_STATE_NULL
)
==
GST_STATE_CHANGE_FAILURE
)
GST_STATE_CHANGE_FAILURE
)
{
{
CV_
ERROR
(
CV_StsError
,
"GStreamer: unable to stop pipeline
\n
"
);
CV_
WARN
(
"GStreamer: unable to stop pipeline
"
);
gst_object_unref
(
pipeline
);
gst_object_unref
(
pipeline
);
pipeline
=
NULL
;
pipeline
=
NULL
;
return
;
}
}
__END__
;
}
}
/*!
/*!
* \brief CvCapture_GStreamer::restartPipeline
* \brief CvCapture_GStreamer::restartPipeline
* Restart the pipeline
* Restart the pipeline
*/
*/
void
CvCapture_GStreamer
::
restartPipeline
()
void
GStreamerCapture
::
restartPipeline
()
{
{
handleMessage
(
pipeline
);
handleMessage
(
pipeline
);
...
@@ -493,7 +480,6 @@ void CvCapture_GStreamer::restartPipeline()
...
@@ -493,7 +480,6 @@ void CvCapture_GStreamer::restartPipeline()
this
->
startPipeline
();
this
->
startPipeline
();
}
}
/*!
/*!
* \brief CvCapture_GStreamer::setFilter
* \brief CvCapture_GStreamer::setFilter
* \param prop the property name
* \param prop the property name
...
@@ -502,7 +488,7 @@ void CvCapture_GStreamer::restartPipeline()
...
@@ -502,7 +488,7 @@ void CvCapture_GStreamer::restartPipeline()
* \param v2 second value of property type requires it, else NULL
* \param v2 second value of property type requires it, else NULL
* Filter the output formats by setting appsink caps properties
* Filter the output formats by setting appsink caps properties
*/
*/
void
CvCapture_GStreamer
::
setFilter
(
const
char
*
prop
,
int
type
,
int
v1
,
int
v2
)
void
GStreamerCapture
::
setFilter
(
const
char
*
prop
,
int
type
,
int
v1
,
int
v2
)
{
{
//printf("GStreamer: setFilter \n");
//printf("GStreamer: setFilter \n");
if
(
!
caps
||
!
(
GST_IS_CAPS
(
caps
)
))
if
(
!
caps
||
!
(
GST_IS_CAPS
(
caps
)
))
...
@@ -545,13 +531,12 @@ void CvCapture_GStreamer::setFilter(const char *prop, int type, int v1, int v2)
...
@@ -545,13 +531,12 @@ void CvCapture_GStreamer::setFilter(const char *prop, int type, int v1, int v2)
//printf("filtering with %s\n", gst_caps_to_string(caps));
//printf("filtering with %s\n", gst_caps_to_string(caps));
}
}
/*!
/*!
* \brief CvCapture_GStreamer::removeFilter
* \brief CvCapture_GStreamer::removeFilter
* \param filter filter to remove
* \param filter filter to remove
* remove the specified filter from the appsink template caps
* remove the specified filter from the appsink template caps
*/
*/
void
CvCapture_GStreamer
::
removeFilter
(
const
char
*
filter
)
void
GStreamerCapture
::
removeFilter
(
const
char
*
filter
)
{
{
if
(
!
caps
)
if
(
!
caps
)
return
;
return
;
...
@@ -574,9 +559,7 @@ void CvCapture_GStreamer::removeFilter(const char *filter)
...
@@ -574,9 +559,7 @@ void CvCapture_GStreamer::removeFilter(const char *filter)
* decodebin creates pads based on stream information, which is not known upfront
* decodebin creates pads based on stream information, which is not known upfront
* on receiving the pad-added signal, we connect it to the colorspace conversion element
* on receiving the pad-added signal, we connect it to the colorspace conversion element
*/
*/
void
CvCapture_GStreamer
::
newPad
(
GstElement
*
/*elem*/
,
void
GStreamerCapture
::
newPad
(
GstElement
*
,
GstPad
*
pad
,
gpointer
data
)
GstPad
*
pad
,
gpointer
data
)
{
{
GstPad
*
sinkpad
;
GstPad
*
sinkpad
;
GstElement
*
color
=
(
GstElement
*
)
data
;
GstElement
*
color
=
(
GstElement
*
)
data
;
...
@@ -591,6 +574,13 @@ void CvCapture_GStreamer::newPad(GstElement * /*elem*/,
...
@@ -591,6 +574,13 @@ void CvCapture_GStreamer::newPad(GstElement * /*elem*/,
gst_object_unref
(
sinkpad
);
gst_object_unref
(
sinkpad
);
}
}
bool
GStreamerCapture
::
isOpened
()
const
{
return
pipeline
!=
NULL
;
}
int
GStreamerCapture
::
getCaptureDomain
()
{
return
CAP_GSTREAMER
;
}
/*!
/*!
* \brief CvCapture_GStreamer::open Open the given file with gstreamer
* \brief CvCapture_GStreamer::open Open the given file with gstreamer
* \param type CvCapture type. One of CV_CAP_GSTREAMER_*
* \param type CvCapture type. One of CV_CAP_GSTREAMER_*
...
@@ -622,40 +612,31 @@ void CvCapture_GStreamer::newPad(GstElement * /*elem*/,
...
@@ -622,40 +612,31 @@ void CvCapture_GStreamer::newPad(GstElement * /*elem*/,
* I expect this to be the same for CV_CAP_GSTREAMER_1394. Is anyone actually still using v4l (v1)?
* I expect this to be the same for CV_CAP_GSTREAMER_1394. Is anyone actually still using v4l (v1)?
*
*
*/
*/
bool
CvCapture_GStreamer
::
open
(
int
type
,
const
char
*
filename
)
bool
GStreamerCapture
::
open
(
int
id
)
{
{
CV_FUNCNAME
(
"cvCaptureFromCAM_GStreamer"
);
if
(
!
is_gst_element_exists
(
"v4l2src"
))
return
false
;
__BEGIN__
;
std
::
ostringstream
desc
;
desc
<<
"v4l2src device-name=/dev/video"
<<
id
<<
" ! "
<<
COLOR_ELEM
<<
" ! appsink"
;
return
open
(
desc
.
str
());
}
bool
GStreamerCapture
::
open
(
const
String
&
filename_
)
{
gst_initializer
::
init
();
gst_initializer
::
init
();
const
gchar
*
filename
=
filename_
.
c_str
();
bool
file
=
false
;
bool
file
=
false
;
bool
stream
=
false
;
bool
stream
=
false
;
bool
manualpipeline
=
false
;
bool
manualpipeline
=
false
;
char
*
uri
=
NULL
;
char
*
uri
=
NULL
;
uridecodebin
=
NULL
;
GstElement
*
uridecodebin
=
NULL
;
GstElement
Factory
*
testfac
;
GstElement
*
color
=
NULL
;
GstStateChangeReturn
status
;
GstStateChangeReturn
status
;
if
(
type
==
CV_CAP_GSTREAMER_V4L
){
testfac
=
gst_element_factory_find
(
"v4lsrc"
);
if
(
!
testfac
){
return
false
;
}
g_object_unref
(
G_OBJECT
(
testfac
));
filename
=
"v4lsrc ! "
COLOR_ELEM
" ! appsink"
;
}
if
(
type
==
CV_CAP_GSTREAMER_V4L2
){
testfac
=
gst_element_factory_find
(
"v4l2src"
);
if
(
!
testfac
){
return
false
;
}
g_object_unref
(
G_OBJECT
(
testfac
));
filename
=
"v4l2src ! "
COLOR_ELEM
" ! appsink"
;
}
// test if we have a valid uri. If so, open it with an uridecodebin
// test if we have a valid uri. If so, open it with an uridecodebin
// else, we might have a file or a manual pipeline.
// else, we might have a file or a manual pipeline.
// if gstreamer cannot parse the manual pipeline, we assume we were given and
// if gstreamer cannot parse the manual pipeline, we assume we were given and
...
@@ -687,7 +668,6 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
...
@@ -687,7 +668,6 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
CV_WARN
(
"GStreamer: Error opening file
\n
"
);
CV_WARN
(
"GStreamer: Error opening file
\n
"
);
CV_WARN
(
filename
);
CV_WARN
(
filename
);
CV_WARN
(
uri
);
CV_WARN
(
uri
);
close
();
return
false
;
return
false
;
}
}
}
}
...
@@ -736,8 +716,7 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
...
@@ -736,8 +716,7 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
if
(
!
uridecodebin
)
if
(
!
uridecodebin
)
{
{
//fprintf(stderr, "GStreamer: Error opening bin: %s\n", err->message);
CV_WARN
(
"Can not parse GStreamer URI bin"
);
close
();
return
false
;
return
false
;
}
}
}
}
...
@@ -802,7 +781,7 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
...
@@ -802,7 +781,7 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
if
(
!
sink
)
if
(
!
sink
)
{
{
CV_
ERROR
(
CV_StsError
,
"GStreamer: cannot find appsink in manual pipeline
\n
"
);
CV_
WARN
(
"GStreamer: cannot find appsink in manual pipeline
\n
"
);
return
false
;
return
false
;
}
}
...
@@ -822,7 +801,7 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
...
@@ -822,7 +801,7 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
{
{
if
(
!
gst_element_link
(
uridecodebin
,
color
))
if
(
!
gst_element_link
(
uridecodebin
,
color
))
{
{
CV_
ERROR
(
CV_StsError
,
"GStreamer: cannot link color -> sink
\n
"
);
CV_
WARN
(
"cannot link color -> sink
"
);
gst_object_unref
(
pipeline
);
gst_object_unref
(
pipeline
);
pipeline
=
NULL
;
pipeline
=
NULL
;
return
false
;
return
false
;
...
@@ -835,7 +814,7 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
...
@@ -835,7 +814,7 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
if
(
!
gst_element_link
(
color
,
sink
))
if
(
!
gst_element_link
(
color
,
sink
))
{
{
CV_
ERROR
(
CV_StsError
,
"GStreamer: cannot link color -> sink
\n
"
);
CV_
WARN
(
"GStreamer: cannot link color -> sink
\n
"
);
gst_object_unref
(
pipeline
);
gst_object_unref
(
pipeline
);
pipeline
=
NULL
;
pipeline
=
NULL
;
return
false
;
return
false
;
...
@@ -844,9 +823,10 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
...
@@ -844,9 +823,10 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
//TODO: is 1 single buffer really high enough?
//TODO: is 1 single buffer really high enough?
gst_app_sink_set_max_buffers
(
GST_APP_SINK
(
sink
),
1
);
gst_app_sink_set_max_buffers
(
GST_APP_SINK
(
sink
),
1
);
gst_app_sink_set_drop
(
GST_APP_SINK
(
sink
),
stream
);
//
gst_app_sink_set_drop (GST_APP_SINK(sink), stream);
//do not emit signals: all calls will be synchronous and blocking
//do not emit signals: all calls will be synchronous and blocking
gst_app_sink_set_emit_signals
(
GST_APP_SINK
(
sink
),
0
);
gst_app_sink_set_emit_signals
(
GST_APP_SINK
(
sink
),
FALSE
);
// gst_base_sink_set_sync(GST_BASE_SINK(sink), FALSE);
#if GST_VERSION_MAJOR == 0
#if GST_VERSION_MAJOR == 0
caps
=
gst_caps_new_simple
(
"video/x-raw-rgb"
,
caps
=
gst_caps_new_simple
(
"video/x-raw-rgb"
,
...
@@ -875,6 +855,8 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
...
@@ -875,6 +855,8 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
gst_caps_unref
(
caps
);
gst_caps_unref
(
caps
);
{
{
GST_DEBUG_BIN_TO_DOT_FILE
(
GST_BIN
(
pipeline
),
GST_DEBUG_GRAPH_SHOW_ALL
,
"pipeline-init"
);
status
=
gst_element_set_state
(
GST_ELEMENT
(
pipeline
),
status
=
gst_element_set_state
(
GST_ELEMENT
(
pipeline
),
file
?
GST_STATE_PAUSED
:
GST_STATE_PLAYING
);
file
?
GST_STATE_PAUSED
:
GST_STATE_PLAYING
);
if
(
status
==
GST_STATE_CHANGE_ASYNC
)
if
(
status
==
GST_STATE_CHANGE_ASYNC
)
...
@@ -884,10 +866,11 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
...
@@ -884,10 +866,11 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
}
}
if
(
status
==
GST_STATE_CHANGE_FAILURE
)
if
(
status
==
GST_STATE_CHANGE_FAILURE
)
{
{
GST_DEBUG_BIN_TO_DOT_FILE
(
GST_BIN
(
pipeline
),
GST_DEBUG_GRAPH_SHOW_ALL
,
"pipeline-error"
);
handleMessage
(
pipeline
);
handleMessage
(
pipeline
);
gst_object_unref
(
pipeline
);
gst_object_unref
(
pipeline
);
pipeline
=
NULL
;
pipeline
=
NULL
;
CV_
ERROR
(
CV_StsError
,
"GStreamer: unable to start pipeline
\n
"
);
CV_
WARN
(
"GStreamer: unable to start pipeline
\n
"
);
return
false
;
return
false
;
}
}
...
@@ -944,7 +927,7 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
...
@@ -944,7 +927,7 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
#else
#else
#define FORMAT format_
#define FORMAT format_
#endif
#endif
status_
=
gst_element_query_position
(
pipeline
,
FORMAT
,
&
value_
);
status_
=
gst_element_query_position
(
sink
,
FORMAT
,
&
value_
);
#undef FORMAT
#undef FORMAT
if
(
!
status_
||
value_
!=
0
||
duration
<
0
)
if
(
!
status_
||
value_
!=
0
||
duration
<
0
)
{
{
...
@@ -961,8 +944,6 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
...
@@ -961,8 +944,6 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
GST_DEBUG_BIN_TO_DOT_FILE
(
GST_BIN
(
pipeline
),
GST_DEBUG_GRAPH_SHOW_ALL
,
"pipeline"
);
GST_DEBUG_BIN_TO_DOT_FILE
(
GST_BIN
(
pipeline
),
GST_DEBUG_GRAPH_SHOW_ALL
,
"pipeline"
);
}
}
__END__
;
return
true
;
return
true
;
}
}
...
@@ -975,7 +956,7 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
...
@@ -975,7 +956,7 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
* For frame-based properties, we use the caps of the lasst receivef sample. This means that some properties
* For frame-based properties, we use the caps of the lasst receivef sample. This means that some properties
* are not available until a first frame was received
* are not available until a first frame was received
*/
*/
double
CvCapture_GStreamer
::
getProperty
(
int
propId
)
const
double
GStreamerCapture
::
getProperty
(
int
propId
)
const
{
{
GstFormat
format
;
GstFormat
format
;
gint64
value
;
gint64
value
;
...
@@ -1032,38 +1013,28 @@ double CvCapture_GStreamer::getProperty( int propId ) const
...
@@ -1032,38 +1013,28 @@ double CvCapture_GStreamer::getProperty( int propId ) const
return
height
;
return
height
;
case
CV_CAP_PROP_FPS
:
case
CV_CAP_PROP_FPS
:
return
fps
;
return
fps
;
case
CV_CAP_PROP_FOURCC
:
break
;
case
CV_CAP_PROP_FRAME_COUNT
:
case
CV_CAP_PROP_FRAME_COUNT
:
return
duration
;
return
duration
;
case
CV_CAP_PROP_FORMAT
:
case
CV_CAP_PROP_MODE
:
case
CV_CAP_PROP_BRIGHTNESS
:
case
CV_CAP_PROP_BRIGHTNESS
:
case
CV_CAP_PROP_CONTRAST
:
case
CV_CAP_PROP_CONTRAST
:
case
CV_CAP_PROP_SATURATION
:
case
CV_CAP_PROP_SATURATION
:
case
CV_CAP_PROP_HUE
:
case
CV_CAP_PROP_HUE
:
if
(
v4l2src
)
if
(
v4l2src
)
{
{
const
gchar
*
propName
=
string
propName
=
get_gst_propname
(
propId
);
propId
==
CV_CAP_PROP_BRIGHTNESS
?
"brightness"
:
if
(
!
propName
.
empty
())
propId
==
CV_CAP_PROP_CONTRAST
?
"contrast"
:
propId
==
CV_CAP_PROP_SATURATION
?
"saturation"
:
propId
==
CV_CAP_PROP_HUE
?
"hue"
:
NULL
;
if
(
propName
)
{
{
gint32
val
ue32
=
0
;
gint32
val
=
0
;
g_object_get
(
G_OBJECT
(
v4l2src
),
propName
,
&
value32
,
NULL
);
g_object_get
(
G_OBJECT
(
v4l2src
),
propName
.
c_str
(),
&
val
,
NULL
);
return
value32
;
return
static_cast
<
double
>
(
val
)
;
}
}
}
}
case
CV_CAP_PROP_GAIN
:
case
CV_CAP_PROP_CONVERT_RGB
:
break
;
break
;
case
CV_CAP_GSTREAMER_QUEUE_LENGTH
:
case
CV_CAP_GSTREAMER_QUEUE_LENGTH
:
if
(
!
sink
)
{
if
(
!
sink
)
CV_WARN
(
"GStreamer: there is no sink yet"
);
{
return
false
;
CV_WARN
(
"there is no sink yet"
);
return
0
;
}
}
return
gst_app_sink_get_max_buffers
(
GST_APP_SINK
(
sink
));
return
gst_app_sink_get_max_buffers
(
GST_APP_SINK
(
sink
));
default
:
default
:
...
@@ -1084,13 +1055,13 @@ double CvCapture_GStreamer::getProperty( int propId ) const
...
@@ -1084,13 +1055,13 @@ double CvCapture_GStreamer::getProperty( int propId ) const
* Sets the desired property id with val. If the pipeline is running,
* Sets the desired property id with val. If the pipeline is running,
* it is briefly stopped and started again after the property was set
* it is briefly stopped and started again after the property was set
*/
*/
bool
CvCapture_GStreamer
::
setProperty
(
int
propId
,
double
value
)
bool
GStreamerCapture
::
setProperty
(
int
propId
,
double
value
)
{
{
GstFormat
format
;
const
GstSeekFlags
flags
=
(
GstSeekFlags
)(
GST_SEEK_FLAG_FLUSH
|
GST_SEEK_FLAG_ACCURATE
);
GstSeekFlags
flags
;
if
(
!
pipeline
)
{
if
(
!
pipeline
)
CV_WARN
(
"GStreamer: no pipeline"
);
{
CV_WARN
(
"no pipeline"
);
return
false
;
return
false
;
}
}
...
@@ -1098,12 +1069,10 @@ bool CvCapture_GStreamer::setProperty( int propId, double value )
...
@@ -1098,12 +1069,10 @@ bool CvCapture_GStreamer::setProperty( int propId, double value )
if
(
wasPlaying
)
if
(
wasPlaying
)
this
->
stopPipeline
();
this
->
stopPipeline
();
switch
(
propId
)
switch
(
propId
)
{
{
case
CV_CAP_PROP_POS_MSEC
:
case
CV_CAP_PROP_POS_MSEC
:
format
=
GST_FORMAT_TIME
;
if
(
!
gst_element_seek_simple
(
GST_ELEMENT
(
pipeline
),
GST_FORMAT_TIME
,
flags
=
(
GstSeekFlags
)
(
GST_SEEK_FLAG_FLUSH
|
GST_SEEK_FLAG_ACCURATE
);
if
(
!
gst_element_seek_simple
(
GST_ELEMENT
(
pipeline
),
format
,
flags
,
(
gint64
)
(
value
*
GST_MSECOND
)))
{
flags
,
(
gint64
)
(
value
*
GST_MSECOND
)))
{
handleMessage
(
pipeline
);
handleMessage
(
pipeline
);
CV_WARN
(
"GStreamer: unable to seek"
);
CV_WARN
(
"GStreamer: unable to seek"
);
...
@@ -1138,10 +1107,9 @@ bool CvCapture_GStreamer::setProperty( int propId, double value )
...
@@ -1138,10 +1107,9 @@ bool CvCapture_GStreamer::setProperty( int propId, double value )
}
}
}
}
return
false
;
return
false
;
CV_WARN
(
"unable to seek"
);
}
}
format
=
GST_FORMAT_DEFAULT
;
if
(
!
gst_element_seek_simple
(
GST_ELEMENT
(
pipeline
),
GST_FORMAT_DEFAULT
,
flags
=
(
GstSeekFlags
)
(
GST_SEEK_FLAG_FLUSH
|
GST_SEEK_FLAG_ACCURATE
);
if
(
!
gst_element_seek_simple
(
GST_ELEMENT
(
pipeline
),
format
,
flags
,
(
gint64
)
value
))
{
flags
,
(
gint64
)
value
))
{
handleMessage
(
pipeline
);
handleMessage
(
pipeline
);
CV_WARN
(
"GStreamer: unable to seek"
);
CV_WARN
(
"GStreamer: unable to seek"
);
...
@@ -1152,9 +1120,7 @@ bool CvCapture_GStreamer::setProperty( int propId, double value )
...
@@ -1152,9 +1120,7 @@ bool CvCapture_GStreamer::setProperty( int propId, double value )
return
true
;
return
true
;
}
}
case
CV_CAP_PROP_POS_AVI_RATIO
:
case
CV_CAP_PROP_POS_AVI_RATIO
:
format
=
GST_FORMAT_PERCENT
;
if
(
!
gst_element_seek_simple
(
GST_ELEMENT
(
pipeline
),
GST_FORMAT_PERCENT
,
flags
=
(
GstSeekFlags
)
(
GST_SEEK_FLAG_FLUSH
|
GST_SEEK_FLAG_ACCURATE
);
if
(
!
gst_element_seek_simple
(
GST_ELEMENT
(
pipeline
),
format
,
flags
,
(
gint64
)
(
value
*
GST_FORMAT_PERCENT_MAX
)))
{
flags
,
(
gint64
)
(
value
*
GST_FORMAT_PERCENT_MAX
)))
{
handleMessage
(
pipeline
);
handleMessage
(
pipeline
);
CV_WARN
(
"GStreamer: unable to seek"
);
CV_WARN
(
"GStreamer: unable to seek"
);
...
@@ -1195,37 +1161,34 @@ bool CvCapture_GStreamer::setProperty( int propId, double value )
...
@@ -1195,37 +1161,34 @@ bool CvCapture_GStreamer::setProperty( int propId, double value )
}
else
}
else
removeFilter
(
"framerate"
);
removeFilter
(
"framerate"
);
break
;
break
;
case
CV_CAP_PROP_FOURCC
:
case
CV_CAP_PROP_FRAME_COUNT
:
case
CV_CAP_PROP_FORMAT
:
case
CV_CAP_PROP_MODE
:
case
CV_CAP_PROP_BRIGHTNESS
:
case
CV_CAP_PROP_BRIGHTNESS
:
case
CV_CAP_PROP_CONTRAST
:
case
CV_CAP_PROP_CONTRAST
:
case
CV_CAP_PROP_SATURATION
:
case
CV_CAP_PROP_SATURATION
:
case
CV_CAP_PROP_HUE
:
case
CV_CAP_PROP_HUE
:
if
(
v4l2src
)
if
(
v4l2src
)
{
{
const
gchar
*
propName
=
string
propName
=
get_gst_propname
(
propId
);
propId
==
CV_CAP_PROP_BRIGHTNESS
?
"brightness"
:
if
(
!
propName
.
empty
())
propId
==
CV_CAP_PROP_CONTRAST
?
"contrast"
:
propId
==
CV_CAP_PROP_SATURATION
?
"saturation"
:
propId
==
CV_CAP_PROP_HUE
?
"hue"
:
NULL
;
if
(
propName
)
{
{
gint32
val
ue32
=
cv
::
saturate_cast
<
gint32
>
(
value
);
gint32
val
=
cv
::
saturate_cast
<
gint32
>
(
value
);
g_object_set
(
G_OBJECT
(
v4l2src
),
propName
,
&
value32
,
NULL
);
g_object_set
(
G_OBJECT
(
v4l2src
),
propName
.
c_str
(),
&
val
,
NULL
);
return
true
;
return
true
;
}
}
}
}
return
false
;
case
CV_CAP_PROP_GAIN
:
case
CV_CAP_PROP_GAIN
:
case
CV_CAP_PROP_CONVERT_RGB
:
case
CV_CAP_PROP_CONVERT_RGB
:
break
;
break
;
case
CV_CAP_GSTREAMER_QUEUE_LENGTH
:
case
CV_CAP_GSTREAMER_QUEUE_LENGTH
:
{
if
(
!
sink
)
if
(
!
sink
)
break
;
{
CV_WARN
(
"there is no sink yet"
);
return
false
;
}
gst_app_sink_set_max_buffers
(
GST_APP_SINK
(
sink
),
(
guint
)
value
);
gst_app_sink_set_max_buffers
(
GST_APP_SINK
(
sink
),
(
guint
)
value
);
break
;
return
true
;
}
default
:
default
:
CV_WARN
(
"GStreamer: unhandled property"
);
CV_WARN
(
"GStreamer: unhandled property"
);
}
}
...
@@ -1236,23 +1199,24 @@ bool CvCapture_GStreamer::setProperty( int propId, double value )
...
@@ -1236,23 +1199,24 @@ bool CvCapture_GStreamer::setProperty( int propId, double value )
return
false
;
return
false
;
}
}
/*!
* \brief cvCreateCapture_GStreamer
* \param type
* \param filename
* \return
*/
CvCapture
*
cvCreateCapture_GStreamer
(
int
type
,
const
char
*
filename
)
{
CvCapture_GStreamer
*
capture
=
new
CvCapture_GStreamer
;
if
(
capture
->
open
(
type
,
filename
))
Ptr
<
IVideoCapture
>
cv
::
createGStreamerCapture
(
const
String
&
filename
)
return
capture
;
{
Ptr
<
GStreamerCapture
>
cap
=
makePtr
<
GStreamerCapture
>
();
if
(
cap
&&
cap
->
open
(
filename
))
return
cap
;
return
Ptr
<
IVideoCapture
>
();
}
delete
capture
;
Ptr
<
IVideoCapture
>
cv
::
createGStreamerCapture
(
int
index
)
return
0
;
{
Ptr
<
GStreamerCapture
>
cap
=
makePtr
<
GStreamerCapture
>
();
if
(
cap
&&
cap
->
open
(
index
))
return
cap
;
return
Ptr
<
IVideoCapture
>
();
}
}
//==================================================================================================
/*!
/*!
* \brief The CvVideoWriter_GStreamer class
* \brief The CvVideoWriter_GStreamer class
...
@@ -1420,8 +1384,6 @@ const char* CvVideoWriter_GStreamer::filenameToMimetype(const char *filename)
...
@@ -1420,8 +1384,6 @@ const char* CvVideoWriter_GStreamer::filenameToMimetype(const char *filename)
bool
CvVideoWriter_GStreamer
::
open
(
const
char
*
filename
,
int
fourcc
,
bool
CvVideoWriter_GStreamer
::
open
(
const
char
*
filename
,
int
fourcc
,
double
fps
,
CvSize
frameSize
,
bool
is_color
)
double
fps
,
CvSize
frameSize
,
bool
is_color
)
{
{
CV_FUNCNAME
(
"CvVideoWriter_GStreamer::open"
);
// check arguments
// check arguments
assert
(
filename
);
assert
(
filename
);
assert
(
fps
>
0
);
assert
(
fps
>
0
);
...
@@ -1459,8 +1421,6 @@ bool CvVideoWriter_GStreamer::open( const char * filename, int fourcc,
...
@@ -1459,8 +1421,6 @@ bool CvVideoWriter_GStreamer::open( const char * filename, int fourcc,
// we first try to construct a pipeline from the given string.
// we first try to construct a pipeline from the given string.
// if that fails, we assume it is an ordinary filename
// if that fails, we assume it is an ordinary filename
__BEGIN__
;
encodebin
=
gst_parse_launch
(
filename
,
&
err
);
encodebin
=
gst_parse_launch
(
filename
,
&
err
);
manualpipeline
=
(
encodebin
!=
NULL
);
manualpipeline
=
(
encodebin
!=
NULL
);
...
@@ -1469,7 +1429,7 @@ bool CvVideoWriter_GStreamer::open( const char * filename, int fourcc,
...
@@ -1469,7 +1429,7 @@ bool CvVideoWriter_GStreamer::open( const char * filename, int fourcc,
#if GST_VERSION_MAJOR == 0
#if GST_VERSION_MAJOR == 0
it
=
gst_bin_iterate_sources
(
GST_BIN
(
encodebin
));
it
=
gst_bin_iterate_sources
(
GST_BIN
(
encodebin
));
if
(
gst_iterator_next
(
it
,
(
gpointer
*
)
&
source
)
!=
GST_ITERATOR_OK
)
{
if
(
gst_iterator_next
(
it
,
(
gpointer
*
)
&
source
)
!=
GST_ITERATOR_OK
)
{
CV_
ERROR
(
CV_StsError
,
"GStreamer: cannot find appsink in manual pipeline
\n
"
);
CV_
WARN
(
"GStreamer: cannot find appsink in manual pipeline
\n
"
);
return
false
;
return
false
;
}
}
#else
#else
...
@@ -1503,7 +1463,7 @@ bool CvVideoWriter_GStreamer::open( const char * filename, int fourcc,
...
@@ -1503,7 +1463,7 @@ bool CvVideoWriter_GStreamer::open( const char * filename, int fourcc,
gst_iterator_free
(
it
);
gst_iterator_free
(
it
);
if
(
!
source
){
if
(
!
source
){
CV_
ERROR
(
CV_StsError
,
"GStreamer: cannot find appsrc in manual pipeline
\n
"
);
CV_
WARN
(
"GStreamer: cannot find appsrc in manual pipeline
\n
"
);
return
false
;
return
false
;
}
}
#endif
#endif
...
@@ -1528,13 +1488,15 @@ bool CvVideoWriter_GStreamer::open( const char * filename, int fourcc,
...
@@ -1528,13 +1488,15 @@ bool CvVideoWriter_GStreamer::open( const char * filename, int fourcc,
videocaps
=
gst_riff_create_video_caps
(
fourcc
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
videocaps
=
gst_riff_create_video_caps
(
fourcc
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
if
(
!
videocaps
){
if
(
!
videocaps
){
CV_ERROR
(
CV_StsUnsupportedFormat
,
"Gstreamer Opencv backend does not support this codec."
);
CV_WARN
(
"Gstreamer Opencv backend does not support this codec."
);
return
false
;
}
}
//create container caps from file extension
//create container caps from file extension
mime
=
filenameToMimetype
(
filename
);
mime
=
filenameToMimetype
(
filename
);
if
(
!
mime
)
{
if
(
!
mime
)
{
CV_ERROR
(
CV_StsUnsupportedFormat
,
"Gstreamer Opencv backend does not support this file type."
);
CV_WARN
(
"Gstreamer Opencv backend does not support this file type."
);
return
false
;
}
}
#if FULL_GST_VERSION >= VERSION_NUM(0,10,32)
#if FULL_GST_VERSION >= VERSION_NUM(0,10,32)
...
@@ -1566,7 +1528,8 @@ bool CvVideoWriter_GStreamer::open( const char * filename, int fourcc,
...
@@ -1566,7 +1528,8 @@ bool CvVideoWriter_GStreamer::open( const char * filename, int fourcc,
NULL
);
NULL
);
caps
=
gst_caps_fixate
(
caps
);
caps
=
gst_caps_fixate
(
caps
);
#else
#else
CV_ERROR
(
CV_StsUnsupportedFormat
,
"Gstreamer 0.10 Opencv backend does not support writing encoded MJPEG data."
);
CV_WARN
(
"Gstreamer 0.10 Opencv backend does not support writing encoded MJPEG data."
);
return
false
;
#endif
#endif
}
}
else
if
(
is_color
)
else
if
(
is_color
)
...
@@ -1633,7 +1596,8 @@ bool CvVideoWriter_GStreamer::open( const char * filename, int fourcc,
...
@@ -1633,7 +1596,8 @@ bool CvVideoWriter_GStreamer::open( const char * filename, int fourcc,
g_object_set
(
G_OBJECT
(
file
),
"buffer-size"
,
bufsize
,
NULL
);
g_object_set
(
G_OBJECT
(
file
),
"buffer-size"
,
bufsize
,
NULL
);
gst_bin_add_many
(
GST_BIN
(
pipeline
),
source
,
encodebin
,
file
,
NULL
);
gst_bin_add_many
(
GST_BIN
(
pipeline
),
source
,
encodebin
,
file
,
NULL
);
if
(
!
gst_element_link_many
(
source
,
encodebin
,
file
,
NULL
))
{
if
(
!
gst_element_link_many
(
source
,
encodebin
,
file
,
NULL
))
{
CV_ERROR
(
CV_StsError
,
"GStreamer: cannot link elements
\n
"
);
CV_WARN
(
"GStreamer: cannot link elements
\n
"
);
return
false
;
}
}
}
}
...
@@ -1697,7 +1661,8 @@ bool CvVideoWriter_GStreamer::open( const char * filename, int fourcc,
...
@@ -1697,7 +1661,8 @@ bool CvVideoWriter_GStreamer::open( const char * filename, int fourcc,
stateret
=
gst_element_set_state
(
GST_ELEMENT
(
pipeline
),
GST_STATE_PLAYING
);
stateret
=
gst_element_set_state
(
GST_ELEMENT
(
pipeline
),
GST_STATE_PLAYING
);
if
(
stateret
==
GST_STATE_CHANGE_FAILURE
)
{
if
(
stateret
==
GST_STATE_CHANGE_FAILURE
)
{
handleMessage
(
pipeline
);
handleMessage
(
pipeline
);
CV_ERROR
(
CV_StsError
,
"GStreamer: cannot put pipeline to play
\n
"
);
CV_WARN
(
"GStreamer: cannot put pipeline to play
\n
"
);
return
false
;
}
}
framerate
=
fps
;
framerate
=
fps
;
...
@@ -1705,8 +1670,6 @@ bool CvVideoWriter_GStreamer::open( const char * filename, int fourcc,
...
@@ -1705,8 +1670,6 @@ bool CvVideoWriter_GStreamer::open( const char * filename, int fourcc,
handleMessage
(
pipeline
);
handleMessage
(
pipeline
);
__END__
;
return
true
;
return
true
;
}
}
...
@@ -1721,38 +1684,37 @@ bool CvVideoWriter_GStreamer::open( const char * filename, int fourcc,
...
@@ -1721,38 +1684,37 @@ bool CvVideoWriter_GStreamer::open( const char * filename, int fourcc,
*/
*/
bool
CvVideoWriter_GStreamer
::
writeFrame
(
const
IplImage
*
image
)
bool
CvVideoWriter_GStreamer
::
writeFrame
(
const
IplImage
*
image
)
{
{
CV_FUNCNAME
(
"CvVideoWriter_GStreamer::writerFrame"
);
GstClockTime
duration
,
timestamp
;
GstClockTime
duration
,
timestamp
;
GstFlowReturn
ret
;
GstFlowReturn
ret
;
int
size
;
int
size
;
__BEGIN__
;
handleMessage
(
pipeline
);
handleMessage
(
pipeline
);
#if GST_VERSION_MAJOR > 0
#if GST_VERSION_MAJOR > 0
if
(
input_pix_fmt
==
GST_VIDEO_FORMAT_ENCODED
)
{
if
(
input_pix_fmt
==
GST_VIDEO_FORMAT_ENCODED
)
{
if
(
image
->
nChannels
!=
1
||
image
->
depth
!=
IPL_DEPTH_8U
||
image
->
height
!=
1
)
{
if
(
image
->
nChannels
!=
1
||
image
->
depth
!=
IPL_DEPTH_8U
||
image
->
height
!=
1
)
{
CV_ERROR
(
CV_StsUnsupportedFormat
,
"cvWriteFrame() needs images with depth = IPL_DEPTH_8U, nChannels = 1 and height = 1."
);
CV_WARN
(
"cvWriteFrame() needs images with depth = IPL_DEPTH_8U, nChannels = 1 and height = 1."
);
return
false
;
}
}
}
}
else
else
#endif
#endif
if
(
input_pix_fmt
==
GST_VIDEO_FORMAT_BGR
)
{
if
(
input_pix_fmt
==
GST_VIDEO_FORMAT_BGR
)
{
if
(
image
->
nChannels
!=
3
||
image
->
depth
!=
IPL_DEPTH_8U
)
{
if
(
image
->
nChannels
!=
3
||
image
->
depth
!=
IPL_DEPTH_8U
)
{
CV_ERROR
(
CV_StsUnsupportedFormat
,
"cvWriteFrame() needs images with depth = IPL_DEPTH_8U and nChannels = 3."
);
CV_WARN
(
"cvWriteFrame() needs images with depth = IPL_DEPTH_8U and nChannels = 3."
);
return
false
;
}
}
}
}
#if FULL_GST_VERSION >= VERSION_NUM(0,10,29)
#if FULL_GST_VERSION >= VERSION_NUM(0,10,29)
else
if
(
input_pix_fmt
==
GST_VIDEO_FORMAT_GRAY8
)
{
else
if
(
input_pix_fmt
==
GST_VIDEO_FORMAT_GRAY8
)
{
if
(
image
->
nChannels
!=
1
||
image
->
depth
!=
IPL_DEPTH_8U
)
{
if
(
image
->
nChannels
!=
1
||
image
->
depth
!=
IPL_DEPTH_8U
)
{
CV_ERROR
(
CV_StsUnsupportedFormat
,
"cvWriteFrame() needs images with depth = IPL_DEPTH_8U and nChannels = 1."
);
CV_WARN
(
"cvWriteFrame() needs images with depth = IPL_DEPTH_8U and nChannels = 1."
);
return
false
;
}
}
}
}
#endif
#endif
else
{
else
{
CV_
ERROR
(
CV_StsUnsupportedFormat
,
"cvWriteFrame() needs BGR or grayscale images
\n
"
);
CV_
WARN
(
"cvWriteFrame() needs BGR or grayscale images
\n
"
);
return
false
;
return
false
;
}
}
...
@@ -1765,7 +1727,7 @@ bool CvVideoWriter_GStreamer::writeFrame( const IplImage * image )
...
@@ -1765,7 +1727,7 @@ bool CvVideoWriter_GStreamer::writeFrame( const IplImage * image )
buffer
=
gst_buffer_try_new_and_alloc
(
size
);
buffer
=
gst_buffer_try_new_and_alloc
(
size
);
if
(
!
buffer
)
if
(
!
buffer
)
{
{
CV_
ERROR
(
CV_StsBadSize
,
"Cannot create GStreamer buffer"
);
CV_
WARN
(
"Cannot create GStreamer buffer"
);
}
}
memcpy
(
GST_BUFFER_DATA
(
buffer
),
(
guint8
*
)
image
->
imageData
,
size
);
memcpy
(
GST_BUFFER_DATA
(
buffer
),
(
guint8
*
)
image
->
imageData
,
size
);
...
@@ -1794,8 +1756,6 @@ bool CvVideoWriter_GStreamer::writeFrame( const IplImage * image )
...
@@ -1794,8 +1756,6 @@ bool CvVideoWriter_GStreamer::writeFrame( const IplImage * image )
++
num_frames
;
++
num_frames
;
__END__
;
return
true
;
return
true
;
}
}
...
@@ -1848,8 +1808,6 @@ void toFraction(double decimal, double &numerator, double &denominator)
...
@@ -1848,8 +1808,6 @@ void toFraction(double decimal, double &numerator, double &denominator)
*/
*/
void
handleMessage
(
GstElement
*
pipeline
)
void
handleMessage
(
GstElement
*
pipeline
)
{
{
CV_FUNCNAME
(
"handlemessage"
);
GError
*
err
=
NULL
;
GError
*
err
=
NULL
;
gchar
*
debug
=
NULL
;
gchar
*
debug
=
NULL
;
GstBus
*
bus
=
NULL
;
GstBus
*
bus
=
NULL
;
...
@@ -1857,7 +1815,6 @@ void handleMessage(GstElement * pipeline)
...
@@ -1857,7 +1815,6 @@ void handleMessage(GstElement * pipeline)
GstElement
*
elem
=
NULL
;
GstElement
*
elem
=
NULL
;
GstMessage
*
msg
=
NULL
;
GstMessage
*
msg
=
NULL
;
__BEGIN__
;
bus
=
gst_element_get_bus
(
pipeline
);
bus
=
gst_element_get_bus
(
pipeline
);
while
(
gst_bus_have_pending
(
bus
))
{
while
(
gst_bus_have_pending
(
bus
))
{
...
@@ -1867,7 +1824,7 @@ void handleMessage(GstElement * pipeline)
...
@@ -1867,7 +1824,7 @@ void handleMessage(GstElement * pipeline)
if
(
gst_is_missing_plugin_message
(
msg
))
if
(
gst_is_missing_plugin_message
(
msg
))
{
{
CV_
ERROR
(
CV_StsError
,
"GStreamer:
your gstreamer installation is missing a required plugin
\n
"
);
CV_
WARN
(
"
your gstreamer installation is missing a required plugin
\n
"
);
}
}
else
else
{
{
...
@@ -1906,6 +1863,4 @@ void handleMessage(GstElement * pipeline)
...
@@ -1906,6 +1863,4 @@ void handleMessage(GstElement * pipeline)
}
}
gst_object_unref
(
GST_OBJECT
(
bus
));
gst_object_unref
(
GST_OBJECT
(
bus
));
__END__
}
}
modules/videoio/src/precomp.hpp
View file @
5ae550c6
...
@@ -139,7 +139,6 @@ CvVideoWriter* cvCreateVideoWriter_Images(const char* filename);
...
@@ -139,7 +139,6 @@ CvVideoWriter* cvCreateVideoWriter_Images(const char* filename);
#define CV_CAP_GSTREAMER_V4L2 2
#define CV_CAP_GSTREAMER_V4L2 2
#define CV_CAP_GSTREAMER_FILE 3
#define CV_CAP_GSTREAMER_FILE 3
CvCapture
*
cvCreateCapture_GStreamer
(
int
type
,
const
char
*
filename
);
CvCapture
*
cvCreateFileCapture_FFMPEG_proxy
(
const
char
*
filename
);
CvCapture
*
cvCreateFileCapture_FFMPEG_proxy
(
const
char
*
filename
);
...
@@ -194,7 +193,11 @@ namespace cv
...
@@ -194,7 +193,11 @@ namespace cv
Ptr
<
IVideoCapture
>
createGPhoto2Capture
(
int
index
);
Ptr
<
IVideoCapture
>
createGPhoto2Capture
(
int
index
);
Ptr
<
IVideoCapture
>
createGPhoto2Capture
(
const
String
&
deviceName
);
Ptr
<
IVideoCapture
>
createGPhoto2Capture
(
const
String
&
deviceName
);
Ptr
<
IVideoCapture
>
createXINECapture
(
const
char
*
filename
);
Ptr
<
IVideoCapture
>
createXINECapture
(
const
char
*
filename
);
Ptr
<
IVideoCapture
>
createGStreamerCapture
(
const
String
&
filename
);
Ptr
<
IVideoCapture
>
createGStreamerCapture
(
int
index
);
}
}
#endif
/* __VIDEOIO_H_ */
#endif
/* __VIDEOIO_H_ */
modules/videoio/test/test_gstreamer.cpp
View file @
5ae550c6
...
@@ -7,6 +7,7 @@
...
@@ -7,6 +7,7 @@
namespace
opencv_test
namespace
opencv_test
{
{
typedef
tuple
<
string
,
Size
,
Size
,
int
>
Param
;
typedef
tuple
<
string
,
Size
,
Size
,
int
>
Param
;
typedef
testing
::
TestWithParam
<
Param
>
Videoio_Gstreamer_Test
;
typedef
testing
::
TestWithParam
<
Param
>
Videoio_Gstreamer_Test
;
...
@@ -19,8 +20,9 @@ TEST_P(Videoio_Gstreamer_Test, test_object_structure)
...
@@ -19,8 +20,9 @@ TEST_P(Videoio_Gstreamer_Test, test_object_structure)
int
count_frames
=
10
;
int
count_frames
=
10
;
std
::
ostringstream
pipeline
;
std
::
ostringstream
pipeline
;
pipeline
<<
"videotestsrc pattern=ball num-buffers="
<<
count_frames
<<
" ! "
<<
format
;
pipeline
<<
"videotestsrc pattern=ball num-buffers="
<<
count_frames
<<
" ! "
<<
format
;
pipeline
<<
", framerate=1/1, width="
<<
frame_size
.
width
<<
", height="
<<
frame_size
.
height
<<
" ! appsink"
;
pipeline
<<
", width="
<<
frame_size
.
width
<<
", height="
<<
frame_size
.
height
<<
" ! appsink"
;
VideoCapture
cap
(
pipeline
.
str
(),
CAP_GSTREAMER
);
VideoCapture
cap
;
ASSERT_NO_THROW
(
cap
.
open
(
pipeline
.
str
(),
CAP_GSTREAMER
));
ASSERT_TRUE
(
cap
.
isOpened
());
ASSERT_TRUE
(
cap
.
isOpened
());
Mat
buffer
,
decode_frame
,
gray_frame
,
rgb_frame
;
Mat
buffer
,
decode_frame
,
gray_frame
,
rgb_frame
;
...
...
modules/videoio/test/test_video_io.cpp
View file @
5ae550c6
...
@@ -46,12 +46,61 @@
...
@@ -46,12 +46,61 @@
namespace
opencv_test
namespace
opencv_test
{
{
struct
VideoCaptureAPI
{
VideoCaptureAPIs
api
;
inline
const
char
*
toString
()
const
{
switch
(
api
)
{
case
CAP_ANY
:
return
"CAP_ANY"
;
#ifdef __linux__
case
CAP_V4L2
:
return
"CAP_V4L/CAP_V4L2"
;
#else
case
CAP_VFW
:
return
"CAP_VFW"
;
#endif
case
CAP_FIREWIRE
:
return
"CAP_FIREWIRE"
;
case
CAP_QT
:
return
"CAP_QT"
;
case
CAP_UNICAP
:
return
"CAP_UNICAP"
;
case
CAP_DSHOW
:
return
"CAP_DSHOW"
;
case
CAP_PVAPI
:
return
"CAP_PVAPI"
;
case
CAP_OPENNI
:
return
"CAP_OPENNI"
;
case
CAP_OPENNI_ASUS
:
return
"CAP_OPENNI_ASUS"
;
case
CAP_ANDROID
:
return
"CAP_ANDROID"
;
case
CAP_XIAPI
:
return
"CAP_XIAPI"
;
case
CAP_AVFOUNDATION
:
return
"CAP_AVFOUNDATION"
;
case
CAP_GIGANETIX
:
return
"CAP_GIGANETIX"
;
case
CAP_MSMF
:
return
"CAP_MSMF"
;
case
CAP_WINRT
:
return
"CAP_WINRT"
;
case
CAP_INTELPERC
:
return
"CAP_INTELPERC"
;
case
CAP_OPENNI2
:
return
"CAP_OPENNI2"
;
case
CAP_OPENNI2_ASUS
:
return
"CAP_OPENNI2_ASUS"
;
case
CAP_GPHOTO2
:
return
"CAP_GPHOTO2"
;
case
CAP_GSTREAMER
:
return
"CAP_GSTREAMER"
;
case
CAP_FFMPEG
:
return
"CAP_FFMPEG"
;
case
CAP_IMAGES
:
return
"CAP_IMAGES"
;
case
CAP_ARAVIS
:
return
"CAP_ARAVIS"
;
case
CAP_OPENCV_MJPEG
:
return
"CAP_OPENCV_MJPEG"
;
case
CAP_INTEL_MFX
:
return
"CAP_INTEL_MFX"
;
}
return
"unknown"
;
}
VideoCaptureAPI
(
int
api_
=
CAP_ANY
)
:
api
((
VideoCaptureAPIs
)
api_
)
{}
operator
int
()
{
return
api
;
}
};
inline
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
const
VideoCaptureAPI
&
api
)
{
out
<<
api
.
toString
();
return
out
;
}
class
Videoio_Test_Base
class
Videoio_Test_Base
{
{
protected
:
protected
:
string
ext
;
string
ext
;
string
video_file
;
string
video_file
;
int
apiPref
;
VideoCaptureAPI
apiPref
;
protected
:
protected
:
Videoio_Test_Base
()
{}
Videoio_Test_Base
()
{}
virtual
~
Videoio_Test_Base
()
{}
virtual
~
Videoio_Test_Base
()
{}
...
@@ -60,14 +109,16 @@ protected:
...
@@ -60,14 +109,16 @@ protected:
void
checkFrameRead
(
int
idx
,
VideoCapture
&
cap
)
void
checkFrameRead
(
int
idx
,
VideoCapture
&
cap
)
{
{
//int frameID = (int)cap.get(CAP_PROP_POS_FRAMES);
//int frameID = (int)cap.get(CAP_PROP_POS_FRAMES);
Mat
img
;
cap
>>
img
;
Mat
img
;
ASSERT_NO_THROW
(
cap
>>
img
);
//std::cout << "idx=" << idx << " img=" << img.size() << " frameID=" << frameID << std::endl;
//std::cout << "idx=" << idx << " img=" << img.size() << " frameID=" << frameID << std::endl;
ASSERT_FALSE
(
img
.
empty
())
<<
"idx="
<<
idx
;
ASSERT_FALSE
(
img
.
empty
())
<<
"idx="
<<
idx
;
checkFrameContent
(
img
,
idx
);
checkFrameContent
(
img
,
idx
);
}
}
void
checkFrameSeek
(
int
idx
,
VideoCapture
&
cap
)
void
checkFrameSeek
(
int
idx
,
VideoCapture
&
cap
)
{
{
bool
canSeek
=
cap
.
set
(
CAP_PROP_POS_FRAMES
,
idx
);
bool
canSeek
=
false
;
ASSERT_NO_THROW
(
canSeek
=
cap
.
set
(
CAP_PROP_POS_FRAMES
,
idx
));
if
(
!
canSeek
)
if
(
!
canSeek
)
{
{
std
::
cout
<<
"Seek to frame '"
<<
idx
<<
"' is not supported. SKIP."
<<
std
::
endl
;
std
::
cout
<<
"Seek to frame '"
<<
idx
<<
"' is not supported. SKIP."
<<
std
::
endl
;
...
@@ -79,26 +130,15 @@ protected:
...
@@ -79,26 +130,15 @@ protected:
public
:
public
:
void
doTest
()
void
doTest
()
{
{
if
(
apiPref
==
CAP_AVFOUNDATION
)
VideoCapture
cap
;
{
ASSERT_NO_THROW
(
cap
.
open
(
video_file
,
apiPref
));
// TODO: fix this backend
std
::
cout
<<
"SKIP test: AVFoundation backend returns invalid frame count"
<<
std
::
endl
;
return
;
}
else
if
(
apiPref
==
CAP_VFW
)
{
// TODO: fix this backend
std
::
cout
<<
"SKIP test: Video for Windows backend not open files"
<<
std
::
endl
;
return
;
}
VideoCapture
cap
(
video_file
,
apiPref
);
if
(
!
cap
.
isOpened
())
if
(
!
cap
.
isOpened
())
{
{
std
::
cout
<<
"SKIP test: backend "
<<
apiPref
<<
" can't open the video: "
<<
video_file
<<
std
::
endl
;
std
::
cout
<<
"SKIP test: backend "
<<
apiPref
<<
" can't open the video: "
<<
video_file
<<
std
::
endl
;
return
;
return
;
}
}
int
n_frames
=
(
int
)
cap
.
get
(
CAP_PROP_FRAME_COUNT
);
int
n_frames
=
-
1
;
EXPECT_NO_THROW
(
n_frames
=
(
int
)
cap
.
get
(
CAP_PROP_FRAME_COUNT
));
if
(
n_frames
>
0
)
if
(
n_frames
>
0
)
{
{
ASSERT_GT
(
n_frames
,
0
);
ASSERT_GT
(
n_frames
,
0
);
...
@@ -124,7 +164,8 @@ public:
...
@@ -124,7 +164,8 @@ public:
checkFrameRead
(
k
,
cap
);
checkFrameRead
(
k
,
cap
);
}
}
}
}
bool
canSeek
=
cap
.
set
(
CAP_PROP_POS_FRAMES
,
0
);
bool
canSeek
=
false
;
EXPECT_NO_THROW
(
canSeek
=
cap
.
set
(
CAP_PROP_POS_FRAMES
,
0
));
if
(
!
canSeek
)
if
(
!
canSeek
)
{
{
std
::
cout
<<
"Seek to frame '0' is not supported. SKIP all 'seek' tests."
<<
std
::
endl
;
std
::
cout
<<
"Seek to frame '0' is not supported. SKIP all 'seek' tests."
<<
std
::
endl
;
...
@@ -134,7 +175,9 @@ public:
...
@@ -134,7 +175,9 @@ public:
if
(
ext
!=
"wmv"
&&
ext
!=
"h264"
&&
ext
!=
"h265"
)
if
(
ext
!=
"wmv"
&&
ext
!=
"h264"
&&
ext
!=
"h265"
)
{
{
SCOPED_TRACE
(
"progressive seek"
);
SCOPED_TRACE
(
"progressive seek"
);
ASSERT_TRUE
(
cap
.
set
(
CAP_PROP_POS_FRAMES
,
0
));
bool
res
=
false
;
EXPECT_NO_THROW
(
res
=
cap
.
set
(
CAP_PROP_POS_FRAMES
,
0
));
ASSERT_TRUE
(
res
);
for
(
int
k
=
0
;
k
<
n_frames
;
k
+=
20
)
for
(
int
k
=
0
;
k
<
n_frames
;
k
+=
20
)
{
{
checkFrameSeek
(
k
,
cap
);
checkFrameSeek
(
k
,
cap
);
...
@@ -144,7 +187,9 @@ public:
...
@@ -144,7 +187,9 @@ public:
if
(
ext
!=
"mpg"
&&
ext
!=
"wmv"
&&
ext
!=
"h264"
&&
ext
!=
"h265"
)
if
(
ext
!=
"mpg"
&&
ext
!=
"wmv"
&&
ext
!=
"h264"
&&
ext
!=
"h265"
)
{
{
SCOPED_TRACE
(
"random seek"
);
SCOPED_TRACE
(
"random seek"
);
ASSERT_TRUE
(
cap
.
set
(
CAP_PROP_POS_FRAMES
,
0
));
bool
res
=
false
;
EXPECT_NO_THROW
(
res
=
cap
.
set
(
CAP_PROP_POS_FRAMES
,
0
));
ASSERT_TRUE
(
res
);
for
(
int
k
=
0
;
k
<
10
;
++
k
)
for
(
int
k
=
0
;
k
<
10
;
++
k
)
{
{
checkFrameSeek
(
cvtest
::
TS
::
ptr
()
->
get_rng
().
uniform
(
0
,
n_frames
),
cap
);
checkFrameSeek
(
cvtest
::
TS
::
ptr
()
->
get_rng
().
uniform
(
0
,
n_frames
),
cap
);
...
@@ -154,7 +199,7 @@ public:
...
@@ -154,7 +199,7 @@ public:
};
};
//==================================================================================================
//==================================================================================================
typedef
tuple
<
string
,
int
>
Backend_Type_Params
;
typedef
tuple
<
string
,
VideoCaptureAPI
>
Backend_Type_Params
;
class
Videoio_Bunny
:
public
Videoio_Test_Base
,
public
testing
::
TestWithParam
<
Backend_Type_Params
>
class
Videoio_Bunny
:
public
Videoio_Test_Base
,
public
testing
::
TestWithParam
<
Backend_Type_Params
>
{
{
...
@@ -168,37 +213,29 @@ public:
...
@@ -168,37 +213,29 @@ public:
}
}
void
doFrameCountTest
()
void
doFrameCountTest
()
{
{
if
(
apiPref
==
CAP_AVFOUNDATION
)
VideoCapture
cap
;
{
EXPECT_NO_THROW
(
cap
.
open
(
video_file
,
apiPref
));
// TODO: fix this backend
std
::
cout
<<
"SKIP test: AVFoundation backend returns invalid frame count"
<<
std
::
endl
;
return
;
}
else
if
(
apiPref
==
CAP_VFW
)
{
// TODO: fix this backend
std
::
cout
<<
"SKIP test: Video for Windows backend not open files"
<<
std
::
endl
;
return
;
}
VideoCapture
cap
(
video_file
,
apiPref
);
if
(
!
cap
.
isOpened
())
if
(
!
cap
.
isOpened
())
{
{
std
::
cout
<<
"SKIP test: backend "
<<
apiPref
<<
" can't open the video: "
<<
video_file
<<
std
::
endl
;
std
::
cout
<<
"SKIP test: backend "
<<
apiPref
<<
" can't open the video: "
<<
video_file
<<
std
::
endl
;
return
;
return
;
}
}
EXPECT_EQ
(
bunny_param
.
getWidth
()
,
cap
.
get
(
CAP_PROP_FRAME_WIDTH
));
Size
actual
;
EXPECT_EQ
(
bunny_param
.
getHeight
(),
cap
.
get
(
CAP_PROP_FRAME_HEIGHT
));
EXPECT_NO_THROW
(
actual
=
Size
((
int
)
cap
.
get
(
CAP_PROP_FRAME_WIDTH
),
(
int
)
cap
.
get
(
CAP_PROP_FRAME_HEIGHT
)));
EXPECT_EQ
(
bunny_param
.
getWidth
(),
actual
.
width
);
EXPECT_EQ
(
bunny_param
.
getHeight
(),
actual
.
height
);
double
fps_prop
=
cap
.
get
(
CAP_PROP_FPS
);
double
fps_prop
=
0
;
EXPECT_NO_THROW
(
fps_prop
=
cap
.
get
(
CAP_PROP_FPS
));
if
(
fps_prop
>
0
)
if
(
fps_prop
>
0
)
EXPECT_NEAR
(
fps_prop
,
bunny_param
.
getFps
(),
1
);
EXPECT_NEAR
(
fps_prop
,
bunny_param
.
getFps
(),
1
);
else
else
std
::
cout
<<
"FPS is not available. SKIP check."
<<
std
::
endl
;
std
::
cout
<<
"FPS is not available. SKIP check."
<<
std
::
endl
;
int
count_prop
=
0
;
int
count_prop
=
0
;
count_prop
=
(
int
)
cap
.
get
(
CAP_PROP_FRAME_COUNT
);
EXPECT_NO_THROW
(
count_prop
=
(
int
)
cap
.
get
(
CAP_PROP_FRAME_COUNT
)
);
// mpg file reports 5.08 sec * 24 fps => property returns 122 frames
// mpg file reports 5.08 sec * 24 fps => property returns 122 frames
// but actual number of frames returned is 125
// but actual number of frames returned is 125
if
(
ext
!=
"mpg"
)
if
(
ext
!=
"mpg"
)
...
@@ -213,7 +250,7 @@ public:
...
@@ -213,7 +250,7 @@ public:
while
(
cap
.
isOpened
())
while
(
cap
.
isOpened
())
{
{
Mat
frame
;
Mat
frame
;
cap
>>
frame
;
EXPECT_NO_THROW
(
cap
>>
frame
)
;
if
(
frame
.
empty
())
if
(
frame
.
empty
())
break
;
break
;
EXPECT_EQ
(
bunny_param
.
getWidth
(),
frame
.
cols
);
EXPECT_EQ
(
bunny_param
.
getWidth
(),
frame
.
cols
);
...
@@ -229,7 +266,15 @@ public:
...
@@ -229,7 +266,15 @@ public:
}
}
};
};
typedef
tuple
<
string
,
string
,
float
,
int
>
Ext_Fourcc_PSNR
;
//==================================================================================================
struct
Ext_Fourcc_PSNR
{
string
ext
;
string
fourcc
;
float
PSNR
;
VideoCaptureAPI
api
;
};
typedef
tuple
<
Size
,
Ext_Fourcc_PSNR
>
Size_Ext_Fourcc_PSNR
;
typedef
tuple
<
Size
,
Ext_Fourcc_PSNR
>
Size_Ext_Fourcc_PSNR
;
class
Videoio_Synthetic
:
public
Videoio_Test_Base
,
public
testing
::
TestWithParam
<
Size_Ext_Fourcc_PSNR
>
class
Videoio_Synthetic
:
public
Videoio_Test_Base
,
public
testing
::
TestWithParam
<
Size_Ext_Fourcc_PSNR
>
...
@@ -243,39 +288,27 @@ public:
...
@@ -243,39 +288,27 @@ public:
Videoio_Synthetic
()
Videoio_Synthetic
()
{
{
frame_size
=
get
<
0
>
(
GetParam
());
frame_size
=
get
<
0
>
(
GetParam
());
const
Ext_Fourcc_PSNR
&
param
=
get
<
1
>
(
GetParam
());
const
Ext_Fourcc_PSNR
p
=
get
<
1
>
(
GetParam
());
ext
=
get
<
0
>
(
param
)
;
ext
=
p
.
ext
;
fourcc
=
fourccFromString
(
get
<
1
>
(
param
)
);
fourcc
=
fourccFromString
(
p
.
fourcc
);
PSNR_GT
=
get
<
2
>
(
param
)
;
PSNR_GT
=
p
.
PSNR
;
video_file
=
cv
::
tempfile
((
fourccToString
(
fourcc
)
+
"."
+
ext
).
c_str
());
video_file
=
cv
::
tempfile
((
fourccToString
(
fourcc
)
+
"."
+
ext
).
c_str
());
frame_count
=
100
;
frame_count
=
100
;
fps
=
25.
;
fps
=
25.
;
apiPref
=
get
<
3
>
(
param
)
;
apiPref
=
p
.
api
;
}
}
void
SetUp
()
void
SetUp
()
{
{
if
(
apiPref
==
CAP_AVFOUNDATION
)
{
// TODO: fix this backend
std
::
cout
<<
"SKIP test: AVFoundation backend can not write video"
<<
std
::
endl
;
return
;
}
else
if
(
apiPref
==
CAP_VFW
)
{
// TODO: fix this backend
std
::
cout
<<
"SKIP test: Video for Windows backend not open files"
<<
std
::
endl
;
return
;
}
Mat
img
(
frame_size
,
CV_8UC3
);
Mat
img
(
frame_size
,
CV_8UC3
);
VideoWriter
writer
(
video_file
,
apiPref
,
fourcc
,
fps
,
frame_size
,
true
);
VideoWriter
writer
;
EXPECT_NO_THROW
(
writer
.
open
(
video_file
,
apiPref
,
fourcc
,
fps
,
frame_size
,
true
));
ASSERT_TRUE
(
writer
.
isOpened
());
ASSERT_TRUE
(
writer
.
isOpened
());
for
(
int
i
=
0
;
i
<
frame_count
;
++
i
)
for
(
int
i
=
0
;
i
<
frame_count
;
++
i
)
{
{
generateFrame
(
i
,
frame_count
,
img
);
generateFrame
(
i
,
frame_count
,
img
);
writer
<<
img
;
EXPECT_NO_THROW
(
writer
<<
img
)
;
}
}
writer
.
release
(
);
EXPECT_NO_THROW
(
writer
.
release
()
);
}
}
void
TearDown
()
void
TearDown
()
{
{
...
@@ -301,6 +334,10 @@ public:
...
@@ -301,6 +334,10 @@ public:
if
(
fourcc
==
VideoWriter
::
fourcc
(
'M'
,
'P'
,
'E'
,
'G'
)
&&
ext
==
"mkv"
)
if
(
fourcc
==
VideoWriter
::
fourcc
(
'M'
,
'P'
,
'E'
,
'G'
)
&&
ext
==
"mkv"
)
expected_frame_count
.
end
+=
1
;
expected_frame_count
.
end
+=
1
;
// Workaround for some gstreamer pipelines
if
(
apiPref
==
CAP_GSTREAMER
)
expected_frame_count
.
start
-=
1
;
ASSERT_LE
(
expected_frame_count
.
start
,
actual
);
ASSERT_LE
(
expected_frame_count
.
start
,
actual
);
ASSERT_GE
(
expected_frame_count
.
end
,
actual
);
ASSERT_GE
(
expected_frame_count
.
end
,
actual
);
...
@@ -310,22 +347,24 @@ public:
...
@@ -310,22 +347,24 @@ public:
//==================================================================================================
//==================================================================================================
int
backend_params
[]
=
{
static
VideoCaptureAPI
backend_params
[]
=
{
#ifdef HAVE_QUICKTIME
#ifdef HAVE_QUICKTIME
CAP_QT
,
CAP_QT
,
#endif
#endif
#ifdef HAVE_AVFOUNDATION
// TODO: Broken?
CAP_AVFOUNDATION
,
//#ifdef HAVE_AVFOUNDATION
#endif
// CAP_AVFOUNDATION,
//#endif
#ifdef HAVE_MSMF
#ifdef HAVE_MSMF
CAP_MSMF
,
CAP_MSMF
,
#endif
#endif
#ifdef HAVE_VFW
// TODO: Broken?
CAP_VFW
,
//#ifdef HAVE_VFW
#endif
// CAP_VFW,
//#endif
#ifdef HAVE_GSTREAMER
#ifdef HAVE_GSTREAMER
CAP_GSTREAMER
,
CAP_GSTREAMER
,
...
@@ -343,7 +382,7 @@ int backend_params[] = {
...
@@ -343,7 +382,7 @@ int backend_params[] = {
// CAP_INTEL_MFX
// CAP_INTEL_MFX
};
};
string
bunny_params
[]
=
{
st
atic
st
ring
bunny_params
[]
=
{
#ifdef HAVE_VIDEO_INPUT
#ifdef HAVE_VIDEO_INPUT
string
(
"wmv"
),
string
(
"wmv"
),
string
(
"mov"
),
string
(
"mov"
),
...
@@ -368,12 +407,22 @@ INSTANTIATE_TEST_CASE_P(videoio, Videoio_Bunny,
...
@@ -368,12 +407,22 @@ INSTANTIATE_TEST_CASE_P(videoio, Videoio_Bunny,
//==================================================================================================
//==================================================================================================
inline
Ext_Fourcc_PSNR
makeParam
(
const
char
*
ext
,
const
char
*
fourcc
,
float
psnr
,
int
apipref
)
inline
Ext_Fourcc_PSNR
makeParam
(
const
char
*
ext
,
const
char
*
fourcc
,
float
psnr
,
VideoCaptureAPIs
apipref
)
{
Ext_Fourcc_PSNR
res
;
res
.
ext
=
ext
;
res
.
fourcc
=
fourcc
;
res
.
PSNR
=
psnr
;
res
.
api
=
apipref
;
return
res
;
}
inline
static
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
const
Ext_Fourcc_PSNR
&
p
)
{
{
return
make_tuple
(
string
(
ext
),
string
(
fourcc
),
(
float
)
psnr
,
(
int
)
apipref
)
;
out
<<
"FOURCC("
<<
p
.
fourcc
<<
"), ."
<<
p
.
ext
<<
", "
<<
p
.
api
<<
", "
<<
p
.
PSNR
<<
"dB"
;
return
out
;
}
}
Ext_Fourcc_PSNR
synthetic_params
[]
=
{
static
Ext_Fourcc_PSNR
synthetic_params
[]
=
{
#ifdef HAVE_MSMF
#ifdef HAVE_MSMF
#if !defined(_M_ARM)
#if !defined(_M_ARM)
...
@@ -385,16 +434,17 @@ Ext_Fourcc_PSNR synthetic_params[] = {
...
@@ -385,16 +434,17 @@ Ext_Fourcc_PSNR synthetic_params[] = {
makeParam
(
"mov"
,
"H264"
,
30.
f
,
CAP_MSMF
),
makeParam
(
"mov"
,
"H264"
,
30.
f
,
CAP_MSMF
),
#endif
#endif
#ifdef HAVE_VFW
// TODO: Broken?
#if !defined(_M_ARM)
//#ifdef HAVE_VFW
makeParam
(
"wmv"
,
"WMV1"
,
30.
f
,
CAP_VFW
),
//#if !defined(_M_ARM)
makeParam
(
"wmv"
,
"WMV2"
,
30.
f
,
CAP_VFW
),
// makeParam("wmv", "WMV1", 30.f, CAP_VFW),
#endif
// makeParam("wmv", "WMV2", 30.f, CAP_VFW),
makeParam
(
"wmv"
,
"WMV3"
,
30.
f
,
CAP_VFW
),
//#endif
makeParam
(
"wmv"
,
"WVC1"
,
30.
f
,
CAP_VFW
),
// makeParam("wmv", "WMV3", 30.f, CAP_VFW),
makeParam
(
"avi"
,
"H264"
,
30.
f
,
CAP_VFW
),
// makeParam("wmv", "WVC1", 30.f, CAP_VFW),
makeParam
(
"avi"
,
"MJPG"
,
30.
f
,
CAP_VFW
),
// makeParam("avi", "H264", 30.f, CAP_VFW),
#endif
// makeParam("avi", "MJPG", 30.f, CAP_VFW),
//#endif
#ifdef HAVE_QUICKTIME
#ifdef HAVE_QUICKTIME
makeParam
(
"mov"
,
"mp4v"
,
30.
f
,
CAP_QT
),
makeParam
(
"mov"
,
"mp4v"
,
30.
f
,
CAP_QT
),
...
@@ -408,17 +458,18 @@ Ext_Fourcc_PSNR synthetic_params[] = {
...
@@ -408,17 +458,18 @@ Ext_Fourcc_PSNR synthetic_params[] = {
makeParam
(
"mkv"
,
"MJPG"
,
30.
f
,
CAP_QT
),
makeParam
(
"mkv"
,
"MJPG"
,
30.
f
,
CAP_QT
),
#endif
#endif
#ifdef HAVE_AVFOUNDATION
// TODO: Broken?
makeParam
(
"mov"
,
"mp4v"
,
30.
f
,
CAP_AVFOUNDATION
),
//#ifdef HAVE_AVFOUNDATION
makeParam
(
"avi"
,
"XVID"
,
30.
f
,
CAP_AVFOUNDATION
),
// makeParam("mov", "mp4v", 30.f, CAP_AVFOUNDATION),
makeParam
(
"avi"
,
"MPEG"
,
30.
f
,
CAP_AVFOUNDATION
),
// makeParam("avi", "XVID", 30.f, CAP_AVFOUNDATION),
makeParam
(
"avi"
,
"IYUV"
,
30.
f
,
CAP_AVFOUNDATION
),
// makeParam("avi", "MPEG", 30.f, CAP_AVFOUNDATION),
makeParam
(
"avi"
,
"MJPG"
,
30.
f
,
CAP_AVFOUNDATION
),
// makeParam("avi", "IYUV", 30.f, CAP_AVFOUNDATION),
// makeParam("avi", "MJPG", 30.f, CAP_AVFOUNDATION),
makeParam
(
"mkv"
,
"XVID"
,
30.
f
,
CAP_AVFOUNDATION
),
//
makeParam("mkv", "XVID", 30.f, CAP_AVFOUNDATION),
makeParam
(
"mkv"
,
"MPEG"
,
30.
f
,
CAP_AVFOUNDATION
),
//
makeParam("mkv", "MPEG", 30.f, CAP_AVFOUNDATION),
makeParam
(
"mkv"
,
"MJPG"
,
30.
f
,
CAP_AVFOUNDATION
),
//
makeParam("mkv", "MJPG", 30.f, CAP_AVFOUNDATION),
#endif
//
#endif
#ifdef HAVE_FFMPEG
#ifdef HAVE_FFMPEG
makeParam
(
"avi"
,
"XVID"
,
30.
f
,
CAP_FFMPEG
),
makeParam
(
"avi"
,
"XVID"
,
30.
f
,
CAP_FFMPEG
),
...
@@ -432,15 +483,13 @@ Ext_Fourcc_PSNR synthetic_params[] = {
...
@@ -432,15 +483,13 @@ Ext_Fourcc_PSNR synthetic_params[] = {
#endif
#endif
#ifdef HAVE_GSTREAMER
#ifdef HAVE_GSTREAMER
// makeParam("avi", "XVID", 30.f, CAP_GSTREAMER), - corrupted frames, broken indexes
makeParam
(
"avi"
,
"MPEG"
,
30.
f
,
CAP_GSTREAMER
),
makeParam
(
"avi"
,
"MPEG"
,
30.
f
,
CAP_GSTREAMER
),
makeParam
(
"avi"
,
"IYUV"
,
30.
f
,
CAP_GSTREAMER
),
makeParam
(
"avi"
,
"MJPG"
,
30.
f
,
CAP_GSTREAMER
),
makeParam
(
"avi"
,
"MJPG"
,
30.
f
,
CAP_GSTREAMER
),
makeParam
(
"avi"
,
"H264"
,
30.
f
,
CAP_GSTREAMER
),
makeParam
(
"avi"
,
"H264"
,
30.
f
,
CAP_GSTREAMER
),
// makeParam("mkv", "XVID", 30.f, CAP_GSTREAMER),
makeParam
(
"mkv"
,
"MPEG"
,
30.
f
,
CAP_GSTREAMER
),
makeParam
(
"mkv"
,
"MPEG"
,
30.
f
,
CAP_GSTREAMER
),
makeParam
(
"mkv"
,
"MJPG"
,
30.
f
,
CAP_GSTREAMER
),
makeParam
(
"mkv"
,
"MJPG"
,
30.
f
,
CAP_GSTREAMER
),
makeParam
(
"mkv"
,
"H264"
,
30.
f
,
CAP_GSTREAMER
),
#endif
#endif
makeParam
(
"avi"
,
"MJPG"
,
30.
f
,
CAP_OPENCV_MJPEG
),
makeParam
(
"avi"
,
"MJPG"
,
30.
f
,
CAP_OPENCV_MJPEG
),
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment