aggregator: Add GstAggregator::negotiate()

For consistency with other base classes and for allowing to completely
override the negotiation behaviour.
This commit is contained in:
Sebastian Dröge 2019-08-14 10:05:53 +03:00
parent e024926636
commit aebff1fcaa
2 changed files with 61 additions and 8 deletions

View file

@ -1008,9 +1008,8 @@ no_decide_allocation:
}
/* WITH SRC_LOCK held */
static GstFlowReturn
gst_aggregator_update_src_caps (GstAggregator * self)
static gboolean
gst_aggregator_default_negotiate (GstAggregator * self)
{
GstAggregatorClass *agg_klass = GST_AGGREGATOR_GET_CLASS (self);
GstCaps *downstream_caps, *template_caps, *caps = NULL;
@ -1100,6 +1099,47 @@ done:
if (caps)
gst_caps_unref (caps);
return ret >= GST_FLOW_OK || ret == GST_AGGREGATOR_FLOW_NEED_DATA;
}
/* WITH SRC_LOCK held */
static gboolean
gst_aggregator_negotiate_unlocked (GstAggregator * self)
{
GstAggregatorClass *agg_klass = GST_AGGREGATOR_GET_CLASS (self);
if (agg_klass->negotiate)
return agg_klass->negotiate (self);
return TRUE;
}
/**
* gst_aggregator_negotiate:
* @self: a #GstAggregator
*
* Negotiates src pad caps with downstream elements.
* Unmarks GST_PAD_FLAG_NEED_RECONFIGURE in any case. But marks it again
* if #GstAggregatorClass.negotiate() fails.
*
* Returns: %TRUE if the negotiation succeeded, else %FALSE.
*
* Since: 1.18
*/
gboolean
gst_aggregator_negotiate (GstAggregator * self)
{
gboolean ret = TRUE;
g_return_val_if_fail (GST_IS_AGGREGATOR (self), FALSE);
GST_PAD_STREAM_LOCK (GST_AGGREGATOR_SRC_PAD (self));
gst_pad_check_reconfigure (GST_AGGREGATOR_SRC_PAD (self));
ret = gst_aggregator_negotiate_unlocked (self);
if (!ret)
gst_pad_mark_reconfigure (GST_AGGREGATOR_SRC_PAD (self));
GST_PAD_STREAM_UNLOCK (GST_AGGREGATOR_SRC_PAD (self));
return ret;
}
@ -1147,11 +1187,14 @@ gst_aggregator_aggregate_func (GstAggregator * self)
continue;
if (gst_pad_check_reconfigure (GST_AGGREGATOR_SRC_PAD (self))) {
flow_return = gst_aggregator_update_src_caps (self);
if (flow_return != GST_FLOW_OK)
if (!gst_aggregator_negotiate_unlocked (self)) {
gst_pad_mark_reconfigure (GST_AGGREGATOR_SRC_PAD (self));
if (flow_return == GST_AGGREGATOR_FLOW_NEED_DATA)
flow_return = GST_FLOW_OK;
if (GST_PAD_IS_FLUSHING (GST_AGGREGATOR_SRC_PAD (self))) {
flow_return = GST_FLOW_FLUSHING;
} else {
flow_return = GST_FLOW_NOT_NEGOTIATED;
}
}
}
if (timeout || flow_return >= GST_FLOW_OK) {
@ -2382,6 +2425,8 @@ gst_aggregator_class_init (GstAggregatorClass * klass)
klass->fixate_src_caps = gst_aggregator_default_fixate_src_caps;
klass->negotiated_src_caps = gst_aggregator_default_negotiated_src_caps;
klass->negotiate = gst_aggregator_default_negotiate;
gstelement_class->request_new_pad =
GST_DEBUG_FUNCPTR (gst_aggregator_request_new_pad);
gstelement_class->send_event = GST_DEBUG_FUNCPTR (gst_aggregator_send_event);

View file

@ -235,6 +235,8 @@ struct _GstAggregator
* downstream allocation query.
* @propose_allocation: Optional.
* Allows the subclass to handle the allocation query from upstream.
* @negotiate: Optional.
* Negotiate the caps with the peer (Since: 1.18).
*
* The aggregator base class will handle in a thread-safe way all manners of
* concurrent flushes, seeks, pad additions and removals, leaving to the
@ -311,8 +313,11 @@ struct _GstAggregatorClass {
GstAggregatorPad * pad,
GstQuery * decide_query,
GstQuery * query);
gboolean (*negotiate) (GstAggregator * self);
/*< private >*/
gpointer _gst_reserved[GST_PADDING_LARGE];
gpointer _gst_reserved[GST_PADDING_LARGE-1];
};
/************************************
@ -341,6 +346,9 @@ GST_BASE_API
void gst_aggregator_set_src_caps (GstAggregator * self,
GstCaps * caps);
GST_BASE_API
gboolean gst_aggregator_negotiate (GstAggregator * self);
GST_BASE_API
void gst_aggregator_set_latency (GstAggregator * self,
GstClockTime min_latency,