PSA: setCodecPreferences requires codecs from the RTCRtpReceiver.getCapabilities (M124)

1,682 views
Skip to first unread message

Philipp Hancke

unread,
Mar 1, 2024, 12:41:44 AMMar 1
to discuss...@googlegroups.com
As of
RTCRtpTransceiver.setCodecPreferences may throw an error if you configure it with input from
  RTCRtpSender.getCapabilities('video').codecs
instead of taking the input from
    RTCRtpReceiver.getCapabilities('video').codecs

Usually this should not make much of a difference but it turns out that on MacOS Chromium exposes a H264 encoder with Level 5.2 while it only claims to support Level 3.1.

This can be an issue if you do something along the lines of
  const codecs = RTCRtpSender.getCapabilities('video').codecs;
  transceiver.setCodecPreferences(codecs.filter(c => c.mimeType === 'video/H264')

In general setCodecPreferences dictates what you prefer to *receive* which was the reason for making this change.
It should be easier to work with, see .e.g  the changes in the samples repository:

Chromium 124 ships in mid-april, see the dashboard:

[MSFT] Diego Perez Botero

unread,
Mar 1, 2024, 3:10:48 AMMar 1
to discuss-webrtc
 Historically, some Android devices were hitting the following error when trying to setCodecPreferences with only the RTCRtpReceiver.getCapabilities('video') output:
        InvalidModificationError: Failed to execute 'setCodecPreferences' on 'RTCRtpTransceiver': Invalid codec preferences: Missing codec from send codec capabilities.

So we had to add the following workaround to append RTCRtpSender.getCapabilities('video') output before calling setCodecPreferences(...):
        // Even though our transceiver is 'recvonly', LibWebRTC demands that it always has something
        // to offer regardless of transceiver.direction. Thus, we must not forget to add the RTCRtpSender's
        // codecs to the very end. Some devices don't support H264 for *outgoing* video and will hit
        // InvalidModificationError during the setCodecPreferences(...) call if we don't do this.
        //
        // See VerifyCodecPreferences at https://chromium.googlesource.com/external/webrtc/+/master/pc/rtp_transceiver.cc
        const supportedSenderVideoCodecCapabilities = RTCRtpSender.getCapabilities('video')?.codecs ?? [];
        codecPreferences.push(...supportedSenderVideoCodecCapabilities);
        videoTransceiver.setCodecPreferences(codecPreferences);

From my reading of this PSA, it sounds like the ugly workaround is now going to blow up in our face. However, my reading of the M124 change indicates that the original Android problem that we were hitting is also going away with M124+, since the VerifyCodecPreferences implementation doesn't care about the sender codecs anymore. Could you please confirm that my understanding is accurate? :)

My plan moving forward would be to:
1. Leave the workaround for M123 and down
2. No longer attempt the workaround for M124 onwards

Thanks!
-Diego

Philipp Hancke

unread,
Mar 1, 2024, 3:13:32 AMMar 1
to discuss...@googlegroups.com
That sounds correct. The lack of H264 SW on Android is what caused all this mess :-|

--
This list falls under the WebRTC Code of Conduct - https://webrtc.org/support/code-of-conduct.
---
You received this message because you are subscribed to the Google Groups "discuss-webrtc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to discuss-webrt...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/discuss-webrtc/90810e3e-c85a-4d74-b7af-90b475e260den%40googlegroups.com.

witaly...@gmail.com

unread,
Mar 20, 2024, 10:57:39 PMMar 20
to discuss-webrtc
Imo it's not Android, but setCodecPreferences itself - it should have been exposed as RTCRtpReceiver and RTCRtpSender API. Adding it to RTCRtpTransceiver not only messed up asymmetrical cases, but also created this little know gotcha that setCodecPreferences actually stands for setReceiveCodecPreferences

witaly...@gmail.com

unread,
Mar 20, 2024, 11:04:48 PMMar 20
to discuss-webrtc
I guess it was done the way it was due to SDP limitations, but don't get me started on SDP...

Philipp Hancke

unread,
Mar 20, 2024, 11:06:16 PMMar 20
to discuss...@googlegroups.com
not going to argue with that but it is kinda hard to fix mistakes like that on the web platform

Khun V

unread,
Mar 21, 2024, 11:42:01 PMMar 21
to discuss...@googlegroups.com
Yes, changing APIs used so extensively is not an easy feat. Thank you for your webrtc service over the years!

Anyway at this point I've decided to get rid of setCodecPreferences completely as it's way too unreliable and go commando. This JS snippet seems to work in my case (enforce H264), old school SDP munging it is: https://gist.github.com/tnoho/948be984f9981b59df43

Reply all
Reply to author
Forward
0 new messages