[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