webrtc音频发送流程

1.概述

webrtc 音频数据整个流程的代码调用图:

img

2 .采集部分

采集部分:使用平台上的麦克风采集api, 代码模块: moudles/audio_devce

ADMWarpper类封装了音频设备类 AudioDeviceModule, AudioDeviceDataObserver 类,AudioTransport类, 其中AudioDeviceModule 封装拉流各个平台的麦克风采集API, AudioDeviceDataObserver 可以将采集到的原始数据向外抛出,进行业务展示; AudioTransport 将原始数据进行编码传输等。

采集部分代码:

img

采集前会遍历麦克风设备,获取设备信息,InitRecordingDMO

使用AEC时麦克风设备属性:

typedef struct tWAVEFORMATEX

{

WORD wFormatTag; WAVE_FORMAT_PCM //音频格式

WORD nChannels; 1 //通道

DWORD nSamplesPerSec; 16000 //采样率

DWORD nAvgBytesPerSec; 32000 //平均每秒的字节数

WORD nBlockAlign; 2 //数据块大小

WORD wBitsPerSample; 16 //位数

WORD cbSize;

} WAVEFORMATEX;

AudioDeviceWindowsCore::StartRecording()

win下启用AEC硬件回音消除,启用AEC是在 WebrtcVoiceEngine::init中 const bool enable_built_in_aec =

*options.echo_cancellation && !use_delay_agnostic_aec;

WSAPICaptureThreadPollDMO->DoCaptureThreadPollDMO,开启采集线程,

DWORD waitResult = WaitForSingleObject(_hShutdownCaptureEvent, 5); 采集音频的间隔是5毫秒

音频数据传输到 AudioDeviceBuffer中, AudioDeviceBuffer 中计算每个通道的帧数等,将数据通过回调传给audio_transport_cb_

ADMWrapper 中接收该数据,并且将数据传输 RecordedDataIsAvailable

observer 是收到了采集到的原始数据, 原始数据打包成AudioFrame, 进行重采样,通过回调observer将数据传输到上层

audio_transport_ 将数据传输到编码层

AudioTransportImpl::RecordedDataIsAvailable

InitializeCaptureFrame 在不丢音频信息的情况下,选择最低的采样率和通道数,选择本机最小的设备输入和编码采样频率,最小的通道数配置AudioFrame

RemixAndResample 重采样 降低或者提高音频的通道数

计算音频声音大小,将数据拷贝到每个要发送的流中。

img

ChannelSend::ProcessAndEncodeAudio 将一个AudioFrame数据放在编码队列中, 编码前处理音频静音(静音是将该帧的音频数据重置为0)、添加帧的时间戳,编码完后调用packetization_callback_->SendData 将数据发送出去

★文末名片可以免费领取音视频开发学习资料,内容包括(FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)以及音视频学习路线图等等。

见下方!↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

3.编码部分

采集到的音频可能存在噪音,所以需要对源数据进行预处理, 预处理模块 AudioProcessing,处理完后对音频进行编码

编码前需要对声音进行预处理 AudioProcessing,

编码部分:一般的编码算法: Opus,G722,G711,Isac,Ilbc, 编码完成后将音频数据打包成rtp, 音频的编码方式是根据sdp协商来的,

m=audio 9 UDP/TLS/RTP/SAVPF 111 102 103 104 9 0 8 106 105 13 110 112 113 126

表示流中包含音频数据, 端口号9, 使用udp协议 tls加密rtp包,SAVPF代表使用srtcp的反馈机制来控制通信过程, 编码方式使用111, 111在后面的sdp中有说明:

a=rtpmap:111 opus/48000/2 //opus编码, 48000hz, 双通道

a=rtcp-fb:111 transport-cc // 支持 rtcp 协议控制拥塞

a=rtcp-fb:111 nack // 支持丢包重传

a=fmtp:111 minptime=10;useinbandfec=1 //对opus编码可选的补充说明,minptime代表最小打包时长是10ms,useinbandfec=1代表使用opus编码内置fec特性。

数据发送:

packetization_callback_->SendData(

frame_type, encoded_info.payload_type, encoded_info.encoded_timestamp,

encode_buffer.data(), encode_buffer.size());

发送音频数据 payload_type就是sdp协商的类型,也是编码方式。

4.发送部分

发送部分主要将音频数据打包成rtp包, 平滑发送 rtp 包和rtcp包, 最后数据通过udp发送到对端。

  1. rtprtcp 部分

RTP(Real-time Transport Protocol 实时传输协议) 协议是网络中对于流媒体传输的基础协议,RTP协议本身只保证数据实时传输,并不保证数据安全到达。与RTP 配套的协议是 RTCP(Real-time Transport Control Protocol) 实时传输控制协议,RTCP提供流量控制和拥塞服务。 rtc会话期间参与者周期性的发送rtcp报文,包括接收和发送数据的内容, 参与者根据 rtcp 数据动态调整。

音频转发到ChannelSend::SendRtpAudio 时,在rtp扩展头中增加音量属性, 对音频数据进行加密, 发送rtcp数据(webrtc中rtcp的发送规则:默认配置rtcp音频间隔5秒钟, 视频间隔1秒钟, 两个rtcp包的发送间隔是 [0.5 ~ 1.5]*默认间隔)。

RTPSender::SendToNetwork 中做了两件事: 1. 判断是否开启了fec,开启fec将rtp包存储到 flexfec_packet_history,否则 将该rtp包存储到packet_history中,为以后重发该rtp包做准备 2. 将该包插入paced_sender中, paced_sender按照优先级发送包, 优先级高的会立即发送

  1. PacedSender 部分

PacedSender 部分:通过gcc估算出的码率来计算当前应该发送多少字节的数据。GoogCcNetworkController: GCC谷歌提出的拥塞控制算法(简称GCC[1])来控制发送端码率,设置两个码率:pacing_rate_bps 和 padding_rate_bps,其中pacing_rate_bps 是发送码率控制, padding_rate_bps 是填充码率控制(webrtc引入padding机制来保障发送尽量大的数据来探测网络带宽上限)。

media_budget和padding_budget 保存了媒体发送预算和填充数据 每次可以发送的字节数。

PacedSender::Process()中先计算了要发送的剩余数据及包的平均剩余时间, 获取最小发送码率, 判断是否暂停和是否有发送包,再发送包时会根据包的优先级和media_budget_ 判断是否发送包, 如果发送失败,会将该包重新重新放入发送队列中。 包发送完后会判断是否发送 padding数据。

PacedSender发送相关类:

img

webrtc module用来处理定时重复任务,module 三个接口:

TimeUntilNextProcess 距离下次任务执行的时间间隔

Process 任务处理函数

ProcessThreadAttached 绑定ProcessThread到当前模块

PacedSender类继承Module类, 内部有ProcessThread 来定时执行发送任务

rtp_transport_controller_send.cc中将 PacedSender线程注册到ProcessThread模块中, ProcessThread线程开始执行,run中会遍历所有的模块, 计算每个模块下次执行的时间,执行每个模块的Process()任务, ProcessThread 还支持PostTask任务。

5.总结

img

音频采集到发送的流程如上图: 音频采集和每个平台的底层API相关, windows上使用core audio, 音频预处理, 主要进行重采样、声道、回音抑制、声音检测等, 音频编码将音频数据进一步压缩,编码算法的选择是sdp协商的结果, 音频数据编码封装成rtp包,同时还会检查是否需要发送rtcp数据, 最后进行平滑发送到udp接口。

原文链接:webrtc音频发送流程-CSDN博客

★文末名片可以免费领取音视频开发学习资料,内容包括(FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)以及音视频学习路线图等等。

见下方!↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

猜你喜欢

转载自blog.csdn.net/yinshipin007/article/details/129903940