diff --git a/ges/ges-structured-interface.c b/ges/ges-structured-interface.c index 45502c6a3e..04ad5be261 100644 --- a/ges/ges-structured-interface.c +++ b/ges/ges-structured-interface.c @@ -150,7 +150,6 @@ _check_fields (GstStructure * structure, FieldsError fields_error, if (error) *error = g_error_new_literal (GES_ERROR, 0, msg->str); - GST_ERROR ("%s", msg->str); g_string_free (msg, TRUE); diff --git a/plugins/ges/gesdemux.c b/plugins/ges/gesdemux.c index 6017978c88..1fa2128219 100644 --- a/plugins/ges/gesdemux.c +++ b/plugins/ges/gesdemux.c @@ -62,6 +62,9 @@ struct _GESDemux GstPad *sinkpad; GstAdapter *input_adapter; + + gchar *upstream_uri; + GStatBuf stats; }; G_DEFINE_TYPE (GESDemux, ges_demux, ges_base_bin_get_type ()); @@ -166,8 +169,54 @@ error_loading_asset_cb (GESProject * project, GError * error, gchar * id, static gboolean ges_demux_src_probe (GstPad * pad, GstPadProbeInfo * info, GstElement * parent) { - GstEvent *event = info->data; + GESDemux *self = GES_DEMUX (parent); + GstEvent *event; + if (info->type & (GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM)) { + GstQuery *query = info->data; + + if (GST_QUERY_TYPE (query) == GST_QUERY_CUSTOM) { + GstStructure *structure = + (GstStructure *) gst_query_get_structure (query); + + if (gst_structure_has_name (structure, + "NleCompositionQueryNeedsTearDown")) { + GstQuery *uri_query = gst_query_new_uri (); + + if (gst_pad_peer_query (self->sinkpad, uri_query)) { + gchar *upstream_uri = NULL; + GStatBuf stats; + gst_query_parse_uri (uri_query, &upstream_uri); + + if (gst_uri_has_protocol (upstream_uri, "file")) { + gchar *location = gst_uri_get_location (upstream_uri); + + g_stat (location, &stats); + g_free (location); + GST_OBJECT_LOCK (self); + if (g_strcmp0 (upstream_uri, self->upstream_uri) + || stats.st_mtime != self->stats.st_mtime + || stats.st_size != self->stats.st_size) { + GST_INFO_OBJECT (self, + "Underlying file changed, asking for an update"); + gst_structure_set (structure, "result", G_TYPE_BOOLEAN, TRUE, + NULL); + g_free (self->upstream_uri); + self->upstream_uri = upstream_uri; + self->stats = stats; + } else { + g_free (upstream_uri); + } + GST_OBJECT_UNLOCK (self); + } + } + gst_query_unref (uri_query); + } + } + + return GST_PAD_PROBE_OK; + } + event = info->data; switch (GST_EVENT_TYPE (event)) { case GST_EVENT_STREAM_START: { @@ -198,7 +247,8 @@ static gboolean ges_demux_set_srcpad_probe (GstElement * element, GstPad * pad, gpointer user_data) { - gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, + gst_pad_add_probe (pad, + GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | GST_PAD_PROBE_TYPE_QUERY_UPSTREAM, (GstPadProbeCallback) ges_demux_src_probe, element, NULL); return TRUE; } @@ -234,21 +284,29 @@ ges_demux_create_timeline (GESDemux * self, gchar * uri, GError ** error) query = gst_query_new_uri (); if (gst_pad_peer_query (self->sinkpad, query)) { - gchar *upstream_uri = NULL; GList *assets, *tmp; - gst_query_parse_uri (query, &upstream_uri); + + GST_OBJECT_LOCK (self); + g_free (self->upstream_uri); + gst_query_parse_uri (query, &self->upstream_uri); + if (gst_uri_has_protocol (self->upstream_uri, "file")) { + gchar *location = gst_uri_get_location (self->upstream_uri); + + g_stat (location, &self->stats); + g_free (location); + } assets = ges_project_list_assets (project, GES_TYPE_URI_CLIP); for (tmp = assets; tmp; tmp = tmp->next) { const gchar *id = ges_asset_get_id (tmp->data); - if (!g_strcmp0 (id, upstream_uri)) { + if (!g_strcmp0 (id, self->upstream_uri)) { g_set_error (error, GST_STREAM_ERROR, GST_STREAM_ERROR_DEMUX, - "Recursively loading uri: %s", upstream_uri); + "Recursively loading uri: %s", self->upstream_uri); break; } } - + GST_OBJECT_UNLOCK (self); g_list_free_full (assets, g_object_unref); } diff --git a/plugins/nle/nlecomposition.c b/plugins/nle/nlecomposition.c index c0ad82b381..828a36a4cb 100644 --- a/plugins/nle/nlecomposition.c +++ b/plugins/nle/nlecomposition.c @@ -3108,6 +3108,23 @@ _dump_stack (NleComposition * comp, GNode * stack) #endif } +static gboolean +nle_composition_query_needs_teardown (NleComposition * comp, + NleUpdateStackReason reason) +{ + gboolean res = FALSE; + GstStructure *structure = + gst_structure_new ("NleCompositionQueryNeedsTearDown", "reason", + G_TYPE_STRING, UPDATE_PIPELINE_REASONS[reason], NULL); + GstQuery *query = gst_query_new_custom (GST_QUERY_CUSTOM, structure); + + gst_pad_query (NLE_OBJECT_SRC (comp), query); + gst_structure_get_boolean (structure, "result", &res); + + gst_query_unref (query); + return res; +} + /* * update_pipeline: * @comp: The #NleComposition @@ -3129,7 +3146,7 @@ update_pipeline (NleComposition * comp, GstClockTime currenttime, gint32 seqnum, GstEvent *toplevel_seek; GNode *stack = NULL; - gboolean samestack = FALSE; + gboolean tear_down = FALSE; gboolean updatestoponly = FALSE; GstState state = GST_STATE (comp); NleCompositionPrivate *priv = comp->priv; @@ -3167,7 +3184,8 @@ update_pipeline (NleComposition * comp, GstClockTime currenttime, gint32 seqnum, /* Get new stack and compare it to current one */ stack = get_clean_toplevel_stack (comp, ¤ttime, &new_start, &new_stop); - samestack = are_same_stacks (priv->current, stack); + tear_down = !are_same_stacks (priv->current, stack) + || nle_composition_query_needs_teardown (comp, update_reason); /* set new current_stack_start/stop (the current zone over which the new stack * is valid) */ @@ -3194,7 +3212,7 @@ update_pipeline (NleComposition * comp, GstClockTime currenttime, gint32 seqnum, stopchanged = priv->current_stack_stop != currenttime; } - if (samestack) { + if (!tear_down) { if (startchanged || stopchanged) { /* Update seek events need to be flushing if not in PLAYING, * else we will encounter deadlocks. */ @@ -3210,7 +3228,7 @@ update_pipeline (NleComposition * comp, GstClockTime currenttime, gint32 seqnum, _remove_update_actions (comp); /* If stacks are different, unlink/relink objects */ - if (!samestack) { + if (tear_down) { _dump_stack (comp, stack); _deactivate_stack (comp, update_reason); _relink_new_stack (comp, stack, toplevel_seek); @@ -3248,7 +3266,7 @@ update_pipeline (NleComposition * comp, GstClockTime currenttime, gint32 seqnum, } /* Activate stack */ - if (!samestack) + if (tear_down) return _activate_new_stack (comp); else return _seek_current_stack (comp, toplevel_seek,