I am getting a segment fault when I try and convert the following, which
works into the C API. gst-launch-1.0 -e -v v4l2src ! 'video/x-raw,width=1280,height=720,framerate=30/1,format=UYVY' ! tee name=t ! queue ! v4l2h264enc extra-controls="controls,h264_profile=4,h264_level=10,video_bitrate=500000;" ! h264parse ! filesink location=foo1.h264 t. ! queue ! v4l2h264enc extra-controls="controls,h264_profile=4,h264_level=10,video_bitrate=2000000;" ! h264parse ! filesink location=foo2.h264 I run the v4l2-ctl commands before executing the gst command. v4l2-ctl --set-edid=file=edid5.txt --fix-edid-checksums v4l2-ctl -v pixelformat=UYVY v4l2-ctl --set-dv-bt-timings query The edid5.txt is. 00,FF,FF,FF,FF,FF,FF,00,52,62,88,88,00,88,88,88,1C,15,01,03,80,00,00,78,0A,EE,91,A3,54,4C,99,26,0F,50,54,00,00,00,01,01,01,01,01,0 1,01,01,01,01,01,01,01,01,01,01,01,1D,00,72,51,D0,1E,20,6E,28,55,00,C4,8E,21,00,00,1E,8C,0A,D0,8A,20,E0,2D,10,10,3E,96,00,13,8E,21 ,00,00,1E,00,00,00,FC,00,54,6F,73,68,69,62,61,2D,48,32,43,0A,20,00,00,00,FD,00,3B,3D,0F,2E,0F,00,0A,20,20,20,20,20,20,01,6D,02,03, 21,41,4D,84,13,03,02,12,11,01,20,21,22,3C,3D,3E,23,09,07,07,66,03,0C,00,30,00,80,E3,00,7F,8C,8C,0A,D0,8A,20,E0,2D,10,10,3E,96,00,C 4,8E,21,00,00,18,8C,0A,D0,8A,20,E0,2D,10,10,3E,96,00,13,8E,21,00,00,18,8C,0A,A0,14,51,F0,16,00,26,7C,43,00,13,8E,21,00,00,98,00,00 ,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,BE When I run this code it crashes with a segment fault on the g_object_set function. #include <gst/gst.h> #include <stdio.h> // gst-launch-1.0 -e -v v4l2src ! 'video/x-raw,width=1280,height=720,framerate=30/1,format=UYVY' ! tee name=t ! queue ! v4l2h264enc extra-controls="controls,h264_profile=4,h264_level=10,video_bitrate=500000;" ! h264parse ! filesink location=foo1.h264 t. ! queue ! v4l2h264enc extra-controls="controls,h264_profile=4,h264_level=10,video_bitrate=2000000;" ! h264parse ! filesink location=foo2.h264 typedef struct _App { GstElement *pipeline; GstElement *appsrc; GMainLoop *loop; guint sourceid; GTimer *timer; } App; App app; gint main(gint argc, gchar *argv[]) { GstElement *src, *split, *enc1, *enc2, *f1, *f2, *h1, *h2, *q1, *q2; GstCaps *filtercaps; GstCaps *enccaps; gst_init(&argc, &argv); app.loop = g_main_loop_new(NULL, FALSE); app.pipeline = gst_pipeline_new("my-pipeline"); src = gst_element_factory_make("v4l2src", "src"); split = gst_element_factory_make("tee", "split"); h1 = gst_element_factory_make("h264parse", "h1"); h2 = gst_element_factory_make("h264parse", "h2"); q1 = gst_element_factory_make("queue", "q1"); q2 = gst_element_factory_make("queue", "q2"); enc1 = gst_element_factory_make("v4l2h264enc", "enc1"); enc2 = gst_element_factory_make("v4l2h264enc", "enc2"); f1 = gst_element_factory_make("filesink", "f1"); f2 = gst_element_factory_make("filesink", "f2"); if (!app.pipeline || !src || !split || !enc1 || !enc2 || !f1 || !f2 || !h1 || !h2 || !q1 || !q2) { g_error ("Could not create elements\npip=%p\nsrc=%p\nsplit=%p\nenc1=%p\nenc2=%p\nf1=%p\nf2=%p\nh1=%p\nh2=%p\nq1=%p\nq2=%p", app.pipeline, src, split, enc1, enc2, f1, f2, h1, h2, q1, q2); return -1; } g_object_set(f1, "location", "foo1.h264", NULL); g_object_set(f2, "location", "foo2.h264", NULL); fprintf(stderr, "Here 1\n"); // g_object_set(enc1, "extra-controls", "controls,h264_profile=4,h264_level=10,video_bitrate=500000;", NULL); enccaps = gst_caps_new_simple ("controls", "h264_profile", G_TYPE_INT, 4, "h264_level", G_TYPE_INT, 10, "video_bitrate", G_TYPE_INT, 500000, NULL); g_object_set (G_OBJECT (enc1), "extra-controls", enccaps, NULL); fprintf(stderr, "Here 2\n"); g_object_set(enc2, "extra-controls", "controls,h264_profile=4,h264_level=10,video_bitrate=2000000;", NULL); fprintf(stderr, "Here 3\n"); gst_bin_add_many(GST_BIN(app.pipeline), src, split, q1, enc1, h1, f1, q2, enc2, h2, f2, NULL); if (!gst_element_link_many(src, split, NULL) || !gst_element_link_many(split, q1, enc1, h1, f1, NULL) || !gst_element_link_many(split, q2, enc2, h2, f2, NULL)) { g_error("Failed to link elements ..."); return -2; } filtercaps = gst_caps_new_simple ("video/x-raw", "format", G_TYPE_STRING, "UYVY", "width", G_TYPE_INT, 1280, "height", G_TYPE_INT, 720, "framerate", GST_TYPE_FRACTION, 30, 1, NULL); g_object_set (G_OBJECT (src), "caps", filtercaps, NULL); gst_caps_unref (filtercaps); gst_element_set_state (app.pipeline, GST_STATE_PLAYING); if (gst_element_get_state (app.pipeline, NULL, NULL, -1) == GST_STATE_CHANGE_FAILURE) { g_error ("Failed to go into PLAYING state"); } g_print ("Running ...\n"); g_main_loop_run (app.loop); /* exit */ gst_element_set_state (app.pipeline, GST_STATE_NULL); gst_object_unref (app.pipeline); return 0; } The 'Here 1' prints then it dies, can any one help me to understand why? Either method of calling g_object_set fails the same way. Thanks -- This email has been checked for viruses by AVG. https://www.avg.com _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
On 24/8/20 5:12 am, Kelly Wiles wrote:
> I am getting a segment fault when I try and convert the following, > which works into the C API. > > gst-launch-1.0 -e -v v4l2src ! > 'video/x-raw,width=1280,height=720,framerate=30/1,format=UYVY' ! tee > name=t ! queue ! v4l2h264enc > extra-controls="controls,h264_profile=4,h264_level=10,video_bitrate=500000;" > ! h264parse ! filesink location=foo1.h264 t. ! queue ! v4l2h264enc > extra-controls="controls,h264_profile=4,h264_level=10,video_bitrate=2000000;" > ! h264parse ! filesink location=foo2.h264 > > I run the v4l2-ctl commands before executing the gst command. > > v4l2-ctl --set-edid=file=edid5.txt --fix-edid-checksums > v4l2-ctl -v pixelformat=UYVY > v4l2-ctl --set-dv-bt-timings query > > The edid5.txt is. > > 00,FF,FF,FF,FF,FF,FF,00,52,62,88,88,00,88,88,88,1C,15,01,03,80,00,00,78,0A,EE,91,A3,54,4C,99,26,0F,50,54,00,00,00,01,01,01,01,01,0 > > 1,01,01,01,01,01,01,01,01,01,01,01,1D,00,72,51,D0,1E,20,6E,28,55,00,C4,8E,21,00,00,1E,8C,0A,D0,8A,20,E0,2D,10,10,3E,96,00,13,8E,21 > > ,00,00,1E,00,00,00,FC,00,54,6F,73,68,69,62,61,2D,48,32,43,0A,20,00,00,00,FD,00,3B,3D,0F,2E,0F,00,0A,20,20,20,20,20,20,01,6D,02,03, > > 21,41,4D,84,13,03,02,12,11,01,20,21,22,3C,3D,3E,23,09,07,07,66,03,0C,00,30,00,80,E3,00,7F,8C,8C,0A,D0,8A,20,E0,2D,10,10,3E,96,00,C > > 4,8E,21,00,00,18,8C,0A,D0,8A,20,E0,2D,10,10,3E,96,00,13,8E,21,00,00,18,8C,0A,A0,14,51,F0,16,00,26,7C,43,00,13,8E,21,00,00,98,00,00 > > ,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,BE > > > When I run this code it crashes with a segment fault on the > g_object_set function. > > #include <gst/gst.h> > #include <stdio.h> > > // gst-launch-1.0 -e -v v4l2src ! > 'video/x-raw,width=1280,height=720,framerate=30/1,format=UYVY' ! tee > name=t ! queue ! v4l2h264enc > extra-controls="controls,h264_profile=4,h264_level=10,video_bitrate=500000;" > ! h264parse ! filesink location=foo1.h264 t. ! queue ! v4l2h264enc > extra-controls="controls,h264_profile=4,h264_level=10,video_bitrate=2000000;" > ! h264parse ! filesink location=foo2.h264 > > typedef struct _App { > GstElement *pipeline; > GstElement *appsrc; > > GMainLoop *loop; > guint sourceid; > > GTimer *timer; > } App; > > App app; > > gint main(gint argc, gchar *argv[]) { > > GstElement *src, *split, *enc1, *enc2, *f1, *f2, *h1, *h2, > *q1, *q2; > GstCaps *filtercaps; > GstCaps *enccaps; > > gst_init(&argc, &argv); > > app.loop = g_main_loop_new(NULL, FALSE); > > app.pipeline = gst_pipeline_new("my-pipeline"); > > src = gst_element_factory_make("v4l2src", "src"); > split = gst_element_factory_make("tee", "split"); > h1 = gst_element_factory_make("h264parse", "h1"); > h2 = gst_element_factory_make("h264parse", "h2"); > q1 = gst_element_factory_make("queue", "q1"); > q2 = gst_element_factory_make("queue", "q2"); > enc1 = gst_element_factory_make("v4l2h264enc", "enc1"); > enc2 = gst_element_factory_make("v4l2h264enc", "enc2"); > f1 = gst_element_factory_make("filesink", "f1"); > f2 = gst_element_factory_make("filesink", "f2"); > > if (!app.pipeline || !src || !split || !enc1 || !enc2 || !f1 > || !f2 || !h1 || !h2 || !q1 || !q2) { > g_error ("Could not create > elements\npip=%p\nsrc=%p\nsplit=%p\nenc1=%p\nenc2=%p\nf1=%p\nf2=%p\nh1=%p\nh2=%p\nq1=%p\nq2=%p", > app.pipeline, src, split, enc1, enc2, > f1, f2, h1, h2, q1, q2); > return -1; > } > > g_object_set(f1, "location", "foo1.h264", NULL); > g_object_set(f2, "location", "foo2.h264", NULL); > > fprintf(stderr, "Here 1\n"); > // g_object_set(enc1, "extra-controls", > "controls,h264_profile=4,h264_level=10,video_bitrate=500000;", NULL); > enccaps = gst_caps_new_simple ("controls", > "h264_profile", G_TYPE_INT, 4, > "h264_level", G_TYPE_INT, 10, > "video_bitrate", G_TYPE_INT, 500000, > NULL); > g_object_set (G_OBJECT (enc1), "extra-controls", enccaps, NULL); extra-controls requires a GstStructure, not a GstCaps. Replace gst_caps_new_simple() with gst_structure_new() (and types). > fprintf(stderr, "Here 2\n"); > g_object_set(enc2, "extra-controls", > "controls,h264_profile=4,h264_level=10,video_bitrate=2000000;", NULL); > fprintf(stderr, "Here 3\n"); > > gst_bin_add_many(GST_BIN(app.pipeline), src, split, q1, enc1, > h1, f1, q2, enc2, h2, f2, NULL); > > if (!gst_element_link_many(src, split, NULL) > || !gst_element_link_many(split, q1, enc1, h1, f1, NULL) > || !gst_element_link_many(split, q2, enc2, h2, f2, > NULL)) { > g_error("Failed to link elements ..."); > return -2; > } > > filtercaps = gst_caps_new_simple ("video/x-raw", > "format", G_TYPE_STRING, "UYVY", > "width", G_TYPE_INT, 1280, > "height", G_TYPE_INT, 720, > "framerate", GST_TYPE_FRACTION, 30, 1, > NULL); > g_object_set (G_OBJECT (src), "caps", filtercaps, NULL); > gst_caps_unref (filtercaps); > > gst_element_set_state (app.pipeline, GST_STATE_PLAYING); > > if (gst_element_get_state (app.pipeline, NULL, NULL, -1) == > GST_STATE_CHANGE_FAILURE) { > g_error ("Failed to go into PLAYING state"); > } > > g_print ("Running ...\n"); > g_main_loop_run (app.loop); > > /* exit */ > gst_element_set_state (app.pipeline, GST_STATE_NULL); > gst_object_unref (app.pipeline); > > return 0; > } > > The 'Here 1' prints then it dies, can any one help me to understand why? > > Either method of calling g_object_set fails the same way. > > Thanks > > > _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel signature.asc (499 bytes) Download Attachment |
Ok, so i fixed the crash and now getting error
Maybe be due to not enough memory or failing driver The code: #include <gst/gst.h> #include <stdio.h> // gst-launch-1.0 -e -v v4l2src ! 'video/x-raw,width=1280,height=720,framerate=30/1,format=UYVY' ! tee name=t ! // queue ! v4l2h264enc extra-controls="controls,h264_profile=4,h264_level=10,video_bitrate=500000;" ! h264parse ! // filesink location=foo1.h264 t. ! queue ! // v4l2h264enc extra-controls="controls,h264_profile=4,h264_level=10,video_bitrate=2000000;" ! h264parse ! // filesink location=foo2.h264 typedef struct _App { GstElement *pipeline; GstElement *appsrc; GMainLoop *loop; guint sourceid; GTimer *timer; } App; App app; gint main(gint argc, gchar *argv[]) { GstBus *bus; GstMessage *msg; GstElement *src, *tee, *enc1, *enc2, *f1, *f2, *h1, *h2, *q1, *q2; GstStructure *srcOpts; GstStructure *encOpts; gst_init(&argc, &argv); app.loop = g_main_loop_new(NULL, FALSE); app.pipeline = gst_pipeline_new("my-pipeline"); src = gst_element_factory_make("v4l2src", "src"); tee = gst_element_factory_make("tee", "tee"); h1 = gst_element_factory_make("h264parse", "h1"); h2 = gst_element_factory_make("h264parse", "h2"); q1 = gst_element_factory_make("queue", "q1"); q2 = gst_element_factory_make("queue", "q2"); enc1 = gst_element_factory_make("v4l2h264enc", "enc1"); enc2 = gst_element_factory_make("v4l2h264enc", "enc2"); f1 = gst_element_factory_make("filesink", "f1"); f2 = gst_element_factory_make("filesink", "f2"); if (!app.pipeline || !src || !tee || !enc1 || !enc2 || !f1 || !f2 || !h1 || !h2 || !q1 || !q2) { g_error ("Could not create elements\npip=%p\nsrc=%p\ntee=%p\nenc1=%p\nenc2=%p\nf1=%p\nf2=%p\nh1=%p\nh2=%p\nq1=%p\nq2=%p", app.pipeline, src, tee, enc1, enc2, f1, f2, h1, h2, q1, q2); return -1; } g_object_set(f1, "location", "foo1.h264", NULL); g_object_set(f2, "location", "foo2.h264", NULL); encOpts = gst_structure_new ("controls", "h264_profile", G_TYPE_INT, 4, "h264_level", G_TYPE_INT, 10, "video_bitrate", G_TYPE_INT, 500000, NULL); g_object_set (G_OBJECT (enc1), "extra-controls", encOpts, NULL); encOpts = gst_structure_new ("controls", "h264_profile", G_TYPE_INT, 4, "h264_level", G_TYPE_INT, 10, "video_bitrate", G_TYPE_INT, 200000, NULL); g_object_set (G_OBJECT (enc2), "extra-controls", encOpts, NULL); gst_bin_add_many(GST_BIN(app.pipeline), src, tee, q1, enc1, h1, f1, q2, enc2, h2, f2, NULL); if (!gst_element_link_many(src, tee, NULL) || !gst_element_link_many(tee, q1, enc1, h1, f1, NULL) || !gst_element_link_many(tee, q2, enc2, h2, f2, NULL)) { g_error("Failed to link elements ..."); return -2; } srcOpts = gst_structure_new ("video/x-raw", "format", G_TYPE_STRING, "UYVY", "width", G_TYPE_INT, 1280, "height", G_TYPE_INT, 720, "framerate", GST_TYPE_FRACTION, 30, 1, NULL); g_object_set (G_OBJECT (src), "extra-controls", srcOpts, NULL); // GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(app.pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "pipeline"); gst_element_set_state (app.pipeline, GST_STATE_PLAYING); #if(0) if (gst_element_get_state (app.pipeline, NULL, NULL, -1) == GST_STATE_CHANGE_FAILURE) { g_error ("Failed to go into PLAYING state"); } g_print ("Running ...\n"); g_main_loop_run (app.loop); #endif bus = gst_element_get_bus (app.pipeline); msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS); /* exit */ /* Free resources */ if (msg != NULL) { GError *err; gchar *debug_info; switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_ERROR: gst_message_parse_error (msg, &err, &debug_info); g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message); g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none"); g_clear_error (&err); g_free (debug_info); break; case GST_MESSAGE_EOS: g_print ("End-Of-Stream reached.\n"); break; default: /* We should not reach here because we only asked for ERRORs and EOS */ g_printerr ("Unexpected message received.\n"); break; } gst_message_unref (msg); } gst_object_unref (bus); gst_element_set_state (app.pipeline, GST_STATE_NULL); gst_object_unref (app.pipeline); return 0; } This works through the command line so I guess i am missing something else in the code. Just do not understand why it works as a command line but not as an API. I enabled the pipeline graph dot files for both the gst-launch-1.0 and my program and they appear to be alike, see attached of my program graph. The graph was created by un-commenting the GST_DEBUG_BIN_TO_DOT_FILE line. I have read most of the tutorials but feel lost if i try anything new that the docs did not cover. Thanks -- This email has been checked for viruses by AVG. https://www.avg.com _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel out.pdf (47K) Download Attachment |
Hi
I don't think you can just use the 'tee' and expect it to work without a bit more work. It has src pads created as when you need them so you'd have to hook into pad_created and link up your src and encoder from there. Are you not getting errors from the calls to gst_element_link_many? ________________________________________ From: gstreamer-devel <[hidden email]> on behalf of Kelly Wiles <[hidden email]> Sent: 24 August 2020 15:03 To: Matthew Waters; Discussion of the development of and with GStreamer Subject: Re: Trying translate working gst-launch command to the API Ok, so i fixed the crash and now getting error Maybe be due to not enough memory or failing driver The code: #include <gst/gst.h> #include <stdio.h> // gst-launch-1.0 -e -v v4l2src ! 'video/x-raw,width=1280,height=720,framerate=30/1,format=UYVY' ! tee name=t ! // queue ! v4l2h264enc extra-controls="controls,h264_profile=4,h264_level=10,video_bitrate=500000;" ! h264parse ! // filesink location=foo1.h264 t. ! queue ! // v4l2h264enc extra-controls="controls,h264_profile=4,h264_level=10,video_bitrate=2000000;" ! h264parse ! // filesink location=foo2.h264 typedef struct _App { GstElement *pipeline; GstElement *appsrc; GMainLoop *loop; guint sourceid; GTimer *timer; } App; App app; gint main(gint argc, gchar *argv[]) { GstBus *bus; GstMessage *msg; GstElement *src, *tee, *enc1, *enc2, *f1, *f2, *h1, *h2, *q1, *q2; GstStructure *srcOpts; GstStructure *encOpts; gst_init(&argc, &argv); app.loop = g_main_loop_new(NULL, FALSE); app.pipeline = gst_pipeline_new("my-pipeline"); src = gst_element_factory_make("v4l2src", "src"); tee = gst_element_factory_make("tee", "tee"); h1 = gst_element_factory_make("h264parse", "h1"); h2 = gst_element_factory_make("h264parse", "h2"); q1 = gst_element_factory_make("queue", "q1"); q2 = gst_element_factory_make("queue", "q2"); enc1 = gst_element_factory_make("v4l2h264enc", "enc1"); enc2 = gst_element_factory_make("v4l2h264enc", "enc2"); f1 = gst_element_factory_make("filesink", "f1"); f2 = gst_element_factory_make("filesink", "f2"); if (!app.pipeline || !src || !tee || !enc1 || !enc2 || !f1 || !f2 || !h1 || !h2 || !q1 || !q2) { g_error ("Could not create elements\npip=%p\nsrc=%p\ntee=%p\nenc1=%p\nenc2=%p\nf1=%p\nf2=%p\nh1=%p\nh2=%p\nq1=%p\nq2=%p", app.pipeline, src, tee, enc1, enc2, f1, f2, h1, h2, q1, q2); return -1; } g_object_set(f1, "location", "foo1.h264", NULL); g_object_set(f2, "location", "foo2.h264", NULL); encOpts = gst_structure_new ("controls", "h264_profile", G_TYPE_INT, 4, "h264_level", G_TYPE_INT, 10, "video_bitrate", G_TYPE_INT, 500000, NULL); g_object_set (G_OBJECT (enc1), "extra-controls", encOpts, NULL); encOpts = gst_structure_new ("controls", "h264_profile", G_TYPE_INT, 4, "h264_level", G_TYPE_INT, 10, "video_bitrate", G_TYPE_INT, 200000, NULL); g_object_set (G_OBJECT (enc2), "extra-controls", encOpts, NULL); gst_bin_add_many(GST_BIN(app.pipeline), src, tee, q1, enc1, h1, f1, q2, enc2, h2, f2, NULL); if (!gst_element_link_many(src, tee, NULL) || !gst_element_link_many(tee, q1, enc1, h1, f1, NULL) || !gst_element_link_many(tee, q2, enc2, h2, f2, NULL)) { g_error("Failed to link elements ..."); return -2; } srcOpts = gst_structure_new ("video/x-raw", "format", G_TYPE_STRING, "UYVY", "width", G_TYPE_INT, 1280, "height", G_TYPE_INT, 720, "framerate", GST_TYPE_FRACTION, 30, 1, NULL); g_object_set (G_OBJECT (src), "extra-controls", srcOpts, NULL); // GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(app.pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "pipeline"); gst_element_set_state (app.pipeline, GST_STATE_PLAYING); #if(0) if (gst_element_get_state (app.pipeline, NULL, NULL, -1) == GST_STATE_CHANGE_FAILURE) { g_error ("Failed to go into PLAYING state"); } g_print ("Running ...\n"); g_main_loop_run (app.loop); #endif bus = gst_element_get_bus (app.pipeline); msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS); /* exit */ /* Free resources */ if (msg != NULL) { GError *err; gchar *debug_info; switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_ERROR: gst_message_parse_error (msg, &err, &debug_info); g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message); g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none"); g_clear_error (&err); g_free (debug_info); break; case GST_MESSAGE_EOS: g_print ("End-Of-Stream reached.\n"); break; default: /* We should not reach here because we only asked for ERRORs and EOS */ g_printerr ("Unexpected message received.\n"); break; } gst_message_unref (msg); } gst_object_unref (bus); gst_element_set_state (app.pipeline, GST_STATE_NULL); gst_object_unref (app.pipeline); return 0; } This works through the command line so I guess i am missing something else in the code. Just do not understand why it works as a command line but not as an API. I enabled the pipeline graph dot files for both the gst-launch-1.0 and my program and they appear to be alike, see attached of my program graph. The graph was created by un-commenting the GST_DEBUG_BIN_TO_DOT_FILE line. I have read most of the tutorials but feel lost if i try anything new that the docs did not cover. Thanks -- This email has been checked for viruses by AVG. https://www.avg.com _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Hi
The code if (!gst_element_link_many(src, tee, NULL) || !gst_element_link_many(tee, q1, enc1, h1, f1, NULL) || !gst_element_link_many(tee, q2, enc2, h2, f2, NULL)) { g_error("Failed to link elements ..."); return -2; } Gives no errors and I think that the code above was linking the tee to src and other elements. I may not be understanding what you are talking about, sorry. Thanks On 8/24/2020 11:46 AM, Gary Metalle wrote: > Hi > > I don't think you can just use the 'tee' and expect it to work without a bit more work. It has src pads created as when you need them so you'd have to hook into pad_created and link up your src and encoder from there. > > Are you not getting errors from the calls to gst_element_link_many? > ________________________________________ > From: gstreamer-devel <[hidden email]> on behalf of Kelly Wiles <[hidden email]> > Sent: 24 August 2020 15:03 > To: Matthew Waters; Discussion of the development of and with GStreamer > Subject: Re: Trying translate working gst-launch command to the API > > Ok, so i fixed the crash and now getting error > > Maybe be due to not enough memory or failing driver > > The code: > > #include <gst/gst.h> > #include <stdio.h> > > // gst-launch-1.0 -e -v v4l2src ! > 'video/x-raw,width=1280,height=720,framerate=30/1,format=UYVY' ! tee > name=t ! > // queue ! v4l2h264enc > extra-controls="controls,h264_profile=4,h264_level=10,video_bitrate=500000;" > ! h264parse ! > // filesink location=foo1.h264 t. ! queue ! > // v4l2h264enc > extra-controls="controls,h264_profile=4,h264_level=10,video_bitrate=2000000;" > ! h264parse ! > // filesink location=foo2.h264 > > typedef struct _App { > GstElement *pipeline; > GstElement *appsrc; > > GMainLoop *loop; > guint sourceid; > > GTimer *timer; > } App; > > App app; > > gint main(gint argc, gchar *argv[]) { > > GstBus *bus; > GstMessage *msg; > GstElement *src, *tee, *enc1, *enc2, *f1, *f2, *h1, *h2, *q1, *q2; > GstStructure *srcOpts; > GstStructure *encOpts; > > gst_init(&argc, &argv); > > app.loop = g_main_loop_new(NULL, FALSE); > > app.pipeline = gst_pipeline_new("my-pipeline"); > > src = gst_element_factory_make("v4l2src", "src"); > tee = gst_element_factory_make("tee", "tee"); > h1 = gst_element_factory_make("h264parse", "h1"); > h2 = gst_element_factory_make("h264parse", "h2"); > q1 = gst_element_factory_make("queue", "q1"); > q2 = gst_element_factory_make("queue", "q2"); > enc1 = gst_element_factory_make("v4l2h264enc", "enc1"); > enc2 = gst_element_factory_make("v4l2h264enc", "enc2"); > f1 = gst_element_factory_make("filesink", "f1"); > f2 = gst_element_factory_make("filesink", "f2"); > > if (!app.pipeline || !src || !tee || !enc1 || !enc2 || !f1 || > !f2 || !h1 || !h2 || !q1 || !q2) { > g_error ("Could not create > elements\npip=%p\nsrc=%p\ntee=%p\nenc1=%p\nenc2=%p\nf1=%p\nf2=%p\nh1=%p\nh2=%p\nq1=%p\nq2=%p", > app.pipeline, src, tee, enc1, enc2, f1, > f2, h1, h2, q1, q2); > return -1; > } > > g_object_set(f1, "location", "foo1.h264", NULL); > g_object_set(f2, "location", "foo2.h264", NULL); > > encOpts = gst_structure_new ("controls", > "h264_profile", G_TYPE_INT, 4, > "h264_level", G_TYPE_INT, 10, > "video_bitrate", G_TYPE_INT, 500000, > NULL); > g_object_set (G_OBJECT (enc1), "extra-controls", encOpts, NULL); > > encOpts = gst_structure_new ("controls", > "h264_profile", G_TYPE_INT, 4, > "h264_level", G_TYPE_INT, 10, > "video_bitrate", G_TYPE_INT, 200000, > NULL); > g_object_set (G_OBJECT (enc2), "extra-controls", encOpts, NULL); > > gst_bin_add_many(GST_BIN(app.pipeline), src, tee, q1, enc1, h1, > f1, q2, enc2, h2, f2, NULL); > > if (!gst_element_link_many(src, tee, NULL) > || !gst_element_link_many(tee, q1, enc1, h1, f1, NULL) > || !gst_element_link_many(tee, q2, enc2, h2, f2, NULL)) { > g_error("Failed to link elements ..."); > return -2; > } > > srcOpts = gst_structure_new ("video/x-raw", > "format", G_TYPE_STRING, "UYVY", > "width", G_TYPE_INT, 1280, > "height", G_TYPE_INT, 720, > "framerate", GST_TYPE_FRACTION, 30, 1, > NULL); > g_object_set (G_OBJECT (src), "extra-controls", srcOpts, NULL); > > // GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(app.pipeline), > GST_DEBUG_GRAPH_SHOW_ALL, "pipeline"); > > gst_element_set_state (app.pipeline, GST_STATE_PLAYING); > > #if(0) > if (gst_element_get_state (app.pipeline, NULL, NULL, -1) == > GST_STATE_CHANGE_FAILURE) { > g_error ("Failed to go into PLAYING state"); > } > > g_print ("Running ...\n"); > g_main_loop_run (app.loop); > #endif > > bus = gst_element_get_bus (app.pipeline); > msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, > GST_MESSAGE_ERROR | GST_MESSAGE_EOS); > > /* exit */ > /* Free resources */ > if (msg != NULL) { > GError *err; > gchar *debug_info; > > switch (GST_MESSAGE_TYPE (msg)) { > case GST_MESSAGE_ERROR: > gst_message_parse_error (msg, &err, &debug_info); > g_printerr ("Error received from element %s: > %s\n", GST_OBJECT_NAME (msg->src), err->message); > g_printerr ("Debugging information: %s\n", > debug_info ? debug_info : "none"); > g_clear_error (&err); > g_free (debug_info); > break; > case GST_MESSAGE_EOS: > g_print ("End-Of-Stream reached.\n"); > break; > default: > /* We should not reach here because we only > asked for ERRORs and EOS */ > g_printerr ("Unexpected message received.\n"); > break; > } > gst_message_unref (msg); > } > gst_object_unref (bus); > gst_element_set_state (app.pipeline, GST_STATE_NULL); > gst_object_unref (app.pipeline); > > return 0; > } > > This works through the command line so I guess i am missing something > else in the code. Just do not understand why it works as a command line > but not as an API. > > I enabled the pipeline graph dot files for both the gst-launch-1.0 and > my program and they appear to be alike, see attached of my program graph. > > The graph was created by un-commenting the GST_DEBUG_BIN_TO_DOT_FILE line. > > I have read most of the tutorials but feel lost if i try anything new > that the docs did not cover. > > Thanks > > > > > -- > This email has been checked for viruses by AVG. > https://www.avg.com > _______________________________________________ > gstreamer-devel mailing list > [hidden email] > https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel -- This email has been checked for viruses by AVG. https://www.avg.com _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Hey Guys,
I am trying to do the same with the incoming stream received from webrtc bin. But adding the caps filter is messing my stream. I cannot even run it on command line to debug. Kelly, can you please answer the question as to why call back does not work when caps is introduced? here is the link : http://gstreamer-devel.966125.n4.nabble.com/Waiting-for-the-reply-Unable-to-get-the-sample-from-Appsink-using-C-td4695139.html -- Sent from: http://gstreamer-devel.966125.n4.nabble.com/ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Sadly I just started playing with this GStreamer stuff a few days ago,
do not think I am qualified to answer your question. On 8/24/2020 3:18 PM, RK29 wrote: > Hey Guys, > I am trying to do the same with the incoming stream received from webrtc > bin. > But adding the caps filter is messing my stream. I cannot even run it on > command line to debug. Kelly, can you please answer the question as to why > call back does not work when caps is introduced? > here is the link : > http://gstreamer-devel.966125.n4.nabble.com/Waiting-for-the-reply-Unable-to-get-the-sample-from-Appsink-using-C-td4695139.html > > > > -- > Sent from: http://gstreamer-devel.966125.n4.nabble.com/ > _______________________________________________ > gstreamer-devel mailing list > [hidden email] > https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel -- This email has been checked for viruses by AVG. https://www.avg.com _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
In reply to this post by Kelly Wiles
Hi
Sorry I think it's ok as it is with the tee because gst_element_link_many can request the src pads for you. I had been reading the following article recently and remembered that they manually linked up the src pads for the tee so that they could be free'd up nicely at the end: https://gstreamer.freedesktop.org/documentation/tutorials/basic/multithreading-and-pad-availability.html?gi-language=c Maybe that example will have some other hints that are useful to you as the beginning of the pipeline is very similar to yours. Also be prepared to trawl through a debug log after you've set "export GST_DEBUG=4" or "export GST_DEBUG=6" because it always has clues, just that it's difficult to find what you need. Lately I've found it easier to start at the end of the log and go backwards. ________________________________________ From: gstreamer-devel <[hidden email]> on behalf of Kelly Wiles <[hidden email]> Sent: 24 August 2020 20:31 To: [hidden email] Subject: Re: Trying translate working gst-launch command to the API Hi The code if (!gst_element_link_many(src, tee, NULL) || !gst_element_link_many(tee, q1, enc1, h1, f1, NULL) || !gst_element_link_many(tee, q2, enc2, h2, f2, NULL)) { g_error("Failed to link elements ..."); return -2; } Gives no errors and I think that the code above was linking the tee to src and other elements. I may not be understanding what you are talking about, sorry. Thanks On 8/24/2020 11:46 AM, Gary Metalle wrote: > Hi > > I don't think you can just use the 'tee' and expect it to work without a bit more work. It has src pads created as when you need them so you'd have to hook into pad_created and link up your src and encoder from there. > > Are you not getting errors from the calls to gst_element_link_many? > ________________________________________ > From: gstreamer-devel <[hidden email]> on behalf of Kelly Wiles <[hidden email]> > Sent: 24 August 2020 15:03 > To: Matthew Waters; Discussion of the development of and with GStreamer > Subject: Re: Trying translate working gst-launch command to the API > > Ok, so i fixed the crash and now getting error > > Maybe be due to not enough memory or failing driver > > The code: > > #include <gst/gst.h> > #include <stdio.h> > > // gst-launch-1.0 -e -v v4l2src ! > 'video/x-raw,width=1280,height=720,framerate=30/1,format=UYVY' ! tee > name=t ! > // queue ! v4l2h264enc > extra-controls="controls,h264_profile=4,h264_level=10,video_bitrate=500000;" > ! h264parse ! > // filesink location=foo1.h264 t. ! queue ! > // v4l2h264enc > extra-controls="controls,h264_profile=4,h264_level=10,video_bitrate=2000000;" > ! h264parse ! > // filesink location=foo2.h264 > > typedef struct _App { > GstElement *pipeline; > GstElement *appsrc; > > GMainLoop *loop; > guint sourceid; > > GTimer *timer; > } App; > > App app; > > gint main(gint argc, gchar *argv[]) { > > GstBus *bus; > GstMessage *msg; > GstElement *src, *tee, *enc1, *enc2, *f1, *f2, *h1, *h2, *q1, *q2; > GstStructure *srcOpts; > GstStructure *encOpts; > > gst_init(&argc, &argv); > > app.loop = g_main_loop_new(NULL, FALSE); > > app.pipeline = gst_pipeline_new("my-pipeline"); > > src = gst_element_factory_make("v4l2src", "src"); > tee = gst_element_factory_make("tee", "tee"); > h1 = gst_element_factory_make("h264parse", "h1"); > h2 = gst_element_factory_make("h264parse", "h2"); > q1 = gst_element_factory_make("queue", "q1"); > q2 = gst_element_factory_make("queue", "q2"); > enc1 = gst_element_factory_make("v4l2h264enc", "enc1"); > enc2 = gst_element_factory_make("v4l2h264enc", "enc2"); > f1 = gst_element_factory_make("filesink", "f1"); > f2 = gst_element_factory_make("filesink", "f2"); > > if (!app.pipeline || !src || !tee || !enc1 || !enc2 || !f1 || > !f2 || !h1 || !h2 || !q1 || !q2) { > g_error ("Could not create > elements\npip=%p\nsrc=%p\ntee=%p\nenc1=%p\nenc2=%p\nf1=%p\nf2=%p\nh1=%p\nh2=%p\nq1=%p\nq2=%p", > app.pipeline, src, tee, enc1, enc2, f1, > f2, h1, h2, q1, q2); > return -1; > } > > g_object_set(f1, "location", "foo1.h264", NULL); > g_object_set(f2, "location", "foo2.h264", NULL); > > encOpts = gst_structure_new ("controls", > "h264_profile", G_TYPE_INT, 4, > "h264_level", G_TYPE_INT, 10, > "video_bitrate", G_TYPE_INT, 500000, > NULL); > g_object_set (G_OBJECT (enc1), "extra-controls", encOpts, NULL); > > encOpts = gst_structure_new ("controls", > "h264_profile", G_TYPE_INT, 4, > "h264_level", G_TYPE_INT, 10, > "video_bitrate", G_TYPE_INT, 200000, > NULL); > g_object_set (G_OBJECT (enc2), "extra-controls", encOpts, NULL); > > gst_bin_add_many(GST_BIN(app.pipeline), src, tee, q1, enc1, h1, > f1, q2, enc2, h2, f2, NULL); > > if (!gst_element_link_many(src, tee, NULL) > || !gst_element_link_many(tee, q1, enc1, h1, f1, NULL) > || !gst_element_link_many(tee, q2, enc2, h2, f2, NULL)) { > g_error("Failed to link elements ..."); > return -2; > } > > srcOpts = gst_structure_new ("video/x-raw", > "format", G_TYPE_STRING, "UYVY", > "width", G_TYPE_INT, 1280, > "height", G_TYPE_INT, 720, > "framerate", GST_TYPE_FRACTION, 30, 1, > NULL); > g_object_set (G_OBJECT (src), "extra-controls", srcOpts, NULL); > > // GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(app.pipeline), > GST_DEBUG_GRAPH_SHOW_ALL, "pipeline"); > > gst_element_set_state (app.pipeline, GST_STATE_PLAYING); > > #if(0) > if (gst_element_get_state (app.pipeline, NULL, NULL, -1) == > GST_STATE_CHANGE_FAILURE) { > g_error ("Failed to go into PLAYING state"); > } > > g_print ("Running ...\n"); > g_main_loop_run (app.loop); > #endif > > bus = gst_element_get_bus (app.pipeline); > msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, > GST_MESSAGE_ERROR | GST_MESSAGE_EOS); > > /* exit */ > /* Free resources */ > if (msg != NULL) { > GError *err; > gchar *debug_info; > > switch (GST_MESSAGE_TYPE (msg)) { > case GST_MESSAGE_ERROR: > gst_message_parse_error (msg, &err, &debug_info); > g_printerr ("Error received from element %s: > %s\n", GST_OBJECT_NAME (msg->src), err->message); > g_printerr ("Debugging information: %s\n", > debug_info ? debug_info : "none"); > g_clear_error (&err); > g_free (debug_info); > break; > case GST_MESSAGE_EOS: > g_print ("End-Of-Stream reached.\n"); > break; > default: > /* We should not reach here because we only > asked for ERRORs and EOS */ > g_printerr ("Unexpected message received.\n"); > break; > } > gst_message_unref (msg); > } > gst_object_unref (bus); > gst_element_set_state (app.pipeline, GST_STATE_NULL); > gst_object_unref (app.pipeline); > > return 0; > } > > This works through the command line so I guess i am missing something > else in the code. Just do not understand why it works as a command line > but not as an API. > > I enabled the pipeline graph dot files for both the gst-launch-1.0 and > my program and they appear to be alike, see attached of my program graph. > > The graph was created by un-commenting the GST_DEBUG_BIN_TO_DOT_FILE line. > > I have read most of the tutorials but feel lost if i try anything new > that the docs did not cover. > > Thanks > > > > > -- > This email has been checked for viruses by AVG. > https://www.avg.com > _______________________________________________ > gstreamer-devel mailing list > [hidden email] > https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel -- This email has been checked for viruses by AVG. https://www.avg.com _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Ok, so I changed the code. The code below mades it work, thanks Gary
Metalle. if (gst_element_link_many(src, tee, NULL) != TRUE || gst_element_link_many(q1, enc1, h1, f1, NULL) != TRUE || gst_element_link_many(q2, enc2, h2, f2, NULL) != TRUE) { g_error("Failed to link elements ..."); return -2; } tee_1_pad = gst_element_get_request_pad (tee, "src_%u"); g_print ("Obtained request pad %s for 500K branch.\n", gst_pad_get_name (tee_1_pad)); queue_1_pad = gst_element_get_static_pad (q1, "sink"); tee_2_pad = gst_element_get_request_pad (tee, "src_%u"); g_print ("Obtained request pad %s for 2M branch.\n", gst_pad_get_name (tee_2_pad)); queue_2_pad = gst_element_get_static_pad (q2, "sink"); if (gst_pad_link (tee_1_pad, queue_1_pad) != GST_PAD_LINK_OK || gst_pad_link (tee_2_pad, queue_2_pad) != GST_PAD_LINK_OK) { g_printerr ("Tee could not be linked.\n"); gst_object_unref (app.pipeline); return -1; } gst_object_unref (queue_1_pad); gst_object_unref (queue_2_pad); It now captures video in 500k and 2M BPS but the resolution is still 640x480 which is should be 1280x720. Thanks On 8/25/2020 3:07 AM, Gary Metalle wrote: > Hi > > Sorry I think it's ok as it is with the tee because gst_element_link_many can request the src pads for you. > > I had been reading the following article recently and remembered that they manually linked up the src pads for the tee so that they could be free'd up nicely at the end: > > https://gstreamer.freedesktop.org/documentation/tutorials/basic/multithreading-and-pad-availability.html?gi-language=c > > Maybe that example will have some other hints that are useful to you as the beginning of the pipeline is very similar to yours. > > Also be prepared to trawl through a debug log after you've set "export GST_DEBUG=4" or "export GST_DEBUG=6" because it always has clues, just that it's difficult to find what you need. Lately I've found it easier to start at the end of the log and go backwards. > ________________________________________ > From: gstreamer-devel <[hidden email]> on behalf of Kelly Wiles <[hidden email]> > Sent: 24 August 2020 20:31 > To: [hidden email] > Subject: Re: Trying translate working gst-launch command to the API > > Hi > > The code > > if (!gst_element_link_many(src, tee, NULL) > || !gst_element_link_many(tee, q1, enc1, h1, f1, NULL) > || !gst_element_link_many(tee, q2, enc2, h2, f2, NULL)) { > g_error("Failed to link elements ..."); > return -2; > } > > > Gives no errors and I think that the code above was linking the tee to > src and other elements. > > I may not be understanding what you are talking about, sorry. > > Thanks > > On 8/24/2020 11:46 AM, Gary Metalle wrote: >> Hi >> >> I don't think you can just use the 'tee' and expect it to work without a bit more work. It has src pads created as when you need them so you'd have to hook into pad_created and link up your src and encoder from there. >> >> Are you not getting errors from the calls to gst_element_link_many? >> ________________________________________ >> From: gstreamer-devel <[hidden email]> on behalf of Kelly Wiles <[hidden email]> >> Sent: 24 August 2020 15:03 >> To: Matthew Waters; Discussion of the development of and with GStreamer >> Subject: Re: Trying translate working gst-launch command to the API >> >> Ok, so i fixed the crash and now getting error >> >> Maybe be due to not enough memory or failing driver >> >> The code: >> >> #include <gst/gst.h> >> #include <stdio.h> >> >> // gst-launch-1.0 -e -v v4l2src ! >> 'video/x-raw,width=1280,height=720,framerate=30/1,format=UYVY' ! tee >> name=t ! >> // queue ! v4l2h264enc >> extra-controls="controls,h264_profile=4,h264_level=10,video_bitrate=500000;" >> ! h264parse ! >> // filesink location=foo1.h264 t. ! queue ! >> // v4l2h264enc >> extra-controls="controls,h264_profile=4,h264_level=10,video_bitrate=2000000;" >> ! h264parse ! >> // filesink location=foo2.h264 >> >> typedef struct _App { >> GstElement *pipeline; >> GstElement *appsrc; >> >> GMainLoop *loop; >> guint sourceid; >> >> GTimer *timer; >> } App; >> >> App app; >> >> gint main(gint argc, gchar *argv[]) { >> >> GstBus *bus; >> GstMessage *msg; >> GstElement *src, *tee, *enc1, *enc2, *f1, *f2, *h1, *h2, *q1, *q2; >> GstStructure *srcOpts; >> GstStructure *encOpts; >> >> gst_init(&argc, &argv); >> >> app.loop = g_main_loop_new(NULL, FALSE); >> >> app.pipeline = gst_pipeline_new("my-pipeline"); >> >> src = gst_element_factory_make("v4l2src", "src"); >> tee = gst_element_factory_make("tee", "tee"); >> h1 = gst_element_factory_make("h264parse", "h1"); >> h2 = gst_element_factory_make("h264parse", "h2"); >> q1 = gst_element_factory_make("queue", "q1"); >> q2 = gst_element_factory_make("queue", "q2"); >> enc1 = gst_element_factory_make("v4l2h264enc", "enc1"); >> enc2 = gst_element_factory_make("v4l2h264enc", "enc2"); >> f1 = gst_element_factory_make("filesink", "f1"); >> f2 = gst_element_factory_make("filesink", "f2"); >> >> if (!app.pipeline || !src || !tee || !enc1 || !enc2 || !f1 || >> !f2 || !h1 || !h2 || !q1 || !q2) { >> g_error ("Could not create >> elements\npip=%p\nsrc=%p\ntee=%p\nenc1=%p\nenc2=%p\nf1=%p\nf2=%p\nh1=%p\nh2=%p\nq1=%p\nq2=%p", >> app.pipeline, src, tee, enc1, enc2, f1, >> f2, h1, h2, q1, q2); >> return -1; >> } >> >> g_object_set(f1, "location", "foo1.h264", NULL); >> g_object_set(f2, "location", "foo2.h264", NULL); >> >> encOpts = gst_structure_new ("controls", >> "h264_profile", G_TYPE_INT, 4, >> "h264_level", G_TYPE_INT, 10, >> "video_bitrate", G_TYPE_INT, 500000, >> NULL); >> g_object_set (G_OBJECT (enc1), "extra-controls", encOpts, NULL); >> >> encOpts = gst_structure_new ("controls", >> "h264_profile", G_TYPE_INT, 4, >> "h264_level", G_TYPE_INT, 10, >> "video_bitrate", G_TYPE_INT, 200000, >> NULL); >> g_object_set (G_OBJECT (enc2), "extra-controls", encOpts, NULL); >> >> gst_bin_add_many(GST_BIN(app.pipeline), src, tee, q1, enc1, h1, >> f1, q2, enc2, h2, f2, NULL); >> >> if (!gst_element_link_many(src, tee, NULL) >> || !gst_element_link_many(tee, q1, enc1, h1, f1, NULL) >> || !gst_element_link_many(tee, q2, enc2, h2, f2, NULL)) { >> g_error("Failed to link elements ..."); >> return -2; >> } >> >> srcOpts = gst_structure_new ("video/x-raw", >> "format", G_TYPE_STRING, "UYVY", >> "width", G_TYPE_INT, 1280, >> "height", G_TYPE_INT, 720, >> "framerate", GST_TYPE_FRACTION, 30, 1, >> NULL); >> g_object_set (G_OBJECT (src), "extra-controls", srcOpts, NULL); >> >> // GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(app.pipeline), >> GST_DEBUG_GRAPH_SHOW_ALL, "pipeline"); >> >> gst_element_set_state (app.pipeline, GST_STATE_PLAYING); >> >> #if(0) >> if (gst_element_get_state (app.pipeline, NULL, NULL, -1) == >> GST_STATE_CHANGE_FAILURE) { >> g_error ("Failed to go into PLAYING state"); >> } >> >> g_print ("Running ...\n"); >> g_main_loop_run (app.loop); >> #endif >> >> bus = gst_element_get_bus (app.pipeline); >> msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, >> GST_MESSAGE_ERROR | GST_MESSAGE_EOS); >> >> /* exit */ >> /* Free resources */ >> if (msg != NULL) { >> GError *err; >> gchar *debug_info; >> >> switch (GST_MESSAGE_TYPE (msg)) { >> case GST_MESSAGE_ERROR: >> gst_message_parse_error (msg, &err, &debug_info); >> g_printerr ("Error received from element %s: >> %s\n", GST_OBJECT_NAME (msg->src), err->message); >> g_printerr ("Debugging information: %s\n", >> debug_info ? debug_info : "none"); >> g_clear_error (&err); >> g_free (debug_info); >> break; >> case GST_MESSAGE_EOS: >> g_print ("End-Of-Stream reached.\n"); >> break; >> default: >> /* We should not reach here because we only >> asked for ERRORs and EOS */ >> g_printerr ("Unexpected message received.\n"); >> break; >> } >> gst_message_unref (msg); >> } >> gst_object_unref (bus); >> gst_element_set_state (app.pipeline, GST_STATE_NULL); >> gst_object_unref (app.pipeline); >> >> return 0; >> } >> >> This works through the command line so I guess i am missing something >> else in the code. Just do not understand why it works as a command line >> but not as an API. >> >> I enabled the pipeline graph dot files for both the gst-launch-1.0 and >> my program and they appear to be alike, see attached of my program graph. >> >> The graph was created by un-commenting the GST_DEBUG_BIN_TO_DOT_FILE line. >> >> I have read most of the tutorials but feel lost if i try anything new >> that the docs did not cover. >> >> Thanks >> >> >> >> >> -- >> This email has been checked for viruses by AVG. >> https://www.avg.com >> _______________________________________________ >> gstreamer-devel mailing list >> [hidden email] >> https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel > -- > This email has been checked for viruses by AVG. > https://www.avg.com > > _______________________________________________ > gstreamer-devel mailing list > [hidden email] > https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel > _______________________________________________ > gstreamer-devel mailing list > [hidden email] > https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel -- This email has been checked for viruses by AVG. https://www.avg.com _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Free forum by Nabble | Edit this page |