2005-03-28 14:54:33 +00:00
|
|
|
|
Negotiation
|
|
|
|
|
-----------
|
|
|
|
|
|
2007-01-10 21:15:08 +00:00
|
|
|
|
Capabilities negotiation is the process of deciding on an adequate
|
|
|
|
|
format for dataflow within a GStreamer pipeline. Ideally, negotiation
|
|
|
|
|
(also known as "capsnego") transfers information from those parts of the
|
|
|
|
|
pipeline that have information to those parts of the pipeline that are
|
|
|
|
|
flexible, constrained by those parts of the pipeline that are not
|
|
|
|
|
flexible.
|
|
|
|
|
|
2012-01-14 18:16:01 +00:00
|
|
|
|
|
|
|
|
|
Basic rules
|
|
|
|
|
~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
The simple rules must be followed:
|
|
|
|
|
|
|
|
|
|
1) downstream suggests formats
|
|
|
|
|
2) upstream decides on format
|
|
|
|
|
|
|
|
|
|
There are 4 queries/events used in caps negotiation:
|
|
|
|
|
|
|
|
|
|
1) GST_QUERY_CAPS : get possible formats
|
|
|
|
|
2) GST_QUERY_ACCEPT_CAPS : check if format is possible
|
|
|
|
|
3) GST_EVENT_CAPS : configure format (downstream)
|
|
|
|
|
4) GST_EVENT_RECONFIGURE : inform upstream of possibly new caps
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Queries
|
|
|
|
|
-------
|
|
|
|
|
|
|
|
|
|
A pad can ask the peer pad for its supported GstCaps. It does this with
|
|
|
|
|
the CAPS query. The list of supported caps can be used to choose an
|
|
|
|
|
appropriate GstCaps for the data transfer.
|
2012-06-05 09:28:38 +00:00
|
|
|
|
The CAPS query works recursively, elements should take their peers into
|
2012-06-05 12:38:25 +00:00
|
|
|
|
consideration when constructing the possible caps. Because the result caps
|
|
|
|
|
can be very large, the filter can be used to restrict the caps. Only the
|
2012-06-06 07:59:55 +00:00
|
|
|
|
caps that match the filter will be returned as the result caps. The
|
|
|
|
|
order of the filter caps gives the order of preference of the caller and
|
|
|
|
|
should be taken into account for the returned caps.
|
2012-01-14 18:16:01 +00:00
|
|
|
|
|
|
|
|
|
(in) "filter", GST_TYPE_CAPS (default NULL)
|
|
|
|
|
- a GstCaps to filter the results against
|
|
|
|
|
|
|
|
|
|
(out) "caps", GST_TYPE_CAPS (default NULL)
|
|
|
|
|
- the result caps
|
|
|
|
|
|
|
|
|
|
|
2012-06-05 09:28:38 +00:00
|
|
|
|
|
2012-01-14 18:16:01 +00:00
|
|
|
|
A pad can ask the peer pad if it supports a given caps. It does this with
|
2012-06-05 09:28:38 +00:00
|
|
|
|
the ACCEPT_CAPS query. The caps must be fixed.
|
|
|
|
|
The ACCEPT_CAPS query is not required to work recursively, it can simply
|
|
|
|
|
return TRUE if a subsequent CAPS event with those caps would return
|
|
|
|
|
success.
|
2012-01-14 18:16:01 +00:00
|
|
|
|
|
|
|
|
|
(in) "caps", GST_TYPE_CAPS
|
2012-06-05 09:28:38 +00:00
|
|
|
|
- a GstCaps to check, must be fixed
|
2012-01-14 18:16:01 +00:00
|
|
|
|
|
|
|
|
|
(out) "result", G_TYPE_BOOLEAN (default FALSE)
|
|
|
|
|
- TRUE if the caps are accepted
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Events
|
|
|
|
|
~~~~~~
|
|
|
|
|
|
|
|
|
|
When a media format is negotiated, peer elements are notified of the GstCaps
|
|
|
|
|
with the CAPS event. The caps must be fixed.
|
|
|
|
|
|
|
|
|
|
"caps", GST_TYPE_CAPS
|
2012-06-05 09:28:38 +00:00
|
|
|
|
- the negotiated GstCaps, must be fixed
|
2012-01-14 18:16:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Operation
|
|
|
|
|
~~~~~~~~~
|
|
|
|
|
|
2007-01-10 21:15:08 +00:00
|
|
|
|
GStreamer's two scheduling modes, push mode and pull mode, lend
|
2007-02-02 11:33:19 +00:00
|
|
|
|
themselves to different mechanisms to achieve this goal. As it is more
|
2007-01-10 21:15:08 +00:00
|
|
|
|
common we describe push mode negotiation first.
|
|
|
|
|
|
2012-01-14 18:16:01 +00:00
|
|
|
|
|
2007-01-10 21:15:08 +00:00
|
|
|
|
Push-mode negotiation
|
2010-11-01 13:32:43 +00:00
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~
|
2007-01-10 21:15:08 +00:00
|
|
|
|
|
2007-02-02 11:33:19 +00:00
|
|
|
|
Push-mode negotiation happens when elements want to push buffers and
|
2007-01-10 21:15:08 +00:00
|
|
|
|
need to decide on the format. This is called downstream negotiation
|
|
|
|
|
because the upstream element decides the format for the downstream
|
|
|
|
|
element. This is the most common case.
|
2005-03-28 14:54:33 +00:00
|
|
|
|
|
|
|
|
|
Negotiation can also happen when a downstream element wants to receive
|
|
|
|
|
another data format from an upstream element. This is called upstream
|
|
|
|
|
negotiation.
|
|
|
|
|
|
|
|
|
|
The basics of negotiation are as follows:
|
|
|
|
|
|
2011-06-06 14:11:31 +00:00
|
|
|
|
- GstCaps (see part-caps.txt) are refcounted before they are pushed as
|
|
|
|
|
an event to describe the contents of the following buffer.
|
|
|
|
|
|
|
|
|
|
- An element should reconfigure itself to the new format received as a CAPS
|
|
|
|
|
event before processing the following buffers. If the data type in the
|
2012-01-14 18:16:01 +00:00
|
|
|
|
caps event is not acceptable, the element should refuse the event. The
|
|
|
|
|
element should also refuse the next buffers by returning an appropriate
|
|
|
|
|
GST_FLOW_NOT_NEGOTIATED return value from the chain function.
|
2005-03-28 14:54:33 +00:00
|
|
|
|
|
2011-06-07 12:03:29 +00:00
|
|
|
|
- Downstream elements can request a format change of the stream by sending a
|
2011-06-06 14:11:31 +00:00
|
|
|
|
RECONFIGURE event upstream. Upstream elements will renegotiate a new format
|
|
|
|
|
when they receive a RECONFIGURE event.
|
2005-03-28 14:54:33 +00:00
|
|
|
|
|
|
|
|
|
The general flow for a source pad starting the negotiation.
|
|
|
|
|
|
|
|
|
|
src sink
|
|
|
|
|
| |
|
2012-01-14 18:16:01 +00:00
|
|
|
|
| querycaps? |
|
|
|
|
|
|---------------->|
|
|
|
|
|
| caps |
|
|
|
|
|
select caps |< - - - - - - - -|
|
|
|
|
|
from the | |
|
|
|
|
|
candidates | |
|
|
|
|
|
| |-.
|
|
|
|
|
| accepts? | |
|
|
|
|
|
type A |---------------->| | optional
|
|
|
|
|
| yes | |
|
|
|
|
|
|< - - - - - - - -| |
|
|
|
|
|
| |-'
|
2011-06-06 14:11:31 +00:00
|
|
|
|
| send_event() |
|
|
|
|
|
send CAPS |---------------->| Receive type A, reconfigure to
|
|
|
|
|
event A | | process type A.
|
2005-03-28 14:54:33 +00:00
|
|
|
|
| |
|
|
|
|
|
| push |
|
2011-06-06 14:11:31 +00:00
|
|
|
|
push buffer |---------------->| Process buffer of type A
|
2005-03-28 14:54:33 +00:00
|
|
|
|
| |
|
|
|
|
|
|
|
|
|
|
One possible implementation in pseudo code:
|
|
|
|
|
|
|
|
|
|
[element wants to create a buffer]
|
|
|
|
|
if not format
|
|
|
|
|
# see what we can do
|
2012-01-14 18:16:01 +00:00
|
|
|
|
ourcaps = gst_pad_query_caps (srcpad)
|
2011-06-22 10:26:19 +00:00
|
|
|
|
# see what the peer can do filtered against our caps
|
2012-01-14 18:16:01 +00:00
|
|
|
|
candidates = gst_pad_peer_query_caps (srcpad, ourcaps)
|
2005-03-28 14:54:33 +00:00
|
|
|
|
|
|
|
|
|
foreach candidate in candidates
|
|
|
|
|
# make sure the caps is fixed
|
|
|
|
|
fixedcaps = gst_pad_fixate_caps (srcpad, candidate)
|
|
|
|
|
|
|
|
|
|
# see if the peer accepts it
|
|
|
|
|
if gst_pad_peer_accept_caps (srcpad, fixedcaps)
|
|
|
|
|
# store the caps as the negotiated caps, this will
|
|
|
|
|
# call the setcaps function on the pad
|
2011-06-06 14:11:31 +00:00
|
|
|
|
gst_pad_push_event (srcpad, gst_event_new_caps (fixedcaps))
|
2005-03-28 14:54:33 +00:00
|
|
|
|
break
|
|
|
|
|
endif
|
|
|
|
|
done
|
|
|
|
|
endif
|
|
|
|
|
|
2011-06-22 10:26:19 +00:00
|
|
|
|
#negotiate allocator/bufferpool with the ALLOCATION query
|
|
|
|
|
|
|
|
|
|
buffer = gst_buffer_new_allocate (NULL, size, 0);
|
|
|
|
|
# fill buffer and push
|
2005-03-28 14:54:33 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The general flow for a sink pad starting a renegotiation.
|
|
|
|
|
|
|
|
|
|
src sink
|
|
|
|
|
| |
|
|
|
|
|
| accepts? |
|
2008-06-29 15:00:26 +00:00
|
|
|
|
|<----------------| type B
|
2005-03-28 14:54:33 +00:00
|
|
|
|
| yes |
|
2011-06-06 14:11:31 +00:00
|
|
|
|
|- - - - - - - - >|-.
|
|
|
|
|
| | | suggest B caps next
|
|
|
|
|
| |<'
|
2005-03-28 14:54:33 +00:00
|
|
|
|
| |
|
2011-06-06 14:11:31 +00:00
|
|
|
|
| push_event() |
|
|
|
|
|
mark .-|<----------------| send RECONFIGURE event
|
|
|
|
|
renegotiate| | |
|
|
|
|
|
'>| |
|
2012-01-14 18:16:01 +00:00
|
|
|
|
| querycaps() |
|
2011-06-06 14:11:31 +00:00
|
|
|
|
renegotiate |---------------->|
|
|
|
|
|
| suggest B |
|
|
|
|
|
|< - - - - - - - -|
|
|
|
|
|
| |
|
|
|
|
|
| send_event() |
|
|
|
|
|
send CAPS |---------------->| Receive type B, reconfigure to
|
|
|
|
|
event B | | process type B.
|
2005-03-28 14:54:33 +00:00
|
|
|
|
| |
|
|
|
|
|
| push |
|
2011-06-06 14:11:31 +00:00
|
|
|
|
push buffer |---------------->| Process buffer of type B
|
2005-03-28 14:54:33 +00:00
|
|
|
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Use case:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
videotestsrc ! xvimagesink
|
|
|
|
|
|
|
|
|
|
1) Who decides what format to use?
|
|
|
|
|
- src pad always decides, by convention. sinkpad can suggest a format
|
2012-01-14 18:16:01 +00:00
|
|
|
|
by putting it high in the caps query result GstCaps.
|
2005-03-28 14:54:33 +00:00
|
|
|
|
- since the src decides, it can always choose something that it can do,
|
|
|
|
|
so this step can only fail if the sinkpad stated it could accept
|
|
|
|
|
something while later on it couldn't.
|
|
|
|
|
|
|
|
|
|
2) When does negotiation happen?
|
|
|
|
|
- before srcpad does a push, it figures out a type as stated in 1), then
|
2011-06-06 14:11:31 +00:00
|
|
|
|
it pushes a caps event with the type. The sink checks the media type and
|
|
|
|
|
configures itself for this type.
|
|
|
|
|
- the source then usually does an ALLOCATION query to negotiate a bufferpool
|
|
|
|
|
with the sink. It then allocates a buffer from the pool and pushes it to
|
|
|
|
|
the sink. since the sink accepted the caps, it can create a pool for the
|
|
|
|
|
format.
|
2005-03-28 14:54:33 +00:00
|
|
|
|
- since the sink stated in 1) it could accept the type, it will be able to
|
2011-06-06 14:11:31 +00:00
|
|
|
|
handle it.
|
2005-03-28 14:54:33 +00:00
|
|
|
|
|
|
|
|
|
3) How can sink request another format?
|
|
|
|
|
- sink asks if new format is possible for the source.
|
2011-06-06 14:11:31 +00:00
|
|
|
|
- sink pushes RECONFIGURE event upstream
|
|
|
|
|
- src receives the RECONFIGURE event and marks renegotiation
|
|
|
|
|
- On the next buffer push, the source renegotiates the caps and the
|
|
|
|
|
bufferpool. The sink will put the new new prefered format high in the list
|
2012-01-14 18:16:01 +00:00
|
|
|
|
of caps it returns from its caps query.
|
2005-03-28 14:54:33 +00:00
|
|
|
|
|
|
|
|
|
videotestsrc ! queue ! xvimagesink
|
|
|
|
|
|
2012-01-14 18:16:01 +00:00
|
|
|
|
- queue proxies all accept and caps queries to the other peer pad.
|
2011-06-06 14:11:31 +00:00
|
|
|
|
- queue proxies the bufferpool
|
|
|
|
|
- queue proxies the RECONFIGURE event
|
|
|
|
|
- queue stores CAPS event in the queue. This means that the queue can contain
|
|
|
|
|
buffers with different types.
|
2005-03-28 14:54:33 +00:00
|
|
|
|
|
|
|
|
|
|
2007-01-10 21:15:08 +00:00
|
|
|
|
Pull-mode negotiation
|
2010-11-01 13:32:43 +00:00
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~
|
2007-01-10 21:15:08 +00:00
|
|
|
|
|
2007-01-12 15:39:57 +00:00
|
|
|
|
Rationale
|
2010-11-01 13:32:43 +00:00
|
|
|
|
^^^^^^^^^
|
2007-01-12 15:39:57 +00:00
|
|
|
|
|
2007-01-10 21:15:08 +00:00
|
|
|
|
A pipeline in pull mode has different negotiation needs than one
|
|
|
|
|
activated in push mode. Push mode is optimized for two use cases:
|
|
|
|
|
|
|
|
|
|
* Playback of media files, in which the demuxers and the decoders are
|
|
|
|
|
the points from which format information should disseminate to the
|
|
|
|
|
rest of the pipeline; and
|
|
|
|
|
|
|
|
|
|
* Recording from live sources, in which users are accustomed to putting
|
|
|
|
|
a capsfilter directly after the source element; thus the caps
|
|
|
|
|
information flow proceeds from the user, through the potential caps
|
|
|
|
|
of the source, to the sinks of the pipeline.
|
|
|
|
|
|
|
|
|
|
In contrast, pull mode has other typical use cases:
|
|
|
|
|
|
|
|
|
|
* Playback from a lossy source, such as RTP, in which more knowledge
|
|
|
|
|
about the latency of the pipeline can increase quality; or
|
|
|
|
|
|
|
|
|
|
* Audio synthesis, in which audio APIs are tuned to producing only the
|
|
|
|
|
necessary number of samples, typically driven by a hardware interrupt
|
|
|
|
|
to fill a DMA buffer or a Jack[0] port buffer.
|
|
|
|
|
|
|
|
|
|
* Low-latency effects processing, whereby filters should be applied as
|
|
|
|
|
data is transferred from a ring buffer to a sink instead of
|
|
|
|
|
beforehand. For example, instead of using the internal alsasink
|
|
|
|
|
ringbuffer thread in push-mode wavsrc ! volume ! alsasink, placing
|
|
|
|
|
the volume inside the sound card writer thread via wavsrc !
|
|
|
|
|
audioringbuffer ! volume ! alsasink.
|
|
|
|
|
|
|
|
|
|
[0] http://jackit.sf.net
|
|
|
|
|
|
2007-01-12 15:39:57 +00:00
|
|
|
|
The problem with pull mode is that the sink has to know the format in
|
2007-01-10 21:15:08 +00:00
|
|
|
|
order to know how many bytes to pull via gst_pad_pull_range(). This
|
|
|
|
|
means that before pulling, the sink must initiate negotation to decide
|
|
|
|
|
on a format.
|
|
|
|
|
|
|
|
|
|
Recalling the principles of capsnego, whereby information must flow from
|
|
|
|
|
those that have it to those that do not, we see that the two named use
|
|
|
|
|
cases have different negotiation requirements:
|
|
|
|
|
|
|
|
|
|
* RTP and low-latency playback are both like the normal playback case,
|
|
|
|
|
in which information flows downstream.
|
|
|
|
|
|
|
|
|
|
* In audio synthesis, the part of the pipeline that has the most
|
|
|
|
|
information is the sink, constrained by the capabilities of the graph
|
|
|
|
|
that feeds it. However the caps are not completely specified; at some
|
|
|
|
|
point the user has to intervene to choose the sample rate, at least.
|
|
|
|
|
This can be done externally to gstreamer, as in the jack elements, or
|
2007-01-10 21:24:08 +00:00
|
|
|
|
internally via a capsfilter, as is customary with live sources.
|
2007-01-10 21:15:08 +00:00
|
|
|
|
|
|
|
|
|
Given that sinks potentially need the input of sources, as in the RTP
|
|
|
|
|
case and at least as a filter in the synthesis case, there must be a
|
2007-01-12 15:39:57 +00:00
|
|
|
|
negotiation phase before the pull thread is activated. Also, given the
|
|
|
|
|
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
|
|
|
|
|
deadlines.
|
|
|
|
|
|
2008-10-10 15:12:11 +00:00
|
|
|
|
The pull thread is usually started in the PAUSED->PLAYING state change. We must
|
|
|
|
|
be able to complete the negotiation before this state change happens.
|
|
|
|
|
|
2011-06-06 14:11:31 +00:00
|
|
|
|
The time to do capsnego, then, is after the SCHEDULING query has succeeded,
|
2008-10-10 15:12:11 +00:00
|
|
|
|
but before the sink has spawned the pulling thread.
|
2007-01-12 15:39:57 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mechanism
|
2010-11-01 13:32:43 +00:00
|
|
|
|
^^^^^^^^^
|
2007-01-12 15:39:57 +00:00
|
|
|
|
|
2008-10-10 15:12:11 +00:00
|
|
|
|
The sink determines that the upstream elements support pull based scheduling by
|
2011-06-06 14:11:31 +00:00
|
|
|
|
doing a SCHEDULING query.
|
2008-10-10 15:12:11 +00:00
|
|
|
|
|
2007-01-12 15:39:57 +00:00
|
|
|
|
The sink initiates the negotiation process by intersecting the results
|
2012-01-14 18:16:01 +00:00
|
|
|
|
of gst_pad_query_caps() on its sink pad and its peer src pad. This is the
|
2007-01-12 15:39:57 +00:00
|
|
|
|
operation performed by gst_pad_get_allowed_caps(). In the simple
|
2012-01-14 18:16:01 +00:00
|
|
|
|
passthrough case, the peer pad's caps query should return the
|
2007-01-12 15:39:57 +00:00
|
|
|
|
intersection of calling get_allowed_caps() on all of its sink pads. In
|
|
|
|
|
this way the sink element knows the capabilities of the entire pipeline.
|
|
|
|
|
|
|
|
|
|
The sink element then fixates the resulting caps, if necessary,
|
2012-01-14 18:16:01 +00:00
|
|
|
|
resulting in the flow caps. From now on, the caps query of the sinkpad
|
|
|
|
|
will only return these fixed caps meaning that upstream elements
|
2008-10-10 15:12:11 +00:00
|
|
|
|
will only be able to produce this format.
|
2007-01-12 15:39:57 +00:00
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
possible.
|
|
|
|
|
|
2008-10-10 15:12:11 +00:00
|
|
|
|
When negotiation succeeded, the sinkpad and all upstream internally linked pads
|
|
|
|
|
are activated in pull mode. Typically, this operation will trigger negotiation
|
|
|
|
|
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.
|
2012-01-14 18:16:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Patterns
|
|
|
|
|
~~~~~~~~
|
|
|
|
|
|
|
|
|
|
We can identify 3 patterns in negotiation:
|
|
|
|
|
|
|
|
|
|
1) Fixed : Can't choose the output format
|
|
|
|
|
- Caps encoded in the stream
|
|
|
|
|
- A video/audio decoder
|
|
|
|
|
- usually uses gst_pad_use_fixed_caps()
|
|
|
|
|
|
2012-10-12 14:09:26 +00:00
|
|
|
|
2) Transform
|
|
|
|
|
- Caps not modified (passthrough)
|
2012-01-14 18:16:01 +00:00
|
|
|
|
- can do caps transform based on element property
|
2012-10-15 10:10:46 +00:00
|
|
|
|
- fixed caps get transformed into fixed caps
|
2012-01-14 18:16:01 +00:00
|
|
|
|
- videobox
|
|
|
|
|
|
|
|
|
|
3) Dynamic : can choose output format
|
|
|
|
|
- A converter element
|
|
|
|
|
- depends on downstream caps, needs to do a CAPS query to find
|
|
|
|
|
transform.
|
|
|
|
|
- usually prefers to use the identity transform
|
2012-10-15 10:10:46 +00:00
|
|
|
|
- fixed caps can be transformed into unfixed caps.
|