GStreamer error : Gstreamer encountered a general stream error - gstreamer

I am working gstreamer for iOS, but having error with demux.
It says "Eror received from element matroskademux0 : Gstreamer encountered a general stream error".
Here is the soure code.
GstBus *bus;
GSource *bus_source;
GstElement *source1, *clrspace1, *clrspace2, *clrspace, *videobox1, *sink, *source2, *mpegenc, *avimux;
GstElement *videomixer;
GstElement *decodebin1, *decodebin2;
GstElement *queue;
/* Build pipeline */
pipeline = gst_pipeline_new("pipelinecomposer");
source1 = gst_element_factory_make("filesrc", "source1");
source2 = gst_element_factory_make("filesrc", "source2");
videobox1 = gst_element_factory_make("videobox", "videobox");
videomixer = gst_element_factory_make("videomixer", "videomixer");
clrspace1 = gst_element_factory_make("videoconvert", "clrspace1");
clrspace2 = gst_element_factory_make("videoconvert", "clrspace2");
clrspace = gst_element_factory_make("videoconvert", "clrspace");
sink = gst_element_factory_make("filesink", "sink");
mpegenc = gst_element_factory_make("x264enc", "mpegenc");
avimux = gst_element_factory_make("mpegtsmux", "avimux");
decodebin1 = gst_element_factory_make("decodebin", "decodebin1");
decodebin2 = gst_element_factory_make("decodebin", "decodebin2");
queue = gst_element_factory_make("queue", "queue");
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectory, #"1.avi"];
NSString *filePath_1 = [NSString stringWithFormat:#"%#", #"/Users/john/Movies/1.webm"];
NSString *filePath_2 = [NSString stringWithFormat:#"%#", #"/Users/john/Movies/2.webm"];
g_object_set (G_OBJECT (source1), "location", [filePath_1 UTF8String], NULL);
g_object_set (G_OBJECT (source2), "location", [filePath_2 UTF8String], NULL);
g_object_set (G_OBJECT (sink), "location", [filePath UTF8String], NULL);
g_object_set(videobox1,"border-alpha",0,"top",0,"left",0,NULL);
gst_bin_add_many(GST_BIN (pipeline), source1, sink, videobox1, videomixer, clrspace1, clrspace2, clrspace, source2, mpegenc, avimux, decodebin1, decodebin2, nil);
gst_element_link_many(source1, decodebin1, clrspace1, videobox1, videomixer, clrspace, mpegenc, avimux, sink, nil);
gst_element_link_many(source2, decodebin2, clrspace2, videomixer, nil);
gst_element_set_state(pipeline, GST_STATE_PLAYING);
Please help me.
Hello guys,
solved problem.
I have to use pad for filesrc.
Here is the modified source codes.
static void on_pad_added (GstElement *element, GstPad *pad, gpointer data)
{
GstPad *sinkpad;
GstElement *decoder = (GstElement *) data;
/* We can now link this pad with the vorbis-decoder sink pad */
g_print ("Dynamic pad created, linking demuxer/decoder\n");
sinkpad = gst_element_get_static_pad (decoder, "sink");
gst_pad_link (pad, sinkpad);
gst_object_unref (sinkpad);
}
/* Main method for the bus monitoring code */
-(void) app_function
{
GstBus *bus;
GSource *bus_source;
GstElement *source1, *clrspace1, *clrspace2, *clrspace, *videobox1, *sink, *source2, *mpegenc, *avimux;
GstElement *videomixer;
GstElement *decodebin1, *decodebin2;
GstElement *matroskademux1, *vp8dec1;
GST_DEBUG ("Creating pipeline");
/* Create our own GLib Main Context and make it the default one */
context = g_main_context_new ();
g_main_context_push_thread_default(context);
/* Build pipeline */
pipeline = gst_pipeline_new("pipelinecomposer");
source1 = gst_element_factory_make("filesrc", "source1");
source2 = gst_element_factory_make("filesrc", "source2");
videobox1 = gst_element_factory_make("videobox", "videobox");
videomixer = gst_element_factory_make("videomixer", "videomixer");
clrspace1 = gst_element_factory_make("videoconvert", "clrspace1");
clrspace2 = gst_element_factory_make("videoconvert", "clrspace2");
clrspace = gst_element_factory_make("videoconvert", "clrspace");
sink = gst_element_factory_make("filesink", "sink");
mpegenc = gst_element_factory_make("x264enc", "mpegenc");
avimux = gst_element_factory_make("mpegtsmux", "avimux");
decodebin1 = gst_element_factory_make("decodebin", "decodebin1");
decodebin2 = gst_element_factory_make("decodebin", "decodebin2");
matroskademux1 = gst_element_factory_make("matroskademux", "matroskademux1");
vp8dec1 = gst_element_factory_make("vp8dec", "vp8dec1");
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectory, #"1.avi"];
NSString *filePath_1 = [NSString stringWithFormat:#"%#", #"/Users/johanbasore1/Movies/1.webm"];
NSString *filePath_2 = [NSString stringWithFormat:#"%#", #"/Users/johanbasore1/Movies/2.webm"];
g_object_set (G_OBJECT (source1), "location", [filePath_1 UTF8String], NULL);
g_object_set (G_OBJECT (source2), "location", [filePath_2 UTF8String], NULL);
g_object_set (G_OBJECT (sink), "location", [filePath UTF8String], NULL);
g_object_set(videobox1,"border-alpha",0,"top",0,"left",0,NULL);
g_signal_connect(matroskademux1, "pad-added", G_CALLBACK(on_pad_added), vp8dec1);
gst_bin_add_many(GST_BIN (pipeline), source1, matroskademux1, vp8dec1 , sink, clrspace1, mpegenc, avimux, nil);
gst_element_link(source1, matroskademux1);
gst_element_link_many(vp8dec1, clrspace1, mpegenc, avimux, sink, nil);
}

Related

How to create gstreamer pipeline with parallel branches having different FPS using tee plugin

Hi I want to create a gstreamer pipeline with two branches having different FPS. The C++ code I wrote is given below
#include <iostream>
#include <string.h>
#include <gst/gst.h>
#include <gst/app/app.h>
using namespace std;
GstElement *src, *dbin, *conv, *tee, *mux, *parse, *pipeline;
GstElement *queue1,*videorate1, *conv1, *jenc1, *sink1;
GstElement *queue2,*videorate2, *conv2, *jenc2, *sink2;
GMainLoop *loop;
static gboolean
message_cb (GstBus * bus, GstMessage * message, gpointer user_data)
{
//Cpipeline *obj_pipeline = (Cpipeline*)user_data;
switch (GST_MESSAGE_TYPE (message)) {
case GST_MESSAGE_ERROR:{
GError *err = NULL;
gchar *name, *debug = NULL;
name = gst_object_get_path_string (message->src);
gst_message_parse_error (message, &err, &debug);
g_printerr ("ERROR: from element %s: %s\n", name, err->message);
if (debug != NULL)
g_printerr ("Additional debug info:\n%s\n", debug);
g_error_free (err);
g_free (debug);
g_free (name);
g_main_loop_quit (loop);
break;
}
case GST_MESSAGE_WARNING:{
GError *err = NULL;
gchar *name, *debug = NULL;
name = gst_object_get_path_string (message->src);
gst_message_parse_warning (message, &err, &debug);
g_printerr ("ERROR: from element %s: %s\n", name, err->message);
if (debug != NULL)
g_printerr ("Additional debug info:\n%s\n", debug);
g_error_free (err);
g_free (debug);
g_free (name);
break;
}
case GST_MESSAGE_EOS:
g_print ("\nGot EOS\n");
g_main_loop_quit (loop);
break;
default:
break;
}
return TRUE;
}
static void pad_added_handler (GstElement *src, GstPad *new_pad, gpointer x)
{
GstPad *sink_pad = gst_element_get_static_pad (parse, "sink");
GstPadLinkReturn ret;
GstCaps *new_pad_caps = NULL;
GstStructure *new_pad_struct = NULL;
const gchar *new_pad_type = NULL;
/* If our converter is already linked, we have nothing to do here */
if (gst_pad_is_linked (sink_pad)) {
g_print ("We are already linked. Ignoring.\n");
goto exit;
}
new_pad_caps = gst_pad_get_current_caps (new_pad);
new_pad_struct = gst_caps_get_structure (new_pad_caps, 0);
new_pad_type = gst_structure_get_name (new_pad_struct);
if (!g_str_has_prefix (new_pad_type, "video/x-h264")) {
g_print ("It has type '%s' which is not raw audio. Ignoring.\n", new_pad_type);
goto exit;
}
ret = gst_pad_link (new_pad, sink_pad);
if (GST_PAD_LINK_FAILED (ret)) {
g_print ("Type is '%s' but link failed.\n", new_pad_type);
goto exit;
}
exit:
/* Unreference the new pad's caps, if we got them */
if (new_pad_caps != NULL)
gst_caps_unref (new_pad_caps);
/* Unreference the sink pad */
gst_object_unref (sink_pad);
}
int main()
{
gst_init (NULL, NULL);
pipeline = gst_pipeline_new (NULL);
src = gst_element_factory_make ("filesrc", NULL);
mux = gst_element_factory_make("qtdemux",NULL);
parse = gst_element_factory_make("h264parse",NULL);
dbin = gst_element_factory_make ("nvv4l2decoder", NULL);
conv = gst_element_factory_make ("nvvideoconvert", NULL);
tee = gst_element_factory_make ("tee", NULL);
std::string url = "VD19_peoplewalking.mp4";
if (!pipeline || !src || !dbin || !conv || !tee || !mux || !parse) {
g_error ("Failed to create elements");
return -1;
}
g_object_set (src, "location", url.c_str(), NULL);
gst_bin_add_many (GST_BIN (pipeline), src, dbin, mux, parse, conv, tee, NULL);
if (!gst_element_link_many(src,mux,NULL) || !gst_element_link_many(parse,dbin,conv, tee,NULL) )//|| !gst_element_link_many (conv, tee, NULL))
{
g_error("Failed to link elements");
return -3;
}
g_signal_connect (mux, "pad-added", G_CALLBACK (pad_added_handler), NULL);
//First Branch creation
GstPadTemplate *templ;
templ =
gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (tee),
"src_%u");
GstPad *teepad1 = gst_element_request_pad (tee, templ, NULL, NULL);
queue1 = gst_element_factory_make ("queue", NULL);
videorate1 = gst_element_factory_make("videorate",NULL);
conv1 = gst_element_factory_make ("nvvideoconvert", NULL);
//jenc = gst_element_factory_make ("jpegenc",NULL);
sink1 = gst_element_factory_make ("autovideosink", NULL);
//sink = gst_element_factory_make ("appsink", NULL);
g_object_set (G_OBJECT(videorate1), "rate", 1.0, NULL);
gst_bin_add_many (GST_BIN (pipeline), queue1, videorate1, conv1, sink1, NULL);
if (!gst_element_link_many ( queue1, conv1, videorate1, sink1, NULL))
{
g_error ("Failed to link elements");
}
GstPad *sinkpad = gst_element_get_static_pad ( queue1, "sink");
gst_pad_link ( teepad1, sinkpad);
gst_object_unref (sinkpad);
//First Branch creation ends
//Second Branc
GstPadTemplate *templ2;
templ2 =
gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (tee),
"src_%u");
GstPad *teepad2 = gst_element_request_pad (tee, templ2, NULL, NULL);
queue2 = gst_element_factory_make ("queue", NULL);
videorate2 = gst_element_factory_make("videorate",NULL);
conv2 = gst_element_factory_make ("nvvideoconvert", NULL);
sink2 = gst_element_factory_make ("autovideosink", NULL);
g_object_set (G_OBJECT(videorate2), "rate", 0.5, NULL);
gst_bin_add_many (GST_BIN (pipeline), queue2, videorate2, conv2, sink2, NULL);
if (!gst_element_link_many ( queue2, conv2, videorate2, sink2, NULL))
{
g_error ("Failed to link elements");
}
GstPad *sinkpad2 = gst_element_get_static_pad ( queue2, "sink");
gst_pad_link ( teepad2, sinkpad2);
gst_object_unref (sinkpad2);
//Second brach creation ends
GstBus *bus;
loop = g_main_loop_new (NULL, FALSE);
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bus_add_signal_watch (bus);
g_signal_connect (G_OBJECT (bus), "message", G_CALLBACK (message_cb), NULL);
gst_object_unref (GST_OBJECT (bus));
gst_element_set_state (pipeline, GST_STATE_PLAYING);
g_main_loop_run (loop);
gst_element_set_state (pipeline, GST_STATE_NULL);
g_main_loop_unref (loop);
gst_object_unref (pipeline);
}
Through command line I am able to run multiple branches with different fps please see the command below
gst-launch-1.0 filesrc location=VD19_peoplewalking.mp4 ! qtdemux ! h264parse ! nvv4l2decoder ! tee name=t ! queue ! videorate ! "video/x-raw(ANY),framerate=1/1" ! nvvideoconvert ! autovideosink t. ! videorate ! "video/x-raw(ANY),framerate=30/1" ! nvvideoconvert ! autovideosink
I am able to run C++ the code but the streams are not played as expected. Both streams get stuck in between while running the code.
Am I missing something?

gstreamer 1.0 rtspsrc to rtph264depay cannot link

I am trying to connect to a ubiquiti camera and successfully with the following command with gstreamer.
gst-launch-1.0 --gst-debug=4 rtspsrc location="rtsp://:554/live/ch00_0" ! rtph264depay ! h264parse ! openh264dec ! d3dvideosink
I look at the debug and it says could not link pads rtspsrc to rtph264depay.
Picture
but it gets the stream alright and can see the video. when I put this into a c project it says cannot link source to rtph264parse. I looked around it says to use a dynamic pad with the following code
static void on_pad_added (GstElement *element, GstPad *pad, gpointer data)
{
GstPad *sinkpad;
GstElement *decoder = (GstElement *) data;
/* We can now link this pad with the rtsp-decoder sink pad */
g_print ("Dynamic pad created, linking source/demuxer\n");
sinkpad = gst_element_get_static_pad (decoder, "sink");
gst_pad_link (pad, sinkpad);
gst_object_unref (sinkpad);
}
int main(int argc, char *argv[])
{
/* Initialize GStreamer */
gst_init(&argc,&argv);
/* Build Pipeline */
pipel.pipeline = gst_pipeline_new("My pipeline");
pipel.source = gst_element_factory_make ("rtspsrc","source");
g_object_set (G_OBJECT (pipel.source), "latency",2000,NULL);
pipel.rtppay = gst_element_factory_make( "rtph264depay", "depayl");
pipel.parse = gst_element_factory_make("h264parse","parse");
pipel.filter1 = gst_element_factory_make("capsfilter","filter");
pipel.decodebin = gst_element_factory_make ("openh264dec","decode");
pipel.sink = gst_element_factory_make("d3dvideosink","sink");
g_object_set (G_OBJECT (pipel.sink), "sync",FALSE,NULL);
//create_uri(url,url_size,ip_address,port);
g_object_set(GST_OBJECT(pipel.source),"location","rtsp://<IP>:554/live/ch00_0",NULL);
filtercaps = gst_caps_from_string("application/x-rtp");
g_object_set (G_OBJECT (pipel.filter1), "caps",filtercaps,NULL);
gst_caps_unref(filtercaps);
gst_bin_add_many (GST_BIN (pipel.pipeline),pipel.source
,pipel.rtppay
,pipel.parse
,pipel.decodebin
,pipel.sink
,NULL);
if(!gst_element_link(pipel.source,pipel.rtppay))
printf("\nFailed source to rtppay\n");
if(!gst_element_link_many(pipel.parse,pipel.decodebin,pipel.sink,NULL))
printf("\nFailed to link parse to sink");
g_signal_connect(pipel.rtppay, "pad-added", G_CALLBACK(on_pad_added), pipel.parse);
}
static void cb_new_rtspsrc_pad(GstElement *element,GstPad*pad,gpointer data)
{
gchar *name;
GstCaps * p_caps;
gchar * description;
GstElement *p_rtph264depay;
name = gst_pad_get_name(pad);
g_print("A new pad %s was created\n", name);
// here, you would setup a new pad link for the newly created pad
// sooo, now find that rtph264depay is needed and link them?
p_caps = gst_pad_get_pad_template_caps (pad);
description = gst_caps_to_string(p_caps);
printf("%s\n",p_caps,", ",description,"\n");
g_free(description);
p_rtph264depay = GST_ELEMENT(data);
// try to link the pads then ...
if(!gst_element_link_pads(element, name, p_rtph264depay, "sink"))
{
printf("Failed to link elements 3\n");
}
g_free(name);
}
/* ---------- Main --------------- */
int main(int argc, char *argv[])
{
/* Initialize GStreamer */
gst_init(&argc,&argv);
/* Build Pipeline */
pipel.pipeline = gst_pipeline_new("My pipeline");
creating_pipeline(ip_address,port);
pipel.source = gst_element_factory_make ("rtspsrc","source");
g_object_set (G_OBJECT (pipel.source), "latency",2000,NULL);
pipel.rtppay = gst_element_factory_make( "rtph264depay", "depayl");
pipel.parse = gst_element_factory_make("h264parse","parse");
pipel.filter1 = gst_element_factory_make("capsfilter","filter");
pipel.decodebin = gst_element_factory_make ("openh264dec","decode");
pipel.sink = gst_element_factory_make("d3dvideosink","sink");
g_object_set (G_OBJECT (pipel.sink), "sync",FALSE,NULL);
//create_uri(url,url_size,ip_address,port);
g_object_set(GST_OBJECT(pipel.source),"location","rtsp://<ip>:554/live/ch00_0",NULL);
filtercaps = gst_caps_from_string("application/x-rtp");
g_object_set (G_OBJECT (pipel.filter1), "caps",filtercaps,NULL);
gst_caps_unref(filtercaps);
gst_bin_add_many (GST_BIN (pipel.pipeline),pipel.source
,pipel.rtppay
,NULL);
// listen for newly created pads
g_signal_connect(pipel.source, "pad-added", G_CALLBACK(cb_new_rtspsrc_pad),pipel.rtppay);
gst_bin_add_many (GST_BIN (pipel.pipeline),pipel.parse,NULL);
if(!gst_element_link(pipel.rtppay,pipel.parse))
printf("\nNOPE\n");
gst_bin_add_many (GST_BIN (pipel.pipeline),pipel.decodebin
,pipel.sink
,NULL);
if(!gst_element_link_many(pipel.parse,pipel.decodebin,pipel.sink,NULL))
printf("\nFailed to link parse to sink");
g_signal_connect(pipel.rtppay, "pad-added", G_CALLBACK(on_pad_added), pipel.parse);
}
Works Now!
use cb_new_rtspsrc_pad to add the pad dynamically
add the parse to bin
link up between rtppay and parse
add the necessary elements the rest of the string to make it work.

GstCaps filter issue

trying to create filter using caps:
GMainLoop *loop;
GstElement *pipeline, *source, *demuxer, *decoder, *typefind, *conv, *sink;;
GstBus *bus;
guint bus_watch_id;
loop = g_main_loop_new(NULL, FALSE);
pipeline = gst_pipeline_new ("audio-player");
source = gst_element_factory_make ("filesrc", "file-source");
typefind = gst_element_factory_make ("typefind", "typefinder");
demuxer = gst_element_factory_make ("oggdemux", "ogg-demuxer");
decoder = gst_element_factory_make ("vorbisdec", "vorbis-decoder");
conv = gst_element_factory_make ("audioconvert", "converter");
sink = gst_element_factory_make ("autoaudiosink", "audio-output");
if (!pipeline || !source || !demuxer || !decoder || !conv || !sink) {
return -1;
}
g_signal_connect (typefind, "have-type", G_CALLBACK (cb_typefound), loop);
g_object_set(G_OBJECT(source), "location", name_of_file, NULL);
bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
bus_watch_id = gst_bus_add_watch(bus, bus_call, loop);
gst_object_unref(bus);
gst_bin_add_many(GST_BIN(pipeline), source, typefind, demuxer, decoder, conv, sink, NULL);
GstCaps *my_caps = gst_caps_new_simple ("audio/x-raw","rate", G_TYPE_INT, 384,NULL);
gboolean test=false;
test = gst_element_link_filtered(source,typefind, my_caps);
test = gst_element_link(typefind, demuxer);
test = gst_element_link_many(decoder, conv,sink, NULL);
g_signal_connect(demuxer, "pad-added", G_CALLBACK(on_pad_added), decoder);
......
Debug: gsttypefindelement.c(1169): gst_type_find_element_loop (): /GstPipeline:a
udio-player/GstTypeFindElement:typefinder:
stream stopped, reason not-linked
Var test == 1 after gst_element_link_filtered(source,typefind,
my_caps);
test == 0 after gst_element_link(typefind, demuxer);
test == 1 after gst_element_link_many(decoder, conv,sink, NULL);
If I just change gst_element_link_filtered on gst_element_link all going ok and file plays.
What am I doing wrong?
You seem to also have posted this to the gst-devel mailing list and you have a reply there:
http://gstreamer-devel.966125.n4.nabble.com/GstCaps-filter-issue-td4672796.html
Setting a filter caps of raw audio between the filesrc and the demuxer while you seem to want to play an OGG file is wrong. You should explain better what you want to do in order for us to provide some more refined guidance.

How to use videomixer element for gstreamer?

I want to play two local video file using gstreamer,but I got an error: Segmentation fault It from libgstvideomixer.so.What's wrong with my code? The videomixer element is needed to play two videos.Should I use videobox for that?
gst-launch --no-fault filesrc location=/mnt/upan/source.264 ! queue ! typefind ! ffdec_h264 ! videomixer name=mix ! xvimagesink sync=false filesrc location=/mnt/upan/source.264 ! queue ! typefind ! ffdec_h264! mix.
static void p_gst_init(void)
{
App *app = &s_app;
GError *error = NULL;
GstBus *bus;
GstElement *parse, *decoder, *queue;
GstElement *parse2, *decoder2, *queue2;
gst_init (NULL, NULL);
/* create a mainloop to get messages */
app->loop = g_main_loop_new (NULL, TRUE);
app->playbin = gst_pipeline_new ("pipeline");
app->appsrc = gst_element_factory_make ("filesrc", "disk_source");
g_object_set (G_OBJECT (app->appsrc), "location", "/mnt/upan/test.264", NULL);
queue = gst_element_factory_make ("queue", "queue");
parse = gst_element_factory_make ("typefind", "parse");
decoder = gst_element_factory_make ("ffdec_h264", "decoder");
GstElement *filesrc2;
filesrc2 = gst_element_factory_make ("filesrc", "disk_source2");
g_object_set (G_OBJECT (appsrc2), "location", "/mnt/upan/source.264", NULL);
queue2 = gst_element_factory_make ("queue", "queue2");
parse2 = gst_element_factory_make ("typefind", "parse2");
decoder2 = gst_element_factory_make ("ffdec_h264", "decoder2");
/*
GstElement * videobox;
videobox = gst_element_factory_make("videobox", NULL);
g_object_set (videobox, "alpha", 0, "border-alpha", 0, "bottom", 100, "left", 100, "right", 100, "top", 100, NULL);
*/
GstElement * videomixer;
videomixer = gst_element_factory_make("videomixer","videomixer");
app->xvimagesink = gst_element_factory_make ("xvimagesink", "play_video");
g_object_set (G_OBJECT (app->xvimagesink), "synchronous", FALSE, NULL);
gst_bin_add_many (GST_BIN (app->playbin), app->appsrc, queue, parse, decoder, videomixer, app->xvimagesink, filesrc2, queue2, parse2, decoder2, NULL);
if(gst_element_link_many (app->appsrc, queue, parse, decoder, videomixer, NULL))
{
printf("---------link element success-----------------\n");
}
else
printf("---------link element failed-----------------\n");
gst_element_link_many (filesrc2, queue2, parse2, decoder2, videomixer, NULL);
gst_element_link_many(videomixer, app->xvimagesink, NULL);
bus = gst_pipeline_get_bus (GST_PIPELINE (app->playbin));
gst_bus_add_watch (bus, (GstBusFunc) bus_message, app);
gst_bus_set_sync_handler(bus, (GstBusSyncHandler)create_window, app);
g_signal_connect (app->appsrc, "need-data", G_CALLBACK (feed_data), app);
return ;
}

why is gstreamer caps is blocking pipeline

I am trying a basic pipeline below. If I run the pipeline without the caps function it passes straight through (assuming same I/O format). Once I add the caps the pre-roll starts but the video does not continue through to the sink output.
Am I coding this wrong?
thx
Art
#include <gst/gst.h>
#include <glib.h>
static void
on_pad_added (GstElement *element,
GstPad *pad,
gpointer data)
{
GstPad *sinkpad;
GstElement *decoder = (GstElement *) data;
g_print ("Dynamic pad created, linking out/in \n");
sinkpad = gst_element_get_static_pad (decoder, "sink");
gst_pad_link (pad, sinkpad);
gst_object_unref (sinkpad);
}
int
main (int argc,
char *argv[])
{
GMainLoop *loop;
gboolean link_ok;
GstElement *pipeline, *source, *decoder, *ffcs, *vidsc, *capsfout, *sink;
GstBus *bus;
GstCaps *caps;
/* Initialisation */
gst_init (&argc, &argv);
loop = g_main_loop_new (NULL, FALSE);
/* Create gstreamer elements */
pipeline = gst_pipeline_new ("video-player");
source = gst_element_factory_make ("filesrc", "file-source");
decoder = gst_element_factory_make ("decodebin2", "dec-bin2");
ffcs = gst_element_factory_make ("ffmpegcolorspace", "ffcs");
vidsc = gst_element_factory_make ("videoscale", "vidsc");
capsfout = gst_element_factory_make ("capsfilter", "capsfout");
sink = gst_element_factory_make ("filesink", "vidout");
if (!pipeline || !source || !decoder || !ffcs || !vidsc || !capsfout || !sink) {
g_printerr ("One element could not be created. Exiting.\n");
return -1;
}
/* we set the input/output filename to the source element */
g_object_set (G_OBJECT (source), "location", argv[1], NULL);
g_object_set (G_OBJECT (sink), "location", argv[2], NULL);
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bin_add_many (GST_BIN (pipeline),
source, decoder, ffcs, vidsc, capsfout, sink, NULL);
/* we link the elements together */
gst_element_link (source, decoder);
gst_element_link (decoder, ffcs);
gst_element_link (ffcs, vidsc);
caps = gst_caps_new_simple("video/x-raw-yuv",
"format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),
"width", G_TYPE_INT, 384,
"height", G_TYPE_INT, 216,
"framerate", GST_TYPE_FRACTION, 25, 1,
NULL);
link_ok = gst_element_link_filtered(vidsc,sink,caps);
gst_caps_unref (caps);
if (!link_ok) {
g_warning ("Failed to link vidsc to sink!");
}else{
g_print("seems ok, no error reported?\n");
}
/* Set the pipeline to "playing" state*/
g_print ("Now playing: %s\n", argv[1]);
gst_element_set_state (pipeline, GST_STATE_PLAYING);
/* Iterate */
g_print ("Running...\n");
g_main_loop_run (loop);
/* Out of the main loop, clean up nicely */
g_print ("Returned, stopping playback\n");
gst_element_set_state (pipeline, GST_STATE_NULL);
g_print ("Deleting pipeline\n");
gst_object_unref (GST_OBJECT (pipeline));
return 0;
}
It may be late to answer but you maybe forgot to do the dynamic pad link between some elements and you never call the on_pad_added function. I had the same problem.
Have you tried to add it since then? For example this line to dynamically link two elements instead of the gst_element_link:
g_signal_connect (decoder, "pad-added", G_CALLBACK (on_pad_added), ffcs);
For what reasons do you need the capsfilter? Only constrain the properties you need. E.g. you set a framerate, but don't have a videorate element before the capsfilter. If you don't care about the framerate (e.g. just want to force a size) remove the framerate from the caps you set on capsfilter..