Hello Jacques,
I might not be the best person to answer your question because I haven't
thought about RTP in a long time, but hopefully those who have
implemented the spec will post to the list, too.
Comments inline.
On 9/24/25 2:34 PM, Jacques Comeaux wrote:
Hi, I have a question about the handling of payload
types in XEP-0167. The spec says that "The session-accept message SHOULD include a
subset of the payload types sent by the initiator". When are two payload types
considered equal?
Equality is always a difficult thing to define, isn't it? ;-)
This is not obvious to me because there are optional
attributes as well as parameters. I would think that definitely name, clockrate, and id
need to match, but I'm not sure about the other attributes and the parameter
values. I think a precise answer to this is needed to determine whether one list of
payload types is a subset of another, and therefore whether a given session-accept meets
this part of the specification.
Based on my understanding of RFC 3551, I would say that a "payload type"
is defined by its registered number, which in Jingle RTP is mapped to
the 'id' attribute. The most common payload types are specified in
Section 6 of RFC 3551 and registered with IANA here:
https://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml
However, there are also dynamically-assigned numbers, as well.
It seems to me that the clockrates can be negotiated down. In your
example, IDs 112, 113, and 114 are all Speex, but a client might not
support clockrates above 8000, so it would not return 112 and 113 in its
subset.
Similarly for the number of channels (e.g., mono vs. stereo).
Here is an example from a call between two XMPP
clients, Dino and Monal
The session-initiate message sent by Dino includes this list of payload types:
<payload-type id='111' channels='2' clockrate='48000'
name='opus'>
<parameter name='useinbandfec' value='1' />
</payload-type>
<payload-type id='112' clockrate='32000' name='speex' />
<payload-type id='113' clockrate='16000' name='speex' />
<payload-type id='114' clockrate='8000' name='speex' />
<payload-type id='9' clockrate='8000' name='G722' />
<payload-type id='0' clockrate='8000' name='PCMU' />
<payload-type id='8' clockrate='8000' name='PCMA' />
And the session-accept message sent by Monal includes this list of payload-types:
<payload-type clockrate='8000' name='PCMU' id='0' />
<payload-type channels='2' id='111' clockrate='48000'
name='opus'>
<parameter name='profile_level_id' value='4325392' />
<parameter name='useinbandfec' value='true' />
<parameter name='minptime' value='10' />
</payload-type>
<payload-type clockrate='8000' name='G722' id='9' />
<payload-type clockrate='8000' name='PCMA' id='8' />
This currently causes a problem in Dino because one of the responder's payload types
(opus) is judged to not be present in the list of sent payload types, because it is not
(strictly speaking) equal to any of the sent payload types, because it has a different
number of parameters.
Well, first of all, Postel's Law applies. :-) How does Dino actually
behave in this situation? Does it fail the entire negotiation? Does it
not choose Opus because of the perceived lack of equality?
I believe that these added parameters are optional and informational
(i.e., intended to help with the negotiation). For instance, regarding
FEC see Section 3 of RFC 7587:
Any compliant Opus decoder is capable of ignoring FEC information
when it is not needed, so encoding with FEC cannot cause
interoperability problems. However, if FEC cannot be used on the
receiving side, then FEC SHOULD NOT be used, as it leads to an
inefficient usage of network resources. Decoder support for FEC
SHOULD be indicated at the time a session is set up.
And, regarding ptime see Section 7.1 of that same spec:
o The "ptime" and "maxptime" parameters are unidirectional
receive-
only parameters and typically will not compromise
interoperability; however, some values might cause application
performance to suffer. [RFC3264] defines the SDP offer/answer
handling of the "ptime" parameter. The "maxptime" parameter
MUST
be handled in the same way.
I don't recall what the profile level ID specifies, but perhaps it's
defined in the Opus API documentation.
In this example, is the responder violating the spec
by including extra parameters for the opus payload type, or is the initiator being too
strict when comparing the payload types for equality?
My feeling is that Dino is probably being too strict.
Peter