WebRTC 发送对象的包含和依赖关系主要是 RtpTransceiver

一分钟快速搭建 rtmpd 服务器: https://blog.csdn.net/freeabc/article/details/102880984

软件下载地址: http://www.qiyicc.com/download/rtmpd.rar

github 地址:https://github.com/superconvert/smart_rtmpd

-----------------------------------------------------------------------------------------------------------------------------------------

WebRTC 发送对象的包含和依赖关系主要是 RtpTransceiver

//-------------------------------------------------------------------

RtpTransceiver 对象产生

//-------------------------------------------------------------------

PeerConnection::AddTrack --->  PeerConnection::AddTrackUnifiedPlan

auto sender = CreateSender(media_type, sender_id, track, stream_ids, {});

    // 我们看到创建的 sender 包含下面两种类型 音频,视频
    // sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
    //   signaling_thread(), AudioRtpSender::Create(worker_thread(), id, stats_.get(), this));
    // sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
    //   signaling_thread(), VideoRtpSender::Create(worker_thread(), id, this));

auto receiver = CreateReceiver(media_type, rtc::CreateRandomUuid());

// 这句产生了 RtpTransceiver 包含两个 
transceiver = CreateAndAddTransceiver(sender, receiver);

我们看到,RtpTransceiver  是与 track 相对应的 , 音频 track 对应音频 RtpTransceiver 视频 track 对应视频 RtpTransceiver。

AddTrack 这个过程两个目的:

1. 一个 track 对应一个 RtpTransceiver,并把 RtpTransceiver 加到 PeerConnection 的 transceivers_, PeerConnection 主要有音频和视频两个 RtpTransceiver  

./pc/peer_connection.cc
PeerConnection 
    transceivers_ ---> RtpTransceiver 类型

RtpTransceiver 对象列表,负责 Rtp 的收发,音频是视频的是分开的 ,参考下面代码    
RtpTransceiver 包含 RtpSenderInternal ( 包含 VideoRtpSender ) 和 RtpReceiverInternal ( 包含 VideoRtpReceiver )
    senders_ ---> RtpSenderInternal ( 包含 VideoRtpSender )
    receivers_ ---> RtpReceiverInternal ( 包含 VideoRtpReceiver )
    channel_ ---> VideoChannel or VoiceChannel ( ./pc/channel.h )
    channel_manager_ ---> ChannelManager ( ./pc/channel_manager.h )
    codec_preferences_

2. 这步也建立了音视频的 source ---> encoder  的 pipeline, 具体参考博文 https://blog.csdn.net/freeabc/article/details/106287318

void WebRtcVideoChannel::WebRtcVideoSendStream::AddOrUpdateSink(
         rtc::VideoSinkInterface<webrtc::VideoFrame>* sink, const rtc::VideoSinkWants& wants)
         encoder_sink_ = sink;
         source_->AddOrUpdateSink(encoder_sink_, wants);

//-------------------------------------------------------------------

RtpTransceiver 关联 Channel 对象

//-------------------------------------------------------------------

当 PeerConnection::ApplyLocalDescription 时,因为是 UnifiedPlan SDP ,所以会调用接口

PeerConnection::UpdateTransceiversAndDataChannels 这个接口会调用

调用 PeerConnection::UpdateTransceiverChannel 这个接口会 CreateVideoChannel 并设置 

transceiver->internal()->SetChannel(channel) 的通道

Channel 的产生是根据 SDP 的内容进行创建的,SDP 中的 audio 对应 VoiceChannel ,vidoe 对应 VideoChannel 

SetChannel 的过程就是绑定 MediaChannel 到 sender 和 receiver 的过程

void RtpTransceiver::SetChannel(cricket::ChannelInterface* channel) {
  ... ...

  channel_ = channel;

  if (channel_) {
    channel_->SignalFirstPacketReceived().connect(this, &RtpTransceiver::OnFirstPacketReceived);
  }

  for (const auto& sender : senders_) {
    sender->internal()->SetMediaChannel(channel_ ? channel_->media_channel() : nullptr);
  }

  for (const auto& receiver : receivers_) {
    if (!channel_) {
      receiver->internal()->Stop();
    }
    receiver->internal()->SetMediaChannel(channel_ ? channel_->media_channel() : nullptr);
  }
}

 
./pc/channel.cc
VideoChannel
    media_channel_ ---> WebRtcVideoChannel 对象,是媒体通道对象    
    rtp_transport_ --->  这个是指向了 JsepTransport 的 rtp_transport() , 具体的传输对象


     RtpTransportInternal* rtp_transport = GetRtpTransport(mid);

     video_channel->SetRtpTransport(rtp_transport);

  
    media_channel_ 创建是接口
    VideoMediaChannel* WebRtcVideoEngine::CreateMediaChannel
        new WebRtcVideoChannel

./media/engine/webrtc_video_engine.cc
WebRtcVideoChannel    
    send_streams_ ---> WebRtcVideoSendStream 对象
    
./media/engine/webrtc_video_engine.cc
WebRtcVideoSendStream

    source_   --->   VideoTrack 对象
    stream_   --->   VideoSendStream 对象
    encoder_sink_ ---> VideoStreamEncoder 对象

   VideoSendStream (构造函数内)负责建立 encoder ---> pacer 的 pipeline 建立

    VideoSendStreamImpl::VideoSendStreamImpl(
        Clock* clock,
        SendStatisticsProxy* stats_proxy,
        rtc::TaskQueue* worker_queue,
        CallStats* call_stats,
        RtpTransportControllerSendInterface* transport,
        BitrateAllocatorInterface* bitrate_allocator,
        SendDelayStats* send_delay_stats,
        VideoStreamEncoderInterface* video_stream_encoder,
        RtcEventLog* event_log,
        const VideoSendStream::Config* config,
        int initial_encoder_max_bitrate,
        double initial_encoder_bitrate_priority,
        std::map<uint32_t, RtpState> suspended_ssrcs,
        std::map<uint32_t, RtpPayloadState> suspended_payload_states,
        VideoEncoderConfig::ContentType content_type,
        std::unique_ptr<FecController> fec_controller)
        // 这个地方调用 VideoStreamEncoder 的 SetSink , 就是关联 VideoStreamEncoder 与 VideoSendStreamImpl
        video_stream_encoder_->SetSink(this, rotation_applied);  


    stream_ 是 internal::VideoSendStream 对象
    
./video/video_send_stream.cc
internal::VideoSendStream : public webrtc::VideoSendStream
    video_stream_encoder_ --->  VideoStreamEncoder ( ./video/video_stream_encoder.cc )
    send_stream_ ---> VideoSendStreamImpl ( ./video/video_send_stream_impl.cc )
    
    VideoSendStream 派生于 webrtc::VideoSendStream ,同时包含 VideoSendStreamImpl 具体的发送流对象

    VideoSendStreamImpl 就是发送逻辑的实现,不是发送数据出去

    
./call/video_send_stream.cc
webrtc::VideoSendStream

 

./video/video_send_stream_impl.h

VideoSendStreamImpl

    transport_ ---> RtpTransportControllerSend 对象

    bitrate_allocator_ --->

    rtp_video_sender_ --->  RtpVideoSender 对象

    video_stream_encoder_ ---> VideoStreamEncoder

pacer 队列就是 RtpTransportControllerSend 的成员 task_queue_pacer_

各类之间的关系详见下图。

 WebRTC 发送对象的包含和依赖关系主要是 RtpTransceiver

上一篇:WebRTC相关


下一篇:这么多流媒体服务器?你怎么技术选型?