GMutex mcontext_lock;
GList *gsources;
GList *update_gsources;
+ GList *seek_gsources;
gboolean running;
gboolean initialized;
#define GET_TASK_LOCK(comp) (&(GNL_COMPOSITION(comp)->task_rec_lock))
static void
+_assert_proper_thread (GnlComposition * comp)
+{
+ if (comp->task && gst_task_get_state (comp->task) != GST_TASK_STOPPED &&
+ g_thread_self () != comp->task->thread) {
+ g_warning ("Trying to touch children in a thread different from"
+ " its dedicated thread!");
+ }
+}
+
+static void
_remove_all_sources (GnlComposition * comp)
{
GSource *source;
}
static void
+_destroy_gsource (GSource * source)
+{
+ g_source_destroy (source);
+ g_source_unref (source);
+}
+
+static void
+_remove_all_update_sources (GnlComposition * comp)
+{
+ MAIN_CONTEXT_LOCK (comp);
+ g_list_free_full (comp->priv->update_gsources,
+ (GDestroyNotify) _destroy_gsource);
+ comp->priv->update_gsources = NULL;
+ MAIN_CONTEXT_UNLOCK (comp);
+}
+
+static void
+_remove_all_seek_sources (GnlComposition * comp)
+{
+ MAIN_CONTEXT_LOCK (comp);
+ g_list_free_full (comp->priv->seek_gsources,
+ (GDestroyNotify) _destroy_gsource);
+ comp->priv->seek_gsources = NULL;
+ MAIN_CONTEXT_UNLOCK (comp);
+}
+
+static void
iterate_main_context_func (GnlComposition * comp)
{
if (comp->priv->running == FALSE) {
if (func == (GSourceFunc) _update_pipeline_func)
priv->update_gsources = g_list_prepend (priv->update_gsources, source);
+ else if (func == (GSourceFunc) _seek_pipeline_func)
+ priv->seek_gsources = g_list_prepend (priv->seek_gsources, source);
else
priv->gsources = g_list_prepend (priv->gsources, source);
GnlComposition *comp = GNL_COMPOSITION (object);
GnlCompositionPrivate *priv = comp->priv;
+ _assert_proper_thread (comp);
+
COMP_OBJECTS_LOCK (comp);
if (priv->current) {
g_node_destroy (priv->current);
GST_DEBUG_OBJECT (comp, "resetting");
+ _assert_proper_thread (comp);
+
COMP_OBJECTS_LOCK (comp);
priv->segment_start = GST_CLOCK_TIME_NONE;
priv->segment_stop = GST_CLOCK_TIME_NONE;
GST_DEBUG_OBJECT (comp, "Setting all children state to %s",
gst_element_state_get_name (state));
- COMP_OBJECTS_LOCK (comp);
gst_element_set_state (comp->priv->current_bin, state);
for (tmp = comp->priv->objects_start; tmp; tmp = tmp->next)
gst_element_set_state (tmp->data, state);
for (tmp = comp->priv->expandables; tmp; tmp = tmp->next)
gst_element_set_state (tmp->data, state);
-
- COMP_OBJECTS_UNLOCK (comp);
}
static GstStateChangeReturn
NULL, G_PRIORITY_DEFAULT);
break;
case GST_STATE_CHANGE_PAUSED_TO_READY:
+ _stop_task (comp);
+
+ _remove_all_update_sources (comp);
+ _remove_all_seek_sources (comp);
_set_all_children_state (comp, GST_STATE_READY);
gnl_composition_reset (comp);
+
+ _start_task (comp);
break;
case GST_STATE_CHANGE_READY_TO_NULL:
_stop_task (comp);
GnlObject *cobj = (GnlObject *) comp;
GnlCompositionPrivate *priv = comp->priv;
+ _assert_proper_thread (comp);
+
if (!priv->objects_start) {
GST_LOG ("no objects, resetting everything to 0");
return FALSE;
}
-static void
-_destroy_gsource (GSource * source)
-{
- g_source_destroy (source);
- g_source_unref (source);
-}
-
-static void
-_remove_all_update_sources (GnlComposition * comp)
-{
- MAIN_CONTEXT_LOCK (comp);
- g_list_free_full (comp->priv->update_gsources,
- (GDestroyNotify) _destroy_gsource);
- comp->priv->update_gsources = NULL;
- MAIN_CONTEXT_UNLOCK (comp);
-}
-
/*
* update_pipeline:
* @comp: The #GnlComposition
GstClockTime new_stop = GST_CLOCK_TIME_NONE;
GstClockTime new_start = GST_CLOCK_TIME_NONE;
-
GstState nextstate = (GST_STATE_NEXT (comp) == GST_STATE_VOID_PENDING) ?
GST_STATE (comp) : GST_STATE_NEXT (comp);
+ _assert_proper_thread (comp);
+
GST_DEBUG_OBJECT (comp,
"currenttime:%" GST_TIME_FORMAT
" Reason: %s", GST_TIME_ARGS (currenttime),