diff options
Diffstat (limited to 'audio/channel_send.cc')
-rw-r--r-- | audio/channel_send.cc | 190 |
1 files changed, 76 insertions, 114 deletions
diff --git a/audio/channel_send.cc b/audio/channel_send.cc index 3387f271ba..80e7ab2f47 100644 --- a/audio/channel_send.cc +++ b/audio/channel_send.cc @@ -29,6 +29,7 @@ #include "modules/audio_coding/include/audio_coding_module.h" #include "modules/audio_processing/rms_level.h" #include "modules/pacing/packet_router.h" +#include "modules/rtp_rtcp/source/rtp_rtcp_impl2.h" #include "modules/utility/include/process_thread.h" #include "rtc_base/checks.h" #include "rtc_base/event.h" @@ -38,6 +39,7 @@ #include "rtc_base/numerics/safe_conversions.h" #include "rtc_base/race_checker.h" #include "rtc_base/rate_limiter.h" +#include "rtc_base/synchronization/mutex.h" #include "rtc_base/task_queue.h" #include "rtc_base/thread_checker.h" #include "rtc_base/time_utils.h" @@ -54,7 +56,6 @@ constexpr int64_t kMaxRetransmissionWindowMs = 1000; constexpr int64_t kMinRetransmissionWindowMs = 30; class RtpPacketSenderProxy; -class TransportFeedbackProxy; class TransportSequenceNumberProxy; class VoERtcpObserver; @@ -77,7 +78,8 @@ class ChannelSend : public ChannelSendInterface, bool extmap_allow_mixed, int rtcp_report_interval_ms, uint32_t ssrc, - rtc::scoped_refptr<FrameTransformerInterface> frame_transformer); + rtc::scoped_refptr<FrameTransformerInterface> frame_transformer, + TransportFeedbackObserver* feedback_observer); ~ChannelSend() override; @@ -106,7 +108,7 @@ class ChannelSend : public ChannelSendInterface, ANAStats GetANAStatistics() const override; // Used by AudioSendStream. - RtpRtcp* GetRtpRtcp() const override; + RtpRtcpInterface* GetRtpRtcp() const override; void RegisterCngPayloadType(int payload_type, int payload_frequency) override; @@ -185,13 +187,13 @@ class ChannelSend : public ChannelSendInterface, // audio thread to another, but access is still sequential. rtc::RaceChecker audio_thread_race_checker_; - rtc::CriticalSection volume_settings_critsect_; + mutable Mutex volume_settings_mutex_; bool sending_ RTC_GUARDED_BY(&worker_thread_checker_) = false; RtcEventLog* const event_log_; - std::unique_ptr<RtpRtcp> _rtpRtcpModule; + std::unique_ptr<ModuleRtpRtcpImpl2> rtp_rtcp_; std::unique_ptr<RTPSenderAudio> rtp_sender_audio_; std::unique_ptr<AudioCodingModule> audio_coding_; @@ -200,7 +202,7 @@ class ChannelSend : public ChannelSendInterface, // uses ProcessThread* const _moduleProcessThreadPtr; RmsLevel rms_level_ RTC_GUARDED_BY(encoder_queue_); - bool input_mute_ RTC_GUARDED_BY(volume_settings_critsect_); + bool input_mute_ RTC_GUARDED_BY(volume_settings_mutex_); bool previous_frame_muted_ RTC_GUARDED_BY(encoder_queue_); // VoeRTP_RTCP // TODO(henrika): can today be accessed on the main thread and on the @@ -212,7 +214,7 @@ class ChannelSend : public ChannelSendInterface, PacketRouter* packet_router_ RTC_GUARDED_BY(&worker_thread_checker_) = nullptr; - const std::unique_ptr<TransportFeedbackProxy> feedback_observer_proxy_; + TransportFeedbackObserver* const feedback_observer_; const std::unique_ptr<RtpPacketSenderProxy> rtp_packet_pacer_proxy_; const std::unique_ptr<RateLimiter> retransmission_rate_limiter_; @@ -233,8 +235,8 @@ class ChannelSend : public ChannelSendInterface, rtc::scoped_refptr<ChannelSendFrameTransformerDelegate> frame_transformer_delegate_ RTC_GUARDED_BY(encoder_queue_); - rtc::CriticalSection bitrate_crit_section_; - int configured_bitrate_bps_ RTC_GUARDED_BY(bitrate_crit_section_) = 0; + mutable Mutex bitrate_mutex_; + int configured_bitrate_bps_ RTC_GUARDED_BY(bitrate_mutex_) = 0; // Defined last to ensure that there are no running tasks when the other // members are destroyed. @@ -243,63 +245,26 @@ class ChannelSend : public ChannelSendInterface, const int kTelephoneEventAttenuationdB = 10; -class TransportFeedbackProxy : public TransportFeedbackObserver { - public: - TransportFeedbackProxy() : feedback_observer_(nullptr) { - pacer_thread_.Detach(); - network_thread_.Detach(); - } - - void SetTransportFeedbackObserver( - TransportFeedbackObserver* feedback_observer) { - RTC_DCHECK(thread_checker_.IsCurrent()); - rtc::CritScope lock(&crit_); - feedback_observer_ = feedback_observer; - } - - // Implements TransportFeedbackObserver. - void OnAddPacket(const RtpPacketSendInfo& packet_info) override { - RTC_DCHECK(pacer_thread_.IsCurrent()); - rtc::CritScope lock(&crit_); - if (feedback_observer_) - feedback_observer_->OnAddPacket(packet_info); - } - - void OnTransportFeedback(const rtcp::TransportFeedback& feedback) override { - RTC_DCHECK(network_thread_.IsCurrent()); - rtc::CritScope lock(&crit_); - if (feedback_observer_) - feedback_observer_->OnTransportFeedback(feedback); - } - - private: - rtc::CriticalSection crit_; - rtc::ThreadChecker thread_checker_; - rtc::ThreadChecker pacer_thread_; - rtc::ThreadChecker network_thread_; - TransportFeedbackObserver* feedback_observer_ RTC_GUARDED_BY(&crit_); -}; - class RtpPacketSenderProxy : public RtpPacketSender { public: RtpPacketSenderProxy() : rtp_packet_pacer_(nullptr) {} void SetPacketPacer(RtpPacketSender* rtp_packet_pacer) { RTC_DCHECK(thread_checker_.IsCurrent()); - rtc::CritScope lock(&crit_); + MutexLock lock(&mutex_); rtp_packet_pacer_ = rtp_packet_pacer; } void EnqueuePackets( std::vector<std::unique_ptr<RtpPacketToSend>> packets) override { - rtc::CritScope lock(&crit_); + MutexLock lock(&mutex_); rtp_packet_pacer_->EnqueuePackets(std::move(packets)); } private: rtc::ThreadChecker thread_checker_; - rtc::CriticalSection crit_; - RtpPacketSender* rtp_packet_pacer_ RTC_GUARDED_BY(&crit_); + Mutex mutex_; + RtpPacketSender* rtp_packet_pacer_ RTC_GUARDED_BY(&mutex_); }; class VoERtcpObserver : public RtcpBandwidthObserver { @@ -309,12 +274,12 @@ class VoERtcpObserver : public RtcpBandwidthObserver { ~VoERtcpObserver() override {} void SetBandwidthObserver(RtcpBandwidthObserver* bandwidth_observer) { - rtc::CritScope lock(&crit_); + MutexLock lock(&mutex_); bandwidth_observer_ = bandwidth_observer; } void OnReceivedEstimatedBitrate(uint32_t bitrate) override { - rtc::CritScope lock(&crit_); + MutexLock lock(&mutex_); if (bandwidth_observer_) { bandwidth_observer_->OnReceivedEstimatedBitrate(bitrate); } @@ -324,7 +289,7 @@ class VoERtcpObserver : public RtcpBandwidthObserver { int64_t rtt, int64_t now_ms) override { { - rtc::CritScope lock(&crit_); + MutexLock lock(&mutex_); if (bandwidth_observer_) { bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, rtt, now_ms); @@ -372,8 +337,8 @@ class VoERtcpObserver : public RtcpBandwidthObserver { ChannelSend* owner_; // Maps remote side ssrc to extended highest sequence number received. std::map<uint32_t, uint32_t> extended_max_sequence_number_; - rtc::CriticalSection crit_; - RtcpBandwidthObserver* bandwidth_observer_ RTC_GUARDED_BY(crit_); + Mutex mutex_; + RtcpBandwidthObserver* bandwidth_observer_ RTC_GUARDED_BY(mutex_); }; int32_t ChannelSend::SendData(AudioFrameType frameType, @@ -388,9 +353,9 @@ int32_t ChannelSend::SendData(AudioFrameType frameType, // Asynchronously transform the payload before sending it. After the payload // is transformed, the delegate will call SendRtpAudio to send it. frame_transformer_delegate_->Transform( - frameType, payloadType, rtp_timestamp, _rtpRtcpModule->StartTimestamp(), + frameType, payloadType, rtp_timestamp, rtp_rtcp_->StartTimestamp(), payloadData, payloadSize, absolute_capture_timestamp_ms, - _rtpRtcpModule->SSRC()); + rtp_rtcp_->SSRC()); return 0; } return SendRtpAudio(frameType, payloadType, rtp_timestamp, payload, @@ -427,7 +392,7 @@ int32_t ChannelSend::SendRtpAudio(AudioFrameType frameType, // Encrypt the audio payload into the buffer. size_t bytes_written = 0; int encrypt_status = frame_encryptor_->Encrypt( - cricket::MEDIA_TYPE_AUDIO, _rtpRtcpModule->SSRC(), + cricket::MEDIA_TYPE_AUDIO, rtp_rtcp_->SSRC(), /*additional_data=*/nullptr, payload, encrypted_audio_payload, &bytes_written); if (encrypt_status != 0) { @@ -449,12 +414,12 @@ int32_t ChannelSend::SendRtpAudio(AudioFrameType frameType, // Push data from ACM to RTP/RTCP-module to deliver audio frame for // packetization. - if (!_rtpRtcpModule->OnSendingRtpFrame(rtp_timestamp, - // Leaving the time when this frame was - // received from the capture device as - // undefined for voice for now. - -1, payloadType, - /*force_sender_report=*/false)) { + if (!rtp_rtcp_->OnSendingRtpFrame(rtp_timestamp, + // Leaving the time when this frame was + // received from the capture device as + // undefined for voice for now. + -1, payloadType, + /*force_sender_report=*/false)) { return -1; } @@ -466,9 +431,8 @@ int32_t ChannelSend::SendRtpAudio(AudioFrameType frameType, // This call will trigger Transport::SendPacket() from the RTP/RTCP module. if (!rtp_sender_audio_->SendAudio( - frameType, payloadType, - rtp_timestamp + _rtpRtcpModule->StartTimestamp(), payload.data(), - payload.size(), absolute_capture_timestamp_ms)) { + frameType, payloadType, rtp_timestamp + rtp_rtcp_->StartTimestamp(), + payload.data(), payload.size(), absolute_capture_timestamp_ms)) { RTC_DLOG(LS_ERROR) << "ChannelSend::SendData() failed to send data to RTP/RTCP module"; return -1; @@ -489,7 +453,8 @@ ChannelSend::ChannelSend( bool extmap_allow_mixed, int rtcp_report_interval_ms, uint32_t ssrc, - rtc::scoped_refptr<FrameTransformerInterface> frame_transformer) + rtc::scoped_refptr<FrameTransformerInterface> frame_transformer, + TransportFeedbackObserver* feedback_observer) : event_log_(rtc_event_log), _timeStamp(0), // This is just an offset, RTP module will add it's own // random offset @@ -498,7 +463,7 @@ ChannelSend::ChannelSend( previous_frame_muted_(false), _includeAudioLevelIndication(false), rtcp_observer_(new VoERtcpObserver(this)), - feedback_observer_proxy_(new TransportFeedbackProxy()), + feedback_observer_(feedback_observer), rtp_packet_pacer_proxy_(new RtpPacketSenderProxy()), retransmission_rate_limiter_( new RateLimiter(clock, kMaxRetransmissionWindowMs)), @@ -512,9 +477,9 @@ ChannelSend::ChannelSend( audio_coding_.reset(AudioCodingModule::Create(AudioCodingModule::Config())); - RtpRtcp::Configuration configuration; + RtpRtcpInterface::Configuration configuration; configuration.bandwidth_callback = rtcp_observer_.get(); - configuration.transport_feedback_callback = feedback_observer_proxy_.get(); + configuration.transport_feedback_callback = feedback_observer_; configuration.clock = (clock ? clock : Clock::GetRealTimeClock()); configuration.audio = true; configuration.outgoing_transport = rtp_transport; @@ -530,16 +495,16 @@ ChannelSend::ChannelSend( configuration.local_media_ssrc = ssrc; - _rtpRtcpModule = RtpRtcp::Create(configuration); - _rtpRtcpModule->SetSendingMediaStatus(false); + rtp_rtcp_ = ModuleRtpRtcpImpl2::Create(configuration); + rtp_rtcp_->SetSendingMediaStatus(false); - rtp_sender_audio_ = std::make_unique<RTPSenderAudio>( - configuration.clock, _rtpRtcpModule->RtpSender()); + rtp_sender_audio_ = std::make_unique<RTPSenderAudio>(configuration.clock, + rtp_rtcp_->RtpSender()); - _moduleProcessThreadPtr->RegisterModule(_rtpRtcpModule.get(), RTC_FROM_HERE); + _moduleProcessThreadPtr->RegisterModule(rtp_rtcp_.get(), RTC_FROM_HERE); // Ensure that RTCP is enabled by default for the created channel. - _rtpRtcpModule->SetRTCPStatus(RtcpMode::kCompound); + rtp_rtcp_->SetRTCPStatus(RtcpMode::kCompound); int error = audio_coding_->RegisterTransportCallback(this); RTC_DCHECK_EQ(0, error); @@ -559,7 +524,7 @@ ChannelSend::~ChannelSend() { RTC_DCHECK_EQ(0, error); if (_moduleProcessThreadPtr) - _moduleProcessThreadPtr->DeRegisterModule(_rtpRtcpModule.get()); + _moduleProcessThreadPtr->DeRegisterModule(rtp_rtcp_.get()); } void ChannelSend::StartSend() { @@ -567,8 +532,8 @@ void ChannelSend::StartSend() { RTC_DCHECK(!sending_); sending_ = true; - _rtpRtcpModule->SetSendingMediaStatus(true); - int ret = _rtpRtcpModule->SetSendingStatus(true); + rtp_rtcp_->SetSendingMediaStatus(true); + int ret = rtp_rtcp_->SetSendingStatus(true); RTC_DCHECK_EQ(0, ret); // It is now OK to start processing on the encoder task queue. encoder_queue_.PostTask([this] { @@ -594,10 +559,10 @@ void ChannelSend::StopSend() { // Reset sending SSRC and sequence number and triggers direct transmission // of RTCP BYE - if (_rtpRtcpModule->SetSendingStatus(false) == -1) { + if (rtp_rtcp_->SetSendingStatus(false) == -1) { RTC_DLOG(LS_ERROR) << "StartSend() RTP/RTCP failed to stop sending"; } - _rtpRtcpModule->SetSendingMediaStatus(false); + rtp_rtcp_->SetSendingMediaStatus(false); } void ChannelSend::SetEncoder(int payload_type, @@ -608,8 +573,8 @@ void ChannelSend::SetEncoder(int payload_type, // The RTP/RTCP module needs to know the RTP timestamp rate (i.e. clockrate) // as well as some other things, so we collect this info and send it along. - _rtpRtcpModule->RegisterSendPayloadFrequency(payload_type, - encoder->RtpTimestampRateHz()); + rtp_rtcp_->RegisterSendPayloadFrequency(payload_type, + encoder->RtpTimestampRateHz()); rtp_sender_audio_->RegisterAudioPayload("audio", payload_type, encoder->RtpTimestampRateHz(), encoder->NumChannels(), 0); @@ -642,7 +607,7 @@ void ChannelSend::OnBitrateAllocation(BitrateAllocationUpdate update) { // rules. // RTC_DCHECK(worker_thread_checker_.IsCurrent() || // module_process_thread_checker_.IsCurrent()); - rtc::CritScope lock(&bitrate_crit_section_); + MutexLock lock(&bitrate_mutex_); CallEncoder([&](AudioEncoder* encoder) { encoder->OnReceivedUplinkAllocation(update); @@ -652,7 +617,7 @@ void ChannelSend::OnBitrateAllocation(BitrateAllocationUpdate update) { } int ChannelSend::GetBitrate() const { - rtc::CritScope lock(&bitrate_crit_section_); + MutexLock lock(&bitrate_mutex_); return configured_bitrate_bps_; } @@ -663,8 +628,10 @@ void ChannelSend::OnUplinkPacketLossRate(float packet_loss_rate) { } void ChannelSend::ReceivedRTCPPacket(const uint8_t* data, size_t length) { + RTC_DCHECK_RUN_ON(&worker_thread_checker_); + // Deliver RTCP packet to RTP/RTCP module for parsing - _rtpRtcpModule->IncomingRtcpPacket(data, length); + rtp_rtcp_->IncomingRtcpPacket(data, length); int64_t rtt = GetRTT(); if (rtt == 0) { @@ -685,12 +652,12 @@ void ChannelSend::ReceivedRTCPPacket(const uint8_t* data, size_t length) { void ChannelSend::SetInputMute(bool enable) { RTC_DCHECK_RUN_ON(&worker_thread_checker_); - rtc::CritScope cs(&volume_settings_critsect_); + MutexLock lock(&volume_settings_mutex_); input_mute_ = enable; } bool ChannelSend::InputMute() const { - rtc::CritScope cs(&volume_settings_critsect_); + MutexLock lock(&volume_settings_mutex_); return input_mute_; } @@ -713,7 +680,7 @@ bool ChannelSend::SendTelephoneEventOutband(int event, int duration_ms) { void ChannelSend::RegisterCngPayloadType(int payload_type, int payload_frequency) { - _rtpRtcpModule->RegisterSendPayloadFrequency(payload_type, payload_frequency); + rtp_rtcp_->RegisterSendPayloadFrequency(payload_type, payload_frequency); rtp_sender_audio_->RegisterAudioPayload("CN", payload_type, payload_frequency, 1, 0); } @@ -723,7 +690,7 @@ void ChannelSend::SetSendTelephoneEventPayloadType(int payload_type, RTC_DCHECK_RUN_ON(&worker_thread_checker_); RTC_DCHECK_LE(0, payload_type); RTC_DCHECK_GE(127, payload_type); - _rtpRtcpModule->RegisterSendPayloadFrequency(payload_type, payload_frequency); + rtp_rtcp_->RegisterSendPayloadFrequency(payload_type, payload_frequency); rtp_sender_audio_->RegisterAudioPayload("telephone-event", payload_type, payload_frequency, 0, 0); } @@ -732,9 +699,9 @@ void ChannelSend::SetSendAudioLevelIndicationStatus(bool enable, int id) { RTC_DCHECK_RUN_ON(&worker_thread_checker_); _includeAudioLevelIndication = enable; if (enable) { - _rtpRtcpModule->RegisterRtpHeaderExtension(AudioLevel::kUri, id); + rtp_rtcp_->RegisterRtpHeaderExtension(AudioLevel::kUri, id); } else { - _rtpRtcpModule->DeregisterSendRtpHeaderExtension(AudioLevel::kUri); + rtp_rtcp_->DeregisterSendRtpHeaderExtension(AudioLevel::kUri); } } @@ -743,31 +710,25 @@ void ChannelSend::RegisterSenderCongestionControlObjects( RtcpBandwidthObserver* bandwidth_observer) { RTC_DCHECK_RUN_ON(&worker_thread_checker_); RtpPacketSender* rtp_packet_pacer = transport->packet_sender(); - TransportFeedbackObserver* transport_feedback_observer = - transport->transport_feedback_observer(); PacketRouter* packet_router = transport->packet_router(); RTC_DCHECK(rtp_packet_pacer); - RTC_DCHECK(transport_feedback_observer); RTC_DCHECK(packet_router); RTC_DCHECK(!packet_router_); rtcp_observer_->SetBandwidthObserver(bandwidth_observer); - feedback_observer_proxy_->SetTransportFeedbackObserver( - transport_feedback_observer); rtp_packet_pacer_proxy_->SetPacketPacer(rtp_packet_pacer); - _rtpRtcpModule->SetStorePacketsStatus(true, 600); + rtp_rtcp_->SetStorePacketsStatus(true, 600); constexpr bool remb_candidate = false; - packet_router->AddSendRtpModule(_rtpRtcpModule.get(), remb_candidate); + packet_router->AddSendRtpModule(rtp_rtcp_.get(), remb_candidate); packet_router_ = packet_router; } void ChannelSend::ResetSenderCongestionControlObjects() { RTC_DCHECK_RUN_ON(&worker_thread_checker_); RTC_DCHECK(packet_router_); - _rtpRtcpModule->SetStorePacketsStatus(false, 600); + rtp_rtcp_->SetStorePacketsStatus(false, 600); rtcp_observer_->SetBandwidthObserver(nullptr); - feedback_observer_proxy_->SetTransportFeedbackObserver(nullptr); - packet_router_->RemoveSendRtpModule(_rtpRtcpModule.get()); + packet_router_->RemoveSendRtpModule(rtp_rtcp_.get()); packet_router_ = nullptr; rtp_packet_pacer_proxy_->SetPacketPacer(nullptr); } @@ -776,7 +737,7 @@ void ChannelSend::SetRTCP_CNAME(absl::string_view c_name) { RTC_DCHECK_RUN_ON(&worker_thread_checker_); // Note: SetCNAME() accepts a c string of length at most 255. const std::string c_name_limited(c_name.substr(0, 255)); - int ret = _rtpRtcpModule->SetCNAME(c_name_limited.c_str()) != 0; + int ret = rtp_rtcp_->SetCNAME(c_name_limited.c_str()) != 0; RTC_DCHECK_EQ(0, ret) << "SetRTCP_CNAME() failed to set RTCP CNAME"; } @@ -787,7 +748,7 @@ std::vector<ReportBlock> ChannelSend::GetRemoteRTCPReportBlocks() const { // report block according to RFC 3550. std::vector<RTCPReportBlock> rtcp_report_blocks; - int ret = _rtpRtcpModule->RemoteRTCPStat(&rtcp_report_blocks); + int ret = rtp_rtcp_->RemoteRTCPStat(&rtcp_report_blocks); RTC_DCHECK_EQ(0, ret); std::vector<ReportBlock> report_blocks; @@ -816,7 +777,7 @@ CallSendStatistics ChannelSend::GetRTCPStatistics() const { StreamDataCounters rtp_stats; StreamDataCounters rtx_stats; - _rtpRtcpModule->GetSendStreamDataCounters(&rtp_stats, &rtx_stats); + rtp_rtcp_->GetSendStreamDataCounters(&rtp_stats, &rtx_stats); stats.payload_bytes_sent = rtp_stats.transmitted.payload_bytes + rtx_stats.transmitted.payload_bytes; stats.header_and_padding_bytes_sent = @@ -829,7 +790,7 @@ CallSendStatistics ChannelSend::GetRTCPStatistics() const { stats.packetsSent = rtp_stats.transmitted.packets + rtx_stats.transmitted.packets; stats.retransmitted_packets_sent = rtp_stats.retransmitted.packets; - stats.report_block_datas = _rtpRtcpModule->GetLatestReportBlockData(); + stats.report_block_datas = rtp_rtcp_->GetLatestReportBlockData(); return stats; } @@ -894,14 +855,14 @@ ANAStats ChannelSend::GetANAStatistics() const { return audio_coding_->GetANAStats(); } -RtpRtcp* ChannelSend::GetRtpRtcp() const { +RtpRtcpInterface* ChannelSend::GetRtpRtcp() const { RTC_DCHECK(module_process_thread_checker_.IsCurrent()); - return _rtpRtcpModule.get(); + return rtp_rtcp_.get(); } int64_t ChannelSend::GetRTT() const { std::vector<RTCPReportBlock> report_blocks; - _rtpRtcpModule->RemoteRTCPStat(&report_blocks); + rtp_rtcp_->RemoteRTCPStat(&report_blocks); if (report_blocks.empty()) { return 0; @@ -913,8 +874,8 @@ int64_t ChannelSend::GetRTT() const { int64_t min_rtt = 0; // We don't know in advance the remote ssrc used by the other end's receiver // reports, so use the SSRC of the first report block for calculating the RTT. - if (_rtpRtcpModule->RTT(report_blocks[0].sender_ssrc, &rtt, &avg_rtt, - &min_rtt, &max_rtt) != 0) { + if (rtp_rtcp_->RTT(report_blocks[0].sender_ssrc, &rtt, &avg_rtt, &min_rtt, + &max_rtt) != 0) { return 0; } return rtt; @@ -985,12 +946,13 @@ std::unique_ptr<ChannelSendInterface> CreateChannelSend( bool extmap_allow_mixed, int rtcp_report_interval_ms, uint32_t ssrc, - rtc::scoped_refptr<FrameTransformerInterface> frame_transformer) { + rtc::scoped_refptr<FrameTransformerInterface> frame_transformer, + TransportFeedbackObserver* feedback_observer) { return std::make_unique<ChannelSend>( clock, task_queue_factory, module_process_thread, rtp_transport, rtcp_rtt_stats, rtc_event_log, frame_encryptor, crypto_options, extmap_allow_mixed, rtcp_report_interval_ms, ssrc, - std::move(frame_transformer)); + std::move(frame_transformer), feedback_observer); } } // namespace voe |