@@ -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
@@ -408,6 +422,9 @@ void CvCapture_GStreamer::startPipeline()
408
422
return ;
409
423
}
410
424
425
+ if (isPosFramesEmulated)
426
+ emulatedFrameNumber = 0 ;
427
+
411
428
// printf("state now playing\n");
412
429
handleMessage (pipeline);
413
430
__END__;
@@ -847,6 +864,8 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
847
864
duration = -1 ;
848
865
}
849
866
867
+ handleMessage (pipeline);
868
+
850
869
GstPad* pad = gst_element_get_static_pad (sink, " sink" );
851
870
#if GST_VERSION_MAJOR == 0
852
871
GstCaps* buffer_caps = gst_pad_get_caps (pad);
@@ -873,9 +892,32 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
873
892
874
893
fps = (double )num/(double )denom;
875
894
876
- // GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "pipeline")
877
- if (file)
878
- stopPipeline ();
895
+ {
896
+ GstFormat format_;
897
+ gint64 value_ = -1 ;
898
+ gboolean status_;
899
+
900
+ format_ = GST_FORMAT_DEFAULT;
901
+ #if GST_VERSION_MAJOR == 0
902
+ #define FORMAT &format_
903
+ #else
904
+ #define FORMAT format_
905
+ #endif
906
+ status_ = gst_element_query_position (pipeline, FORMAT, &value_);
907
+ #undef FORMAT
908
+ if (!status_ || value_ != 0 || duration < 0 )
909
+ {
910
+ CV_WARN (cv::format (" Cannot query video position: status=%d value=%lld duration=%lld\n " ,
911
+ (int )status_, (long long int )value_, (long long int )duration).c_str ());
912
+ isPosFramesSupported = false ;
913
+ isPosFramesEmulated = true ;
914
+ emulatedFrameNumber = 0 ;
915
+ }
916
+ else
917
+ isPosFramesSupported = true ;
918
+ }
919
+
920
+ GST_DEBUG_BIN_TO_DOT_FILE (GST_BIN (pipeline), GST_DEBUG_GRAPH_SHOW_ALL, " pipeline" );
879
921
}
880
922
881
923
__END__;
@@ -914,14 +956,22 @@ double CvCapture_GStreamer::getProperty( int propId ) const
914
956
format = GST_FORMAT_TIME;
915
957
status = gst_element_query_position (sink, FORMAT, &value);
916
958
if (!status) {
959
+ handleMessage (pipeline);
917
960
CV_WARN (" GStreamer: unable to query position of stream" );
918
961
return 0 ;
919
962
}
920
963
return value * 1e-6 ; // nano seconds to milli seconds
921
964
case CV_CAP_PROP_POS_FRAMES:
965
+ if (!isPosFramesSupported)
966
+ {
967
+ if (isPosFramesEmulated)
968
+ return emulatedFrameNumber;
969
+ return 0 ; // TODO getProperty() "unsupported" value should be changed
970
+ }
922
971
format = GST_FORMAT_DEFAULT;
923
972
status = gst_element_query_position (sink, FORMAT, &value);
924
973
if (!status) {
974
+ handleMessage (pipeline);
925
975
CV_WARN (" GStreamer: unable to query position of stream" );
926
976
return 0 ;
927
977
}
@@ -930,6 +980,7 @@ double CvCapture_GStreamer::getProperty( int propId ) const
930
980
format = GST_FORMAT_PERCENT;
931
981
status = gst_element_query_position (sink, FORMAT, &value);
932
982
if (!status) {
983
+ handleMessage (pipeline);
933
984
CV_WARN (" GStreamer: unable to query position of stream" );
934
985
return 0 ;
935
986
}
@@ -1013,24 +1064,75 @@ bool CvCapture_GStreamer::setProperty( int propId, double value )
1013
1064
flags = (GstSeekFlags) (GST_SEEK_FLAG_FLUSH|GST_SEEK_FLAG_ACCURATE);
1014
1065
if (!gst_element_seek_simple (GST_ELEMENT (pipeline), format,
1015
1066
flags, (gint64) (value * GST_MSECOND))) {
1067
+ handleMessage (pipeline);
1016
1068
CV_WARN (" GStreamer: unable to seek" );
1017
1069
}
1070
+ else
1071
+ {
1072
+ if (isPosFramesEmulated)
1073
+ {
1074
+ if (value == 0 )
1075
+ {
1076
+ emulatedFrameNumber = 0 ;
1077
+ return true ;
1078
+ }
1079
+ else
1080
+ {
1081
+ isPosFramesEmulated = false ; // reset frame counter emulation
1082
+ }
1083
+ }
1084
+ }
1018
1085
break ;
1019
1086
case CV_CAP_PROP_POS_FRAMES:
1087
+ {
1088
+ if (!isPosFramesSupported)
1089
+ {
1090
+ if (isPosFramesEmulated)
1091
+ {
1092
+ if (value == 0 )
1093
+ {
1094
+ restartPipeline ();
1095
+ emulatedFrameNumber = 0 ;
1096
+ return true ;
1097
+ }
1098
+ }
1099
+ return false ;
1100
+ }
1020
1101
format = GST_FORMAT_DEFAULT;
1021
1102
flags = (GstSeekFlags) (GST_SEEK_FLAG_FLUSH|GST_SEEK_FLAG_ACCURATE);
1022
1103
if (!gst_element_seek_simple (GST_ELEMENT (pipeline), format,
1023
1104
flags, (gint64) value)) {
1105
+ handleMessage (pipeline);
1024
1106
CV_WARN (" GStreamer: unable to seek" );
1107
+ break ;
1025
1108
}
1026
- break ;
1109
+ // wait for status update
1110
+ gst_element_get_state (pipeline, NULL , NULL , GST_CLOCK_TIME_NONE);
1111
+ return true ;
1112
+ }
1027
1113
case CV_CAP_PROP_POS_AVI_RATIO:
1028
1114
format = GST_FORMAT_PERCENT;
1029
1115
flags = (GstSeekFlags) (GST_SEEK_FLAG_FLUSH|GST_SEEK_FLAG_ACCURATE);
1030
1116
if (!gst_element_seek_simple (GST_ELEMENT (pipeline), format,
1031
1117
flags, (gint64) (value * GST_FORMAT_PERCENT_MAX))) {
1118
+ handleMessage (pipeline);
1032
1119
CV_WARN (" GStreamer: unable to seek" );
1033
1120
}
1121
+ else
1122
+ {
1123
+ if (isPosFramesEmulated)
1124
+ {
1125
+ if (value == 0 )
1126
+ {
1127
+ emulatedFrameNumber = 0 ;
1128
+ return true ;
1129
+ }
1130
+ else
1131
+ {
1132
+ isPosFramesEmulated = false ; // reset frame counter emulation
1133
+ }
1134
+ }
1135
+ }
1034
1136
break ;
1035
1137
case CV_CAP_PROP_FRAME_WIDTH:
1036
1138
if (value > 0 )
@@ -1719,7 +1821,7 @@ void handleMessage(GstElement * pipeline)
1719
1821
while (gst_bus_have_pending (bus)) {
1720
1822
msg = gst_bus_pop (bus);
1721
1823
1722
- // printf("Got %s message\n", GST_MESSAGE_TYPE_NAME(msg));
1824
+ // printf("\t\tGot %s message\n", GST_MESSAGE_TYPE_NAME(msg));
1723
1825
1724
1826
if (gst_is_missing_plugin_message (msg))
1725
1827
{
@@ -1731,28 +1833,30 @@ void handleMessage(GstElement * pipeline)
1731
1833
case GST_MESSAGE_STATE_CHANGED:
1732
1834
GstState oldstate, newstate, pendstate;
1733
1835
gst_message_parse_state_changed (msg, &oldstate, &newstate, &pendstate);
1734
- // fprintf(stderr, "state changed from %s to %s (pending: %s)\n", gst_element_state_get_name(oldstate),
1836
+ // fprintf(stderr, "\t\t%s: state changed from %s to %s (pending: %s)\n",
1837
+ // gst_element_get_name(GST_MESSAGE_SRC (msg)),
1838
+ // gst_element_state_get_name(oldstate),
1735
1839
// gst_element_state_get_name(newstate), gst_element_state_get_name(pendstate));
1736
1840
break ;
1737
1841
case GST_MESSAGE_ERROR:
1738
1842
gst_message_parse_error (msg, &err, &debug);
1739
- fprintf (stderr, " GStreamer Plugin: Embedded video playback halted; module %s reported: %s\n " ,
1740
- gst_element_get_name (GST_MESSAGE_SRC (msg)), err->message );
1843
+ // fprintf(stderr, "\t\tGStreamer Plugin: Embedded video playback halted; module %s reported: %s\n",
1844
+ // gst_element_get_name(GST_MESSAGE_SRC (msg)), err->message);
1741
1845
1742
1846
g_error_free (err);
1743
1847
g_free (debug);
1744
1848
1745
1849
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
1746
1850
break ;
1747
1851
case GST_MESSAGE_EOS:
1748
- // fprintf(stderr, "reached the end of the stream.");
1852
+ // fprintf(stderr, "\t\treached the end of the stream.");
1749
1853
break ;
1750
1854
case GST_MESSAGE_STREAM_STATUS:
1751
1855
gst_message_parse_stream_status (msg,&tp,&elem);
1752
- // fprintf(stderr, "stream status: elem %s, %i\n", GST_ELEMENT_NAME(elem), tp);
1856
+ // fprintf(stderr, "\t\tstream status: elem %s, %i\n", GST_ELEMENT_NAME(elem), tp);
1753
1857
break ;
1754
1858
default :
1755
- // fprintf(stderr, "unhandled message %s\n",GST_MESSAGE_TYPE_NAME(msg));
1859
+ // fprintf(stderr, "\t\tunhandled message %s\n",GST_MESSAGE_TYPE_NAME(msg));
1756
1860
break ;
1757
1861
}
1758
1862
}
0 commit comments