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
1a4c22fc
Commit
1a4c22fc
authored
Jul 14, 2017
by
Alexander Alekhin
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #9095 from alalek:fix_gstreamer
parents
5f4c7372
cc862e99
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
195 additions
and
55 deletions
+195
-55
cap_gstreamer.cpp
modules/videoio/src/cap_gstreamer.cpp
+115
-11
test_mfx.cpp
modules/videoio/test/test_mfx.cpp
+1
-8
test_precomp.hpp
modules/videoio/test/test_precomp.hpp
+9
-3
test_video_io.cpp
modules/videoio/test/test_video_io.cpp
+70
-33
No files found.
modules/videoio/src/cap_gstreamer.cpp
View file @
1a4c22fc
...
...
@@ -168,6 +168,10 @@ protected:
gint
width
;
gint
height
;
double
fps
;
bool
isPosFramesSupported
;
bool
isPosFramesEmulated
;
gint64
emulatedFrameNumber
;
};
/*!
...
...
@@ -191,6 +195,10 @@ void CvCapture_GStreamer::init()
width
=
-
1
;
height
=
-
1
;
fps
=
-
1
;
isPosFramesSupported
=
false
;
isPosFramesEmulated
=
false
;
emulatedFrameNumber
=
-
1
;
}
/*!
...
...
@@ -212,6 +220,9 @@ void CvCapture_GStreamer::close()
width
=
-
1
;
height
=
-
1
;
fps
=
-
1
;
isPosFramesSupported
=
false
;
isPosFramesEmulated
=
false
;
emulatedFrameNumber
=
-
1
;
}
/*!
...
...
@@ -253,6 +264,9 @@ bool CvCapture_GStreamer::grabFrame()
if
(
!
buffer
)
return
false
;
if
(
isPosFramesEmulated
)
emulatedFrameNumber
++
;
return
true
;
}
...
...
@@ -428,6 +442,9 @@ void CvCapture_GStreamer::startPipeline()
return
;
}
if
(
isPosFramesEmulated
)
emulatedFrameNumber
=
0
;
//printf("state now playing\n");
handleMessage
(
pipeline
);
__END__
;
...
...
@@ -879,6 +896,8 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
duration
=
-
1
;
}
handleMessage
(
pipeline
);
GstPad
*
pad
=
gst_element_get_static_pad
(
sink
,
"sink"
);
#if GST_VERSION_MAJOR == 0
GstCaps
*
buffer_caps
=
gst_pad_get_caps
(
pad
);
...
...
@@ -905,9 +924,32 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
fps
=
(
double
)
num
/
(
double
)
denom
;
// GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "pipeline")
if
(
file
)
stopPipeline
();
{
GstFormat
format_
;
gint64
value_
=
-
1
;
gboolean
status_
;
format_
=
GST_FORMAT_DEFAULT
;
#if GST_VERSION_MAJOR == 0
#define FORMAT &format_
#else
#define FORMAT format_
#endif
status_
=
gst_element_query_position
(
pipeline
,
FORMAT
,
&
value_
);
#undef FORMAT
if
(
!
status_
||
value_
!=
0
||
duration
<
0
)
{
CV_WARN
(
cv
::
format
(
"Cannot query video position: status=%d value=%lld duration=%lld
\n
"
,
(
int
)
status_
,
(
long
long
int
)
value_
,
(
long
long
int
)
duration
).
c_str
());
isPosFramesSupported
=
false
;
isPosFramesEmulated
=
true
;
emulatedFrameNumber
=
0
;
}
else
isPosFramesSupported
=
true
;
}
GST_DEBUG_BIN_TO_DOT_FILE
(
GST_BIN
(
pipeline
),
GST_DEBUG_GRAPH_SHOW_ALL
,
"pipeline"
);
}
__END__
;
...
...
@@ -946,14 +988,22 @@ double CvCapture_GStreamer::getProperty( int propId ) const
format
=
GST_FORMAT_TIME
;
status
=
gst_element_query_position
(
sink
,
FORMAT
,
&
value
);
if
(
!
status
)
{
handleMessage
(
pipeline
);
CV_WARN
(
"GStreamer: unable to query position of stream"
);
return
0
;
}
return
value
*
1e-6
;
// nano seconds to milli seconds
case
CV_CAP_PROP_POS_FRAMES
:
if
(
!
isPosFramesSupported
)
{
if
(
isPosFramesEmulated
)
return
emulatedFrameNumber
;
return
0
;
// TODO getProperty() "unsupported" value should be changed
}
format
=
GST_FORMAT_DEFAULT
;
status
=
gst_element_query_position
(
sink
,
FORMAT
,
&
value
);
if
(
!
status
)
{
handleMessage
(
pipeline
);
CV_WARN
(
"GStreamer: unable to query position of stream"
);
return
0
;
}
...
...
@@ -962,6 +1012,7 @@ double CvCapture_GStreamer::getProperty( int propId ) const
format
=
GST_FORMAT_PERCENT
;
status
=
gst_element_query_position
(
sink
,
FORMAT
,
&
value
);
if
(
!
status
)
{
handleMessage
(
pipeline
);
CV_WARN
(
"GStreamer: unable to query position of stream"
);
return
0
;
}
...
...
@@ -1045,24 +1096,75 @@ bool CvCapture_GStreamer::setProperty( int propId, double value )
flags
=
(
GstSeekFlags
)
(
GST_SEEK_FLAG_FLUSH
|
GST_SEEK_FLAG_ACCURATE
);
if
(
!
gst_element_seek_simple
(
GST_ELEMENT
(
pipeline
),
format
,
flags
,
(
gint64
)
(
value
*
GST_MSECOND
)))
{
handleMessage
(
pipeline
);
CV_WARN
(
"GStreamer: unable to seek"
);
}
else
{
if
(
isPosFramesEmulated
)
{
if
(
value
==
0
)
{
emulatedFrameNumber
=
0
;
return
true
;
}
else
{
isPosFramesEmulated
=
false
;
// reset frame counter emulation
}
}
}
break
;
case
CV_CAP_PROP_POS_FRAMES
:
{
if
(
!
isPosFramesSupported
)
{
if
(
isPosFramesEmulated
)
{
if
(
value
==
0
)
{
restartPipeline
();
emulatedFrameNumber
=
0
;
return
true
;
}
}
return
false
;
}
format
=
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
))
{
handleMessage
(
pipeline
);
CV_WARN
(
"GStreamer: unable to seek"
);
break
;
}
break
;
// wait for status update
gst_element_get_state
(
pipeline
,
NULL
,
NULL
,
GST_CLOCK_TIME_NONE
);
return
true
;
}
case
CV_CAP_PROP_POS_AVI_RATIO
:
format
=
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
)))
{
handleMessage
(
pipeline
);
CV_WARN
(
"GStreamer: unable to seek"
);
}
else
{
if
(
isPosFramesEmulated
)
{
if
(
value
==
0
)
{
emulatedFrameNumber
=
0
;
return
true
;
}
else
{
isPosFramesEmulated
=
false
;
// reset frame counter emulation
}
}
}
break
;
case
CV_CAP_PROP_FRAME_WIDTH
:
if
(
value
>
0
)
...
...
@@ -1751,7 +1853,7 @@ void handleMessage(GstElement * pipeline)
while
(
gst_bus_have_pending
(
bus
))
{
msg
=
gst_bus_pop
(
bus
);
//printf("Got %s message\n", GST_MESSAGE_TYPE_NAME(msg));
//printf("
\t\t
Got %s message\n", GST_MESSAGE_TYPE_NAME(msg));
if
(
gst_is_missing_plugin_message
(
msg
))
{
...
...
@@ -1763,13 +1865,15 @@ void handleMessage(GstElement * pipeline)
case
GST_MESSAGE_STATE_CHANGED
:
GstState
oldstate
,
newstate
,
pendstate
;
gst_message_parse_state_changed
(
msg
,
&
oldstate
,
&
newstate
,
&
pendstate
);
//fprintf(stderr, "state changed from %s to %s (pending: %s)\n", gst_element_state_get_name(oldstate),
//fprintf(stderr, "\t\t%s: state changed from %s to %s (pending: %s)\n",
// gst_element_get_name(GST_MESSAGE_SRC (msg)),
// gst_element_state_get_name(oldstate),
// gst_element_state_get_name(newstate), gst_element_state_get_name(pendstate));
break
;
case
GST_MESSAGE_ERROR
:
gst_message_parse_error
(
msg
,
&
err
,
&
debug
);
fprintf
(
stderr
,
"
GStreamer Plugin: Embedded video playback halted; module %s reported: %s
\n
"
,
gst_element_get_name
(
GST_MESSAGE_SRC
(
msg
)),
err
->
message
);
//fprintf(stderr, "\t\t
GStreamer Plugin: Embedded video playback halted; module %s reported: %s\n",
//
gst_element_get_name(GST_MESSAGE_SRC (msg)), err->message);
g_error_free
(
err
);
g_free
(
debug
);
...
...
@@ -1777,14 +1881,14 @@ void handleMessage(GstElement * pipeline)
gst_element_set_state
(
GST_ELEMENT
(
pipeline
),
GST_STATE_NULL
);
break
;
case
GST_MESSAGE_EOS
:
//fprintf(stderr, "reached the end of the stream.");
//fprintf(stderr, "
\t\t
reached the end of the stream.");
break
;
case
GST_MESSAGE_STREAM_STATUS
:
gst_message_parse_stream_status
(
msg
,
&
tp
,
&
elem
);
//fprintf(stderr, "stream status: elem %s, %i\n", GST_ELEMENT_NAME(elem), tp);
//fprintf(stderr, "
\t\t
stream status: elem %s, %i\n", GST_ELEMENT_NAME(elem), tp);
break
;
default
:
//fprintf(stderr, "unhandled message %s\n",GST_MESSAGE_TYPE_NAME(msg));
//fprintf(stderr, "
\t\t
unhandled message %s\n",GST_MESSAGE_TYPE_NAME(msg));
break
;
}
}
...
...
modules/videoio/test/test_mfx.cpp
View file @
1a4c22fc
...
...
@@ -71,14 +71,7 @@ const int FRAME_COUNT = 20;
inline
void
generateFrame
(
int
i
,
Mat
&
frame
)
{
frame
=
0
;
ostringstream
buf
;
buf
<<
"Frame "
<<
setw
(
2
)
<<
setfill
(
'0'
)
<<
i
+
1
;
int
baseLine
=
0
;
Size
box
=
getTextSize
(
buf
.
str
(),
FONT_HERSHEY_COMPLEX
,
2
,
5
,
&
baseLine
);
putText
(
frame
,
buf
.
str
(),
Point
((
frame
.
cols
-
box
.
width
)
/
2
,
(
frame
.
rows
-
box
.
height
)
/
2
+
baseLine
),
FONT_HERSHEY_COMPLEX
,
2
,
Scalar
(
255
,
255
,
255
),
5
,
LINE_AA
);
Point
p
(
i
*
frame
.
cols
/
(
FRAME_COUNT
-
1
),
i
*
frame
.
rows
/
(
FRAME_COUNT
-
1
));
circle
(
frame
,
p
,
20
,
Scalar
(
200
,
25
,
55
),
5
,
LINE_AA
);
generateFrame
(
i
,
FRAME_COUNT
,
frame
);
}
inline
int
fourccByExt
(
const
String
&
ext
)
...
...
modules/videoio/test/test_precomp.hpp
View file @
1a4c22fc
...
...
@@ -33,14 +33,20 @@ inline void generateFrame(int i, int FRAME_COUNT, cv::Mat & frame)
{
using
namespace
cv
;
using
namespace
std
;
frame
=
Scalar
(
30
,
140
,
10
);
int
offset
=
(((
i
*
5
)
%
FRAME_COUNT
)
-
FRAME_COUNT
/
2
)
*
(
frame
.
cols
/
2
)
/
FRAME_COUNT
;
frame
(
cv
::
Rect
(
0
,
0
,
frame
.
cols
/
2
+
offset
,
frame
.
rows
))
=
Scalar
(
255
,
255
,
255
);
frame
(
cv
::
Rect
(
frame
.
cols
/
2
+
offset
,
0
,
frame
.
cols
-
frame
.
cols
/
2
-
offset
,
frame
.
rows
))
=
Scalar
(
0
,
0
,
0
);
ostringstream
buf
;
buf
<<
"Frame "
<<
setw
(
2
)
<<
setfill
(
'0'
)
<<
i
+
1
;
int
baseLine
=
0
;
Size
box
=
getTextSize
(
buf
.
str
(),
FONT_HERSHEY_COMPLEX
,
2
,
5
,
&
baseLine
);
putText
(
frame
,
buf
.
str
(),
Point
((
frame
.
cols
-
box
.
width
)
/
2
,
(
frame
.
rows
-
box
.
height
)
/
2
+
baseLine
),
FONT_HERSHEY_COMPLEX
,
2
,
Scalar
(
255
,
255
,
255
),
5
,
LINE_AA
);
FONT_HERSHEY_COMPLEX
,
2
,
Scalar
(
0
,
0
,
255
),
5
,
LINE_AA
);
Point
p
(
i
*
frame
.
cols
/
(
FRAME_COUNT
-
1
),
i
*
frame
.
rows
/
(
FRAME_COUNT
-
1
));
circle
(
frame
,
p
,
20
,
Scalar
(
200
,
25
,
55
),
5
,
LINE_AA
);
circle
(
frame
,
p
,
50
,
Scalar
(
200
,
25
,
55
),
8
,
LINE_AA
);
#if 0
imshow("frame", frame);
waitKey();
#endif
}
#endif
modules/videoio/test/test_video_io.cpp
View file @
1a4c22fc
...
...
@@ -61,25 +61,44 @@ protected:
virtual
void
checkFrameCount
(
int
&
)
{}
void
checkFrameRead
(
int
idx
,
VideoCapture
&
cap
)
{
//int frameID = (int)cap.get(CAP_PROP_POS_FRAMES);
Mat
img
;
cap
>>
img
;
ASSERT_FALSE
(
img
.
empty
());
//std::cout << "idx=" << idx << " img=" << img.size() << " frameID=" << frameID << std::endl;
ASSERT_FALSE
(
img
.
empty
())
<<
"idx="
<<
idx
;
checkFrameContent
(
img
,
idx
);
}
void
checkFrameSeek
(
int
idx
,
VideoCapture
&
cap
)
{
ASSERT_TRUE
(
cap
.
set
(
CAP_PROP_POS_FRAMES
,
idx
));
ASSERT_EQ
(
idx
,
(
int
)
cap
.
get
(
CAP_PROP_POS_FRAMES
));
bool
canSeek
=
cap
.
set
(
CAP_PROP_POS_FRAMES
,
idx
);
if
(
!
canSeek
)
{
std
::
cout
<<
"Seek to frame '"
<<
idx
<<
"' is not supported. SKIP."
<<
std
::
endl
;
return
;
}
EXPECT_EQ
(
idx
,
(
int
)
cap
.
get
(
CAP_PROP_POS_FRAMES
));
checkFrameRead
(
idx
,
cap
);
}
public
:
void
doTest
()
{
VideoCapture
cap
(
video_file
);
ASSERT_TRUE
(
cap
.
isOpened
());
if
(
!
cap
.
isOpened
())
{
std
::
cout
<<
"SKIP test: Can't open video: "
<<
video_file
<<
std
::
endl
;
return
;
}
int
n_frames
=
(
int
)
cap
.
get
(
CAP_PROP_FRAME_COUNT
);
ASSERT_GT
(
n_frames
,
0
);
checkFrameCount
(
n_frames
);
if
(
n_frames
>
0
)
{
ASSERT_GT
(
n_frames
,
0
);
checkFrameCount
(
n_frames
);
}
else
{
std
::
cout
<<
"CAP_PROP_FRAME_COUNT is not supported by backend. Assume 50 frames."
<<
std
::
endl
;
n_frames
=
50
;
}
{
SCOPED_TRACE
(
"consecutive read"
);
...
...
@@ -89,25 +108,32 @@ public:
}
}
if
(
ext
!=
"mpg"
&&
ext
!=
"wmv"
)
bool
canSeek
=
cap
.
set
(
CAP_PROP_POS_FRAMES
,
0
);
if
(
!
canSeek
)
{
SCOPED_TRACE
(
"random seek"
);
ASSERT_TRUE
(
cap
.
set
(
CAP_PROP_POS_FRAMES
,
0
));
for
(
int
k
=
0
;
k
<
10
;
++
k
)
{
checkFrameSeek
(
cvtest
::
TS
::
ptr
()
->
get_rng
().
uniform
(
0
,
n_frames
),
cap
);
}
std
::
cout
<<
"Seek to frame '0' is not supported. SKIP all 'seek' tests."
<<
std
::
endl
;
return
;
}
if
(
ext
!=
"wmv"
)
{
SCOPED_TRACE
(
"progressive seek"
);
ASSERT_TRUE
(
cap
.
set
(
CAP_PROP_POS_FRAMES
,
0
));
for
(
int
k
=
1
;
k
<
n_frames
;
k
+=
20
)
for
(
int
k
=
0
;
k
<
n_frames
;
k
+=
20
)
{
checkFrameSeek
(
k
,
cap
);
}
}
if
(
ext
!=
"mpg"
&&
ext
!=
"wmv"
)
{
SCOPED_TRACE
(
"random seek"
);
ASSERT_TRUE
(
cap
.
set
(
CAP_PROP_POS_FRAMES
,
0
));
for
(
int
k
=
0
;
k
<
10
;
++
k
)
{
checkFrameSeek
(
cvtest
::
TS
::
ptr
()
->
get_rng
().
uniform
(
0
,
n_frames
),
cap
);
}
}
}
};
...
...
@@ -124,7 +150,11 @@ public:
void
doFrameCountTest
()
{
VideoCapture
cap
(
video_file
);
ASSERT_TRUE
(
cap
.
isOpened
());
if
(
!
cap
.
isOpened
())
{
std
::
cout
<<
"SKIP test: Can't open video: "
<<
video_file
<<
std
::
endl
;
return
;
}
const
int
width_gt
=
672
;
const
int
height_gt
=
384
;
...
...
@@ -135,16 +165,20 @@ public:
EXPECT_EQ
(
width_gt
,
cap
.
get
(
CAP_PROP_FRAME_WIDTH
));
EXPECT_EQ
(
height_gt
,
cap
.
get
(
CAP_PROP_FRAME_HEIGHT
));
int
fps_prop
=
(
int
)
cap
.
get
(
CAP_PROP_FPS
);
EXPECT_EQ
(
fps_gt
,
fps_prop
);
double
fps_prop
=
cap
.
get
(
CAP_PROP_FPS
);
if
(
fps_prop
>
0
)
EXPECT_NEAR
(
fps_prop
,
fps_gt
,
1
);
else
std
::
cout
<<
"FPS is not available. SKIP check."
<<
std
::
endl
;
int
count_prop
=
(
int
)
cap
.
get
(
CAP_PROP_FRAME_COUNT
);
ASSERT_GT
(
count_prop
,
0
);
// mpg file reports 5.08 sec * 24 fps => property returns 122 frames
// but actual number of frames returned is 125
if
(
ext
!=
"mpg"
)
{
EXPECT_EQ
(
count_gt
,
count_prop
);
if
(
count_prop
>
0
)
EXPECT_EQ
(
count_gt
,
count_prop
);
}
int
count_actual
=
0
;
...
...
@@ -158,7 +192,10 @@ public:
EXPECT_EQ
(
height_gt
,
frame
.
rows
);
count_actual
+=
1
;
}
EXPECT_EQ
(
count_gt
,
count_actual
);
if
(
count_prop
>
0
)
EXPECT_NEAR
(
count_gt
,
count_actual
,
1
);
else
std
::
cout
<<
"Frames counter is not available. Actual frames: "
<<
count_actual
<<
". SKIP check."
<<
std
::
endl
;
}
};
...
...
@@ -268,30 +305,30 @@ Ext_Fourcc_PSNR synthetic_params[] = {
#ifdef HAVE_MSMF
#if !defined(_M_ARM)
makeParam
(
"wmv"
,
"WMV1"
,
3
9
.
f
),
makeParam
(
"wmv"
,
"WMV2"
,
3
9
.
f
),
makeParam
(
"wmv"
,
"WMV1"
,
3
0
.
f
),
makeParam
(
"wmv"
,
"WMV2"
,
3
0
.
f
),
#endif
makeParam
(
"wmv"
,
"WMV3"
,
3
9
.
f
),
makeParam
(
"avi"
,
"H264"
,
3
9
.
f
),
makeParam
(
"wmv"
,
"WVC1"
,
3
9
.
f
),
makeParam
(
"wmv"
,
"WMV3"
,
3
0
.
f
),
makeParam
(
"avi"
,
"H264"
,
3
0
.
f
),
makeParam
(
"wmv"
,
"WVC1"
,
3
0
.
f
),
#else // HAVE_MSMF
makeParam
(
"avi"
,
"XVID"
,
3
5
.
f
),
makeParam
(
"avi"
,
"MPEG"
,
3
5
.
f
),
makeParam
(
"avi"
,
"IYUV"
,
3
5
.
f
),
makeParam
(
"mkv"
,
"XVID"
,
3
5
.
f
),
makeParam
(
"mkv"
,
"MPEG"
,
3
5
.
f
),
makeParam
(
"mkv"
,
"MJPG"
,
3
5
.
f
),
makeParam
(
"avi"
,
"XVID"
,
3
0
.
f
),
makeParam
(
"avi"
,
"MPEG"
,
3
0
.
f
),
makeParam
(
"avi"
,
"IYUV"
,
3
0
.
f
),
makeParam
(
"mkv"
,
"XVID"
,
3
0
.
f
),
makeParam
(
"mkv"
,
"MPEG"
,
3
0
.
f
),
makeParam
(
"mkv"
,
"MJPG"
,
3
0
.
f
),
#ifndef HAVE_GSTREAMER
makeParam
(
"mov"
,
"mp4v"
,
3
5
.
f
),
makeParam
(
"mov"
,
"mp4v"
,
3
0
.
f
),
#endif
#endif // HAVE_MSMF
#endif // HAVE_VIDEO_INPUT && HAVE_VIDEO_OUTPUT ...
makeParam
(
"avi"
,
"MJPG"
,
41
.
f
)
makeParam
(
"avi"
,
"MJPG"
,
30
.
f
)
};
Size
all_sizes
[]
=
{
...
...
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