| <chapter id="chapter-negotiation" xreflabel="Caps negotiation"> | 
 |   <title>Caps negotiation</title> | 
 |   <para> | 
 |     Caps negotiation is the act of finding a media format (GstCaps) between | 
 |     elements that they can handle. This process in &GStreamer; can in most | 
 |     cases find an optimal solution for the complete pipeline. In this section | 
 |     we explain how this works. | 
 |   </para> | 
 |  | 
 |   <sect1 id="section-nego-basics"> | 
 |     <title>Caps negotiation basics</title> | 
 |     <para> | 
 |       In &GStreamer;, negotiation of the media format always follows the | 
 |       following simple rules: | 
 |     </para> | 
 |     <itemizedlist> | 
 |       <listitem> | 
 |         <para> | 
 |           A downstream element suggest a format on its sinkpad and places the | 
 |           suggestion in the result of the CAPS query performed on the sinkpad. | 
 |           See also <xref linkend="section-nego-getcaps"/>. | 
 |         </para> | 
 |       </listitem> | 
 |       <listitem> | 
 |         <para> | 
 |           An upstream element decides on a format. It sends the selected media | 
 |           format downstream on its source pad with a CAPS event. Downstream | 
 |           elements reconfigure themselves to handle the media type in the CAPS | 
 |           event on the sinkpad. | 
 |         </para> | 
 |       </listitem> | 
 |       <listitem> | 
 |         <para> | 
 |           A downstream element can inform upstream that it would like to | 
 |           suggest a new format by sending a RECONFIGURE event upstream. The | 
 |           RECONFIGURE event simply instructs an upstream element to restart | 
 |           the negotiation phase. Because the element that sent out the | 
 |           RECONFIGURE event is now suggesting another format, the format | 
 |           in the pipeline might change. | 
 |         </para> | 
 |       </listitem> | 
 |     </itemizedlist> | 
 |     <para> | 
 |       In addition to the CAPS and RECONFIGURE event and the CAPS query, there | 
 |       is an ACCEPT_CAPS query to quickly check if a certain caps can | 
 |       be accepted by an element. | 
 |     </para> | 
 |     <para> | 
 |       All negotiation follows these simple rules. Let's take a look at some | 
 |       typical uses cases and how negotiation happens. | 
 |     </para> | 
 |   </sect1> | 
 |  | 
 |   <sect1 id="section-nego-usecases"> | 
 |     <title>Caps negotiation use cases</title> | 
 |     <para> | 
 |       In what follows we will look at some use cases for push-mode scheduling. | 
 |       The pull-mode scheduling negotiation phase is discussed in | 
 |       <xref linkend="section-nego-pullmode"/> and is actually similar as we | 
 |       will see.  | 
 |     </para> | 
 |     <para> | 
 |       Since the sink pads only suggest formats and the source pads need to | 
 |       decide, the most complicated work is done in the source pads. | 
 |       We can identify 3 caps negotiation use cases for the source pads: | 
 |     </para> | 
 |     <itemizedlist> | 
 |       <listitem> | 
 |         <para> | 
 |           Fixed negotiation. An element can output one format only. | 
 |           See <xref linkend="section-nego-fixed"/>. | 
 |         </para> | 
 |       </listitem> | 
 |       <listitem> | 
 |         <para> | 
 |           Transform negotiation. There is a (fixed) transform between the | 
 |           input and output format of the element, usually based on some | 
 |           element property. The caps that the element will produce depend | 
 |           on the upstream caps and the caps that the element can accept | 
 |           depend on the downstream caps. | 
 |           See <xref linkend="section-nego-transform"/>. | 
 |         </para> | 
 |       </listitem> | 
 |       <listitem> | 
 |         <para> | 
 |           Dynamic negotiation. An element can output many formats. | 
 |           See <xref linkend="section-nego-dynamic"/>. | 
 |         </para> | 
 |       </listitem> | 
 |     </itemizedlist> | 
 |  | 
 |     <sect2 id="section-nego-fixed"> | 
 |       <title>Fixed negotiation</title> | 
 |       <para> | 
 |         In this case, the source pad can only produce a fixed format. Usually | 
 |         this format is encoded inside the media. No downstream element can | 
 |         ask for a different format, the only way that the source pad will | 
 |         renegotiate is when the element decides to change the caps itself. | 
 |       </para> | 
 |       <para> | 
 |         Elements that could implement fixed caps (on their source pads) are, | 
 |         in general, all elements that are not renegotiable. Examples include: | 
 |       </para> | 
 |       <itemizedlist> | 
 |         <listitem> | 
 |           <para> | 
 |             A typefinder, since the type found is part of the actual data stream | 
 |             and can thus not be re-negotiated. The typefinder will look at the | 
 |             stream of bytes, figure out the type, send a CAPS event with the | 
 |             caps and then push buffers of the type. | 
 |           </para> | 
 |         </listitem> | 
 |         <listitem> | 
 |           <para> | 
 |             Pretty much all demuxers, since the contained elementary data | 
 |             streams are defined in the file headers, and thus not | 
 |             renegotiable. | 
 |           </para> | 
 |         </listitem> | 
 |         <listitem> | 
 |           <para> | 
 |             Some decoders, where the format is embedded in the data stream | 
 |             and not part of the peercaps <emphasis>and</emphasis> where the | 
 |             decoder itself is not reconfigurable, too. | 
 |           </para> | 
 |         </listitem> | 
 |         <listitem> | 
 |           <para> | 
 |             Some sources that produce a fixed format. | 
 |           </para> | 
 |         </listitem> | 
 |       </itemizedlist> | 
 |       <para> | 
 |         <function>gst_pad_use_fixed_caps()</function> is used on the source | 
 |         pad with fixed caps. As long as the pad is not negotiated, the default | 
 |         CAPS query will return the caps presented in the padtemplate. As soon | 
 |         as the pad is negotiated, the CAPS query will return the negotiated | 
 |         caps (and nothing else). These are the relevant code snippets for fixed | 
 |         caps source pads. | 
 |       </para> | 
 |       <programlisting> | 
 | <![CDATA[ | 
 | [..] | 
 |   pad = gst_pad_new_from_static_template (..); | 
 |   gst_pad_use_fixed_caps (pad); | 
 | [..] | 
 | ]]> | 
 |       </programlisting> | 
 |       <para> | 
 |         The fixed caps can then be set on the pad by calling | 
 |         <function>gst_pad_set_caps ()</function>. | 
 |       </para> | 
 |       <programlisting> | 
 | <![CDATA[ | 
 | [..] | 
 |     caps = gst_caps_new_simple ("audio/x-raw", | 
 |         "format", G_TYPE_STRING, GST_AUDIO_NE(F32), | 
 |         "rate", G_TYPE_INT, <samplerate>, | 
 |         "channels", G_TYPE_INT, <num-channels>, NULL); | 
 |     if (!gst_pad_set_caps (pad, caps)) { | 
 |       GST_ELEMENT_ERROR (element, CORE, NEGOTIATION, (NULL), | 
 |           ("Some debug information here")); | 
 |       return GST_FLOW_ERROR; | 
 |     } | 
 | [..] | 
 | ]]> | 
 |       </programlisting> | 
 |       <para> | 
 |         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. | 
 |       </para> | 
 |       <para> | 
 |         All other elements that need to be configured for the format should | 
 |         implement full caps negotiation, which will be explained in the next | 
 |         few sections. | 
 |       </para> | 
 |     </sect2> | 
 |  | 
 |     <sect2 id="section-nego-transform"> | 
 |       <title>Transform negotiation</title> | 
 |       <para> | 
 |         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 <xref linkend="section-nego-fixed"/> | 
 |         for that use-case). | 
 |       </para> | 
 |       <para> | 
 |         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. | 
 |       </para> | 
 |       <para> | 
 |         This type of element can usually set caps on its source pad from | 
 |         the <function>_event()</function> 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: | 
 |       </para> | 
 |       <itemizedlist> | 
 |         <listitem> | 
 |           <para> | 
 |             Videobox. It adds configurable border around a video frame | 
 |             depending on object properties. | 
 |           </para> | 
 |         </listitem> | 
 |         <listitem> | 
 |           <para> | 
 |             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. | 
 |           </para> | 
 |         </listitem> | 
 |         <listitem> | 
 |           <para> | 
 |             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. | 
 |           </para> | 
 |         </listitem> | 
 |       </itemizedlist> | 
 |       <para> | 
 |         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. | 
 |       </para> | 
 |       <programlisting> | 
 | <![CDATA[ | 
 |   [...] | 
 |  | 
 | static gboolean | 
 | gst_my_filter_setcaps (GstMyFilter *filter, | 
 | 		       GstCaps *caps) | 
 | { | 
 |   GstStructure *structure; | 
 |   int rate, channels; | 
 |   gboolean ret; | 
 |   GstCaps *outcaps; | 
 |  | 
 |   structure = gst_caps_get_structure (caps, 0); | 
 |   ret = gst_structure_get_int (structure, "rate", &rate); | 
 |   ret = ret && gst_structure_get_int (structure, "channels", &channels); | 
 |   if (!ret) | 
 |     return FALSE; | 
 |  | 
 |   outcaps = gst_caps_new_simple ("audio/x-raw", | 
 |       "format", G_TYPE_STRING, GST_AUDIO_NE(S16), | 
 |       "rate", G_TYPE_INT, rate, | 
 |       "channels", G_TYPE_INT, channels, NULL); | 
 |   ret = gst_pad_set_caps (filter->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; | 
 | } | 
 |  | 
 |   [...] | 
 | ]]> | 
 |       </programlisting> | 
 |     </sect2> | 
 |  | 
 |     <sect2 id="section-nego-dynamic"> | 
 |       <title>Dynamic negotiation</title> | 
 |       <para> | 
 |         A last negotiation method is the most complex and powerful dynamic | 
 |         negotiation. | 
 |       </para> | 
 |       <para> | 
 |         Like with the transform negotiation in  | 
 |         <xref linkend="section-nego-transform"/>, 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 (see a QUERY_CAPS function in | 
 |         <xref linkend="section-nego-getcaps"/>). | 
 |       </para> | 
 |       <para> | 
 |         A typical flow goes like this: | 
 |       </para> | 
 |       <itemizedlist> | 
 |         <listitem> | 
 |           <para> | 
 |             Caps are received on the sink pad of the element. | 
 |           </para> | 
 |         </listitem> | 
 |         <listitem> | 
 |           <para> | 
 |             If the element prefers to operate in passthrough mode, check | 
 |             if downstream accepts the caps with the ACCEPT_CAPS query. If it | 
 |             does, we can complete negotiation and we can operate in | 
 |             passthrough mode. | 
 |           </para> | 
 |         </listitem> | 
 |         <listitem> | 
 |           <para> | 
 |             Calculate the possible caps for the source pad. | 
 |           </para> | 
 |         </listitem> | 
 |         <listitem> | 
 |           <para> | 
 |             Query the downstream peer pad for the list of possible | 
 |             caps. | 
 |           </para> | 
 |         </listitem> | 
 |         <listitem> | 
 |           <para> | 
 |             Select from the downstream list the first caps that you can | 
 |             transform to and set this as the output caps. You might have to | 
 |             fixate the caps to some reasonable defaults to construct | 
 |             fixed caps. | 
 |           </para> | 
 |         </listitem> | 
 |       </itemizedlist> | 
 |       <para> | 
 |         Examples of this type of elements include: | 
 |       </para> | 
 |       <itemizedlist> | 
 |         <listitem> | 
 |           <para> | 
 |             Converter elements such as videoconvert, audioconvert, audioresample, | 
 |             videoscale, ... | 
 |           </para> | 
 |         </listitem> | 
 |         <listitem> | 
 |           <para> | 
 |             Source elements such as audiotestsrc, videotestsrc, v4l2src, | 
 |             pulsesrc, ... | 
 |           </para> | 
 |         </listitem> | 
 |       </itemizedlist> | 
 |       <para> | 
 |         Let's look at the example of an element that can convert between | 
 |         samplerates, so where input and output samplerate don't have to be | 
 |         the same: | 
 |       </para> | 
 |       <programlisting> | 
 | <![CDATA[ | 
 | static gboolean | 
 | gst_my_filter_setcaps (GstMyFilter *filter, | 
 | 		       GstCaps *caps) | 
 | { | 
 |   if (gst_pad_set_caps (filter->srcpad, caps)) { | 
 |     filter->passthrough = TRUE; | 
 |   } else { | 
 |     GstCaps *othercaps, *newcaps; | 
 |     GstStructure *s = gst_caps_get_structure (caps, 0), *others; | 
 |  | 
 |     /* no passthrough, setup internal conversion */ | 
 |     gst_structure_get_int (s, "channels", &filter->channels); | 
 |     othercaps = gst_pad_get_allowed_caps (filter->srcpad); | 
 |     others = gst_caps_get_structure (othercaps, 0); | 
 |     gst_structure_set (others, | 
 |       "channels", G_TYPE_INT, filter->channels, NULL); | 
 |  | 
 |     /* now, the samplerate value can optionally have multiple values, so | 
 |      * we "fixate" it, which means that one fixed value is chosen */ | 
 |     newcaps = gst_caps_copy_nth (othercaps, 0); | 
 |     gst_caps_unref (othercaps); | 
 |     gst_pad_fixate_caps (filter->srcpad, newcaps); | 
 |     if (!gst_pad_set_caps (filter->srcpad, newcaps)) | 
 |       return FALSE; | 
 |  | 
 |     /* we are now set up, configure internally */ | 
 |     filter->passthrough = FALSE; | 
 |     gst_structure_get_int (s, "rate", &filter->from_samplerate); | 
 |     others = gst_caps_get_structure (newcaps, 0); | 
 |     gst_structure_get_int (others, "rate", &filter->to_samplerate); | 
 |   } | 
 |  | 
 |   return TRUE; | 
 | } | 
 |  | 
 | 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; | 
 | } | 
 |  | 
 | static GstFlowReturn | 
 | gst_my_filter_chain (GstPad    *pad, | 
 | 		     GstObject *parent, | 
 | 		     GstBuffer *buf) | 
 | { | 
 |   GstMyFilter *filter = GST_MY_FILTER (parent); | 
 |   GstBuffer *out; | 
 |  | 
 |   /* push on if in passthrough mode */ | 
 |   if (filter->passthrough) | 
 |     return gst_pad_push (filter->srcpad, buf); | 
 |  | 
 |   /* convert, push */ | 
 |   out = gst_my_filter_convert (filter, buf); | 
 |   gst_buffer_unref (buf); | 
 |  | 
 |   return gst_pad_push (filter->srcpad, out); | 
 | } | 
 | ]]> | 
 |       </programlisting> | 
 |     </sect2> | 
 |   </sect1> | 
 |  | 
 |   <sect1 id="section-nego-upstream" xreflabel="Upstream caps (re)negotiation"> | 
 |     <title>Upstream caps (re)negotiation</title> | 
 |     <para> | 
 |       Upstream negotiation's primary use is to renegotiate (part of) an | 
 |       already-negotiated pipeline to a new format. Some practical examples | 
 |       include to select a different video size because the size of the video | 
 |       window changed, and the video output itself is not capable of rescaling, | 
 |       or because the audio channel configuration changed. | 
 |     </para> | 
 |     <para> | 
 |       Upstream caps renegotiation is requested by sending a GST_EVENT_RECONFIGURE | 
 |       event upstream. The idea is that it will instruct the upstream element | 
 |       to reconfigure its caps by doing a new query for the allowed caps and then | 
 |       choosing a new caps. The element that sends out the RECONFIGURE event | 
 |       would influence the selection of the new caps by returning the new | 
 |       preferred caps from its GST_QUERY_CAPS query function. The RECONFIGURE | 
 |       event will set the GST_PAD_FLAG_NEED_RECONFIGURE on all pads that it | 
 |       travels over. | 
 |     </para> | 
 |     <para> | 
 |       It is important to note here that different elements actually have | 
 |       different responsibilities here: | 
 |     </para> | 
 |     <itemizedlist> | 
 |       <listitem> | 
 |         <para> | 
 |           Elements that want to propose a new format upstream need to first | 
 |           check if the new caps are acceptable upstream with an ACCEPT_CAPS | 
 |           query. Then they would send a RECONFIGURE event and be prepared to | 
 |           answer the CAPS query with the new preferred format. It should be | 
 |           noted that when there is no upstream element that can (or wants) | 
 |           to renegotiate, the element needs to deal with the currently | 
 |           configured format. | 
 |         </para> | 
 |       </listitem> | 
 |       <listitem> | 
 |         <para> | 
 |           Elements that operate in transform negotiation according to | 
 |           <xref linkend="section-nego-transform"/> pass the RECONFIGURE | 
 |           event upstream. Because these elements simply do a fixed transform | 
 |           based on the upstream caps, they need to send the event upstream | 
 |           so that it can select a new format. | 
 |         </para> | 
 |       </listitem> | 
 |       <listitem> | 
 |         <para> | 
 |           Elements that operate in fixed negotiation  | 
 |           (<xref linkend="section-nego-fixed"/>) drop the RECONFIGURE event. | 
 |           These elements can't reconfigure and their output caps don't depend | 
 |           on the upstream caps so the event can be dropped. | 
 |         </para> | 
 |       </listitem> | 
 |       <listitem> | 
 |         <para> | 
 |           Elements that can be reconfigured on the source pad (source pads | 
 |           implementing dynamic negotiation in | 
 |           <xref linkend="section-nego-dynamic"/>) should check its | 
 |           NEED_RECONFIGURE flag with | 
 |           <function>gst_pad_check_reconfigure ()</function> and it should | 
 |           start renegotiation when the function returns TRUE. | 
 |         </para> | 
 |       </listitem> | 
 |     </itemizedlist> | 
 |   </sect1> | 
 |  | 
 |   <sect1 id="section-nego-getcaps" xreflabel="Implementing a CAPS query function"> | 
 |     <title>Implementing a CAPS query function</title> | 
 |     <para> | 
 |       A <function>_query ()</function>-function with the GST_QUERY_CAPS query | 
 |       type is called when a peer element would like to know which formats | 
 |       this pad supports, and in what order of preference. The return value | 
 |       should be all formats that this elements supports, taking into account | 
 |       limitations of peer elements further downstream or upstream, sorted by | 
 |       order of preference, highest preference first. | 
 |     </para> | 
 |     <para> | 
 |     </para> | 
 |     <programlisting> | 
 | <![CDATA[ | 
 | static gboolean | 
 | gst_my_filter_query (GstPad *pad, GstObject * parent, GstQuery * query) | 
 | { | 
 |   gboolean ret; | 
 |   GstMyFilter *filter = GST_MY_FILTER (parent); | 
 |  | 
 |   switch (GST_QUERY_TYPE (query)) { | 
 |     case GST_QUERY_CAPS | 
 |     { | 
 |       GstPad *otherpad; | 
 |       GstCaps *temp, *caps, *filt, *tcaps; | 
 |       gint i; | 
 |  | 
 |       otherpad = (pad == filter->srcpad) ? filter->sinkpad : | 
 |                                            filter->srcpad; | 
 |       caps = gst_pad_get_allowed_caps (otherpad); | 
 |  | 
 |       gst_query_parse_caps (query, &filt); | 
 |  | 
 |       /* 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++) { | 
 |         GstStructure *structure = gst_caps_get_structure (caps, i); | 
 |  | 
 |         gst_structure_remove_field (structure, "rate"); | 
 |       } | 
 |  | 
 |       /* make sure we only return results that intersect our | 
 |        * padtemplate */ | 
 |       tcaps = gst_pad_get_pad_template_caps (pad); | 
 |       if (tcaps) { | 
 |         temp = gst_caps_intersect (caps, tcaps); | 
 |         gst_caps_unref (caps); | 
 |         gst_caps_unref (tcaps); | 
 |         caps = temp; | 
 |       } | 
 |       /* filter against the query filter when needed */ | 
 |       if (filt) { | 
 |         temp = gst_caps_intersect (caps, filt); | 
 |         gst_caps_unref (caps); | 
 |         caps = temp; | 
 |       } | 
 |       gst_query_set_caps_result (query, caps); | 
 |       gst_caps_unref (caps); | 
 |       ret = TRUE; | 
 |       break; | 
 |     } | 
 |     default: | 
 |       ret = gst_pad_query_default (pad, parent, query); | 
 |       break; | 
 |   } | 
 |   return ret; | 
 | } | 
 | ]]> | 
 |     </programlisting> | 
 |   </sect1> | 
 |  | 
 |   <sect1 id="section-nego-pullmode"> | 
 |     <title>Pull-mode Caps negotiation</title> | 
 |     <para> | 
 |       WRITEME, the mechanism of pull-mode negotiation is not yet fully | 
 |       understood. | 
 |     </para> | 
 |  | 
 |     <para> | 
 |       Using all the knowledge you've acquired by reading this chapter, you | 
 |       should be able to write an element that does correct caps negotiation. | 
 |       If in doubt, look at other elements of the same type in our git | 
 |       repository to get an idea of how they do what you want to do. | 
 |     </para> | 
 |   </sect1> | 
 | </chapter> |