diff --git a/docs/design/part-negotiation.txt b/docs/design/part-negotiation.txt index 3884f69e56..0a89bb6530 100644 --- a/docs/design/part-negotiation.txt +++ b/docs/design/part-negotiation.txt @@ -342,6 +342,7 @@ We can identify 3 patterns in negotiation: 2) Transform - Caps not modified (passthrough) - can do caps transform based on element property + - fixed caps get transformed into fixed caps - videobox 3) Dynamic : can choose output format @@ -349,3 +350,4 @@ We can identify 3 patterns in negotiation: - depends on downstream caps, needs to do a CAPS query to find transform. - usually prefers to use the identity transform + - fixed caps can be transformed into unfixed caps. diff --git a/docs/pwg/advanced-negotiation.xml b/docs/pwg/advanced-negotiation.xml index ca47402c00..77ac5a4a18 100644 --- a/docs/pwg/advanced-negotiation.xml +++ b/docs/pwg/advanced-negotiation.xml @@ -124,6 +124,11 @@ decoder itself is not reconfigurable, too. + + + Some sources that produce a fixed format. + + gst_pad_use_fixed_caps() is used on the source @@ -160,6 +165,11 @@ [..] ]]> + + These types of elements also don't have a relation between the input + format and the output format, the input caps simply don't contain the + information needed to produce the output caps. + All other elements that need to be configured for the format should implement full caps negotiation, which will be explained in the next @@ -170,12 +180,129 @@ Transform negotiation + In this negotiation technique, there is a fixed transform between + the element input caps and the output caps. This transformation + could be parameterized by element properties but not by the + content of the stream (see + for that use-case). + + The caps that the element can accept depend on the (fixed + transformation) downstream caps. The caps that the element can + produce depend on the (fixed transformation of) the upstream + caps. + + + This type of element can usually set caps on its source pad from + the _event() function on the sink pad when + it received the CAPS event. This means that the caps transform + function transforms a fixed caps into another fixed caps. + Examples of elements include: + + + + + Videobox. It adds configurable border around a video frame + depending on object properties. + + + + + Identity elements. All elements that don't change the format + of the data, only the content. Video and audio effects are an + example. Other examples include elements that inspect the + stream. + + + + + Some decoders and encoders, where the output format is defined + by input format, like mulawdec and mulawenc. These decoders + usually have no headers that define the content of the stream. + They are usually more like conversion elements. + + + + + Below is an example of a negotiation steps of a typical transform + element. In the sink pad CAPS event handler, we compute the caps + for the source pad and set those. + + +srcpad, outcaps); + gst_caps_unref (outcaps); + + return ret; +} + +static gboolean +gst_my_filter_sink_event (GstPad *pad, + GstObject *parent, + GstEvent *event) +{ + gboolean ret; + GstMyFilter *filter = GST_MY_FILTER (parent); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_CAPS: + { + GstCaps *caps; + + gst_event_parse_caps (event, &caps); + ret = gst_my_filter_setcaps (filter, caps); + break; + } + default: + ret = gst_pad_event_default (pad, parent, event); + break; + } + return ret; +} + + [...] +]]> + Dynamic negotiation + A last negotiation method is the most complex and powerful dynamic + negotiation. + + + Like with the transform negotiation in + , dynamic negotiation will + perform a transformation on the downstream/upstream caps. Unlike the + transform + negotiation, this transform will convert fixed caps to unfixed caps. This + means that the sink pad input caps can be converted into unfixed (multiple) + formats. The source pad will have to choose a format from all the + possibilities. It would usually like to choose a format that requires the + least amount of effort to produce but it does not have to be. The selection + of the format should also depend on the caps that can be accepted downstream @@ -259,75 +386,6 @@ Negotiating caps embedded in input caps - - Many elements, particularly effects and converters, will be able - to parse the format of the stream from their input caps, and decide - the output format right at that time already. For those elements, all - (downstream) caps negotiation can be done from the - _event () function when a GST_EVENT_CAPS is - received on the sinkpad. This CAPS event is received whenever the - format changes or when no format was negotiated yet. It will always - be called before you receive the buffer in the format specified in - the CAPS event. - - - In the _event ()-function, the element can - forward the CAPS event to the next element and, if that pad accepts the - format too, the element can parse the relevant parameters from the - caps and configure itself internally. The caps passed to this function - is always a subset of the template caps, so - there's no need for extensive safety checking. The following example - should give a clear indication of how such a function can be - implemented: - - - -static gboolean -gst_my_filter_sink_event (GstPad *pad, - GstObject *parent, - GstEvent *event) -{ - gboolean ret; - GstMyFilter *filter = GST_MY_FILTER (parent); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_CAPS: - { - GstCaps *caps; - GstStructure *s; - - gst_event_parse_caps (event, &caps); - - /* forward-negotiate */ - ret = gst_pad_set_caps (filter->srcpad, caps); - if (!ret) - return FALSE; - - /* negotiation succeeded, so now configure ourselves */ - s = gst_caps_get_structure (caps, 0); - gst_structure_get_int (s, "rate", &filter->samplerate); - gst_structure_get_int (s, "channels", &filter->channels); - break; - } - default: - ret = gst_pad_event_default (pad, parent, event); - break; - } - return ret; -} - - There may also be cases where the filter actually is able to change the format of the stream. In those cases, @@ -446,30 +504,6 @@ gst_my_filter_chain (GstPad *pad, #include "register.func" --> - - - Parsing and setting caps - - Other elements, such as certain types of decoders, will not be able - to parse the caps from their input, simply because the input format - does not contain the information required to know the output format - yet; rather, the data headers need to be parsed, too. In many cases, - fixed-caps will be enough, but in some cases, particularly in cases - where such decoders are renegotiable, it is also possible to use - full caps negotiation. - - - Fortunately, the code required to do so is very similar to the last - code example in , with - the difference being that the caps is selected in the _chain - ()-function rather than in the _event - ()-function. The rest, as for getting all allowed caps from - the source pad, fixating and such, is all the same. Re-negotiation, - which will be handled in the next section, is very different for such - elements, though. - - @@ -528,10 +562,8 @@ gst_my_filter_chain (GstPad *pad, - - + +srcpad) ? filter->sinkpad : + filter->srcpad; caps = gst_pad_get_allowed_caps (otherpad); - gst_query_parse_caps (query, &filter); + gst_query_parse_caps (query, &filter); /* We support *any* samplerate, indifferent from the samplerate * supported by the linked elements on both sides. */ - for (i = 0; i < gst_caps_get_size (caps); i++) { + for (i = 0; i < gst_caps_get_size (caps); i++) { GstStructure *structure = gst_caps_get_structure (caps, i); gst_structure_remove_field (structure, "rate"); @@ -585,17 +617,8 @@ gst_my_filter_query (GstPad *pad, GstObject * parent, GstQuery * query) } return ret; } - - +]]> + Using all the knowledge you've acquired by reading this chapter, you should be able to write an element that does correct caps negotiation.