Commit 56b206dc authored by Nils Hasler's avatar Nils Hasler

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
parent b906ad31
......@@ -299,6 +299,8 @@ void CvCapture_GStreamer::newPad(GstElement *uridecodebin,
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_object_unref (sinkpad);
......@@ -311,52 +313,71 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
__BEGIN__;
// teststreamer(filename);
// return false;
if(!isInited) {
// printf("gst_init\n");
gst_init (NULL, NULL);
// gst_debug_set_active(TRUE);
// gst_debug_set_colored(TRUE);
// gst_debug_set_default_threshold(GST_LEVEL_WARNING);
isInited = true;
}
bool stream=false;
char *uri=NULL;
//const char *sourcetypes[] = {"dv1394src", "v4lsrc", "v4l2src", "filesrc"};
//printf("entered capturecreator %d\n", type);
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");
bool stream = false;
bool manualpipeline = false;
char *uri = NULL;
uridecodebin = NULL;
if(type != CV_CAP_GSTREAMER_FILE) {
close();
return false;
}
stream=false;
}
else {
stream=true;
uri=g_strdup (filename);
printf("Trying to connect to stream \n");
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;
}
uridecodebin = gst_element_factory_make ("uridecodebin", NULL);
g_object_set(G_OBJECT(uridecodebin),"uri",uri, NULL);
} 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 {
// printf("file '%s' is uri\n", filename);
stream = true;
uri = g_strdup(filename);
}
if(!uridecodebin) {
// printf("creating uridecodebin\n");
uridecodebin = gst_element_factory_make ("uridecodebin", NULL);
g_object_set(G_OBJECT(uridecodebin),"uri",uri, NULL);
}
if(!uridecodebin) {
CV_WARN("GStreamer: Failed to create uridecodebin\n");
close();
return false;
}
// printf("Trying to connect to stream \n");
color = gst_element_factory_make("ffmpegcolorspace", NULL);
//printf("%sstreaming\n", stream ? "" : "not ");
#ifdef HAVE_GSTREAMER_APP
sink = gst_element_factory_make("appsink", NULL);
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,
"blue_mask", G_TYPE_INT, 16711680,
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_caps_unref(caps);
g_signal_connect(uridecodebin, "pad-added", G_CALLBACK(newPad), color);
pipeline = gst_pipeline_new (NULL);
//printf("adding stuff to pipeline\n");
if(manualpipeline) {
// it is easier to link elements inside the same bin
gst_bin_add_many(GST_BIN(uridecodebin), color, sink, NULL);
// need the pipeline around the bin because bins don't know about timing
gst_bin_add(GST_BIN(pipeline), uridecodebin);
}
else {
gst_bin_add_many(GST_BIN(pipeline), uridecodebin, color, sink, NULL);
}
switch(type) {
case CV_CAP_GSTREAMER_V4L2: // default to 640x480, 30 fps
break;
case CV_CAP_GSTREAMER_V4L:
case CV_CAP_GSTREAMER_1394:
break;
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)) {
CV_ERROR(CV_StsError, "GStreamer: cannot link color -> sink\n");
gst_object_unref(pipeline);
return false;
}
// printf("linked, pausing\n");
if(gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_READY) ==
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);
// cvReleaseCapture((CvCapture **)(void *)&capture);
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) ==
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);
// cvReleaseCapture((CvCapture **)(void *)&capture);
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,
frameSize.width,
frameSize.height,
fps,
1,
(int) (fps * 1000),
1000,
1,
1);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment