Hi,
I am trying to make a simple bin plugin using the gst-template <https://gitlab.freedesktop.org/gstreamer/gst-template> . By simple I mean just using elements already available in the official gstreamer plugins. However, I am having trouble doing so. Following the tutorials about creating bin plugins <https://gstreamer.freedesktop.org/documentation/plugin-development/element-types/manager.html> it seems I should be able to do so primarily in the *_init()* function. Now I've done it very similar to writing a gstreamer pipeline in an application, in the hopes that I don't have to care too much about the underlying data flow of an element/bin. So far, so good. I have added ghostpads and the bin is able to compile and be used as an element in a pipeline. However, when I try to run it using: *gst-launch-1.0 audiotestsrc ! dizzy ! pulsesink -v * it gives me the following error: Deinterleave pad Interleave pad Ghost pad added: Sink Ghost pad added: Src degree: 0.000000 Left=1.000000 Right=0.000000 Setting pipeline to PAUSED ... Pipeline is PREROLLING ... /GstPipeline:pipeline0/GstAudioTestSrc:audiotestsrc0.GstPad:src: caps = audio/x-raw, format=(string)S16LE, layout=(string)interleaved, rate=(int)44100, channels=(int)2 /GstPipeline:pipeline0/Gstdizzy:dizzy0.GstPad:src: caps = audio/x-raw, format=(string)S16LE, layout=(string)interleaved, rate=(int)44100, channels=(int)2 Redistribute latency... /GstPipeline:pipeline0/GstPulseSink:pulsesink0.GstPad:sink: caps = audio/x-raw, format=(string)S16LE, layout=(string)interleaved, rate=(int)44100, channels=(int)2 /GstPipeline:pipeline0/Gstdizzy:dizzy0.GstPad:sink: caps = audio/x-raw, format=(string)S16LE, layout=(string)interleaved, rate=(int)44100, channels=(int)2 *(gst-launch-1.0:113107): GStreamer-CRITICAL **: 09:34:52.799: chain on pad dizzy0:sink but it has no chainfunction* ERROR: from element /GstPipeline:pipeline0/GstAudioTestSrc:audiotestsrc0: Internal data stream error. Additional debug info: gstbasesrc.c(3055): gst_base_src_loop (): /GstPipeline:pipeline0/GstAudioTestSrc:audiotestsrc0: streaming stopped, reason not-supported (-6) ERROR: pipeline doesn't want to preroll. Setting pipeline to NULL ... Freeing pipeline ... I've focused on the "chain on pad dizzy0:sink but it has no chainfunction", since I don't really understand that. I understand the purpose of the chain function, but not why I am required to use it in my case. Also when I look at the source code of other plugins, most of them don't even have a chain function and in the tutorials I can't remember seeing an example without a chain function and how that works. If I add the chain function from the generated template, it seems all the data is not entering my bin, but simply flowing through my plugin, since it just pushes the buffer to the next element in the pipeline. In that case the plugin "works", but it doesn't serve a purpose, since it isn't doing anything with the data. The template chain function (when not commented): static void gst_dizzy_chain(GstPad *pad, GstObject *parent, GstBuffer *buf) { Gstdizzy *filter; filter = GST_DIZZY(parent); /* just push out the incoming buffer without touching it */ return gst_pad_push(filter->srcpad, buf); } Do I have to push the buffer into my bin somehow in the chain function? My *_init()* function with really just a simple bin and some ghostpads added to the sink and source. static void gst_dizzy_init(Gstdizzy *filter) { filter->sinkpad = gst_pad_new_from_static_template(&sink_factory, "sink"); filter->srcpad = gst_pad_new_from_static_template(&src_factory, "src"); // Create Bin filter->bin = gst_bin_new("3dsound"); GST_PAD_SET_PROXY_CAPS(filter->sinkpad); GST_PAD_SET_PROXY_CAPS(filter->srcpad); // filter->elements.alsasrc = gst_element_factory_make("alsasrc", "src"); filter->elements.deinterleave = gst_element_factory_make("deinterleave", "split"); filter->elements.amplify = gst_element_factory_make("audioamplify", "sink"); filter->elements.queue_1 = gst_element_factory_make("queue", "queue1"); filter->elements.queue_2 = gst_element_factory_make("queue", "queue2"); filter->elements.volume = gst_element_factory_make("volume", "volume1"); filter->elements.audio_panorama_1 = gst_element_factory_make("audiopanorama", "panorama1"); filter->elements.audio_panorama_2 = gst_element_factory_make("audiopanorama", "panorama2"); filter->elements.phaseshift_1 = gst_element_factory_make("audioinvert", "phaseshift1"); filter->elements.phaseshift_2 = gst_element_factory_make("audioinvert", "phaseshift2"); filter->elements.audio_convert_1_1 = gst_element_factory_make("audioconvert", "convert1_1"); filter->elements.audio_convert_1_2 = gst_element_factory_make("audioconvert", "convert1_2"); filter->elements.audio_convert_2_1 = gst_element_factory_make("audioconvert", "convert2_1"); filter->elements.audio_convert_2_2 = gst_element_factory_make("audioconvert", "convert2_2"); filter->elements.interleave = gst_element_factory_make("interleave", "combine"); filter->elements.sink_1 = gst_element_factory_make("pulsesink", "sink1"); filter->elements.sink_2 = gst_element_factory_make("pulsesink", "sink2"); filter->elements.alsasink = gst_element_factory_make("alsasink", "alsasink"); filter->elements.adder = gst_element_factory_make("adder", "add"); // Ghost Pads GstPad *sinkpad = gst_element_get_static_pad(filter->elements.amplify, "sink"); GstPad *srcpad = gst_element_get_static_pad(filter->elements.interleave, "src"); filter->bin = GST_BIN(gst_pipeline_new("Stereopicture")); filter->elements.caps = gst_caps_new_simple("audio/x-raw", "channels", G_TYPE_INT, 4, NULL); // Amplifier g_object_set(filter->elements.amplify, "amplification", 12.0, NULL); // Deinterleave g_object_set(filter->elements.deinterleave, "keep-positions", TRUE, NULL); g_object_set(filter->elements.interleave, "channel-positions-from-input", FALSE, NULL); // Volumes g_object_set(filter->elements.volume, "volume", 1.0, NULL); // Panoramas g_object_set(filter->elements.audio_panorama_1, "panorama", 1.0, NULL); g_object_set(filter->elements.audio_panorama_2, "panorama", -1.0, NULL); gst_bin_add_many(GST_BIN_CAST(filter->bin), gst_object_ref (filter->elements.amplify), gst_object_ref (filter->elements.deinterleave), gst_object_ref (filter->elements.queue_1), gst_object_ref (filter->elements.queue_2), gst_object_ref (filter->elements.volume), gst_object_ref (filter->elements.audio_panorama_1), gst_object_ref (filter->elements.audio_panorama_2), gst_object_ref (filter->elements.phaseshift_1), gst_object_ref (filter->elements.phaseshift_2), gst_object_ref (filter->elements.audio_convert_1_1), gst_object_ref (filter->elements.audio_convert_1_2), gst_object_ref (filter->elements.audio_convert_2_1), gst_object_ref (filter->elements.audio_convert_2_2), gst_object_ref (filter->elements.interleave), gst_object_ref (filter->elements.sink_1), gst_object_ref (filter->elements.sink_2), NULL); gst_element_link_filtered(filter->elements.amplify, filter->elements.deinterleave, filter->elements.caps); gst_element_link_pads_full(filter->elements.amplify, "src", filter->elements.deinterleave, "sink", GST_PAD_LINK_CHECK_NOTHING); printf("Deinterleave pad\n"); gst_element_link_pads_full(filter->elements.deinterleave, "src_3", filter->elements.queue_1, "sink",GST_PAD_LINK_CHECK_CAPS); gst_element_link_pads_full(filter->elements.deinterleave, "src_0", filter->elements.queue_2, "sink",GST_PAD_LINK_CHECK_CAPS); // // Channel 1 gst_element_link_pads_full(filter->elements.queue_1, "src", filter->elements.audio_panorama_1, "sink", GST_PAD_LINK_CHECK_CAPS); gst_element_link_pads_full(filter->elements.audio_panorama_1, "src", filter->elements.audio_convert_1_1, "sink", GST_PAD_LINK_CHECK_CAPS); gst_element_link_pads_full(filter->elements.audio_convert_1_1, "src", filter->elements.phaseshift_1, "sink", GST_PAD_LINK_CHECK_CAPS); gst_element_link_pads_full(filter->elements.phaseshift_1, "src", filter->elements.interleave, "sink_0", GST_PAD_LINK_CHECK_CAPS); // // Channel 2 gst_element_link_pads_full(filter->elements.queue_2, "src", filter->elements.audio_panorama_2, "sink", GST_PAD_LINK_CHECK_CAPS); gst_element_link_pads_full(filter->elements.audio_panorama_2, "src", filter->elements.audio_convert_2_1, "sink", GST_PAD_LINK_CHECK_CAPS); gst_element_link_pads_full(filter->elements.audio_convert_2_1, "src", filter->elements.phaseshift_2, "sink", GST_PAD_LINK_CHECK_CAPS); gst_element_link_pads_full(filter->elements.phaseshift_2, "src", filter->elements.interleave, "sink_1", GST_PAD_LINK_CHECK_CAPS); GstPad *ghost_sinkpad = gst_ghost_pad_new("sink", sinkpad); GstPad *ghost_srcpad = gst_ghost_pad_new("src", srcpad); if(gst_element_add_pad(filter, filter->sinkpad)) { printf("Ghost pad added: Sink\n"); } else { printf("Ghost pad could not be added: Sink\n"); } if(gst_element_add_pad(filter, filter->srcpad)) { printf("Ghost pad added: Src\n"); } else { printf("Ghost pad could not be added: Src\n"); } } Maybe there is some good example on how to create a bin like this or I just don't understand how to do it, but I find writing a manager <https://gstreamer.freedesktop.org/documentation/plugin-development/element-types/manager.html> a little sparse and can't find anybody here with the same chain function problem. Yesterday I found this post <http://gstreamer-devel.966125.n4.nabble.com/Creating-a-gstreamer-bin-element-td4676819.html#a4676822> , which from a higher perspective seems to try and achieve the same as me, but also has problems doing so due to lack of clear examples/documentation on the subject. Any help is very much appreciated. Am I on the right track and is is possible to do what I am trying to do, or should I go a whole other route? -- Sent from: http://gstreamer-devel.966125.n4.nabble.com/ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Which Gst base class you have used to write your Bin ?? Is it on Element
class ?? Bin do not have chain function, not sure why you are getting Chain function error. filter->bin is overwritten with pipeline_new() is it correct ?? -- Sent from: http://gstreamer-devel.966125.n4.nabble.com/ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Thank you very much and pardon me for answering so late.
It indeed was the case, that I was still using the GstTransform class and not the GstBin class as I thought. Maybe it was just me, but I found the documentation on this very sparse, as I weren't entirely sure how to derive a class and only used the default or generated one by the gst-template repository. -- Sent from: http://gstreamer-devel.966125.n4.nabble.com/ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Free forum by Nabble | Edit this page |