diff --git a/gst/gstpad.c b/gst/gstpad.c index c6b660ff1b..79d71a33c3 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -1987,6 +1987,50 @@ gst_pad_recalc_allowed_caps (GstPad *pad) return TRUE; } +/** + * gst_pad_recover_caps_error: + * @pad: a #GstPad that had a failed capsnego + * @allowed: possible caps for the link + * + * Attempt to recover from a failed caps negotiation. This function + * is typically called by a plugin that exhausted its list of caps + * and wants the application to resolve the issue. The application + * should connect to the pad's caps_nego_failed signal and should + * resolve the issue by connecting another element for example. + * + * Returns: TRUE when the issue was resolved, dumps detailed information + * on the console and returns FALSE otherwise. + */ +gboolean +gst_pad_recover_caps_error (GstPad *pad, GstCaps *allowed) +{ + GstElement *parent; + + g_return_val_if_fail (GST_IS_PAD (pad), FALSE); + + /* see if someone can resolve this */ + if (g_signal_has_handler_pending (G_OBJECT (pad), + gst_real_pad_signals[REAL_CAPS_NEGO_FAILED], 0, FALSE)) + { + /* clear pad caps first */ + gst_caps_replace (&GST_PAD_CAPS (pad), NULL); + + /* lets hope some signal manages to set the caps again */ + g_signal_emit (G_OBJECT (pad), gst_real_pad_signals[REAL_CAPS_NEGO_FAILED], 0, allowed); + + /* if the pad has caps now or is disabled, it's ok */ + if (GST_PAD_CAPS (pad) != NULL || !GST_PAD_IS_ACTIVE (pad)) + return TRUE; + } + + /* report error */ + parent = gst_pad_get_parent (pad); + gst_element_error (parent, "negotiation failed on pad %s:%s", + GST_DEBUG_PAD_NAME (pad)); + + return FALSE; +} + /** * gst_pad_get_bufferpool: * @pad: a #GstPad to get the bufferpool from. diff --git a/gst/gstpad.h b/gst/gstpad.h index 307597ec1e..baed59e2c1 100644 --- a/gst/gstpad.h +++ b/gst/gstpad.h @@ -217,12 +217,13 @@ struct _GstRealPad { }; struct _GstRealPadClass { - GstPadClass parent_class; + GstPadClass parent_class; /* signal callbacks */ - void (*caps_nego_failed) (GstPad *pad); - void (*linked) (GstPad *pad, GstPad *peer); - void (*unlinked) (GstPad *pad, GstPad *peer); + void (*caps_nego_failed) (GstPad *pad, GstCaps *caps); + + void (*linked) (GstPad *pad, GstPad *peer); + void (*unlinked) (GstPad *pad, GstPad *peer); }; struct _GstGhostPad { @@ -446,6 +447,8 @@ gboolean gst_pad_try_relink_filtered (GstPad *srcpad, GstPad *sinkpad, GstCaps GstCaps* gst_pad_get_allowed_caps (GstPad *pad); gboolean gst_pad_recalc_allowed_caps (GstPad *pad); +gboolean gst_pad_recover_caps_error (GstPad *pad, GstCaps *allowed); + /* data passing functions */ void gst_pad_push (GstPad *pad, GstBuffer *buf); GstBuffer* gst_pad_pull (GstPad *pad);