DVB Remux
Jan Schmidt
thaytan at noraisin.net
Fri Jan 30 19:09:11 PST 2015
Hi Bernhard,
As a general rule, whenever you have a demuxer you also need a queue (or
use multiqueue) on the output of each demuxer pad to decouple the
streams, or your pipeline will stall exactly like you are seeing.
Regards,
Jan.
On 31/01/15 06:34, Bernhard Graaf wrote:
> I've tried to use following code:
>
> #include <stdio.h>
> #include <unistd.h>
> #include <string.h>
> #include <gst/gst.h>
> #include <glib.h>
>
>
> GstElement *pipeline;
> GstElement *parser, *parser2;
>
> static gboolean
> bus_call (GstBus *bus,
> GstMessage *msg,
> gpointer data)
> {
> GMainLoop *loop = (GMainLoop *) data;
>
> switch (GST_MESSAGE_TYPE (msg)) {
>
> case GST_MESSAGE_EOS:
> g_print ("End of stream\n");
> g_main_loop_quit (loop);
> break;
>
> case GST_MESSAGE_ERROR: {
> gchar *debug;
> GError *error;
>
> gst_message_parse_error (msg, &error, &debug);
> g_free (debug);
>
> g_printerr ("Error: %s\n", error->message);
> g_error_free (error);
>
> g_main_loop_quit (loop);
> break;
> }
> /* case GST_MESSAGE_ELEMENT:
> {
> const GstStructure *str;
>
> str = gst_message_get_structure (msg);
> const gchar *name = gst_structure_get_name (str);
>
> printf("got message from %s\n", name);
> } */
> default:
> break;
> }
>
> return TRUE;
> }
>
>
> void link_to_mux (GstPad *tolink_pad, GstElement *mux)
> {
> GstPad *pad;
> gchar *srcname, *sinkname;
>
> srcname = gst_pad_get_name (tolink_pad);
> pad = gst_element_get_compatible_pad (mux, tolink_pad, NULL);
> gst_pad_link (tolink_pad, pad);
> sinkname = gst_pad_get_name (pad);
> if (GST_PAD_IS_LINKED (pad)) g_print ("A new pad %s was created and linked
> to %s\n", srcname, sinkname);
> else g_print("Link failed: %s to %s\n",srcname, sinkname);
> gst_object_unref (GST_OBJECT (pad));
>
>
> g_free (sinkname);
> g_free (srcname);
> }
>
> void on_pad_added (GstElement *element,
> GstPad *pad,
> gpointer data)
> {
> GstElement *mux = (GstElement *) data;
> GstCaps *caps;
> gchar *caps_string;
> gchar *name;
>
> GstPad *to_link_pad, *from_link_pad;
>
> name = gst_pad_get_name (pad);
> printf("A new pad %s was created\n", name);
>
> caps = gst_pad_query_caps (pad, NULL);
> caps_string = gst_caps_to_string (caps);
> g_print (" Capability: %s\n", caps_string);
>
> if (strstr(caps_string, "video/mpeg"))
> {
> parser = gst_element_factory_make ("mpegvideoparse", NULL);
> if(!parser)
> {
> g_print("Parser not found\n");
> exit (-1);
> }
> gst_bin_add (GST_BIN (pipeline), parser);
> gst_element_set_state (parser, GST_STATE_PLAYING);
> to_link_pad = gst_element_get_static_pad (parser, "sink");
> from_link_pad = gst_element_get_static_pad (parser, "src");
> gst_pad_link (pad, to_link_pad);
> link_to_mux(from_link_pad, mux);
> gst_object_unref (GST_OBJECT (to_link_pad));
> gst_object_unref (GST_OBJECT (from_link_pad));
> }
> else if (strstr(caps_string, "audio/mpeg"))
> {
> parser2 = gst_element_factory_make ("mpegaudioparse", NULL);
> if(!parser2)
> {
> g_print("Parser2 not found\n");
> exit (-1);
> }
> gst_bin_add (GST_BIN (pipeline), parser2);
> gst_element_set_state (parser2, GST_STATE_PLAYING);
> to_link_pad = gst_element_get_static_pad (parser2, "sink");
> from_link_pad = gst_element_get_static_pad (parser2, "src");
> gst_pad_link (pad, to_link_pad);
> link_to_mux(from_link_pad, mux);
> gst_object_unref (GST_OBJECT (to_link_pad));
> gst_object_unref (GST_OBJECT (from_link_pad));
> }
>
>
> gst_caps_unref (caps);
> g_free (name);
> g_free (caps_string);
>
> }
>
>
> void no_more_pads (GstElement* object, gpointer user_data)
> {
> g_print("No more pads event from %s\n", gst_element_get_name(object));
> }
>
> int
> main ()
> {
> GMainLoop *loop;
>
> GstElement *source, *demux, *mux, *sink;
> GstBus *bus;
>
> gst_init (0, NULL);
>
> loop = g_main_loop_new (NULL, FALSE);
>
> pipeline = gst_pipeline_new ("DVB-Filesave");
> source = gst_element_factory_make ("dvbbasebin", "dvb-source");
> demux = gst_element_factory_make ("tsdemux", "dvb-demux");
> mux = gst_element_factory_make ("mpegtsmux", "dvb-mux");
> sink = gst_element_factory_make ("filesink", "file-output");
>
> if (!pipeline || !source || !demux || !mux || !sink) {
> g_printerr ("One element could not be created. Exiting.\n");
> if(!pipeline) g_printerr("Pipeline not created\n");
> else if(!source) g_printerr("Source not created\n");
> else if(!demux) g_printerr("Demux not created\n");
> else if(!mux) g_printerr("Muxer not created\n");
> else if(!sink) g_printerr("Sink not created\n");
> return -1;
> }
>
> g_object_set (G_OBJECT (source), "adapter", 2, NULL);
> g_object_set (G_OBJECT (source), "frequency", 12544000, NULL);
> g_object_set (G_OBJECT (source), "program-numbers", "17501", NULL);
> g_object_set (G_OBJECT (source), "polarity", "h", NULL);
> g_object_set (G_OBJECT (source), "symbol-rate", 22000, NULL);
>
> g_object_set (G_OBJECT (sink), "location", "remux_test.mpg", NULL);
>
> bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
> gst_bus_add_watch (bus, bus_call, loop);
> gst_object_unref (bus);
>
> gst_bin_add_many (GST_BIN (pipeline), source, demux, mux, sink, NULL);
>
> gst_element_link (source, demux);
> gst_element_link (mux, sink);
>
> g_signal_connect (demux, "pad-added", G_CALLBACK (on_pad_added), mux);
> g_signal_connect (demux, "no-more-pads", G_CALLBACK (on_pad_added), NULL);
>
>
>
> g_print ("Now playing: ");
> gst_element_set_state (pipeline, GST_STATE_PLAYING);
>
> g_print ("Running...\n");
> g_main_loop_run (loop);
>
> return 0;
> }
>
> But the pipeline hangs on this:
> <snipe>
> 0:00:00.760394705 18570 0xb0d8a0 INFO GST_ELEMENT_PADS
> gstelement.c:643:gst_element_add_pad:<dvb-mux> adding pad 'sink_65'
> 0:00:00.760454365 18570 0xb0d8a0 INFO GST_PADS
> gstpad.c:2186:gst_pad_link_prepare: trying to link mpegvparse0:src and
> dvb-mux:sink_65
> 0:00:00.760506215 18570 0xb0d8a0 INFO GST_PADS
> gstpad.c:2388:gst_pad_link_full: linked mpegvparse0:src and dvb-mux:sink_65,
> successful
> 0:00:00.760534970 18570 0xb0d8a0 INFO GST_EVENT
> gstevent.c:1373:gst_event_new_reconfigure: creating reconfigure event
> A new pad src was created and linked to sink_65
> 0:00:00.760658475 18570 0xb0d8a0 INFO GST_EVENT
> gstevent.c:759:gst_event_new_segment: creating segment event time segment
> start=0:00:00.000000000, offset=0:00:00.000000000, stop=99:99:99.999999999,
> rate=1.000000, applied_rate=1.000000, flags=0x00, time=0:00:00.000000000,
> base=0:00:00.000000000, position 0:00:00.000000000, duration
> 99:99:99.999999999
> 0:00:00.760934626 18570 0xb0d8a0 INFO GST_ELEMENT_PADS
> gstelement.c:643:gst_element_add_pad:<dvb-demux> adding pad 'private_0021'
> A new pad private_0021 was created
> Capability: application/x-teletext
> 0:00:00.788089961 18570 0xb0d850 INFO GST_EVENT
> gstevent.c:678:gst_event_new_caps: creating caps event video/mpegts,
> mpegversion=(int)2, systemstream=(boolean)true
> 0:00:00.877835322 18570 0xb0d8a0 INFO GST_ELEMENT_PADS
> gstelement.c:643:gst_element_add_pad:<dvb-demux> adding pad 'audio_0203'
> A new pad audio_0203 was created
> Capability: audio/x-ac3
> 0:00:00.878095442 18570 0xb0d8a0 INFO GST_ELEMENT_PADS
> gstelement.c:643:gst_element_add_pad:<dvb-demux> adding pad 'audio_0200'
> A new pad audio_0200 was created
> Capability: audio/mpeg, mpegversion=(int)1
> 0:00:00.878752238 18570 0xb0d8a0 INFO GST_PLUGIN_LOADING
> gstplugin.c:833:gst_plugin_load_file: plugin
> "/usr/local/lib/gstreamer-1.0/libgstaudioparsers.so" loaded
> 0:00:00.878804593 18570 0xb0d8a0 INFO GST_ELEMENT_FACTORY
> gstelementfactory.c:364:gst_element_factory_create: creating element
> "mpegaudioparse"
> 0:00:00.879019978 18570 0xb0d8a0 INFO GST_ELEMENT_PADS
> gstelement.c:643:gst_element_add_pad:<GstBaseParse at 0x7f3604179660> adding
> pad 'sink'
> 0:00:00.879085838 18570 0xb0d8a0 INFO GST_ELEMENT_PADS
> gstelement.c:643:gst_element_add_pad:<GstBaseParse at 0x7f3604179660> adding
> pad 'src'
> 0:00:00.879169348 18570 0xb0d8a0 INFO GST_STATES
> gstelement.c:2303:gst_element_continue_state:<mpegaudioparse0> committing
> state from NULL to READY, pending PLAYING, next PAUSED
> 0:00:00.879212453 18570 0xb0d8a0 INFO GST_STATES
> gstelement.c:2233:_priv_gst_element_state_changed:<mpegaudioparse0>
> notifying about state-changed NULL to READY (PLAYING pending)
> 0:00:00.879259623 18570 0xb0d8a0 INFO GST_STATES
> gstelement.c:2310:gst_element_continue_state:<mpegaudioparse0> continue
> state change READY to PAUSED, final PLAYING
> 0:00:00.879340888 18570 0xb0d8a0 INFO GST_PADS
> gstpad.c:3748:gst_pad_peer_query:<mpegaudioparse0:sink> pad has no peer
> 0:00:00.879379959 18570 0xb0d8a0 INFO GST_STATES
> gstelement.c:2303:gst_element_continue_state:<mpegaudioparse0> committing
> state from READY to PAUSED, pending PLAYING, next PLAYING
> 0:00:00.879409529 18570 0xb0d8a0 INFO GST_STATES
> gstelement.c:2233:_priv_gst_element_state_changed:<mpegaudioparse0>
> notifying about state-changed READY to PAUSED (PLAYING pending)
> 0:00:00.879450104 18570 0xb0d8a0 INFO GST_STATES
> gstelement.c:2310:gst_element_continue_state:<mpegaudioparse0> continue
> state change PAUSED to PLAYING, final PLAYING
> 0:00:00.879480739 18570 0xb0d8a0 INFO GST_STATES
> gstelement.c:2328:gst_element_continue_state:<mpegaudioparse0> completed
> state change to PLAYING
> 0:00:00.879504654 18570 0xb0d8a0 INFO GST_STATES
> gstelement.c:2233:_priv_gst_element_state_changed:<mpegaudioparse0>
> notifying about state-changed PAUSED to PLAYING (VOID_PENDING pending)
> 0:00:00.879556579 18570 0xb0d8a0 INFO GST_ELEMENT_PADS
> gstelement.c:895:gst_element_get_static_pad: found pad mpegaudioparse0:sink
> 0:00:00.879586924 18570 0xb0d8a0 INFO GST_ELEMENT_PADS
> gstelement.c:895:gst_element_get_static_pad: found pad mpegaudioparse0:src
> 0:00:00.879622269 18570 0xb0d8a0 INFO GST_PADS
> gstpad.c:2186:gst_pad_link_prepare: trying to link dvb-demux:audio_0200 and
> mpegaudioparse0:sink
> 0:00:00.879671664 18570 0xb0d8a0 INFO GST_PADS
> gstpad.c:3748:gst_pad_peer_query:<mpegaudioparse0:src> pad has no peer
> 0:00:00.879711444 18570 0xb0d8a0 INFO GST_PADS
> gstpad.c:2388:gst_pad_link_full: linked dvb-demux:audio_0200 and
> mpegaudioparse0:sink, successful
> 0:00:00.879745204 18570 0xb0d8a0 INFO GST_EVENT
> gstevent.c:1373:gst_event_new_reconfigure: creating reconfigure event
> 0:00:00.879894009 18570 0xb0d8a0 INFO GST_ELEMENT_PADS
> gstelement.c:643:gst_element_add_pad:<dvb-mux> adding pad 'sink_66'
> 0:00:00.879950774 18570 0xb0d8a0 INFO GST_PADS
> gstpad.c:2186:gst_pad_link_prepare: trying to link mpegaudioparse0:src and
> dvb-mux:sink_66
> 0:00:00.880001239 18570 0xb0d8a0 INFO GST_PADS
> gstpad.c:2388:gst_pad_link_full: linked mpegaudioparse0:src and
> dvb-mux:sink_66, successful
> 0:00:00.880032749 18570 0xb0d8a0 INFO GST_EVENT
> gstevent.c:1373:gst_event_new_reconfigure: creating reconfigure event
> A new pad src was created and linked to sink_66
>
> (remux_test:18570): GStreamer-CRITICAL **: gst_object_get_name: assertion
> 'GST_IS_OBJECT (object)' failed
> A new pad (null) was created
>
> (remux_test:18570): GStreamer-CRITICAL **: gst_pad_query_caps: assertion
> 'GST_IS_PAD (pad)' failed
> Capability: NULL
>
> (remux_test:18570): GStreamer-CRITICAL **: gst_mini_object_unref: assertion
> 'mini_object != NULL' failed
> 0:00:00.880440385 18570 0xb0d8a0 INFO GST_EVENT
> gstevent.c:678:gst_event_new_caps: creating caps event audio/mpeg,
> mpegversion=(int)1, mpegaudioversion=(int)1, layer=(int)2, rate=(int)48000,
> channels=(int)2, parsed=(boolean)true
> 0:00:00.907704596 18570 0xb0d850 INFO GST_EVENT
> gstevent.c:678:gst_event_new_caps: creating caps event video/mpegts,
> mpegversion=(int)2, systemstream=(boolean)true
>
> I know there is a smarter way with typefind, but I need only the
> mpegvideo/mpegaudio-streams.
>
> But why the pipline hangs on this, I don't know.
> Any further idea?
>
> Thanks again!
> Bernhard
>
> -----Ursprüngliche Nachricht-----
> Von: gstreamer-devel [mailto:gstreamer-devel-bounces at lists.freedesktop.org]
> Im Auftrag von Jan Schmidt
> Gesendet: Freitag, 30. Januar 2015 15:11
> An: Discussion of the development of and with GStreamer
> Betreff: Re: DVB Remux
>
> On 30/01/15 23:52, Bernhard Graaf wrote:
>
> Hi Bernhard,
>
> In general for this kind of operation, you need a parser for each stream
> before connecting to the muxer. i.e. h264parse, mpegvideoparse,
> mpegaudioparse etc.
>
> You'll need to do some autoplugging and find the right parsers, unless
> you known which formats are in your DVB stream and can hard-code them.
>
> - Jan.
>
>
> _______________________________________________
> gstreamer-devel mailing list
> gstreamer-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
>
More information about the gstreamer-devel
mailing list