这几天在做一些WebRTC音频改进方面的调查工作,在阅读Chromium源码的过程中,就顺便记录下来,便于日后回顾。本文基于Chromium 85源码分析,由于Chromium的快速发展,很有可能不适合于跨度太大的Chromium版本。
大家知道Opus内置了两种编码器:CELT和SILK,并且可以针对采样率、采样间隔、码率、通道数……等属性进行设置。创建的参数设置,是从sdp来的。本文的主要目的,是来看看sdp中的信息,是如何对应到native世界里的代码的。
Native调用序列:

上图中,我保留的起点是从http://channel.cc中的VoiceChannel::SetRemoteContent_w() 方法被调用开始的,再往上的调用栈就没有画了。整个序列中,需要关注的主要是 AudioEncoderOpusImpl 的 SdpToConfig 和 RecreateEncoderInstance 这两个方法。
SdpToConfig,顾名思义,它会把sdp的内容(SdpAudioFormat)转换成 AudioEncoderOpusConfig 对象。AudioEncoderOpusConfig类的头文件件位于:webrtc\api\audio_codecs\opus\audio_encoder_opus_config.h。它定义了十几个Opus的相关属性,如采样率sample_rate_hz、帧长度frame_size_ms、通道数num_channels、音频模式application(决定内部编码使用celt还是silk)、fec_enabled、cbr_enabled……等等。
OK,接下来,让我们拿一个具体的例子来展开说明。假设SDP中音频部分是这样:
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:d3VL
a=ice-pwd:5ccIbts7ExcJCOlQXdRs+lzp
a=ice-options:trickle
a=fingerprint:sha-256 67:E5:3E:05:AC:F4:CE:56:06:4B:7B:74:AB:DA:92:D2:CE:88:1E:2E:78:13:49:69:EA:F3:2B:A0:BB:04:40:DA
a=setup:actpass
a=mid:audio
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level