@@ -168,6 +168,10 @@ class CvCapture_GStreamer : public CvCapture
168
168
gint width;
169
169
gint height;
170
170
double fps;
171
+
172
+ bool isPosFramesSupported;
173
+ bool isPosFramesEmulated;
174
+ gint64 emulatedFrameNumber;
171
175
};
172
176
173
177
/* !
@@ -191,6 +195,10 @@ void CvCapture_GStreamer::init()
191
195
width = -1 ;
192
196
height = -1 ;
193
197
fps = -1 ;
198
+
199
+ isPosFramesSupported = false ;
200
+ isPosFramesEmulated = false ;
201
+ emulatedFrameNumber = -1 ;
194
202
}
195
203
196
204
/* !
@@ -212,6 +220,9 @@ void CvCapture_GStreamer::close()
212
220
width = -1 ;
213
221
height = -1 ;
214
222
fps = -1 ;
223
+ isPosFramesSupported = false ;
224
+ isPosFramesEmulated = false ;
225
+ emulatedFrameNumber = -1 ;
215
226
}
216
227
217
228
/* !
@@ -253,6 +264,9 @@ bool CvCapture_GStreamer::grabFrame()
253
264
if (!buffer)
254
265
return false ;
255
266
267
+ if (isPosFramesEmulated)
268
+ emulatedFrameNumber++;
269
+
256
270
return true ;
257
271
}
258
272
@@ -428,6 +442,9 @@ void CvCapture_GStreamer::startPipeline()
428
442
return ;
429
443
}
430
444
445
+ if (isPosFramesEmulated)
446
+ emulatedFrameNumber = 0 ;
447
+
431
448
// printf("state now playing\n");
432
449
handleMessage (pipeline);
433
450
__END__;
@@ -879,6 +896,8 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
879
896
duration = -1 ;
880
897
}
881
898
899
+ handleMessage (pipeline);
900
+
882
901
GstPad* pad = gst_element_get_static_pad (sink, " sink" );
883
902
#if GST_VERSION_MAJOR == 0
884
903
GstCaps* buffer_caps = gst_pad_get_caps (pad);
@@ -905,9 +924,32 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
905
924
906
925
fps = (double )num/(double )denom;
907
926
908
- // GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "pipeline")
909
- if (file)
910
- stopPipeline ();
927
+ {
928
+ GstFormat format_;
929
+ gint64 value_ = -1 ;
930
+ gboolean status_;
931
+
932
+ format_ = GST_FORMAT_DEFAULT;
933
+ #if GST_VERSION_MAJOR == 0
934
+ #define FORMAT &format_
935
+ #else
936
+ #define FORMAT format_
937
+ #endif
938
+ status_ = gst_element_query_position (pipeline, FORMAT, &value_);
939
+ #undef FORMAT
940
+ if (!status_ || value_ != 0 || duration < 0 )
941
+ {
942
+ CV_WARN (cv::format (" Cannot query video position: status=%d value=%lld duration=%lld\n " ,
943
+ (int )status_, (long long int )value_, (long long int )duration).c_str ());
944
+ isPosFramesSupported = false ;
945
+ isPosFramesEmulated = true ;
946
+ emulatedFrameNumber = 0 ;
947
+ }
948
+ else
949
+ isPosFramesSupported = true ;
950
+ }
951
+
952
+ GST_DEBUG_BIN_TO_DOT_FILE (GST_BIN (pipeline), GST_DEBUG_GRAPH_SHOW_ALL, " pipeline" );
911
953
}
912
954
913
955
__END__;
@@ -946,14 +988,22 @@ double CvCapture_GStreamer::getProperty( int propId ) const
946
988
format = GST_FORMAT_TIME;
947
989
status = gst_element_query_position (sink, FORMAT, &value);
948
990
if (!status) {
991
+ handleMessage (pipeline);
949
992
CV_WARN (" GStreamer: unable to query position of stream" );
950
993
return 0 ;
951
994
}
952
995
return value * 1e-6 ; // nano seconds to milli seconds
953
996
case CV_CAP_PROP_POS_FRAMES:
997
+ if (!isPosFramesSupported)
998
+ {
999
+ if (isPosFramesEmulated)
1000
+ return emulatedFrameNumber;
1001
+ return 0 ; // TODO getProperty() "unsupported" value should be changed
1002
+ }
954
1003
format = GST_FORMAT_DEFAULT;
955
1004
status = gst_element_query_position (sink, FORMAT, &value);
956
1005
if (!status) {
1006
+ handleMessage (pipeline);
957
1007
CV_WARN (" GStreamer: unable to query position of stream" );
958
1008
return 0 ;
959
1009
}
@@ -962,6 +1012,7 @@ double CvCapture_GStreamer::getProperty( int propId ) const
962
1012
format = GST_FORMAT_PERCENT;
963
1013
status = gst_element_query_position (sink, FORMAT, &value);
964
1014
if (!status) {
1015
+ handleMessage (pipeline);
965
1016
CV_WARN (" GStreamer: unable to query position of stream" );
966
1017
return 0 ;
967
1018
}
@@ -1045,24 +1096,75 @@ bool CvCapture_GStreamer::setProperty( int propId, double value )
1045
1096
flags = (GstSeekFlags) (GST_SEEK_FLAG_FLUSH|GST_SEEK_FLAG_ACCURATE);
1046
1097
if (!gst_element_seek_simple (GST_ELEMENT (pipeline), format,
1047
1098
flags, (gint64) (value * GST_MSECOND))) {
1099
+ handleMessage (pipeline);
1048
1100
CV_WARN (" GStreamer: unable to seek" );
1049
1101
}
1102
+ else
1103
+ {
1104
+ if (isPosFramesEmulated)
1105
+ {
1106
+ if (value == 0 )
1107
+ {
1108
+ emulatedFrameNumber = 0 ;
1109
+ return true ;
1110
+ }
1111
+ else
1112
+ {
1113
+ isPosFramesEmulated = false ; // reset frame counter emulation
1114
+ }
1115
+ }
1116
+ }
1050
1117
break ;
1051
1118
case CV_CAP_PROP_POS_FRAMES:
1119
+ {
1120
+ if (!isPosFramesSupported)
1121
+ {
1122
+ if (isPosFramesEmulated)
1123
+ {
1124
+ if (value == 0 )
1125
+ {
1126
+ restartPipeline ();
1127
+ emulatedFrameNumber = 0 ;
1128
+ return true ;
1129
+ }
1130
+ }
1131
+ return false ;
1132
+ }
1052
1133
format = GST_FORMAT_DEFAULT;
1053
1134
flags = (GstSeekFlags) (GST_SEEK_FLAG_FLUSH|GST_SEEK_FLAG_ACCURATE);
1054
1135
if (!gst_element_seek_simple (GST_ELEMENT (pipeline), format,
1055
1136
flags, (gint64) value)) {
1137
+ handleMessage (pipeline);
1056
1138
CV_WARN (" GStreamer: unable to seek" );
1139
+ break ;
1057
1140
}
1058
- break ;
1141
+ // wait for status update
1142
+ gst_element_get_state (pipeline, NULL , NULL , GST_CLOCK_TIME_NONE);
1143
+ return true ;
1144
+ }
1059
1145
case CV_CAP_PROP_POS_AVI_RATIO:
1060
1146
format = GST_FORMAT_PERCENT;
1061
1147
flags = (GstSeekFlags) (GST_SEEK_FLAG_FLUSH|GST_SEEK_FLAG_ACCURATE);
1062
1148
if (!gst_element_seek_simple (GST_ELEMENT (pipeline), format,
1063
1149
flags, (gint64) (value * GST_FORMAT_PERCENT_MAX))) {
1150
+ handleMessage (pipeline);
1064
1151
CV_WARN (" GStreamer: unable to seek" );
1065
1152
}
1153
+ else
1154
+ {
1155
+ if (isPosFramesEmulated)
1156
+ {
1157
+ if (value == 0 )
1158
+ {
1159
+ emulatedFrameNumber = 0 ;
1160
+ return true ;
1161
+ }
1162
+ else
1163
+ {
1164
+ isPosFramesEmulated = false ; // reset frame counter emulation
1165
+ }
1166
+ }
1167
+ }
1066
1168
break ;
1067
1169
case CV_CAP_PROP_FRAME_WIDTH:
1068
1170
if (value > 0 )
@@ -1751,7 +1853,7 @@ void handleMessage(GstElement * pipeline)
1751
1853
while (gst_bus_have_pending (bus)) {
1752
1854
msg = gst_bus_pop (bus);
1753
1855
1754
- // printf("Got %s message\n", GST_MESSAGE_TYPE_NAME(msg));
1856
+ // printf("\t\tGot %s message\n", GST_MESSAGE_TYPE_NAME(msg));
1755
1857
1756
1858
if (gst_is_missing_plugin_message (msg))
1757
1859
{
@@ -1763,28 +1865,30 @@ void handleMessage(GstElement * pipeline)
1763
1865
case GST_MESSAGE_STATE_CHANGED:
1764
1866
GstState oldstate, newstate, pendstate;
1765
1867
gst_message_parse_state_changed (msg, &oldstate, &newstate, &pendstate);
1766
- // fprintf(stderr, "state changed from %s to %s (pending: %s)\n", gst_element_state_get_name(oldstate),
1868
+ // fprintf(stderr, "\t\t%s: state changed from %s to %s (pending: %s)\n",
1869
+ // gst_element_get_name(GST_MESSAGE_SRC (msg)),
1870
+ // gst_element_state_get_name(oldstate),
1767
1871
// gst_element_state_get_name(newstate), gst_element_state_get_name(pendstate));
1768
1872
break ;
1769
1873
case GST_MESSAGE_ERROR:
1770
1874
gst_message_parse_error (msg, &err, &debug);
1771
- fprintf (stderr, " GStreamer Plugin: Embedded video playback halted; module %s reported: %s\n " ,
1772
- gst_element_get_name (GST_MESSAGE_SRC (msg)), err->message );
1875
+ // fprintf(stderr, "\t\tGStreamer Plugin: Embedded video playback halted; module %s reported: %s\n",
1876
+ // gst_element_get_name(GST_MESSAGE_SRC (msg)), err->message);
1773
1877
1774
1878
g_error_free (err);
1775
1879
g_free (debug);
1776
1880
1777
1881
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
1778
1882
break ;
1779
1883
case GST_MESSAGE_EOS:
1780
- // fprintf(stderr, "reached the end of the stream.");
1884
+ // fprintf(stderr, "\t\treached the end of the stream.");
1781
1885
break ;
1782
1886
case GST_MESSAGE_STREAM_STATUS:
1783
1887
gst_message_parse_stream_status (msg,&tp,&elem);
1784
- // fprintf(stderr, "stream status: elem %s, %i\n", GST_ELEMENT_NAME(elem), tp);
1888
+ // fprintf(stderr, "\t\tstream status: elem %s, %i\n", GST_ELEMENT_NAME(elem), tp);
1785
1889
break ;
1786
1890
default :
1787
- // fprintf(stderr, "unhandled message %s\n",GST_MESSAGE_TYPE_NAME(msg));
1891
+ // fprintf(stderr, "\t\tunhandled message %s\n",GST_MESSAGE_TYPE_NAME(msg));
1788
1892
break ;
1789
1893
}
1790
1894
}
0 commit comments