AW: mpegtsmux (need help!)

Bernhard Graaf bernhard.graaf at gmx.de
Sun Dec 30 06:36:15 PST 2012


Hi again,

 

Now I've learned that mpegtsmux needs a ,pad on request' and I've change
something a little bit simpler:

 

int init_tv()  /* Initiating DVB-Streamer variables */

{

 

  printf("init_tv\n");

 

  dvb_pipe = gst_pipeline_new ("DVB-Streamer");

  dvb_source   = gst_element_factory_make ("dvbbasebin",    "dvb-source");

  dvb_demux    = gst_element_factory_make ("tsdemux",       "dvb-demux");

  dvb_mux      = gst_element_factory_make ("mpegtsmux",     "dvb-mux");

  dvb_sink     = gst_element_factory_make ("tcpserversink", "tcp-output");

 

  if (!dvb_pipe || !dvb_source || !dvb_demux || !dvb_mux || !dvb_sink ) 

  {

    g_printerr ("One element could not be created. Exiting.\n");

    syslog(LOG_ERR, "One element could not be created. Exiting.\n");

    if(!dvb_pipe) g_printerr("DVB-Pipeline not created\n");

    else if(!dvb_source) g_printerr("DVB-Source not created\n");

    else if(!dvb_demux) g_printerr("DVB-Demux not created\n");

    else if(!dvb_mux) g_printerr("DVB-Mux not created\n");

    else if(!dvb_sink) g_printerr("DVB-Sink not created\n");

    return -1;

  }

 

 

  dvb_bus = gst_pipeline_get_bus (GST_PIPELINE (dvb_pipe));

  gst_bus_add_watch (dvb_bus, dvb_bus_call, NULL);

  gst_object_unref (dvb_bus); 

 

  gst_bin_add_many (GST_BIN (dvb_pipe), dvb_source, dvb_demux, dvb_mux,
dvb_sink, NULL);

  gst_element_link_many (dvb_source, dvb_demux, dvb_mux, dvb_sink, NULL);

 

  g_signal_connect (dvb_demux, "pad-added", G_CALLBACK (dvb_pad_added),
NULL); 

 

 

  return 1;

}

 

 

static void dvb_pad_added (GstElement *element, GstPad *pad, gpointer
data) /* Demuxer pad_added */

{

  GstPad *muxpad;

  gchar *name;

  GstCaps *caps;

  gchar *caps_string;

 

  name = gst_pad_get_name (pad);

  g_print ("A new pad %s was created\n", name);

 

  caps = gst_pad_query_caps (pad, NULL);

  caps_string = gst_caps_to_string (caps);

  gst_caps_unref (caps);

  g_print (" Capability:  %s\n", caps_string);

  syslog(LOG_NOTICE, " Capability of %s:  %s\n", name, caps_string);

   

  if (strncmp (caps_string, "video/mpeg", 10) == 0) 

  {

    g_print ("Dynamic Video-pad created, linking %s to
TS-Demuxer/TS-muxer\n", name);

    syslog(LOG_NOTICE,"Dynamic pad created, linking %s to
TS-Demuxer/TS-Muxer\n", name);

    muxpad = gst_element_get_request_pad(dvb_mux, "sink_%d");

    g_print("muxpad: %s ", gst_pad_get_name (muxpad));

    if (gst_pad_link (pad, muxpad) == GST_PAD_LINK_OK) g_print ("linked\n");


    else g_print ("NOT linked\n");

    gst_object_unref (muxpad);

  }

  else if (strncmp (caps_string, "audio/mpeg", 10) == 0) 

  {

    g_print ("Dynamic Audio-pad created, linking %s to
TS-Demuxer/TS-muxer\n", name);

    syslog(LOG_NOTICE,"Dynamic pad created, linking %s to
TS-Demuxer/TS-Muxer\n", name);

    muxpad = gst_element_get_request_pad(dvb_mux, "sink_%d");

    g_print("muxpad: %s ", gst_pad_get_name (muxpad));

    if (gst_pad_link (pad, muxpad) == GST_PAD_LINK_OK) g_print ("linked\n");


    else g_print ("NOT linked\n");

    gst_object_unref (muxpad);

  } 

  g_free (name);

  g_free (caps_string);

  

}

 

 

The result is:

 

Running...

A new pad video_01ff was created

 Capability:  video/mpeg, mpegversion=(int)2, systemstream=(boolean)false

Dynamic Video-pad created, linking video_01ff to TS-Demuxer/TS-muxer

muxpad: sink_65 linked

A new pad private_0021 was created

 Capability:  private/teletext

A new pad audio_0200 was created

 Capability:  audio/mpeg, mpegversion=(int)1

Dynamic Audio-pad created, linking audio_0200 to TS-Demuxer/TS-muxer

muxpad: sink_66 linked

 

So it's looks not so bad. But I don't get a stream on the client (on
gstreamer as well as on vlc, something misses?).

Someone out there to help?

 

Thanks again.

Bernhard

 

  _____  

Von: gstreamer-devel-bounces+bernhard.graaf=gmx.de at lists.freedesktop.org
[mailto:gstreamer-devel-bounces+bernhard.graaf=gmx.de at lists.freedesktop.org]
Im Auftrag von Bernhard Graaf
Gesendet: Sonntag, 30. Dezember 2012 11:19
An: 'Discussion of the development of and with GStreamer'
Betreff: mpegtsmux (need help!)

 

Hi @ all,

 

I have a problem with mpegtsmux under gstreamer 1.0:

 

I try to exclude the only relevant streams out of dvbbasebin (mpeg-video and
mpeg-audio) and send it over a server to a client.

I use tsdemux, look into the generated pads and use mpegtsmux to generate a
stream. But it's not simple. I'm working on it since a lot of time.

I don't know who has tried to do the same. I think I forgot to link a pad.

I know that this kind of help is usually frowned upon in this forum, but I
hope that someone has a heart of gold today.

 

The code:

 

 

int init_tv() /* Initiating DVB-Streamer variables */

{

 

  printf("init_tv\n");

 

  dvb_pipe = gst_pipeline_new ("DVB-Streamer");

  dvb_source   = gst_element_factory_make ("dvbbasebin",    "dvb-source");

  dvb_demux    = gst_element_factory_make ("tsdemux",       "dvb-demux");

  dvb_v_queue  = gst_element_factory_make ("queue",         "dvb-v-queue");

  dvb_v_parse  = gst_element_factory_make ("mpegvideoparse","dvb-v-parse");

  dvb_a_queue  = gst_element_factory_make ("queue",         "dvb-a-queue");

  dvb_a_parse  = gst_element_factory_make ("mpegaudioparse","dvb-a-parse");

  dvb_mux      = gst_element_factory_make ("mpegtsmux",     "dvb-mux");

  dvb_v_queue2 = gst_element_factory_make ("queue",         "dvb-v-queue2");

  dvb_a_queue2 = gst_element_factory_make ("queue",         "dvb-a-queue2");

  dvb_sink     = gst_element_factory_make ("tcpserversink", "tcp-output");

  dvb_f_queue  = gst_element_factory_make ("queue",         "dvb-f-queue");

  dvb_f_sink   = gst_element_factory_make ("fakesink",      "fake-output");

 

  if (!dvb_pipe || !dvb_source || !dvb_demux || !dvb_v_queue || !dvb_v_parse
|| !dvb_a_queue|| !dvb_a_parse || !dvb_mux || !dvb_v_queue2 || !dvb_a_queue2
|| !dvb_sink || !dvb_f_queue || !dvb_f_sink) 

  {

    g_printerr ("One element could not be created. Exiting.\n");

    syslog(LOG_ERR, "One element could not be created. Exiting.\n");

    if(!dvb_pipe) g_printerr("DVB-Pipeline not created\n");

    else if(!dvb_source) g_printerr("DVB-Source not created\n");

    else if(!dvb_demux) g_printerr("DVB-Demux not created\n");

    else if(!dvb_v_queue) g_printerr("DVB-Video Queue not created\n");

    else if(!dvb_v_parse) g_printerr("DVB-Video Parse not created\n");

    else if(!dvb_a_queue) g_printerr("DVB-Audio Queue not created\n");

    else if(!dvb_a_parse) g_printerr("DVB-Audio Parse not created\n");

    else if(!dvb_mux) g_printerr("DVB-Mux not created\n");

    else if(!dvb_v_queue2) g_printerr("DVB-V-Queue2 not created\n");

    else if(!dvb_a_queue2) g_printerr("DVB-A-Queue2 not created\n");

    else if(!dvb_sink) g_printerr("DVB-Sink not created\n");

    else if(!dvb_f_queue) g_printerr("DVB-F-Queue not created\n");

    else if(!dvb_f_sink) g_printerr("DVB-Fakesink not created\n");

    return -1;

  }

 

 

  dvb_bus = gst_pipeline_get_bus (GST_PIPELINE (dvb_pipe));

  gst_bus_add_watch (dvb_bus, dvb_bus_call, NULL);

  gst_object_unref (dvb_bus); 

 

  gst_bin_add_many (GST_BIN (dvb_pipe), dvb_source, dvb_demux, dvb_v_queue,
dvb_v_parse, dvb_a_queue, dvb_a_parse, dvb_v_queue2, dvb_a_queue2, dvb_mux,
dvb_sink, dvb_f_queue, dvb_f_sink, NULL);

  gst_element_link (dvb_source, dvb_demux);

  gst_element_link_many(dvb_v_queue, dvb_v_parse, dvb_mux, dvb_v_queue2,
dvb_sink, NULL);

  gst_element_link_many(dvb_a_queue, dvb_a_parse, dvb_mux, dvb_a_queue2,
dvb_sink, NULL);

  gst_element_link_many(dvb_f_queue, dvb_f_sink, NULL);

 

 

 

  g_signal_connect (dvb_demux, "pad-added", G_CALLBACK (dvb_pad_added),
NULL); 

  g_signal_connect (dvb_mux, "pad-added", G_CALLBACK (dvb_mux_pad_added),
NULL); 

 

  return 1;

}

 

static void dvb_pad_added (GstElement *element, GstPad *pad, gpointer
data) /* Demuxer pad_added */

{

  GstPad *sinkpad;

  gchar *name;

  GstCaps *caps;

  gchar *caps_string;

 

  name = gst_pad_get_name (pad);

  g_print ("A new pad %s was created\n", name);

 

  caps = gst_pad_query_caps (pad, NULL);

  caps_string = gst_caps_to_string (caps);

  gst_caps_unref (caps);

  g_print (" Capability:  %s\n", caps_string);

  syslog(LOG_NOTICE, " Capability of %s:  %s\n", name, caps_string);

   

  if (strncmp (caps_string, "video/mpeg", 10) == 0) /* Only mpeg-video */

  {

    sinkpad = gst_element_get_static_pad (dvb_v_queue, "sink");

    g_print ("Dynamic pad created, linking %s to TS-Demuxer/Video-Queue\n",
name);

    syslog(LOG_NOTICE,"Dynamic pad created, linking %s to
TS-Demuxer/Video-Queue\n", name);

    gst_pad_link (pad, sinkpad);

    gst_object_unref (sinkpad);

  }

  else if (strncmp (caps_string, "audio/mpeg", 10) == 0) /* Only mpeg-audio
*/

  {

    sinkpad = gst_element_get_static_pad (dvb_a_queue, "sink");

    g_print ("Dynamic pad created, linking pad %s to
TS-Demuxer/Audio-Queue\n",name);

    syslog(LOG_NOTICE,"Dynamic pad created, linking pad %s to
TS-Demuxer/Audio-Queue\n",name);

    gst_pad_link (pad, sinkpad);

    gst_object_unref (sinkpad);

  } 

  else    /* Rest to fake */

  {

    sinkpad = gst_element_get_static_pad (dvb_f_queue, "sink"); 

    g_print ("Dynamic pad created, linking %s to TS-Demuxer/Fake-Queue\n",
name);

    syslog(LOG_NOTICE,"Dynamic pad created, linking %s to
TS-Demuxer/Fake-Queue\n", name);

    gst_pad_link (pad, sinkpad);

    gst_object_unref (sinkpad);

  }

  g_free (name);

  g_free (caps_string);

  

}

 

static void dvb_mux_pad_added (GstElement *element, GstPad *pad, gpointer
data) /* Muxer pad_added */

{

  GstPad *sinkpad;

  gchar *name;

  GstCaps *caps;

  gchar *caps_string;

 

  name = gst_pad_get_name (pad);

  g_print ("A new MUX-pad %s was created\n", name);

 

  caps = gst_pad_query_caps (pad, NULL);

  caps_string = gst_caps_to_string (caps);

  gst_caps_unref (caps);

  g_print (" Capability:  %s\n", caps_string);

  syslog(LOG_NOTICE, " Capability of %s:  %s\n", name, caps_string);

   

  if (strncmp (caps_string, "audio/mpeg", 10) == 0)

  {

    sinkpad = gst_element_get_static_pad (dvb_a_queue2, "sink");

    g_print ("Dynamic pad created, linking pad %s to
TS-Demuxer/Audio-Queue\n",name);

    syslog(LOG_NOTICE,"Dynamic pad created, linking pad %s to
TS-Muxer/Audio-Queue\n",name);

    gst_pad_link (pad, sinkpad);

    gst_object_unref (sinkpad);

  }

  else if (strncmp (caps_string, "video/mpeg", 10) == 0) 

  {

    sinkpad = gst_element_get_static_pad (dvb_v_queue2, "sink");

    g_print ("Dynamic pad created, linking %s to TS-Demuxer/Video-Queue\n",
name);

    syslog(LOG_NOTICE,"Dynamic pad created, linking %s to
TS-Muxer/Video-Queue\n", name);

    gst_pad_link (pad, sinkpad);

    gst_object_unref (sinkpad);

  } 

  g_free (name);

  g_free (caps_string);

  

}

 

int tv_send(int http_port, char *ip_adr) /* Call to run */

{

  char tmp_str[254];

 

  g_print("tv_send from %s\n", ip_adr);

 

  g_object_set (G_OBJECT (dvb_sink), "host",   ip_adr, NULL);

 

  gst_element_set_state (dvb_pipe, GST_STATE_NULL); 

 

  g_object_set (G_OBJECT (dvb_source), "adapter", ad_ad, NULL);

  g_object_set (G_OBJECT (dvb_source), "frontend", ad_fe, NULL);

 

  sprintf(tmp_str,"%s000", freq);

  g_object_set (G_OBJECT (dvb_source), "frequency", atoi(tmp_str), NULL);

  g_object_set (G_OBJECT (dvb_source), "program_numbers", s_prog, NULL);

  g_object_set (G_OBJECT (dvb_source), "polarity", pol, NULL);

 

  g_object_set (G_OBJECT (dvb_source), "symbol-rate", atoi(s_rate), NULL);

 

  g_object_set (G_OBJECT (dvb_sink), "port", http_port, NULL);

 

  g_print ("Now playing: %s on %i\n", tmp_str, http_port);

  gst_element_set_state (dvb_pipe, GST_STATE_PLAYING);

  

  g_print ("Running...\n");

 

  return 0;

}

 

 

The pipe 'dvbbasebin -> tcpserversink' (without 'demux -> parser -> mux')
runs fine.

 

The result of this pipe is: The Demuxer pad_added will call without any
problems and the pad link runs as expected. The Muxer pad_added will never
be called.

On the client a get only the first frame of the Video-Stream and see the
video-pad_added on it, but I never get the Audio-Stream and the client is
waiting.

On VLC on the client I have the same result.

I think, I forgot something like static pad definitions, but I don't know
which one.

 

I know, that I shouldn't use this forum to solve my problems, but I will be
very happy if someone has a some pity with me.

 

Thanks a lot

Bernhard

 

 

 

 

 

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20121230/683b379a/attachment-0001.html>


More information about the gstreamer-devel mailing list