Hello,
I've already posted a couple of questions here concerning my case with duplicated video stream. Now it works quite right but some strange behavior still exists. When I change the pipeline while it's in PAUSED state and then try to resume it (setting state PLAYING with gst_element_set_state) it never continues to play anymore. gst_element_set_state() returns GST_STATE_CHANGE_ASYNC and gst_element_get_state() (as in documentation) waits for change to complete forever. Here's a test program: #include <glib.h> #include <gst/gst.h> GstElement *_pipeline, *_fakesink, *_remotesink, *_mpoint, *_queue1, *_queue2, *_videobin, *_pipe, *gdppay; void create_pipeline_bin() { GstElement *tee, *queue1, *queue2, *valve, *xvimagesink, *audiosink; _pipeline = gst_element_factory_make("playbin", NULL); tee = gst_element_factory_make("tee", NULL); xvimagesink = gst_element_factory_make("ximagesink", NULL); GstPad* pad; _videobin = gst_bin_new("videobin"); _queue1 = queue1 = gst_element_factory_make("queue", NULL); _queue2 = queue2 = gst_element_factory_make("queue", NULL); valve = gst_element_factory_make("valve", NULL); _fakesink = gst_element_factory_make("fakesink", NULL); audiosink = 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.mp4", NULL); g_object_set(G_OBJECT (_pipeline), "video-sink", _videobin, NULL); g_object_set(G_OBJECT (_pipeline), "audio-sink", audiosink, NULL); gst_element_set_state (_pipeline, GST_STATE_PLAYING); } void create_remote_bin() { GstElement *videomixer, *ffmpegcolorspace; GstPad* pad; videomixer = gst_element_factory_make("videomixer", NULL); ffmpegcolorspace = gst_element_factory_make("ffmpegcolorspace", NULL); _pipe = gst_element_factory_make("xvimagesink", NULL); _remotesink = gst_bin_new("vmixerbin"); gst_bin_add_many(GST_BIN(_remotesink), videomixer, ffmpegcolorspace, _pipe, NULL); gst_element_link_many(videomixer, ffmpegcolorspace, _pipe, NULL); pad = gst_element_get_request_pad (videomixer, "sink_%d"); gst_element_add_pad (_remotesink, gst_ghost_pad_new ("sink", pad)); gst_object_unref (GST_OBJECT (pad)); gst_object_ref(_remotesink); } void connect_remote_client() { if (_remotesink && _mpoint && _videobin) { GstState state = GST_STATE(_pipeline); 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, state); } } void disconnect_remote_client() { if (_remotesink && _mpoint && _videobin && _fakesink) { GstState state = GST_STATE(_pipeline); gst_element_unlink(_mpoint, _remotesink); gst_bin_remove(GST_BIN(_videobin), _remotesink); gst_element_set_state (_remotesink, GST_STATE_NULL); gst_bin_add(GST_BIN(_videobin), _fakesink); gst_element_link(_mpoint, _fakesink); gst_element_sync_state_with_parent(_fakesink); gst_element_set_state (_pipeline, state); } } void pause_pipeline() { gst_element_set_state(_pipeline, GST_STATE_PAUSED); } void play_pipeline() { gst_element_set_state(_pipeline, GST_STATE_PLAYING); } gboolean connect_callback(gpointer) { connect_remote_client(); return FALSE; } gboolean disconnect_callback(gpointer) { disconnect_remote_client(); return FALSE; } gboolean pause_callback(gpointer) { pause_pipeline(); return FALSE; } gboolean play_callback(gpointer) { play_pipeline(); return FALSE; } int main(int argc, char *argv[]) { GMainLoop* loop = g_main_loop_new (NULL, FALSE); gst_init(&argc, &argv); create_remote_bin(); create_pipeline_bin(); g_timeout_add(7000, connect_callback, NULL); g_timeout_add(16000, pause_callback, NULL); g_timeout_add(17000, disconnect_callback, NULL); g_timeout_add(18000, play_callback, NULL); g_main_loop_run (loop); return 0; } Second xvimagesink connects successfully in 7 secs after start. Then in 16 sec the pipeline is set to PAUSED and in 17 sec second video sink is disconnected. But in 18 sec pipeline doesn't want to get to PLAYING state anymore. No messages is posted to output after trying to set the pipeline PLAYING state, even on DEBUG log level. One certain message is posted before it: GST_STATES gstelement.c:2515:gst_element_set_state_func:<playbin0> element was busy with async state change I should also notice that if I make pipeline changes in PLAYING state everything work flawlessly. Is it bug in GStreamer or should I make state change any other way? ------------------------------------------------------------------------------ What happens now with your Lotus Notes apps - do you make another costly upgrade, or settle for being marooned without product support? Time to move off Lotus Notes and onto the cloud with Force.com, apps are easier to build, use, and manage than apps on traditional platforms. Sign up for the Lotus Notes Migration Kit to learn more. http://p.sf.net/sfu/salesforce-d2d _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/gstreamer-devel |
Free forum by Nabble | Edit this page |