From a739ae387d411fb657843d2de4134fea19b8cf19 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 10 Oct 2008 15:12:11 +0000 Subject: [PATCH] docs/design/part-negotiation.txt: Update the docs some more. Original commit message from CVS: * docs/design/part-negotiation.txt: Update the docs some more. * libs/gst/base/gsttypefindhelper.c: (helper_find_peek): If we pull a buffer with non-trivial caps, suggest those caps with the max probability. --- ChangeLog | 9 +++++++++ docs/design/part-negotiation.txt | 33 ++++++++++++++++++++----------- libs/gst/base/gsttypefindhelper.c | 17 ++++++++++++++++ 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8925c4dee0..0503b657eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2008-10-10 Wim Taymans + + * docs/design/part-negotiation.txt: + Update the docs some more. + + * libs/gst/base/gsttypefindhelper.c: (helper_find_peek): + If we pull a buffer with non-trivial caps, suggest those caps with the + max probability. + 2008-10-10 Edward Hervey * docs/design/part-TODO.txt: diff --git a/docs/design/part-negotiation.txt b/docs/design/part-negotiation.txt index 0c8ac08e28..20f7feee84 100644 --- a/docs/design/part-negotiation.txt +++ b/docs/design/part-negotiation.txt @@ -229,15 +229,19 @@ low latency offered by pull mode, we want to avoid capsnego from within the pulling thread, in case it causes us to miss our scheduling deadlines. -The time to do capsnego, then, is after activate_pull() has succeeded, -but before the sink has spawned the pulling thread. Because of the -latency concerns just mentioned, capsnego does not occur in the pulling -thread. +The pull thread is usually started in the PAUSED->PLAYING state change. We must +be able to complete the negotiation before this state change happens. + +The time to do capsnego, then, is after _check_pull_range() has succeeded, +but before the sink has spawned the pulling thread. Mechanism ......... +The sink determines that the upstream elements support pull based scheduling by +calling gst_pad_check_pull_range(). + The sink initiates the negotiation process by intersecting the results of gst_pad_get_caps() on its sink pad and its peer src pad. This is the operation performed by gst_pad_get_allowed_caps(). In the simple @@ -247,19 +251,24 @@ this way the sink element knows the capabilities of the entire pipeline. The sink element then fixates the resulting caps, if necessary, resulting in the flow caps. It notifies the pipeline of the caps by -calling gst_pad_set_caps() on its sink pad. Sink pads should proxy the -setcaps() to their peer src pads. In the simple passthrough case, src -pads' setcaps() functions proxy the setcaps() to all of their sink pads, -which then set_caps() on their peers, and so the entire pipeline becomes -configured before dataflow has started. All pads have fixed caps. +calling gst_pad_set_caps() on its sink pad. From now on, the getcaps function +of the sinkpad will only return these fixed caps meaning that upstream elements +will only be able to produce this format. If the sink element could not set caps on its sink pad, it should post an error message on the bus indicating that negotiation was not possible. -In this way all pads are negotiated before data starts flowing, so all -getrange() requests have a defined meaning for the number of bytes being -pulled. +When negotiation succeeded, the sinkpad and all upstream internally linked pads +are activated in pull mode. Typically, this operation will trigger negotiation +on the downstream elements, which will now be forced to negotiation to the +final fixed desired caps of the sinkpad. + +After these steps, the sink element returns ASYNC from the state change +function. The state will commit to PAUSED when the first buffer is received in +the sink. This is needed to provide a consistent API to the applications that +expect ASYNC return values from sinks but it also allows us to perform the +remainder of the negotiation outside of the context of the pulling thread. During dataflow, gst_pad_pull_range() checks the caps on the pulled buffer. If they are different from the sink pad's caps, it will return diff --git a/libs/gst/base/gsttypefindhelper.c b/libs/gst/base/gsttypefindhelper.c index 9061d2c9e1..24eceebc00 100644 --- a/libs/gst/base/gsttypefindhelper.c +++ b/libs/gst/base/gsttypefindhelper.c @@ -54,6 +54,9 @@ type_find_factory_rank_cmp (gconstpointer fac1, gconstpointer fac2) /* ********************** typefinding in pull mode ************************ */ +static void +helper_find_suggest (gpointer data, guint probability, const GstCaps * caps); + typedef struct { GSList *buffers; /* buffer cache */ @@ -88,6 +91,7 @@ helper_find_peek (gpointer data, gint64 offset, guint size) GSList *insert_pos = NULL; guint buf_size; guint64 buf_offset; + GstCaps *caps; helper = (GstTypeFindHelper *) data; @@ -139,6 +143,19 @@ helper_find_peek (gpointer data, gint64 offset, guint size) if (ret != GST_FLOW_OK) goto error; + caps = GST_BUFFER_CAPS (buffer); + + if (caps && !gst_caps_is_empty (caps) && !gst_caps_is_any (caps)) { + GST_DEBUG ("buffer has caps %" GST_PTR_FORMAT ", suggest max probability", + caps); + + gst_caps_replace (&helper->caps, caps); + helper->best_probability = GST_TYPE_FIND_MAXIMUM; + + gst_buffer_unref (buffer); + return NULL; + } + /* getrange might silently return shortened buffers at the end of a file, * we must, however, always return either the full requested data or NULL */ buf_offset = GST_BUFFER_OFFSET (buffer);