When opening a file with GStreamer:
* if the filename looks like a URI, it is opened in non-blocking mode, cvQueryFrame() could skip frames or grab one frame more than once * if the filename looks like a filename, it is opened in blocking mode. cvQueryFrame() grabs consecutive frames * otherwise the filename is interpreted as a gstreamer pipeline as used with gst-launch. The last element of the pipeline has to have the property name=to-opencv
This commit is contained in:
parent
b906ad3108
commit
56b206dc7b
@ -299,6 +299,8 @@ void CvCapture_GStreamer::newPad(GstElement *uridecodebin,
|
|||||||
|
|
||||||
sinkpad = gst_element_get_static_pad (color, "sink");
|
sinkpad = gst_element_get_static_pad (color, "sink");
|
||||||
|
|
||||||
|
// printf("linking dynamic pad to colourconverter %p %p\n", uridecodebin, pad);
|
||||||
|
|
||||||
gst_pad_link (pad, sinkpad);
|
gst_pad_link (pad, sinkpad);
|
||||||
|
|
||||||
gst_object_unref (sinkpad);
|
gst_object_unref (sinkpad);
|
||||||
@ -311,52 +313,71 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
|
|||||||
|
|
||||||
__BEGIN__;
|
__BEGIN__;
|
||||||
|
|
||||||
// teststreamer(filename);
|
|
||||||
|
|
||||||
// return false;
|
|
||||||
|
|
||||||
if(!isInited) {
|
if(!isInited) {
|
||||||
// printf("gst_init\n");
|
// printf("gst_init\n");
|
||||||
gst_init (NULL, NULL);
|
gst_init (NULL, NULL);
|
||||||
|
|
||||||
|
// gst_debug_set_active(TRUE);
|
||||||
|
// gst_debug_set_colored(TRUE);
|
||||||
|
// gst_debug_set_default_threshold(GST_LEVEL_WARNING);
|
||||||
|
|
||||||
isInited = true;
|
isInited = true;
|
||||||
}
|
}
|
||||||
bool stream = false;
|
bool stream = false;
|
||||||
|
bool manualpipeline = false;
|
||||||
char *uri = NULL;
|
char *uri = NULL;
|
||||||
//const char *sourcetypes[] = {"dv1394src", "v4lsrc", "v4l2src", "filesrc"};
|
uridecodebin = NULL;
|
||||||
//printf("entered capturecreator %d\n", type);
|
if(type != CV_CAP_GSTREAMER_FILE) {
|
||||||
if (type == CV_CAP_GSTREAMER_FILE) {
|
|
||||||
if (!gst_uri_is_valid(filename)) {
|
|
||||||
uri=realpath(filename,NULL);
|
|
||||||
if (uri)
|
|
||||||
uri=g_filename_to_uri(uri,NULL,NULL);
|
|
||||||
else {
|
|
||||||
CV_WARN("Error opening file\n");
|
|
||||||
close();
|
close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
stream=false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if(!gst_uri_is_valid(filename)) {
|
||||||
|
// printf("file '%s' is not uri\n", filename);
|
||||||
|
uri = realpath(filename, NULL);
|
||||||
|
stream=false;
|
||||||
|
if(uri) {
|
||||||
|
// printf("is file... ? %s\n", uri);
|
||||||
|
uri = g_filename_to_uri(uri, NULL, NULL);
|
||||||
|
if(!uri) {
|
||||||
|
CV_WARN("GStreamer: Error opening file\n");
|
||||||
|
close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GError *err = NULL;
|
||||||
|
uridecodebin = gst_parse_bin_from_description(filename, FALSE, &err);
|
||||||
|
if(!uridecodebin) {
|
||||||
|
CV_WARN("GStreamer: Error opening bin\n");
|
||||||
|
close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
stream = true;
|
||||||
|
// printf("created custom bin\n");
|
||||||
|
manualpipeline = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
|
// printf("file '%s' is uri\n", filename);
|
||||||
stream = true;
|
stream = true;
|
||||||
uri = g_strdup(filename);
|
uri = g_strdup(filename);
|
||||||
printf("Trying to connect to stream \n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!uridecodebin) {
|
||||||
|
// printf("creating uridecodebin\n");
|
||||||
uridecodebin = gst_element_factory_make ("uridecodebin", NULL);
|
uridecodebin = gst_element_factory_make ("uridecodebin", NULL);
|
||||||
g_object_set(G_OBJECT(uridecodebin),"uri",uri, NULL);
|
g_object_set(G_OBJECT(uridecodebin),"uri",uri, NULL);
|
||||||
|
}
|
||||||
if(!uridecodebin) {
|
if(!uridecodebin) {
|
||||||
|
CV_WARN("GStreamer: Failed to create uridecodebin\n");
|
||||||
close();
|
close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
// printf("Trying to connect to stream \n");
|
||||||
else {
|
|
||||||
close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
color = gst_element_factory_make("ffmpegcolorspace", NULL);
|
color = gst_element_factory_make("ffmpegcolorspace", NULL);
|
||||||
|
|
||||||
|
//printf("%sstreaming\n", stream ? "" : "not ");
|
||||||
|
|
||||||
#ifdef HAVE_GSTREAMER_APP
|
#ifdef HAVE_GSTREAMER_APP
|
||||||
sink = gst_element_factory_make("appsink", NULL);
|
sink = gst_element_factory_make("appsink", NULL);
|
||||||
gst_app_sink_set_max_buffers (GST_APP_SINK(sink),1);
|
gst_app_sink_set_max_buffers (GST_APP_SINK(sink),1);
|
||||||
@ -371,33 +392,50 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
|
|||||||
"green_mask", G_TYPE_INT, 65280,
|
"green_mask", G_TYPE_INT, 65280,
|
||||||
"blue_mask", G_TYPE_INT, 16711680,
|
"blue_mask", G_TYPE_INT, 16711680,
|
||||||
NULL);
|
NULL);
|
||||||
//GstCaps *caps=gst_video_format_new_caps(GST_VIDEO_FORMAT_BGR,,368,30,1,1,1);
|
|
||||||
gst_app_sink_set_caps(GST_APP_SINK(sink), caps);
|
gst_app_sink_set_caps(GST_APP_SINK(sink), caps);
|
||||||
gst_caps_unref(caps);
|
gst_caps_unref(caps);
|
||||||
g_signal_connect(uridecodebin, "pad-added", G_CALLBACK(newPad), color);
|
|
||||||
|
|
||||||
pipeline = gst_pipeline_new (NULL);
|
pipeline = gst_pipeline_new (NULL);
|
||||||
|
|
||||||
gst_bin_add_many(GST_BIN(pipeline), uridecodebin, color, sink, NULL);
|
//printf("adding stuff to pipeline\n");
|
||||||
|
if(manualpipeline) {
|
||||||
switch(type) {
|
// it is easier to link elements inside the same bin
|
||||||
case CV_CAP_GSTREAMER_V4L2: // default to 640x480, 30 fps
|
gst_bin_add_many(GST_BIN(uridecodebin), color, sink, NULL);
|
||||||
break;
|
// need the pipeline around the bin because bins don't know about timing
|
||||||
case CV_CAP_GSTREAMER_V4L:
|
gst_bin_add(GST_BIN(pipeline), uridecodebin);
|
||||||
case CV_CAP_GSTREAMER_1394:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
gst_bin_add_many(GST_BIN(pipeline), uridecodebin, color, sink, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(manualpipeline) {
|
||||||
|
GstElement *e = gst_bin_get_by_name(GST_BIN(uridecodebin), "to-opencv");
|
||||||
|
if(e) {
|
||||||
|
if(!gst_element_link(e, color)) {
|
||||||
|
//printf("catching 'pad-added' for element 'to-opencv'\n");
|
||||||
|
g_signal_connect(e, "pad-added", G_CALLBACK(newPad), color);
|
||||||
|
}/* else {
|
||||||
|
printf("linked to-opencv -> color\n");
|
||||||
|
}*/
|
||||||
|
gst_object_unref(e);
|
||||||
|
} else {
|
||||||
|
CV_WARN("GStreamer: no element with 'name=to-opencv'\n");
|
||||||
|
gst_object_unref(pipeline);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
g_signal_connect(uridecodebin, "pad-added", G_CALLBACK(newPad), color);
|
||||||
|
}
|
||||||
|
|
||||||
if(!gst_element_link(color, sink)) {
|
if(!gst_element_link(color, sink)) {
|
||||||
CV_ERROR(CV_StsError, "GStreamer: cannot link color -> sink\n");
|
CV_ERROR(CV_StsError, "GStreamer: cannot link color -> sink\n");
|
||||||
gst_object_unref(pipeline);
|
gst_object_unref(pipeline);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// printf("linked, pausing\n");
|
|
||||||
|
|
||||||
if(gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_READY) ==
|
if(gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_READY) ==
|
||||||
GST_STATE_CHANGE_FAILURE) {
|
GST_STATE_CHANGE_FAILURE) {
|
||||||
CV_WARN("GStreamer: unable to set pipeline to paused\n");
|
CV_WARN("GStreamer: unable to set pipeline to ready\n");
|
||||||
// icvHandleMessage(capture);
|
// icvHandleMessage(capture);
|
||||||
// cvReleaseCapture((CvCapture **)(void *)&capture);
|
// cvReleaseCapture((CvCapture **)(void *)&capture);
|
||||||
gst_object_unref(pipeline);
|
gst_object_unref(pipeline);
|
||||||
@ -406,7 +444,7 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
|
|||||||
|
|
||||||
if(gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING) ==
|
if(gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING) ==
|
||||||
GST_STATE_CHANGE_FAILURE) {
|
GST_STATE_CHANGE_FAILURE) {
|
||||||
CV_WARN("GStreamer: unable to set pipeline to paused\n");
|
CV_WARN("GStreamer: unable to set pipeline to playing\n");
|
||||||
// icvHandleMessage(capture);
|
// icvHandleMessage(capture);
|
||||||
// cvReleaseCapture((CvCapture **)(void *)&capture);
|
// cvReleaseCapture((CvCapture **)(void *)&capture);
|
||||||
gst_object_unref(pipeline);
|
gst_object_unref(pipeline);
|
||||||
@ -507,8 +545,8 @@ bool CvVideoWriter_GStreamer::open( const char * filename, int fourcc,
|
|||||||
caps= gst_video_format_new_caps(GST_VIDEO_FORMAT_BGR,
|
caps= gst_video_format_new_caps(GST_VIDEO_FORMAT_BGR,
|
||||||
frameSize.width,
|
frameSize.width,
|
||||||
frameSize.height,
|
frameSize.height,
|
||||||
fps,
|
(int) (fps * 1000),
|
||||||
1,
|
1000,
|
||||||
1,
|
1,
|
||||||
1);
|
1);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user