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");
|
||||
|
||||
// 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;
|
||||
bool manualpipeline = 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");
|
||||
uridecodebin = NULL;
|
||||
if(type != CV_CAP_GSTREAMER_FILE) {
|
||||
close();
|
||||
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 {
|
||||
// printf("file '%s' is uri\n", filename);
|
||||
stream = true;
|
||||
uri = g_strdup(filename);
|
||||
printf("Trying to connect to stream \n");
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
else {
|
||||
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);
|
||||
|
||||
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;
|
||||
//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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user