GNOME Bugzilla – Bug 561241
metadatademux pad activation deadlock
Last modified: 2009-01-09 23:23:18 UTC
I found a bug similar to http://bugzilla.gnome.org/show_bug.cgi?id=560380 in metadatademux. I'm seeing it frequently running Elisa but I can't isolate it in a script. Again the problem is that filesrc is activated in push mode while downstream is pulling. The source of the problem is in gstbasemetadata.c:gst_base_metadata_sink_activate static gboolean gst_base_metadata_sink_activate (GstPad * pad) { GstBaseMetadata *filter = NULL; gboolean ret = TRUE; filter = GST_BASE_METADATA (GST_PAD_PARENT (pad)); if (!gst_pad_check_pull_range (pad) || !gst_pad_activate_pull (filter->sinkpad, TRUE)) { /* Fail here ? nothing to be done by now, activate push mode */ return gst_pad_activate_push (pad, TRUE); } /* try to base */ if (filter->state == MT_STATE_NULL) { ret = gst_base_metadata_pull_range_parse (filter); } if (ret) { gst_pad_activate_pull (pad, FALSE); gst_pad_activate_push (filter->srcpad, FALSE); if (!gst_pad_is_active (pad)) { ret = gst_pad_activate_push (filter->srcpad, TRUE); ret = ret && gst_pad_activate_push (pad, TRUE); } } return ret; } It tries to do something like typefind does, but looks really wrong. Here's the stack trace I get when it deadlocks: (gdb) thr a a bt
+ Trace 209936
This seems to solve my issue: --- ext/metadata/gstbasemetadata.c 18 Jun 2008 06:31:11 -0000 1.9 +++ ext/metadata/gstbasemetadata.c 17 Nov 2008 17:50:52 -0000 @@ -1807,16 +1807,24 @@ } if (ret) { - gst_pad_activate_pull (pad, FALSE); - gst_pad_activate_push (filter->srcpad, FALSE); - if (!gst_pad_is_active (pad)) { - ret = gst_pad_activate_push (filter->srcpad, TRUE); - ret = ret && gst_pad_activate_push (pad, TRUE); + GstActivateMode mode; + + /* in gst_base_metadata_pull_range_parse() we could have triggered + * negotiation and plugged new downstream elements. + * If GST_PAD_ACTIVATE_MODE (filter->srcpad) is GST_ACTIVATE_PULL it means + * that downstream is active in pull mode so we don't deactivate pull mode. + */ + GST_OBJECT_LOCK (filter->srcpad); + mode = GST_PAD_ACTIVATE_MODE (filter->srcpad); + GST_OBJECT_UNLOCK (filter->srcpad); + + if (mode != GST_ACTIVATE_PULL) { + /* change from PULL to PUSH */ + gst_pad_activate_push (pad, TRUE); } } return ret; - }