[gst-devel] Timestamping problem with gdppay element

4ernov 4ernov at gmail.com
Tue Nov 16 16:19:19 CET 2010


Hello,

I continue working at some complex pipeline which I wrote about
previously ("Problems with video, tee and queues"). Solution proposed
by Marco works just fine for the pipeline I noticed there:

                     queue -- xvimagesink
                  /
playbin -- tee
                  \
                    queue -- fakesink

converted dynamically to:

                     queue -- xvimagesink
                  /
playbin -- tee
                  \
                     queue -- xvimagesink

But the final destination of my experiments is the following case:


                     queue -- xvimagesink
                  /
playbin -- tee
                  \
                    queue -- fakesink

converted dynamically to:

                     queue -- xvimagesink
                  /
playbin -- tee
                  \
                     queue -- gdppay -- filesink

with remote end like this:

filesrc -- gdpdepay -- decodebin -- ffmpegcolorspace -- xvimagesink

And for this case it doesn't work.

Well, what is the result for now:
1. Everything works fine if the final pipeline is hardcoded from the
beginning (i.e. we have gdppay right from start).
2. Everything works fine without gdppay (with xvimagesink or smth. instead).

But when I start the desired configuration I have the following:
1. Xv window of the remote end appears and stalls the playing but
start to refresh slowly (several frames are shown rapidly in intervals
of 4-5 secs)
2. Xv window of the main pipeline stops to play properly, too, and
behaves just the same way like the remote one.
3. The main pipeline prints the following warnings to console:

0:00:07.134552825 19490  0x95be9c8 WARN  gdppay
gstgdppay.c:594:gst_gdp_pay_chain:<gdppay0> did not receive
new-segment before first buffer
0:00:14.095700940 19490  0x948d2b0 WARN  ffmpeg
gstffmpegdec.c:2002:gst_ffmpegdec_video_frame:<ffdec_h2640> Dropping
non-keyframe (seek/init)
0:00:14.691007420 19490  0x95b4978 WARN  basesink
gstbasesink.c:2686:gst_base_sink_is_too_late:<xvimagesink0> warning: A
lot of buffers are being dropped.
0:00:14.691055331 19490  0x95b4978 WARN  basesink
gstbasesink.c:2686:gst_base_sink_is_too_late:<xvimagesink0> warning:
There may be a timestamping problem, or this computer is too slow.

Here's the source code of the main app:

#include <gst/gst.h>
#include <glib.h>

GstElement *_pipeline, *_fakesink, *_remotesink, *_valve, *_mpoint,
*_videobin, *_pipe;

void create_pipeline_bin()
{
	GstElement *tee, *queue1, *queue2, *xvimagesink;

	_pipeline      = gst_element_factory_make("playbin",  NULL);

	tee			= gst_element_factory_make("tee",  NULL);
	xvimagesink   = gst_element_factory_make("xvimagesink", NULL);

	GstPad* pad;

	_videobin = gst_bin_new("videobin");
	queue1			= gst_element_factory_make("queue", NULL);
	queue2			= gst_element_factory_make("queue", NULL);
	_valve			= gst_element_factory_make("valve", NULL);

	_fakesink		= gst_element_factory_make("fakesink", NULL);

	gst_object_ref(_fakesink);

	_mpoint = _valve;

	gst_bin_add_many(GST_BIN(_videobin), tee, queue1, queue2, _valve,
xvimagesink, _fakesink, NULL);

	gst_element_link_many(tee, queue1, xvimagesink, NULL);
	gst_element_link_many(tee, queue2, _valve, _fakesink, NULL);
	pad = gst_element_get_static_pad (tee, "sink");
	gst_element_add_pad (_videobin, gst_ghost_pad_new ("sink", pad));
	gst_object_unref (GST_OBJECT (pad));

	g_object_set(G_OBJECT (_pipeline), "uri", "file:///home/alex/test.mkv", NULL);
	g_object_set(G_OBJECT (_pipeline), "video-sink", _videobin, NULL);
	g_object_set(G_OBJECT (_pipeline), "audio-sink", NULL, NULL);

	gst_element_set_state (_pipeline, GST_STATE_PLAYING);
}

void create_remote_bin()
{
	GstElement *gdppay;
	GstPad* pad;

	gdppay		= gst_element_factory_make("gdppay",  NULL);
	_pipe		= gst_element_factory_make("filesink",  NULL);

	g_object_set(G_OBJECT (_pipe), "location",
"/home/alex/work/playground/test.gdp", NULL);

	_remotesink = gst_bin_new("gdpbin");
	gst_bin_add_many(GST_BIN(_remotesink), gdppay, _pipe, NULL);
	gst_element_link_many(gdppay, _pipe, NULL);

	pad = gst_element_get_static_pad (gdppay, "sink");
	gst_element_add_pad (_remotesink, gst_ghost_pad_new ("sink", pad));
	gst_object_unref (GST_OBJECT (pad));
}

void connect_remote_client()
{
	if (_remotesink && _mpoint && _videobin)
	{
		g_object_set(G_OBJECT (_valve), "drop", TRUE, NULL);

		gst_element_unlink(_mpoint, _fakesink);
		gst_bin_remove(GST_BIN(_videobin), _fakesink);
		gst_element_set_state (_fakesink, GST_STATE_NULL);

		gst_bin_add(GST_BIN(_videobin), _remotesink);
		gst_element_link(_mpoint, _remotesink);

		gst_element_sync_state_with_parent(_remotesink);

		gst_element_set_state (_pipeline, GST_STATE_PLAYING);
		g_object_set(G_OBJECT (_valve), "drop", FALSE, NULL);
	}
}

gboolean connect_callback(gpointer)
{
	connect_remote_client();
	return FALSE;
}

int main(int argc, char *argv[])
{
	gst_init(&argc, &argv);

	gst_debug_set_active(true);
	gst_debug_set_default_threshold(GST_LEVEL_WARNING);

	create_remote_bin();
	create_pipeline_bin();

	g_timeout_add(7000, connect_callback, NULL);

	GMainLoop *loop;

        loop = g_main_loop_new (NULL, FALSE);

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

        return 0;
}

End on the remote end there's gst-launch command:

gst-launch -v filesrc location=/home/alex/work/playground/test.gdp !
gdpdepay ! decodebin ! ffmpegcolorspace ! xvimagesink

What is the essential problem? Is it possible to keep the "main"
branch (i.e. with xvimagesink in main pipeline) playing while the
second establishes connection via GDP protocol and then keep them
synced? I hoped on valve element very much and it works perfectly for
a couple xvimagesink but with GDP element it doesn't work, everything
is almost stalled.




More information about the gstreamer-devel mailing list