Hi there.
I’ve been asking for help on this topic in the Matrix instance but I think it will be better to post here so it’s easier to keep track of everything.
The app I’m trying to port uses gtk3.0 for the UI and it initially used queue2 which gave errors on the newer gstreamer version, but that’s changed now to queue instead of queue2.
Right now, audio playback is working but video is not shown in the GTK window that’s generated. I can only see a black screen and the UI buttons. The UI is completely functional except for the video playback.
Here you have some code snippets and logs from the working (gst 1.6.4) and non working (gst-1.25) version of the app:
- Pipeline creation and linking of all elements except tsdemux source pads
gst_init (&argc, &argv);
gtk_init (&argc, &argv);
/* Create the elements */
dvb.pipeline = gst_element_factory_make ("pipeline", "pipeline");
pipeline = dvb.pipeline;
dvb.dvbsrc = gst_element_factory_make ("dvbsrc", "dvbsrc");
dvb.dummy_buffer = gst_element_factory_make("identity", "dummy-buffer");
if(PERDIDA_PAQUETES != 0)
g_object_set(G_OBJECT(dvb.dummy_buffer), "drop-probability", pkt_loss, NULL);
dvb.tsdemux = gst_element_factory_make ("tsdemux", "tsdemux");
tsdemux = dvb.tsdemux;
dvb.queue_video = gst_element_factory_make ("queue", "queue_video");
dvb.pts_inspector = gst_element_factory_make("identity", "pts-inspector");
dvb.video_parse = gst_element_factory_make ("h264parse", "h264-parse");
dvb.video_dec = gst_element_factory_make ("avdec_h264", "h264dec");
dvb.video_sink = gst_element_factory_make ("xvimagesink", "xvimagesink");
dvb.queue_audio = gst_element_factory_make ("queue", "queue_audio");
dvb.audio_parse = gst_element_factory_make ("aacparse", "mpegaudioparse");
dvb.audio_dec = gst_element_factory_make ("faad", "mad");
dvb.audio_sink = gst_element_factory_make ("autoaudiosink", "autoaudiosink");
/* aumentamos el buffer de las dos queues (a/v) para que soporte mas pausas */
g_object_set(G_OBJECT(dvb.queue_video), "max-size-buffers", 1000, NULL);// default 100
g_object_set(G_OBJECT(dvb.queue_video), "max-size-bytes", 20971520, NULL);// default 2097152
g_object_set(G_OBJECT(dvb.queue_video), "max-size-time", 20000000000, NULL);// default 2000000000
g_object_set(G_OBJECT(dvb.queue_audio), "max-size-buffers", 1000, NULL);// default 100
g_object_set(G_OBJECT(dvb.queue_audio), "max-size-bytes", 20971520, NULL);// default 2097152
g_object_set(G_OBJECT(dvb.queue_audio), "max-size-time", 20000000000, NULL);// default 2000000000
/* Set up the pipeline */
/* General dvbsrc properties */
g_object_set (G_OBJECT (dvb.dvbsrc), "adapter", 0, NULL);
g_object_set (G_OBJECT (dvb.dvbsrc), "modulation", 3, NULL);
g_object_set (G_OBJECT (dvb.dvbsrc), "trans-mode", 1, NULL);
g_object_set (G_OBJECT (dvb.dvbsrc), "bandwidth-hz", 8000000, NULL);
g_object_set (G_OBJECT (dvb.dvbsrc), "code-rate-hp", 9, NULL);
g_object_set (G_OBJECT (dvb.dvbsrc), "code-rate-lp", 9, NULL);
g_object_set (G_OBJECT (dvb.dvbsrc), "guard", 0, NULL);
g_object_set (G_OBJECT (dvb.dvbsrc), "hierarchy", 4, NULL);
g_object_set (G_OBJECT (dvb.dvbsrc), "inversion", 2, NULL);
g_object_set (G_OBJECT (dvb.dvbsrc), "frequency", 770000000, NULL);
g_object_set (G_OBJECT (dvb.tsdemux), "emit-stats", TRUE, NULL);
g_object_get (G_OBJECT (dvb.tsdemux), "program-number", &program_number, NULL);
g_print("Program_number %" G_GINT16_FORMAT "\n",program_number);
gst_bin_add_many(GST_BIN(dvb.pipeline), dvb.dvbsrc, dvb.dummy_buffer, dvb.tsdemux, dvb.queue_video, dvb.pts_inspector, dvb.video_parse, dvb.video_dec, dvb.video_sink, dvb.queue_audio, dvb.audio_parse, dvb.audio_dec, dvb.audio_sink, NULL);
if (!dvb.pipeline || !dvb.dvbsrc || !dvb.dummy_buffer || !dvb.tsdemux || !dvb.queue_video || !dvb.pts_inspector || !dvb.video_parse || !dvb.video_dec || !dvb.video_sink || !dvb.queue_audio || !dvb.audio_parse || !dvb.audio_dec || !dvb.audio_sink) {
g_printerr ("Not all elements could be created.\n");
return -1;
}
else{
g_print ("Elements created\n");
}
//gst_element_link(dvb.dvbsrc, dvb.tsdemux);
if (!gst_element_link_many(dvb.dvbsrc, dvb.dummy_buffer, dvb.tsdemux, NULL) ||
!gst_element_link_many(dvb.pts_inspector, dvb.queue_video, dvb.video_parse, dvb.video_dec, dvb.video_sink, NULL) ||
!gst_element_link_many(dvb.queue_audio, dvb.audio_parse, dvb.audio_dec, dvb.audio_sink, NULL)){
g_printerr ("Elements could not be linked.\n");
return -1;
}
else{
g_print ("Elements linked\n");
}
g_signal_connect (dvb.tsdemux, "pad-added", G_CALLBACK (dynamic_addpad_dvb), &dvb);
- Function that links tsdemux src pads to the rest of the pipeline.
static void dynamic_addpad_dvb(GstElement *src, GstPad *new_pad, CustomData *dvb) {
char* pad_name = gst_pad_get_name(new_pad);
g_print(" In dynamic ADDING PAD %s\n", pad_name);
if (g_str_has_prefix(pad_name,"audio")) {
GstPad *audiodemuxsink = gst_element_get_static_pad(dvb->queue_audio,"sink");
gst_pad_link(new_pad,audiodemuxsink );
g_print ("Sink pad link: '%s'\n", pad_name);
}
else if (g_str_has_prefix(pad_name,"video")) {
GstPad *videodemuxsink = gst_element_get_static_pad(dvb->pts_inspector, "sink");
gst_pad_link(new_pad,videodemuxsink );
g_print ("Sink pad link: '%s'\n", pad_name);
}
}
Useful logs (GST_DEBUG=4):