GstPad *sinkpad;
GstAdapter *input_adapter;
+
+ gchar *upstream_uri;
+ GStatBuf stats;
};
G_DEFINE_TYPE (GESDemux, ges_demux, ges_base_bin_get_type ());
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:
{
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;
}
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);
}
#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
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;
/* 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) */
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. */
_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);
}
/* Activate stack */
- if (!samestack)
+ if (tear_down)
return _activate_new_stack (comp);
else
return _seek_current_stack (comp, toplevel_seek,