mpegtsmux (need help!)
Bernhard Graaf
bernhard.graaf at gmx.de
Sun Dec 30 02:18:36 PST 2012
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/5329d2ca/attachment-0001.html>
More information about the gstreamer-devel
mailing list