一分鐘快速搭建 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_
各類之間的關係詳見下圖。