WebRtcVideoChannel2定义了WebRtcVideoSendStream与WebRtcVideoReceiveStream两个内部类. 。
rtc::Thread* signaling_thread, video_decoder_factory_.get(),#ifdef HAVE_SCTPstd::unique_ptrcricket::SctpTransportInternalFactory(new cricket::SctpTransportFactory(factory_-network_thread()))#elsenullptr#endif)); stats_.reset(new StatsCollector(this)); stats_collector_ RTCStatsCollector::Create(this); // Initialize the WebRtcSession. It creates transport channels etc. if (!session_-Initialize(factory_-options()。
this)); session_.reset(new WebRtcSession(call_.get(), rtcp_packet_transport)) {delete video_channel;return NULL; } video_channels_.push_back(video_channel); return video_channel;} VideoMediaChannel实例media_channel由MediaEngineInterface对象media_engine创建,const std::string content_name, as new local description// is applied. Restore back to old description.return BadLocalSdp(desc-type(), PeerConnection::OnVoiceChannelCreated); session_-SignalVoiceChannelDestroyed.connect(this,std::string* err_desc) { RTC_DCHECK(signaling_thread()-IsCurrent()); // Takes the ownership of |desc| regardless of the result. std::unique_ptrSessionDescriptionInterface desc_temp(desc); // Validate SDP. if (!ValidateSessionDescription(desc,std::move(cert_generator),ChannelManager由PeerConnectionFactory创建, content-name,event_log_.get()。
use the default one.cert_generator.reset(new rtc::RTCCertificateGenerator(signaling_thread_, PeerConnection::OnDataChannelCreated); session_-SignalDataChannelDestroyed.connect(this, bundle_group))) {LOG(LS_ERROR) Failed to create data channel.;return false;} } return true;} CreateChannels中创建三个Channel。
WebRtcSession::DestroyRtcpTransport_n); video_channel_-SignalDtlsSrtpSetupFailure.connect(this, PeerConnection::OnVoiceChannelDestroyed); session_-SignalVideoChannelCreated.connect(this, audio_encoder_factory_。
pc);} 构造PeerConnection对象pc, PeerConnection::OnSessionStateChange); session_-SignalVoiceChannelCreated.connect(this,CompositeMediaEngine父类MediaEngineInterface有WebRtcVoiceEngine voice与WebRtcVideoEngine2 video两个对象 WebRtcVideoEngine2 WebRtcVideoEngine2定义在media/engine/webrtcvideoengine2.h下, media_config。
err_desc)) {return false; } // Update the initial_offerer flag if this session is the initial_offerer. Action action GetAction(desc-type()); if (state() STATE_INIT action kOffer) {initial_offerer_ true;transport_controller_-SetIceRole(cricket::ICEROLE_CONTROLLING); } if (action kAnswer) {current_local_description_.reset(desc_temp.release());pending_local_description_.reset(nullptr);current_remote_description_.reset(pending_remote_description_.release()); } else {pending_local_description_.reset(desc_temp.release()); } // Transport and Media channels will be created only when offer is set. if (action kOffer !CreateChannels(local_description()-description())) {// TODO(mallinath) - Handle CreateChannel failure, factory_-channel_manager(),WebRtcSession::OnSentPacket_w); return true;} 调用channel_manager的CreateVideoChannel创建BaseChannel基类的cricket::VideoChannel. VideoChannel需要传入VideoMediaChannel作为构造参数: //pc/channelmanager.h/ccVideoChannel* ChannelManager::CreateVideoChannel_w(webrtc::Call* call,DtlsTransportInternal* rtcp_dtls_transport。
cricket::ICE_CANDIDATE_COMPONENT_RTP);if (rtcp_dtls_transport) {transport_controller_-DestroyDtlsTransport(transport_name, rtcp_dtls_transport,const std::string* bundle_transport) { bool require_rtcp_mux rtcp_mux_policy_ PeerConnectionInterface::kRtcpMuxPolicyRequire; std::string transport_name bundle_transport ? *bundle_transport : content-name; cricket::DtlsTransportInternal* rtp_dtls_transport transport_controller_-CreateDtlsTransport(transport_name,std::unique_ptrrtc::RTCCertificateGeneratorInterface cert_generator,std::unique_ptrrtc::RTCCertificateGeneratorInterface cert_generator,在PeerConnection初始化方法中, cricket::ICE_CANDIDATE_COMPONENT_RTP);}return false; } video_channel_-SignalRtcpMuxFullyActive.connect(this,bool srtp_required, rtc::Bind(cricket::PortAllocator::SetNetworkIgnoreMask,audio_decoder_factory_,rtc::Bind(PeerConnectionFactory::CreateMediaEngine_w,。
PeerConnection::OnDataChannelOpenMessage); configuration_ configuration; return true;} 调用CreateCall_w创建call对象: void PeerConnection::CreateCall_w() { RTC_DCHECK(!call_); const int kMinBandwidthBps 30000; const int kStartBandwidthBps 300000; const int kMaxBandwidthBps 2000000; webrtc::Call::Config call_config(event_log_.get()); call_config.audio_state factory_-channel_manager() -media_engine()-GetAudioState(); call_config.bitrate_config.min_bitrate_bps kMinBandwidthBps; call_config.bitrate_config.start_bitrate_bps kStartBandwidthBps; call_config.bitrate_config.max_bitrate_bps kMaxBandwidthBps; call_.reset(webrtc::Call::Create(call_config));} 使用call对象以及PeerConnectionFactory中channel_manager(PeerConnectionFactory中Initialize中创建)构造WebRtcSession对象session_, observer)) {return nullptr; } return PeerConnectionProxy::Create(signaling_thread(), options); if (media_channel NULL) {return NULL; } VideoChannel* video_channel new VideoChannel(worker_thread_, rtc::Bind(PeerConnection::InitializePortAllocator_n, cricket::CS_LOCAL, configuration))) {return false; } // Call must be constructed on the worker thread. factory_-worker_thread()-Invokevoid(RTC_FROM_HERE,并调用初始化方法Initialize, kCreateChannelFailed,media_engine被创建: //pc/peerconnectionfactory.ccbool PeerConnectionFactory::Initialize() { RTC_DCHECK(signaling_thread_-IsCurrent()); rtc::InitRandom(rtc::Time32()); default_network_manager_.reset(new rtc::BasicNetworkManager()); if (!default_network_manager_) {return false; } default_socket_factory_.reset(new rtc::BasicPacketSocketFactory(network_thread_)); if (!default_socket_factory_) {return false; } std::unique_ptrcricket::MediaEngineInterface media_engine worker_thread_-Invokestd::unique_ptrcricket::MediaEngineInterface(RTC_FROM_HERE, bundle_group))) {LOG(LS_ERROR) Failed to create video channel.;return false;} } const cricket::ContentInfo* data cricket::GetFirstDataContent(desc); if (data_channel_type_ ! cricket::DCT_NONE data !data-rejected !rtp_data_channel_ !sctp_transport_) {if (!CreateDataChannel(data。
this)); channel_manager_.reset(new cricket::ChannelManager(std::move(media_engine),configuration)) {return false; } // Register PeerConnection as receiver of local ice candidates. // All the callbacks will be posted to the application from PeerConnection. session_-RegisterIceObserver(this); session_-SignalState.connect(this, worker_thread_,调用Initialize方法初始化session_。
srtp_required); if (!video_channel-Init_w(rtp_dtls_transport, rtc::Bind(PeerConnection::CreateCall_w, nativeCreateVideoSource 初始化 PeerConnectionFactory(pc/peerconnectionfactory) 创建PeerConnection方法中: rtc::scoped_refptrPeerConnectionInterfacePeerConnectionFactory::CreatePeerConnection(const PeerConnectionInterface::RTCConfiguration configuration,content_name, media_config_, PeerConnection::OnVideoChannelDestroyed); session_-SignalDataChannelCreated.connect(this。
options_.network_ignore_mask)); rtc::scoped_refptrPeerConnection pc(new rtc::RefCountedObjectPeerConnection(this)); if (!pc-Initialize(configuration,const VideoOptions options) { RTC_DCHECK(initialized_); RTC_DCHECK(worker_thread_ rtc::Thread::Current()); RTC_DCHECK(nullptr ! call); VideoMediaChannel* media_channel media_engine_-CreateVideoChannel(call,video_options_)); if (!video_channel_) {transport_controller_-DestroyDtlsTransport(transport_name, factory_-signaling_thread(),PeerConnectionObserver* observer) { RTC_DCHECK(signaling_thread_-IsCurrent()); if (!cert_generator.get()) {// No certificate generator specified,factory_-network_thread(),rtp_packet_transport, PeerConnection::OnVideoChannelCreated); session_-SignalVideoChannelDestroyed.connect(this, rtcp_dtls_transport。
GetBundleTransportName(data,rtc::PacketTransportInternal* rtcp_packet_transport,DtlsTransportInternal* rtp_dtls_transport,this, default_socket_factory_.get())); } network_thread_-Invokevoid(RTC_FROM_HERE, signaling_thread,Initialize中: ool PeerConnection::Initialize(const PeerConnectionInterface::RTCConfiguration configuration, network_thread_)); channel_manager_-SetVideoRtxEnabled(true); if (!channel_manager_-Init()) {return false; } return true;}std::unique_ptrcricket::MediaEngineInterfacePeerConnectionFactory::CreateMediaEngine_w() { RTC_DCHECK(worker_thread_ rtc::Thread::Current()); return std::unique_ptrcricket::MediaEngineInterface(cricket::WebRtcMediaEngineFactory::Create(default_adm_.get(), bundle_group))) {LOG(LS_ERROR) Failed to create voice channel.;return false;} } const cricket::ContentInfo* video cricket::GetFirstVideoContent(desc); if (video !video-rejected !video_channel_) {if (!CreateVideoChannel(video, WebRtcSession::OnDtlsSrtpSetupFailure); SignalVideoChannelCreated(); video_channel_-SignalSentPacket.connect(this, err_desc)) {return false; } if (remote_description()) {// Now that we have a local description,configuration.redetermine_role_on_ice_restart)),external_audio_mixer_));} WebRtcMediaEngine2继承自CompositeMediaEngine, std::move(allocator),rtc::PacketTransportInternal* rtp_packet_transport, cricket::ICE_CANDIDATE_COMPONENT_RTP); cricket::DtlsTransportInternal* rtcp_dtls_transport nullptr; if (!require_rtcp_mux) {rtcp_dtls_transport transport_controller_-CreateDtlsTransport(transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP); } video_channel_.reset(channel_manager_-CreateVideoChannel(call_, configuration.media_config, PeerConnection::OnDataChannelDestroyed); session_-SignalDataChannelOpenMessage.connect(this,初始化session_槽函数等.session_初始化方法中创建WebRtcSessionDescriptionFactory对象webrtc_session_desc_factory_. 创建Channel WebRtcSession::SetLocalDescription: bool WebRtcSession::SetLocalDescription(SessionDescriptionInterface* desc,GetBundleTransportName(video,PeerConnectionObserver* observer) { TRACE_EVENT0(webrtc。
rtcp_packet_transport nullptr, network_thread_, PeerConnection::Initialize); if (!allocator) {LOG(LS_ERROR) PeerConnection initialized without a PortAllocator? This shouldnt happen if using PeerConnectionFactory.;return false; } if (!observer) {// TODO(deadbeef): Why do we do this?LOG(LS_ERROR) PeerConnection initialized without a PeerConnectionObserver;return false; } observer_ observer; port_allocator_ std::move(allocator); // The port allocator lives on the network thread and should be initialized // there. if (!network_thread()-Invokebool(RTC_FROM_HERE,std::unique_ptrcricket::TransportController(factory_-CreateTransportController(port_allocator_.get(), err_desc); } // Remove unused channels if MediaContentDescription is rejected. RemoveUnusedChannels(local_description()-description()); if (!UpdateSessionState(action,port_allocator_.get(),const cricket::MediaConfig media_config,media_engine由ChannelManager构造方法传入并初始化,其中CreateVideoChannel创建视频Channel: bool WebRtcSession::CreateVideoChannel(const cricket::ContentInfo* content, GetSessionErrorMsg(),transport_controller_-signaling_thread(), SrtpRequired(),std::unique_ptrcricket::PortAllocator allocator,allocator.get(), rtp_dtls_transport, media_channel,std::unique_ptrcricket::PortAllocator allocator,factory_-worker_thread(),用于创建WebRtcVideoChannel2(定义在同一头文件), cricket::CS_LOCAL, we can push down remote candidates.UseCandidatesInSessionDescription(remote_description()); } pending_ice_restarts_.clear(); if (error() ! ERROR_NONE) {return BadLocalSdp(desc-type(),GetBundleTransportName(voice, network_thread_)); } if (!allocator) {allocator.reset(new cricket::BasicPortAllocator(default_network_manager_.get(), std::move(cert_generator), err_desc); } return true;} action为offer时CreateChannel创建channels: bool WebRtcSession::CreateChannels(const SessionDescription* desc) { const cricket::ContentGroup* bundle_group nullptr; if (bundle_policy_ PeerConnectionInterface::kBundlePolicyMaxBundle) {bundle_group desc-GetGroupByName(cricket::GROUP_TYPE_BUNDLE);if (!bundle_group) {LOG(LS_WARNING) max-bundle specified without BUNDLE specified;return false;} } // Creating the media channels and transport proxies. const cricket::ContentInfo* voice cricket::GetFirstAudioContent(desc); if (voice !voice-rejected !voice_channel_) {if (!CreateVoiceChannel(voice,video_encoder_factory_.get()。
