video
收集candidate之后,就可以建立好数据传输的通道了,现在通过源码走读下视频数据是如何 采集 & 编码 & 传输的
videosource && videotrack
1 | _localVideoTrack = [self createLocalVideoTrack]; |
这里的 videosource 跟 videotrack 就是 后面 capture的过程的 delegate
capture
1 | RTC_OBJC_TYPE(RTCCameraVideoCapturer) *capturer = |
1 | - (void)startCaptureWithDevice:(AVCaptureDevice *)device |
1 | void ObjCVideoTrackSource::OnCapturedFrame(RTC_OBJC_TYPE(RTCVideoFrame) * frame) { |
1 | .../webrtc/src/media/base/video_broadcaster.cc |
capture采集到frame最后都会回调到 video_broadcaster,然后通过 broadcaster 遍历sink 分发出去
通过 track 添加的sink 都会 经过 source 进到 broadcaster 来管理
1 |
|
sink 拿到 采集的 frame 就会 进到 encode 的过程
encode 过程中 frame_cadence_adapter 实现了 VideoSinkInterface 接口 会作为sink 添加到 broadcaster中,最终会进到 VideoStreamEncoder的 核心逻辑中。
encode
encode 的过程是最复杂的逻辑。。。。
.../webrtc/src/pc/sdp_offer_answer.cc
SdpOfferAnswerHandler::ApplyLocalDescription ->
SdpOfferAnswerHandler::UpdateTransceiversAndDataChannels ->
SdpOfferAnswerHandler::UpdateTransceiverChannel // 创建 channel
SdpOfferAnswerHandler::UpdateSessionState ->
SdpOfferAnswerHandler::PushdownMediaDescription ->
1 |
|
1 |
|
media_engine 是创建 factory 的过程中 生成的
dependencies.media_engine = cricket::CreateMediaEngine(std::move(media_dependencies));
1 |
|
1 | .../src/media/engine/webrtc_video_engine.cc |
1 | .../webrtc/src/pc/channel.cc |
1 | .../webrtc/src/media/engine/webrtc_video_engine.cc |
1 | .../webrtc/src/call/degraded_call.cc |
1 | .../webrtc/src/call/call.cc |
1 |
|
addtrack 过程 会创建 transceiver ,transceiver 分别创建 audiochannel & videochannel
后续channel 会针对 sdp 做解析(local/remote), 协商出 音视频 传输的各种参数 ,参数会存储在 VideoSendStream中,这时候encoder 还没开始创建
VideoSendStream 构造函数 会 创建 VideoStreamEncoder VideoStreamEncoder 是后续 创建具体的 encode 以及 接收 videoframe 经过 encode 编码,接收EncodedImage 回调的 关键类
1 | .../webrtc/src/pc/rtp_transmission_manager.cc |
RtpTransmissionManager::AddTrackUnifiedPlan ->
RtpSenderBase::SetTrack ->
VideoRtpSender::SetSend ->
WebRtcVideoChannel::WebRtcVideoSendStream::SetVideoSend ->
VideoSendStream::SetSource ->
1 | .../src/video/video_send_stream.cc |
send_stream_ 就是 VideoSendStreamImpl 继承了 VideoStreamEncoderInterface::EncoderSink 实现了 OnEncodedImage 方法
1 |
|
1 | .../webrtc/src/video/video_stream_encoder.cc |
videostreamencode 通过 video_source_sink_controller_ frame_cadence_adapter_ 注入到 videotrack sink ,进而接受 onframe 的回调1
2
3
4
5
cadence_callback_(*this),
video_source_sink_controller_(/*sink=*/frame_cadence_adapter_.get(),
/*source=*/nullptr),
1 |
|
ReconfigureEncoder() 中根据 encodefactory 创建 encoder encoder_ = settings_.encoder_factory->CreateVideoEncoder(encoder_config_.video_format);
然后注册 encoder 的 回调 encoder_->RegisterEncodeCompleteCallback(this);
1 |
|
sink_->OnEncodedImage(image_copy, codec_specific_info);
进到了 VideoSendStreamImpl的OnEncodedImage处理逻辑
1 | VideoSendStreamImpl::VideoSendStreamImpl( |
video_stream_encoder_->SetSink(this, rotation_applied);
VideoSendStreamImpl 作为 VideoStreamEncoder 的sink, 接收经过编码之后的图像数据
1 | .../webrtc/src/video/video_send_stream_impl.cc |
send
1 |
|
1 |
|
1 | .../webrtc/src/modules/rtp_rtcp/source/rtp_sender.cc |
1 | .../webrtc/src/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc |
paced_sender_ 是在 RtpTransportControllerSend中创建的 pacer_ 是 TaskQueuePacedSender 类型
1 | .../src/modules/pacing/task_queue_paced_sender.cc |
PacingController::ProcessPackets ->
PacketRouter::SendPacket ->
ModuleRtpRtcpImpl2::TrySendPacket ->
RtpSenderEgress::SendPacket ->
RtpSenderEgress::SendPacketToNetwork ->
DegradedCall::FakeNetworkPipeTransportAdapter::SendRtp ->
DegradedCall::FakeNetworkPipeOnTaskQueue::SendRtp ->
FakeNetworkPipe::DeliverNetworkPacket ->
WebRtcVideoChannel::SendRtp ->
MediaChannel::SendRtp ->
MediaChannel::DoSendPacket ->
BaseChannel::SendPacket ->
RtpTransport::SendPacket -> rtp_transport_
就是在 分析candidate文章中 创建的那个 。
P2PTransportChannel::SendPacket ->
ProxyConnection::Send ->
UDPPort::SendTo ->
Socket -> send
到这里 图中的 左半部分 send的过程 结束了
receive
…
RtpTransport::OnReadPacket->
RtpTransport::OnRtpPacketReceived ->
…
BaseChannel::OnRtpPacket ->
MediaChannel::OnPacketReceived ->
Call::DeliverRtpPacket ->
RtpStreamReceiverController::OnRtpPacket ->
RtpVideoStreamReceiver2::OnRtpPacket ->
RtpVideoStreamReceiver2::OnCompleteFrames ->
VideoReceiveStream2::OnCompleteFrame ->
VideoReceiveStream2::OnFrame ->
WebRtcVideoReceiveStream::OnFrame ->
VideoBroadcaster::OnFrame ->
VideoRendererAdapter OnFrame ->
RTCEAGLVideoView renderFrame
…
receive 就是 send 逆向的过程,不重复了
over ….