validate: Wait for switch-track to complete before executing next action

This action type can take some time, we need to make sure that the
combiner/input-selector element properly pushed a buffer marked
as DISCONT to concider the action is done.

https://bugzilla.gnome.org/show_bug.cgi?id=743994
This commit is contained in:
Thibault Saunier 2014-12-11 14:21:12 +01:00
parent d7b5d57305
commit bee292f548
2 changed files with 67 additions and 5 deletions

View file

@ -702,6 +702,19 @@ find_sink_pad_index (GstElement * element, GstPad * pad)
return index; return index;
} }
static GstPadProbeReturn
_check_select_pad_done (GstPad * pad, GstPadProbeInfo * info,
GstValidateAction * action)
{
if (GST_BUFFER_FLAG_IS_SET (info->data, GST_BUFFER_FLAG_DISCONT)) {
gst_validate_action_set_done (action);
return GST_PAD_PROBE_REMOVE;
}
return GST_PAD_PROBE_OK;
}
static gboolean static gboolean
_execute_switch_track (GstValidateScenario * scenario, _execute_switch_track (GstValidateScenario * scenario,
GstValidateAction * action) GstValidateAction * action)
@ -718,7 +731,10 @@ _execute_switch_track (GstValidateScenario * scenario,
input_selector = input_selector =
find_input_selector_with_type (GST_BIN (scenario->pipeline), type); find_input_selector_with_type (GST_BIN (scenario->pipeline), type);
if (input_selector) { if (input_selector) {
GstPad *pad, *cpad; GstState state, next;
GstPad *pad, *cpad, *srcpad;
GstValidateExecuteActionReturn res = GST_VALIDATE_EXECUTE_ACTION_OK;
if ((str_index = gst_structure_get_string (action->structure, "index"))) { if ((str_index = gst_structure_get_string (action->structure, "index"))) {
if (!gst_structure_get_uint (action->structure, "index", &index)) { if (!gst_structure_get_uint (action->structure, "index", &index)) {
@ -748,16 +764,28 @@ _execute_switch_track (GstValidateScenario * scenario,
gst_validate_printf (action, "Switching to track number: %i," gst_validate_printf (action, "Switching to track number: %i,"
" (from %s:%s to %s:%s)\n", " (from %s:%s to %s:%s)\n",
index, GST_DEBUG_PAD_NAME (cpad), GST_DEBUG_PAD_NAME (pad)); index, GST_DEBUG_PAD_NAME (cpad), GST_DEBUG_PAD_NAME (pad));
if (gst_element_get_state (scenario->pipeline, &state, &next, 0) &&
state == GST_STATE_PLAYING && next == GST_STATE_VOID_PENDING) {
srcpad = gst_element_get_static_pad (input_selector, "src");
gst_pad_add_probe (srcpad,
GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_BUFFER_LIST,
(GstPadProbeCallback) _check_select_pad_done, action, NULL);
res = GST_VALIDATE_EXECUTE_ACTION_ASYNC;
gst_object_unref (srcpad);
}
g_object_set (input_selector, "active-pad", pad, NULL); g_object_set (input_selector, "active-pad", pad, NULL);
gst_object_unref (pad); gst_object_unref (pad);
gst_object_unref (cpad); gst_object_unref (cpad);
gst_object_unref (input_selector); gst_object_unref (input_selector);
return TRUE; return res;
} }
/* No selector found -> Failed */ /* No selector found -> Failed */
return FALSE; return GST_VALIDATE_EXECUTE_ACTION_ERROR;
} }
static gboolean static gboolean

View file

@ -236,18 +236,35 @@ _execute_set_subtitles (GstValidateScenario * scenario,
return TRUE; return TRUE;
} }
static GstPadProbeReturn
_check_pad_selection_done (GstPad * pad, GstPadProbeInfo * info,
GstValidateAction * action)
{
if (GST_BUFFER_FLAG_IS_SET (info->data, GST_BUFFER_FLAG_DISCONT)) {
gst_validate_action_set_done (action);
return GST_PAD_PROBE_REMOVE;
}
return GST_PAD_PROBE_OK;
}
static gboolean static gboolean
_execute_switch_track (GstValidateScenario * scenario, _execute_switch_track (GstValidateScenario * scenario,
GstValidateAction * action) GstValidateAction * action)
{ {
gint index, n; gint index, n;
GstPad *srcpad;
GstElement *combiner;
GstPad *oldpad, *newpad; GstPad *oldpad, *newpad;
gboolean relative = FALSE, disabling = FALSE;
const gchar *type, *str_index; const gchar *type, *str_index;
gint flags, current, tflag; gint flags, current, tflag;
gchar *tmp, *current_txt; gchar *tmp, *current_txt;
gint res = GST_VALIDATE_EXECUTE_ACTION_OK;
gboolean relative = FALSE, disabling = FALSE;
if (!(type = gst_structure_get_string (action->structure, "type"))) if (!(type = gst_structure_get_string (action->structure, "type")))
type = "audio"; type = "audio";
@ -285,6 +302,7 @@ _execute_switch_track (GstValidateScenario * scenario,
} }
if (!disabling) { if (!disabling) {
GstState state, next;
tmp = g_strdup_printf ("get-%s-pad", type); tmp = g_strdup_printf ("get-%s-pad", type);
g_signal_emit_by_name (G_OBJECT (scenario->pipeline), tmp, current, g_signal_emit_by_name (G_OBJECT (scenario->pipeline), tmp, current,
&oldpad); &oldpad);
@ -295,6 +313,22 @@ _execute_switch_track (GstValidateScenario * scenario,
GST_DEBUG_PAD_NAME (newpad)); GST_DEBUG_PAD_NAME (newpad));
flags |= tflag; flags |= tflag;
g_free (tmp); g_free (tmp);
if (gst_element_get_state (scenario->pipeline, &state, &next, 0) &&
state == GST_STATE_PLAYING && next == GST_STATE_VOID_PENDING) {
combiner = GST_ELEMENT (gst_object_get_parent (GST_OBJECT (newpad)));
srcpad = gst_element_get_static_pad (combiner, "src");
gst_object_unref (combiner);
gst_pad_add_probe (srcpad,
GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_BUFFER_LIST,
(GstPadProbeCallback) _check_pad_selection_done, action, NULL);
gst_object_unref (srcpad);
res = GST_VALIDATE_EXECUTE_ACTION_ASYNC;
}
} else { } else {
gst_validate_printf (action, "Disabling track type %s", type); gst_validate_printf (action, "Disabling track type %s", type);
} }
@ -302,7 +336,7 @@ _execute_switch_track (GstValidateScenario * scenario,
g_object_set (scenario->pipeline, "flags", flags, current_txt, index, NULL); g_object_set (scenario->pipeline, "flags", flags, current_txt, index, NULL);
g_free (current_txt); g_free (current_txt);
return TRUE; return res;
} }
static void static void