Skip to content

Commit

Permalink
validate:scenario: Make get_position happen on idle
Browse files Browse the repository at this point in the history
Summary:
- Add a way to force action to be executed in their own GSource dispatch, disabling chain action execution

API:
  GstValidateScenario::execute-on-idle property

Test Plan: Just running gst-validate-launcher -m

Reviewers: mathieu.duponchelle

Differential Revision: http://internal.opencreed.com:8888/D4
  • Loading branch information
tsaunier committed Feb 14, 2015
1 parent e9e7851 commit edfb5c9
Showing 1 changed file with 80 additions and 11 deletions.
91 changes: 80 additions & 11 deletions validate/gst/validate/gst-validate-scenario.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ enum
PROP_0,
PROP_RUNNER,
PROP_HANDLES_STATE,
PROP_EXECUTE_ON_IDLE,
PROP_LAST
};

Expand All @@ -91,6 +92,7 @@ static GPrivate main_thread_priv;
struct _GstValidateScenarioPrivate
{
GstValidateRunner *runner;
gboolean execute_on_idle;

GMutex lock;

Expand All @@ -116,7 +118,7 @@ struct _GstValidateScenarioPrivate

gboolean handles_state;

guint get_pos_id;
guint get_pos_id; /* Protect with SCENARIO_LOCK */
guint wait_id;

gboolean buffering;
Expand Down Expand Up @@ -863,17 +865,20 @@ _set_rank (GstValidateScenario * scenario, GstValidateAction * action)
return TRUE;
}

static gboolean
static inline gboolean
_add_get_position_source (GstValidateScenario * scenario)
{
GstValidateScenarioPrivate *priv = scenario->priv;

SCENARIO_LOCK (scenario);
if (priv->get_pos_id == 0 && priv->wait_id == 0) {
priv->get_pos_id = g_timeout_add (50, (GSourceFunc) get_position, scenario);
priv->get_pos_id = g_idle_add ((GSourceFunc) get_position, scenario);
SCENARIO_UNLOCK (scenario);

GST_DEBUG_OBJECT (scenario, "Start checking position again");
return TRUE;
}
SCENARIO_UNLOCK (scenario);

GST_DEBUG_OBJECT (scenario, "No need to start a new gsource");
return FALSE;
Expand Down Expand Up @@ -1053,6 +1058,8 @@ get_position (GstValidateScenario * scenario)

if (has_pos && has_dur) {
if (position > duration) {
_add_get_position_source (scenario);

GST_VALIDATE_REPORT (scenario,
QUERY_POSITION_SUPERIOR_DURATION,
"Reported position %" GST_TIME_FORMAT " > reported duration %"
Expand All @@ -1067,8 +1074,11 @@ get_position (GstValidateScenario * scenario)

_check_position (scenario, rate, position);

if (!_should_execute_action (scenario, act, position, rate))
if (!_should_execute_action (scenario, act, position, rate)) {
_add_get_position_source (scenario);

return TRUE;
}

type = _find_action_type (act->type);

Expand Down Expand Up @@ -1121,7 +1131,26 @@ get_position (GstValidateScenario * scenario)

/* Recurse to the next action if it is possible
* to execute right away */
return get_position (scenario);
if (!scenario->priv->execute_on_idle) {
GST_DEBUG_OBJECT (scenario, "linking next action execution");

return get_position (scenario);
} else {
_add_get_position_source (scenario);
GST_DEBUG_OBJECT (scenario, "Executing only on idle, waiting for"
" next dispatch");

return TRUE;
}
} else {
GST_DEBUG_OBJECT (scenario, "Remove source, waiting for action"
" to be done.");

SCENARIO_LOCK (scenario);
priv->get_pos_id = 0;
SCENARIO_UNLOCK (scenario);

return G_SOURCE_REMOVE;
}

return TRUE;
Expand All @@ -1134,7 +1163,10 @@ stop_waiting (GstValidateAction * action)

gst_validate_printf (action->scenario, "Stop waiting\n");

SCENARIO_LOCK (scenario);
scenario->priv->wait_id = 0;
SCENARIO_UNLOCK (scenario);

gst_validate_action_set_done (action);
_add_get_position_source (scenario);

Expand Down Expand Up @@ -1180,13 +1212,17 @@ _execute_wait (GstValidateScenario * scenario, GstValidateAction * action)
"Waiting for %" GST_TIME_FORMAT " (wait_multiplier: %f)\n",
GST_TIME_ARGS (duration), wait_multiplier);

SCENARIO_LOCK (scenario);
if (priv->get_pos_id) {
g_source_remove (priv->get_pos_id);
priv->get_pos_id = 0;
}
SCENARIO_UNLOCK (scenario);

SCENARIO_LOCK (scenario);
priv->wait_id = g_timeout_add (duration / G_USEC_PER_SEC,
(GSourceFunc) stop_waiting, action);
SCENARIO_UNLOCK (scenario);

return GST_VALIDATE_EXECUTE_ACTION_ASYNC;
}
Expand Down Expand Up @@ -1537,6 +1573,7 @@ _pipeline_freed_cb (GstValidateScenario * scenario,
{
GstValidateScenarioPrivate *priv = scenario->priv;

SCENARIO_LOCK (scenario);
if (priv->get_pos_id) {
g_source_remove (priv->get_pos_id);
priv->get_pos_id = 0;
Expand All @@ -1546,6 +1583,8 @@ _pipeline_freed_cb (GstValidateScenario * scenario,
g_source_remove (priv->wait_id);
priv->wait_id = 0;
}
SCENARIO_UNLOCK (scenario);

scenario->pipeline = NULL;

GST_DEBUG_OBJECT (scenario, "pipeline was freed");
Expand Down Expand Up @@ -1810,6 +1849,8 @@ static void
gst_validate_scenario_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstValidateScenario *self = GST_VALIDATE_SCENARIO (object);

switch (prop_id) {
case PROP_RUNNER:
/* we assume the runner is valid as long as this scenario is,
Expand All @@ -1820,6 +1861,9 @@ gst_validate_scenario_set_property (GObject * object, guint prop_id,
case PROP_HANDLES_STATE:
g_assert_not_reached ();
break;
case PROP_EXECUTE_ON_IDLE:
self->priv->execute_on_idle = g_value_get_boolean (value);
break;
default:
break;
}
Expand All @@ -1841,6 +1885,9 @@ gst_validate_scenario_get_property (GObject * object, guint prop_id,
case PROP_HANDLES_STATE:
g_value_set_boolean (value, self->priv->handles_state);
break;
case PROP_EXECUTE_ON_IDLE:
g_value_set_boolean (value, self->priv->execute_on_idle);
break;
default:
break;
}
Expand Down Expand Up @@ -1871,6 +1918,16 @@ gst_validate_scenario_class_init (GstValidateScenarioClass * klass)
" False if it is application responsibility",
FALSE, G_PARAM_READABLE));

g_object_class_install_property (object_class,
PROP_EXECUTE_ON_IDLE,
g_param_spec_boolean ("execute-on-idle",
"Force waiting between actions",
"Always execute actions on idle and do not chain them"
" to execute as fast as possible. That is usefull if action execution"
" can lead to the addition of source on the same main loop."
" It allows those other GSources to have a chance to be dispatch between"
" validate actions execution", FALSE, G_PARAM_READWRITE));

/**
* GstValidateScenario::done:
* @scenario: The scenario runing
Expand Down Expand Up @@ -2261,6 +2318,8 @@ _execute_sub_action_action (GstValidateAction * action)
void
gst_validate_action_set_done (GstValidateAction * action)
{
GstValidateScenario *scenario = action->scenario;

if (action->state == GST_VALIDATE_EXECUTE_ACTION_INTERLACED) {

if (action->scenario) {
Expand All @@ -2274,17 +2333,27 @@ gst_validate_action_set_done (GstValidateAction * action)
}

action->state = _execute_sub_action_action (action);
if (action->state == GST_VALIDATE_EXECUTE_ACTION_ASYNC) {
GST_DEBUG_OBJECT (scenario, "Sub action executed ASYNC");

return;
}

if (action->scenario) {
if (scenario) {
if (GPOINTER_TO_INT (g_private_get (&main_thread_priv))) {
GST_DEBUG_OBJECT (action->scenario, "Right thread, executing next?");
get_position (action->scenario);
} else {
if (!scenario->priv->execute_on_idle) {
GST_DEBUG_OBJECT (scenario, "Right thread, executing next?");
get_position (scenario);

return;
} else
GST_DEBUG_OBJECT (scenario, "Right thread, but executing only on idle");
} else
GST_DEBUG_OBJECT (action->scenario, "Not doing anything outside the"
" 'main' thread");

}
}

_add_get_position_source (scenario);
}

/**
Expand Down

0 comments on commit edfb5c9

Please sign in to comment.