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

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

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

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_

各類之間的關係詳見下圖。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章