GNOME Bugzilla – Bug 755426
decklinkvideosrc: Can't go to PAUSED again from READY
Last modified: 2015-09-25 18:33:39 UTC
Created attachment 311889 [details] debug output from code in issue The pipeline containing the decklinkvideosrc fails to return to GST_STATE_PLAYING when following the sequence of state changes Null->Playing -> Ready -> Playing. Below is the code use to produce this. #include <gst/gst.h> #include <glib.h> static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data) { GMainLoop *loop = (GMainLoop *) data; switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_EOS: g_print ("End of stream\n"); g_main_loop_quit (loop); break; case GST_MESSAGE_ERROR: { gchar *debug; GError *error; gst_message_parse_error (msg, &error, &debug); g_free (debug); g_printerr ("Error: %s\n", error->message); g_error_free (error); g_main_loop_quit (loop); break; } default: break; } return TRUE; } void printStateChange(GstStateChangeReturn value) { switch(value) { case GST_STATE_CHANGE_FAILURE: g_print("GST_STATE_CHANGE_FAILURE\n"); break; case GST_STATE_CHANGE_SUCCESS: g_print("GST_STATE_CHANGE_SUCCESS\n"); break; case GST_STATE_CHANGE_ASYNC: g_print("GST_STATE_CHANGE_ASYNC\n"); break; case GST_STATE_CHANGE_NO_PREROLL: g_print("GST_STATE_CHANGE_NO_PREROLL\n"); break; default: g_print("Unknown state\n"); break; return; } } GstStateChangeReturn handleAsync(GstElement *element) { GstState *currentState = NULL, *pendingState = NULL; GstClockTime timeout = GST_CLOCK_TIME_NONE; GstStateChangeReturn result; g_print("handeling state\n"); result = gst_element_get_state(element, currentState, pendingState, timeout); printStateChange(result); return result; } int main (int argc, char *argv[]) { GMainLoop *loop; GstElement *pipeline, *source, *conv, *sink; GstBus *bus; guint bus_watch_id; GstStateChangeReturn result; gst_init (&argc, &argv); loop = g_main_loop_new (NULL, FALSE); pipeline = gst_pipeline_new ("test"); source = gst_element_factory_make ("decklinkvideosrc", "source"); conv = gst_element_factory_make ("autovideoconvert", "converter"); sink = gst_element_factory_make ("xvimagesink", "sink"); if (!pipeline || !source || !conv || !sink) { g_printerr ("One element could not be created. Exiting.\n"); return -1; } gst_util_set_object_arg (G_OBJECT(source), "mode", "auto"); gst_util_set_object_arg (G_OBJECT(source), "connection", "hdmi"); bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); bus_watch_id = gst_bus_add_watch (bus, bus_call, loop); gst_object_unref (bus); gst_bin_add_many (GST_BIN (pipeline), source, conv, sink, NULL); gst_element_link_many (source, conv, sink, NULL); int delay = 2; //begin test of toggling states g_print ("setting state: GST_STATE_PLAYING\n"); result = gst_element_set_state (pipeline, GST_STATE_PLAYING); printStateChange(result); if(result == GST_STATE_CHANGE_ASYNC) { if(handleAsync(pipeline) == GST_STATE_CHANGE_FAILURE){ return 0; } } sleep(delay); g_print ("setting state: GST_STATE_READY\n"); result = gst_element_set_state (pipeline, GST_STATE_READY); printStateChange(result); if(result == GST_STATE_CHANGE_ASYNC) { if(handleAsync(pipeline) == GST_STATE_CHANGE_FAILURE){ return 0; } } sleep(delay); g_print ("setting state: GST_STATE_PLAYING\n"); result = gst_element_set_state (pipeline, GST_STATE_PLAYING); printStateChange(result); if(result == GST_STATE_CHANGE_ASYNC) { if(handleAsync(pipeline) == GST_STATE_CHANGE_FAILURE){ return 0; } } sleep(delay); g_print ("Returned, stopping playback\n"); result = gst_element_set_state (pipeline, GST_STATE_NULL); printStateChange(result); if(result == GST_STATE_CHANGE_ASYNC) { if(handleAsync(pipeline) == GST_STATE_CHANGE_FAILURE){ return 0; } } g_print ("Deleting pipeline\n"); gst_object_unref (GST_OBJECT (pipeline)); g_source_remove (bus_watch_id); g_main_loop_unref (loop); return 0; }
Thanks, I should have a patch for testing in a few minutes. Found the problem.
Created attachment 311895 [details] [review] decklink: Disable inputs/outputs in PAUSED->READY to allow going to PAUSED again from there
Comment on attachment 311895 [details] [review] decklink: Disable inputs/outputs in PAUSED->READY to allow going to PAUSED again from there Looks good to me. I assume you've tested this at least for the using-it-once case?
I have tested the patch and the pipeline does transition to the playing state now. However it looks like the mode is changing. It was originally set to 0(auto) but I see in the debug output it is trying to change to 1. I have attached the log. Should I create a new bug for this?
Created attachment 311908 [details] log from showing dropped frames after READY->PLAYING fix
No, let's handle it in this bug. It seems like the fix is not complete yet.
(In reply to Jeff from comment #4) > I have tested the patch and the pipeline does transition to the playing > state now. However it looks like the mode is changing. It was originally > set to 0(auto) but I see in the debug output it is trying to change to 1. I > have attached the log. Should I create a new bug for this? It changed the mode from 0 to 1 in both cases. 0 is auto, and it apparently detected NTSC for you. That's all expected: it internally configures itself with the autodetected mode, but the mode property is still taken into account and not overridden. I don't know why it doesn't transition to PLAYING, but it never calls create() anymore. Which is why frames are captured and then dropped later
Created attachment 311948 [details] [review] decklink: Add a clock epoch that is used as offset whenever restarting the clock Otherwise we're going to return times starting at 0 again after shutting down an element for a specific input/output and then using it again later.
(In reply to Sebastian Dröge (slomo) from comment #7) > (In reply to Jeff from comment #4) > > I have tested the patch and the pipeline does transition to the playing > > state now. However it looks like the mode is changing. It was originally > > set to 0(auto) but I see in the debug output it is trying to change to 1. I > > have attached the log. Should I create a new bug for this? > > It changed the mode from 0 to 1 in both cases. 0 is auto, and it apparently > detected NTSC for you. That's all expected: it internally configures itself > with the autodetected mode, but the mode property is still taken into > account and not overridden. > > > I don't know why it doesn't transition to PLAYING, but it never calls > create() anymore. Which is why frames are captured and then dropped later The connection is set to hdmi and the mode is auto. None of the other inputs to the capture card are connected. The source is outputting at 1080i5994. After setting the pipeline to playing the first time, the video is detected and displayed. After going to ready then back to playing video is not displayed in the output window, only back with a slight green bar across the top. After applying both patches, If I set the mode in the code to 1080i5994, the video does correctly. Seems like the issue is only happening now in auto mode.
Ok, so the patches solve it for you? Except in auto mode, where it's still broken? Can you open a new bug about the auto mode problem?
commit 9764e22a5c150238fe5e5368c3816bcacc8dc0a4 Author: Sebastian Dröge <sebastian@centricular.com> Date: Wed Sep 23 15:56:26 2015 +0200 decklink: Add a clock epoch that is used as offset whenever restarting the clock Otherwise we're going to return times starting at 0 again after shutting down an element for a specific input/output and then using it again later. https://bugzilla.gnome.org/show_bug.cgi?id=755426 commit e0fd5317df193acb671e67f276a2ca2e5fa8c4b8 Author: Sebastian Dröge <sebastian@centricular.com> Date: Tue Sep 22 19:35:00 2015 +0200 decklink: Disable inputs/outputs in PAUSED->READY to allow going to PAUSED again from there https://bugzilla.gnome.org/show_bug.cgi?id=755426
(In reply to Sebastian Dröge (slomo) from comment #10) > Ok, so the patches solve it for you? Except in auto mode, where it's still > broken? > > Can you open a new bug about the auto mode problem? Yes, the patches have fixed the issues except for auto mode. I opened two new bugs one for auto mode and one for ntsp-p. Thank you for fixing this so fast.