一分钟快速搭建 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_
各类之间的关系详见下图。