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.