最近更新了M89代码,看了下Release Notes,有几个需要关心的地方。
Plan B SDP语法后续处理计划
WebRTC 1.0已经正式成为W3C标准,推荐使用标准SDP格式:Unified Plan,主流浏览器基本都支持Unified Plan SDP。Plan B SDP后续将会不赞成使用,直到移除掉。官方后续时间计划如下:
- M89 (2021.02):在开发者控制台增加不赞成使用警告
- M93 (2021.08): Plan B被移除掉, 但是增加了选项,可以延长移除的截止日期
- M96 (2022.01): 不再允许延长截止日期,Plan B将彻底移除
rtp payload类型增加新范围
M89中RTP payload类型增加了新的值范围:35-65。
首先根据RFC3551,回顾下目前用于标准音视频编码器的RTP payload类型。
音频编码器的payload类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
PT encoding media type clock rate channels name (Hz) ___________________________________________________ 0 PCMU A 8,000 1 1 reserved A 2 reserved A 3 GSM A 8,000 1 4 G723 A 8,000 1 5 DVI4 A 8,000 1 6 DVI4 A 16,000 1 7 LPC A 8,000 1 8 PCMA A 8,000 1 9 G722 A 8,000 1 10 L16 A 44,100 2 11 L16 A 44,100 1 12 QCELP A 8,000 1 13 CN A 8,000 1 14 MPA A 90,000 15 G728 A 8,000 1 16 DVI4 A 11,025 1 17 DVI4 A 22,050 1 18 G729 A 8,000 1 19 reserved A 20 unassigned A 21 unassigned A 22 unassigned A 23 unassigned A dyn G726-40 A 8,000 1 dyn G726-32 A 8,000 1 dyn G726-24 A 8,000 1 dyn G726-16 A 8,000 1 dyn G729D A 8,000 1 dyn G729E A 8,000 1 dyn GSM-EFR A 8,000 1 dyn L8 A var. var. dyn RED A dyn VDVI A var. 1 |
视频编码器的payload类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
PT encoding media type clock rate name (Hz) _____________________________________________ 24 unassigned V 25 CelB V 90,000 26 JPEG V 90,000 27 unassigned V 28 nv V 90,000 29 unassigned V 30 unassigned V 31 H261 V 90,000 32 MPV V 90,000 33 MP2T AV 90,000 34 H263 V 90,000 35-71 unassigned ? 72-76 reserved N/A N/A 77-95 unassigned ? 96-127 dynamic ? dyn H263-1998 V 90,000 |
原有动态RTP payload类型范围局限性
RFC 3551中定义的动态RTP payload类型范围[96,127]只能表示32种payload类型。由于Chrome支持的音视频编解码器越来越多,而且像DTMF,FEC,RTX机制,冗余编码,H264不同profile/打包模式等都需要占用一个RTP payload类型。原先的范围已经不够使用了。
这里我们看下某个默认生成的Offer SDP中的内容(有点长),a=rtpmap后面跟着就是某种RTP payload类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
type: offer, sdp: v=0 o=- 6788055534693219431 2 IN IP4 127.0.0.1 s=- t=0 0 a=group:BUNDLE 0 1 a=msid-semantic: WMS m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126 c=IN IP4 0.0.0.0 a=rtcp:9 IN IP4 0.0.0.0 a=ice-ufrag:ZyMc a=ice-pwd:QE73GpurJc/kg/ODTTG6/u3Y a=ice-options:trickle a=fingerprint:sha-256 A6:B0:BE:CF:84:3B:71:77:8F:B1:A7:64:E7:58:A9:33:DB:81:06:A2:D4:D6:4D:34:40:97:6F:4C:DD:00:C3:24 a=setup:actpass a=mid:0 a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01 a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid a=extmap:5 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id a=extmap:6 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id a=sendonly a=msid:- 91ccb8de-681d-43aa-97a2-eefc12623c36 a=rtcp-mux a=rtpmap:111 opus/48000/2 a=rtcp-fb:111 transport-cc a=fmtp:111 minptime=10;useinbandfec=1 a=rtpmap:103 ISAC/16000 a=rtpmap:104 ISAC/32000 a=rtpmap:9 G722/8000 a=rtpmap:0 PCMU/8000 a=rtpmap:8 PCMA/8000 a=rtpmap:106 CN/32000 a=rtpmap:105 CN/16000 a=rtpmap:13 CN/8000 a=rtpmap:110 telephone-event/48000 a=rtpmap:112 telephone-event/32000 a=rtpmap:113 telephone-event/16000 a=rtpmap:126 telephone-event/8000 m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 102 121 127 120 125 107 108 109 124 119 123 118 114 115 116 c=IN IP4 0.0.0.0 a=rtcp:9 IN IP4 0.0.0.0 a=ice-ufrag:ZyMc a=ice-pwd:QE73GpurJc/kg/ODTTG6/u3Y a=ice-options:trickle a=fingerprint:sha-256 A6:B0:BE:CF:84:3B:71:77:8F:B1:A7:64:E7:58:A9:33:DB:81:06:A2:D4:D6:4D:34:40:97:6F:4C:DD:00:C3:24 a=setup:actpass a=mid:1 a=extmap:14 urn:ietf:params:rtp-hdrext:toffset a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time a=extmap:13 urn:3gpp:video-orientation a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01 a=extmap:12 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay a=extmap:11 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/color-space a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid a=extmap:5 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id a=extmap:6 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id a=sendonly a=msid:- 4c9c6691-2673-48f8-bebd-b35ab5cd095f a=rtcp-mux a=rtcp-rsize a=rtpmap:96 VP8/90000 a=rtcp-fb:96 goog-remb a=rtcp-fb:96 transport-cc a=rtcp-fb:96 ccm fir a=rtcp-fb:96 nack a=rtcp-fb:96 nack pli a=rtpmap:97 rtx/90000 a=fmtp:97 apt=96 a=rtpmap:98 VP9/90000 a=rtcp-fb:98 goog-remb a=rtcp-fb:98 transport-cc a=rtcp-fb:98 ccm fir a=rtcp-fb:98 nack a=rtcp-fb:98 nack pli a=fmtp:98 profile-id=0 a=rtpmap:99 rtx/90000 a=fmtp:99 apt=98 a=rtpmap:100 VP9/90000 a=rtcp-fb:100 goog-remb a=rtcp-fb:100 transport-cc a=rtcp-fb:100 ccm fir a=rtcp-fb:100 nack a=rtcp-fb:100 nack pli a=fmtp:100 profile-id=2 a=rtpmap:101 rtx/90000 a=fmtp:101 apt=100 a=rtpmap:102 H264/90000 a=rtcp-fb:102 goog-remb a=rtcp-fb:102 transport-cc a=rtcp-fb:102 ccm fir a=rtcp-fb:102 nack a=rtcp-fb:102 nack pli a=fmtp:102 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f a=rtpmap:121 rtx/90000 a=fmtp:121 apt=102 a=rtpmap:127 H264/90000 a=rtcp-fb:127 goog-remb a=rtcp-fb:127 transport-cc a=rtcp-fb:127 ccm fir a=rtcp-fb:127 nack a=rtcp-fb:127 nack pli a=fmtp:127 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f a=rtpmap:120 rtx/90000 a=fmtp:120 apt=127 a=rtpmap:125 H264/90000 a=rtcp-fb:125 goog-remb a=rtcp-fb:125 transport-cc a=rtcp-fb:125 ccm fir a=rtcp-fb:125 nack a=rtcp-fb:125 nack pli a=fmtp:125 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f a=rtpmap:107 rtx/90000 a=fmtp:107 apt=125 a=rtpmap:108 H264/90000 a=rtcp-fb:108 goog-remb a=rtcp-fb:108 transport-cc a=rtcp-fb:108 ccm fir a=rtcp-fb:108 nack a=rtcp-fb:108 nack pli a=fmtp:108 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f a=rtpmap:109 rtx/90000 a=fmtp:109 apt=108 a=rtpmap:124 H264/90000 a=rtcp-fb:124 goog-remb a=rtcp-fb:124 transport-cc a=rtcp-fb:124 ccm fir a=rtcp-fb:124 nack a=rtcp-fb:124 nack pli a=fmtp:124 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=4d001f a=rtpmap:119 rtx/90000 a=fmtp:119 apt=124 a=rtpmap:123 H264/90000 a=rtcp-fb:123 goog-remb a=rtcp-fb:123 transport-cc a=rtcp-fb:123 ccm fir a=rtcp-fb:123 nack a=rtcp-fb:123 nack pli a=fmtp:123 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=64001f a=rtpmap:118 rtx/90000 a=fmtp:118 apt=123 a=rtpmap:114 red/90000 a=rtpmap:115 rtx/90000 a=fmtp:115 apt=114 a=rtpmap:116 ulpfec/90000 |
根据m-line,可知,音频用到的RTP payload类型有:111 103 104 9 0 8 106 105 13 110 112 113 126
。视频用到的RTP payload类型有:96 97 98 99 100 101 102 121 127 120 125 107 108 109 124 119 123 118 114 115 116
。
在动态RTP payload类型[96,127]范围内,用到了31个取值,如果稍微再复杂些,[96,127]确实不够用了。
新增RTP payload类型范围
RFC3551中,section-3中提到,当需要定义的动态payload类型超过32个时,推荐优先使用unassigned payload类型这个范围的值。
为了兼容旧版Chrome,所以M89中增加了新的RTP payload类型范围:35-65。由前面视频编码器的payload类型可知[35,65]位于[35,71]这个Unassigned payload类型范围内。
在webrtc_video_engine.cc中相关说明代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// This function will assign dynamic payload types (in the range [96, 127] and // for new additions the [35, 65] range) to the input codecs, and also add // ULPFEC, RED, FlexFEC, and associated RTX codecs for recognized codecs (VP8, // VP9, H264 and RED). It will also add default feedback params to the codecs. std::vector<VideoCodec> AssignPayloadTypesAndDefaultCodecs( std::vector<webrtc::SdpVideoFormat> input_formats, const webrtc::WebRtcKeyValueConfig& trials) { if (input_formats.empty()) return std::vector<VideoCodec>(); // Due to interoperability issues with old Chrome/WebRTC versions only use // the lower range for new codecs. static const int kFirstDynamicPayloadTypeLowerRange = 35; static const int kLastDynamicPayloadTypeLowerRange = 65; static const int kFirstDynamicPayloadTypeUpperRange = 96; static const int kLastDynamicPayloadTypeUpperRange = 127; int payload_type_upper = kFirstDynamicPayloadTypeUpperRange; int payload_type_lower = kFirstDynamicPayloadTypeLowerRange; |
总结
针对前面提到的两点重要更新,我觉得后续我们WebRTC服务器开发的得注意下,需要完全支持Unified Plan,同时需要能正确识别[35,65]这个范围表示的RTP payload类型。
参考
[1] WebRTC M89 Release Notes.https://groups.google.com/g/discuss-webrtc/c/Zrsn2hi8FV0/m/7Y4RLluHAQAJ.
[2] RFC3551.https://tools.ietf.org/html/rfc3551.
本文已收录到大话WebRTC专栏,更多精彩请访问《大话WebRTC》。
文章评论
我看市面上开源的mcu基本都是软编解码,很耗cpu,是否可以通过显卡(比如nvidia T4)编解码以减少服务器上cpu的使用。预计承载能力会有很大提高吗
@liu 通过显卡硬件加速视频编解码当然提升承载能力,至于提升多大还得看你的具体硬件配置
请问你未公开的文章可以付费阅读么?你写文章比较到位。
@miiyu 没这打算,搞WebRTC急不得。