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.
This commit is contained in:
Wim Taymans 2008-10-10 15:12:11 +00:00
parent 6bb3d02305
commit a739ae387d
3 changed files with 47 additions and 12 deletions

View file

@ -1,3 +1,12 @@
2008-10-10 Wim Taymans <wim.taymans@collabora.co.uk>
* 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 <edward.hervey@collabora.co.uk> 2008-10-10 Edward Hervey <edward.hervey@collabora.co.uk>
* docs/design/part-TODO.txt: * docs/design/part-TODO.txt:

View file

@ -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 the pulling thread, in case it causes us to miss our scheduling
deadlines. deadlines.
The time to do capsnego, then, is after activate_pull() has succeeded, The pull thread is usually started in the PAUSED->PLAYING state change. We must
but before the sink has spawned the pulling thread. Because of the be able to complete the negotiation before this state change happens.
latency concerns just mentioned, capsnego does not occur in the pulling
thread. The time to do capsnego, then, is after _check_pull_range() has succeeded,
but before the sink has spawned the pulling thread.
Mechanism 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 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 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 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, The sink element then fixates the resulting caps, if necessary,
resulting in the flow caps. It notifies the pipeline of the caps by 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 calling gst_pad_set_caps() on its sink pad. From now on, the getcaps function
setcaps() to their peer src pads. In the simple passthrough case, src of the sinkpad will only return these fixed caps meaning that upstream elements
pads' setcaps() functions proxy the setcaps() to all of their sink pads, will only be able to produce this format.
which then set_caps() on their peers, and so the entire pipeline becomes
configured before dataflow has started. All pads have fixed caps.
If the sink element could not set caps on its sink pad, it should post 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 an error message on the bus indicating that negotiation was not
possible. possible.
In this way all pads are negotiated before data starts flowing, so all When negotiation succeeded, the sinkpad and all upstream internally linked pads
getrange() requests have a defined meaning for the number of bytes being are activated in pull mode. Typically, this operation will trigger negotiation
pulled. 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 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 buffer. If they are different from the sink pad's caps, it will return

View file

@ -54,6 +54,9 @@ type_find_factory_rank_cmp (gconstpointer fac1, gconstpointer fac2)
/* ********************** typefinding in pull mode ************************ */ /* ********************** typefinding in pull mode ************************ */
static void
helper_find_suggest (gpointer data, guint probability, const GstCaps * caps);
typedef struct typedef struct
{ {
GSList *buffers; /* buffer cache */ GSList *buffers; /* buffer cache */
@ -88,6 +91,7 @@ helper_find_peek (gpointer data, gint64 offset, guint size)
GSList *insert_pos = NULL; GSList *insert_pos = NULL;
guint buf_size; guint buf_size;
guint64 buf_offset; guint64 buf_offset;
GstCaps *caps;
helper = (GstTypeFindHelper *) data; helper = (GstTypeFindHelper *) data;
@ -139,6 +143,19 @@ helper_find_peek (gpointer data, gint64 offset, guint size)
if (ret != GST_FLOW_OK) if (ret != GST_FLOW_OK)
goto error; 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, /* getrange might silently return shortened buffers at the end of a file,
* we must, however, always return either the full requested data or NULL */ * we must, however, always return either the full requested data or NULL */
buf_offset = GST_BUFFER_OFFSET (buffer); buf_offset = GST_BUFFER_OFFSET (buffer);