| |
| Some notes on pad negotiation |
| |
| |
| A "pad link" is a connection between two pads. It can be in one of |
| two states, "negotiated" or "not negotiated". Pad links are created |
| by gst_pad_link(). |
| |
| A "pad link" is created when two pads are linked using gst_pad_link(). |
| When initially created, the link only specifies a src pad, a sink pad, |
| and optionally a filter caps provided by the application. |
| |
| In order to pass data through a link, the peer pads must decide on |
| what data format to use. This is called negotiation. Pads |
| describe acceptable data formats by using a combination of pad |
| template caps and (optionally) a pad->getcaps function. |
| |
| |
| Negotiation can happen in one of two forms, directed or undirected. |
| Directed negotiation happens when one element has decided (usually |
| during negotiation on another pad) to ask for a specific format on |
| a pad. This happens when a pad calls gst_pad_try_set_caps(). |
| Undirected negotiation happens when the core decides to negotiate |
| a link, either due to a state change or a specific application |
| request. |
| |
| Steps in undirected negotiation (core view): |
| |
| - core checks that both pad's parent elements are in the READY or |
| higher state. |
| |
| - core calls gst_pad_get_caps() on each pad, intersects the two caps, |
| and intersects again with the filter caps. If the intersection is |
| empty, then the pads have no formats in common, and the link fails. |
| |
| - If the intersection caps is not fixed, there are multiple possible |
| formats that the link could use. If this is the case, fixate |
| functions are called until the caps are fixed. The fixate functions |
| are called by priority -- src application fixate function, sink |
| application fixate function, src and sink fixate functions, and |
| the default core fixate function. The application fixate functions |
| are implemented by the "fixate" signal on each pad. The core |
| loops through the fixate functions until a fixed caps is decided |
| on. |
| |
| - Each pad may have a pad_link function, which is called with the |
| fixed caps. The pad_link function has the option of accepting, |
| rejecting, or delaying the negotiation. |
| |
| - If both pads accept the caps, the link is then negotiated. |
| |
| Steps in directed negotiation (gst_pad_try_set_caps): |
| |
| - the originator is the pad that gst_pad_try_set_caps() is called |
| on. |
| |
| - the elements owning both pads are assumed to be in a non-NULL state |
| |
| - the caps argument of try_set_caps() must be fixed. |
| |
| - gst_pad_get_caps() is called on the peer pad, and intersected with |
| the originating pad's pad template caps and the filter caps. The |
| caps argument is checked to be a subset of the intersection. (It's |
| important that this intersection uses the pad _template_ caps.) |
| |
| - Fixate functions don't need to be called, since the caps are |
| already fixed. |
| |
| - The peer's pad_link function is called. |
| |
| - If the peer's pad_link function accepts the caps, the link is then |
| negotiated. |
| |
| - If the peer's pad_link function refuses the caps, and the link had |
| already been negotiated, the peer's pad_link function is called |
| with the caps of the old negotiation. |
| |
| - Note: the originator's pad_link function is _not_ called. The |
| originator must take appropriate alternative steps. |
| |
| |
| Notes about renegotiation: |
| |
| - same as negotiation. Note that get_caps() functions should always |
| ignore the currently negotiated caps of a link. |
| |
| - if renegotiation fails, the previous negotiation is still in effect. |
| If the renegotiation fails in the last pad_link step, the pad_link |
| functions are called with the previously negotiated caps. |
| |
| |
| Notes for sources and sinks: |
| |
| - sources and sinks that talk to hardware may not be able to fully |
| describe their available formats, and thus need to rely on pad_link |
| functions to test a particular format. FIXME: currently, the core |
| completely fails negotiation if a pad_link function refuses a caps, |
| instead of attempting with an alternate caps. |
| |
| Example: Assume osssink advertises rate=(int)[8000,48000], but |
| the device cannot actually handle rate=44100 (unknown to osssink). |
| Assume that the pad_link function is called with rate=44100 -- |
| ideally, the pad_link function should return GST_PAD_LINK_DELAYED, |
| and future calls to getcaps should return {[8000,44099],[44101, |
| 48000]}. I don't know how to make this easy and/or work well. |
| |
| |
| Notes for decoders/demuxers: |
| |
| - Decoders will typically negotiate a sink pad, receive some data, |
| determine the output format, and call try_set_caps() with the given |
| format. If the output format is non-fixed, gst_pad_renegotiate() |
| may be used instead, in order to have the fixate functions choose |
| the optimal format. Note that this requires communication so that |
| the pad's getcaps function returns the correct caps. |
| |
| Notes for converters: |
| |
| - Converters change one or more properties of the format of a data |
| stream. A typical converter's getcaps function will call |
| gst_pad_get_allowed_caps() for the opposite pad in the element, |
| change one or more fields in the caps, and return the result. |
| |
| - getcaps function: |
| |
| - call gst_pad_get_allowed_caps() on the other pad in the element |
| |
| - for each possible format ("A") in the allowed caps, determine all |
| the formats ("B") that your converter could convert the original |
| format (A) to. The union of all these formats (all the B's) is |
| the caps that should be returned. (This is how to do it |
| _theoretically_, but an optimal implementation will probably be |
| quite different.) |
| For example, a simple way to do this for an element that can convert |
| a given field of the caps is to remove the field(s) from the structure, |
| then intersect with the pad template. |
| |
| - As an example, videoscale can convert any sized video to any other |
| sized video. Its getcaps function iterates over each structure in |
| the caps, and replaces the width and height with the range |
| [1,MAXINT]. |
| |
| - pad_link function: |
| |
| - the "otherpad" is the opposite pad in the element. |
| |
| - extract fields from the caps that are relevant for your converter |
| handling the format. Store these in _local_ variables. (E.g, |
| things like video size, sample rate, etc.) |
| |
| - If it's possible to pass buffers through without modifying them |
| (passthrough), you should call gst_try_set_caps() with the caps |
| that was specified as the parameter to the pad_link function. If |
| this is successful, save the local variables to the element |
| structure, perform whatever other setup is necessary for your |
| element, and return GST_PAD_LINK_OK. |
| |
| - Otherwise, you're not using passthrough, and may need to |
| change the caps on the otherpad to match the given format. |
| |
| - If the otherpad is not negotiated (!gst_pad_is_negotiated()), |
| you shouldn't attempt to set a format on it. It will eventually |
| be negotiated. Save the local variables to the element structure, |
| perform whatever other setup is necessary, and return |
| GST_PAD_LINK_OK. |
| |
| - At this point, the other pad is already negotiated, but won't |
| accept the passthrough format, so you should combine the existing |
| negotiated caps on the otherpad and the caps that was the pad link |
| argument. This can either be done using existing information in the |
| element that was saved during a previous pad_link call, or you can |
| get the information from the negotiated caps |
| (gst_pad_get_negotiated_caps()). |
| |
| As an example, consider the videoscale element. Assume that |
| videoscale.src has already negotiated "video/x-raw-yuv, |
| format=(fourcc)I420, width=320, height=240", and that the sink |
| pad's link function is called with "video/x-raw-yuv, |
| format=(fourcc)YUY2, width=640, height=480". Since it's the |
| videoscale element, we can have different width and height |
| fields on the pads, but the format must be the same. So we'll |
| use the existing negotiated size (640x480), and the new format, |
| and call gst_pad_try_set_caps() with "video/x-raw-yuv, |
| format=(fourcc)I420, width=640, height=480". |
| |
| This may seem overkill, but most of the time, you'll end up |
| calling try_set_caps() with the same caps that are currently |
| negotiated -- try_set_caps() just returns GST_PAD_LINK_OK in |
| this case. |
| |
| - If gst_pad_try_set_caps() returns GST_PAD_LINK_OK, save the |
| local variables to the element structure. In any case, return |
| the return value of gst_pad_try_set_caps(). |
| |
| |
| Notes for filters: |
| |
| - Filters can almost always use gst_pad_proxy_getcaps() as the |
| getcaps function. This just returns gst_pad_get_allowed_caps() |
| on the otherpad. |
| |
| - You may be able to use gst_pad_proxy_pad_link() as the pad link |
| function, but only if you don't need to extract parameters from |
| the caps. |
| |
| |
| Notes for encoders/muxers: |
| |
| - Encoders and muxers should roughly work like converters. Many |
| converters are symmetric; encoders and muxers obvious are not, |
| thus it may make the code clearer to have separate src and sink |
| getcaps and pad_link functions. |
| |
| - Encoders and muxers should handle multiple negotiations until |
| the first buffer has been passed. After this point, it's unlikely |
| that additional negotiations will happen in well-constructed |
| pipelines, but it may be wise to "lock" the caps after the |
| muxer has committed to a format. (FIXME: it's still unclear to |
| me when the caps should get "unlocked". Obviously at EOS or |
| PAUSED->READY transitions. Any others?) |
| |
| - Locking caps can be done by adding (near the top) of the getcaps |
| function: |
| |
| if (my_element->lock_caps) { |
| return gst_pad_get_negotiated_caps (pad); |
| } |
| |
| |
| Explicit caps: |
| |
| - There's a hack in the core to make the code for decoder elements |
| a lot simpler. This hack can be used only for src pads of elements |
| that get their srcpad capabilities directly from the data stream, |
| i.e., decoders, demuxers, and typefind. This hack overrides the |
| pad's getcaps() and pad_link() function, so that they work correctly |
| in all decoder states. |
| |
| - To enable this hack on a pad, call gst_pad_use_explicit_caps(). |
| |
| - To indicate that a decoder has found the format of the stream, call |
| gst_pad_set_explicit_caps(pad,caps) with the caps of the stream. |
| This caps must be fixed. |
| |
| - To indicate that a decoder has lost the format of the stream, i.e., |
| there's been a NEW_MEDIA event, call gst_pad_set_explicit_caps(pad, |
| NULL). |
| |
| - If the explicit caps are set, the getcaps function will return that |
| caps, and the pad_link function will return GST_PAD_LINK_OK. If |
| the explicit caps are not set, the getcaps function returns the pad |
| template caps, and the pad_link function returns GST_PAD_LINK_DELAYED. |
| |
| |
| |
| Other junk: |
| |
| - negotiation can happen at any time |
| |
| - negotiation can happen multiple times/often happens multiple times |
| |
| - initial negotiation can lead to strange caps |
| |
| - directed negotiation can happen in either direction (src to sink or |
| sink to src) |
| |
| - Other considerations ignored, every pad should have a getcaps function. |
| |
| - If a pad's getcaps function returns the same caps in every |
| circumstance, the getcaps function can be omitted. |
| |
| - If you use gst_pad_use_explicit_caps(), the getcaps function must |
| be ommitted. |
| |
| - fixate functions are a method for applications to exert influence |
| on how a format is chosen from a caps. It's also used as a hack to |
| allow elements to do the same. Element fixate functions are _not_ |
| intended to give good results for applications -- they're intended |
| to give non-disgusting results in gst-launch. Don't attempt to |
| make them do more than they're capable of. |
| |
| - Fixate functions should not be implemented on anything except source |
| and sink elements. |
| |
| |
| |