diff --git a/src/channel/audio_channel_send.cpp b/src/channel/audio_channel_send.cpp index a7c66b1..4d4bdf3 100644 --- a/src/channel/audio_channel_send.cpp +++ b/src/channel/audio_channel_send.cpp @@ -12,8 +12,10 @@ AudioChannelSend::AudioChannelSend( : ice_agent_(ice_agent), ice_io_statistics_(ice_io_statistics) {} void AudioChannelSend::Initialize(rtp::PAYLOAD_TYPE payload_type) { - rtp_packetizer_ = RtpPacketizer::Create(payload_type); rtp_audio_sender_ = std::make_unique(ice_io_statistics_); + rtp_packetizer_ = + RtpPacketizer::Create(payload_type, rtp_audio_sender_->GetSsrc()); + rtp_audio_sender_->SetSendDataFunc( [this](const char *data, size_t size) -> int { if (!ice_agent_) { diff --git a/src/channel/data_channel_send.cpp b/src/channel/data_channel_send.cpp index c79cc6a..172c918 100644 --- a/src/channel/data_channel_send.cpp +++ b/src/channel/data_channel_send.cpp @@ -12,8 +12,10 @@ DataChannelSend::DataChannelSend( : ice_agent_(ice_agent), ice_io_statistics_(ice_io_statistics) {} void DataChannelSend::Initialize(rtp::PAYLOAD_TYPE payload_type) { - rtp_packetizer_ = RtpPacketizer::Create(payload_type); rtp_data_sender_ = std::make_unique(ice_io_statistics_); + rtp_packetizer_ = + RtpPacketizer::Create(payload_type, rtp_data_sender_->GetSsrc()); + rtp_data_sender_->SetSendDataFunc( [this](const char *data, size_t size) -> int { if (!ice_agent_) { diff --git a/src/channel/rtp_channel/rtp_audio_sender.cpp b/src/channel/rtp_channel/rtp_audio_sender.cpp index ff56fb5..9a1af5f 100644 --- a/src/channel/rtp_channel/rtp_audio_sender.cpp +++ b/src/channel/rtp_channel/rtp_audio_sender.cpp @@ -2,6 +2,7 @@ #include +#include "common.h" #include "log.h" #define RTCP_SR_INTERVAL 1000 @@ -9,7 +10,7 @@ RtpAudioSender::RtpAudioSender() { SetPeriod(std::chrono::milliseconds(5)); } RtpAudioSender::RtpAudioSender(std::shared_ptr io_statistics) - : io_statistics_(io_statistics) { + : ssrc_(GenerateUniqueSsrc()), io_statistics_(io_statistics) { SetPeriod(std::chrono::milliseconds(5)); } @@ -17,6 +18,8 @@ RtpAudioSender::~RtpAudioSender() { if (rtp_statistics_) { rtp_statistics_->Stop(); } + + SSRCManager::Instance().DeleteSsrc(ssrc_); } void RtpAudioSender::Enqueue(std::vector& rtp_packets) { diff --git a/src/channel/rtp_channel/rtp_audio_sender.h b/src/channel/rtp_channel/rtp_audio_sender.h index 7d624d6..9fbf1e5 100644 --- a/src/channel/rtp_channel/rtp_audio_sender.h +++ b/src/channel/rtp_channel/rtp_audio_sender.h @@ -25,8 +25,8 @@ class RtpAudioSender : public ThreadBase { public: void Enqueue(std::vector &rtp_packets); void SetSendDataFunc(std::function data_send_func); + uint32_t GetSsrc() { return ssrc_; } - private: private: int SendRtpPacket(RtpPacket &rtp_packet); int SendRtcpSR(RtcpSenderReport &rtcp_sr); @@ -39,6 +39,9 @@ class RtpAudioSender : public ThreadBase { private: std::function data_send_func_ = nullptr; RingBuffer rtp_packe_queue_; + + private: + uint32_t ssrc_ = 0; std::unique_ptr rtp_statistics_ = nullptr; std::shared_ptr io_statistics_ = nullptr; uint32_t last_send_bytes_ = 0; diff --git a/src/channel/rtp_channel/rtp_data_sender.cpp b/src/channel/rtp_channel/rtp_data_sender.cpp index fe0897a..5eac720 100644 --- a/src/channel/rtp_channel/rtp_data_sender.cpp +++ b/src/channel/rtp_channel/rtp_data_sender.cpp @@ -2,6 +2,7 @@ #include +#include "common.h" #include "log.h" #define RTCP_SR_INTERVAL 1000 @@ -9,7 +10,7 @@ RtpDataSender::RtpDataSender() {} RtpDataSender::RtpDataSender(std::shared_ptr io_statistics) - : io_statistics_(io_statistics) { + : ssrc_(GenerateUniqueSsrc()), io_statistics_(io_statistics) { SetPeriod(std::chrono::milliseconds(5)); } @@ -17,6 +18,8 @@ RtpDataSender::~RtpDataSender() { if (rtp_statistics_) { rtp_statistics_->Stop(); } + + SSRCManager::Instance().DeleteSsrc(ssrc_); } void RtpDataSender::Enqueue(std::vector& rtp_packets) { diff --git a/src/channel/rtp_channel/rtp_data_sender.h b/src/channel/rtp_channel/rtp_data_sender.h index e41f81d..0f68849 100644 --- a/src/channel/rtp_channel/rtp_data_sender.h +++ b/src/channel/rtp_channel/rtp_data_sender.h @@ -25,6 +25,7 @@ class RtpDataSender : public ThreadBase { public: void Enqueue(std::vector &rtp_packets); void SetSendDataFunc(std::function data_send_func); + uint32_t GetSsrc() { return ssrc_; } private: private: @@ -41,6 +42,7 @@ class RtpDataSender : public ThreadBase { RingBuffer rtp_packe_queue_; private: + uint32_t ssrc_ = 0; std::unique_ptr rtp_statistics_ = nullptr; std::shared_ptr io_statistics_ = nullptr; uint32_t last_send_bytes_ = 0; diff --git a/src/channel/rtp_channel/rtp_video_receiver.cpp b/src/channel/rtp_channel/rtp_video_receiver.cpp index 2762966..7498e45 100644 --- a/src/channel/rtp_channel/rtp_video_receiver.cpp +++ b/src/channel/rtp_channel/rtp_video_receiver.cpp @@ -9,34 +9,35 @@ #define NV12_BUFFER_SIZE (1280 * 720 * 3 / 2) #define RTCP_RR_INTERVAL 1000 -RtpVideoReceiver::RtpVideoReceiver() +RtpVideoReceiver::RtpVideoReceiver(std::shared_ptr clock) : feedback_ssrc_(GenerateUniqueSsrc()), active_remb_module_(nullptr), receive_side_congestion_controller_( - clock_, + clock, [this](std::vector> packets) { SendCombinedRtcpPacket(std::move(packets)); }, [this](int64_t bitrate_bps, std::vector ssrcs) { SendRemb(bitrate_bps, ssrcs); }), - clock_(Clock::GetRealTimeClockShared()) { + clock_(clock) { SetPeriod(std::chrono::milliseconds(5)); // rtcp_thread_ = std::thread(&RtpVideoReceiver::RtcpThread, this); } -RtpVideoReceiver::RtpVideoReceiver(std::shared_ptr io_statistics) +RtpVideoReceiver::RtpVideoReceiver(std::shared_ptr clock, + std::shared_ptr io_statistics) : io_statistics_(io_statistics), feedback_ssrc_(GenerateUniqueSsrc()), receive_side_congestion_controller_( - clock_, + clock, [this](std::vector> packets) { SendCombinedRtcpPacket(std::move(packets)); }, [this](int64_t bitrate_bps, std::vector ssrcs) { SendRemb(bitrate_bps, ssrcs); }), - clock_(Clock::GetRealTimeClockShared()) { + clock_(clock) { SetPeriod(std::chrono::milliseconds(5)); // rtcp_thread_ = std::thread(&RtpVideoReceiver::RtcpThread, this); @@ -404,6 +405,21 @@ int RtpVideoReceiver::SendRtcpRR(RtcpReceiverReport& rtcp_rr) { return 0; } +TimeDelta AtoToTimeDelta(uint16_t receive_info) { + // receive_info + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |R|ECN| Arrival time offset | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + const uint16_t ato = receive_info & 0x1FFF; + if (ato == 0x1FFE) { + return TimeDelta::PlusInfinity(); + } + if (ato == 0x1FFF) { + return TimeDelta::MinusInfinity(); + } + return TimeDelta::Seconds(ato) / 1024; +} + void RtpVideoReceiver::SendCombinedRtcpPacket( std::vector> rtcp_packets) { if (!data_send_func_) { @@ -414,9 +430,18 @@ void RtpVideoReceiver::SendCombinedRtcpPacket( RTCPSender rtcp_sender( [this](const uint8_t* buffer, size_t size) -> int { + webrtc::rtcp::CommonHeader rtcp_block; + // bool valid = true; + // if (!rtcp_block.Parse(buffer, size)) { + // valid = false; + // } + + webrtc::rtcp::CongestionControlFeedback feedback; + feedback.Parse(rtcp_block); + return data_send_func_((const char*)buffer, size); }, - IP_PACKET_SIZE); + 1200); for (auto& rtcp_packet : rtcp_packets) { rtcp_packet->SetSenderSsrc(feedback_ssrc_); diff --git a/src/channel/rtp_channel/rtp_video_receiver.h b/src/channel/rtp_channel/rtp_video_receiver.h index 33df3c3..b708516 100644 --- a/src/channel/rtp_channel/rtp_video_receiver.h +++ b/src/channel/rtp_channel/rtp_video_receiver.h @@ -23,8 +23,9 @@ using namespace webrtc; class RtpVideoReceiver : public ThreadBase { public: - RtpVideoReceiver(); - RtpVideoReceiver(std::shared_ptr io_statistics); + RtpVideoReceiver(std::shared_ptr clock); + RtpVideoReceiver(std::shared_ptr clock, + std::shared_ptr io_statistics); virtual ~RtpVideoReceiver(); public: diff --git a/src/channel/rtp_channel/rtp_video_sender.cpp b/src/channel/rtp_channel/rtp_video_sender.cpp index d1f3164..74fa821 100644 --- a/src/channel/rtp_channel/rtp_video_sender.cpp +++ b/src/channel/rtp_channel/rtp_video_sender.cpp @@ -2,6 +2,7 @@ #include +#include "common.h" #include "log.h" // #define SAVE_RTP_SENT_STREAM @@ -11,7 +12,7 @@ RtpVideoSender::RtpVideoSender() {} RtpVideoSender::RtpVideoSender(std::shared_ptr io_statistics) - : io_statistics_(io_statistics) { + : ssrc_(GenerateUniqueSsrc()), io_statistics_(io_statistics) { SetPeriod(std::chrono::milliseconds(5)); #ifdef SAVE_RTP_SENT_STREAM file_rtp_sent_ = fopen("rtp_sent_stream.h264", "w+b"); @@ -26,6 +27,8 @@ RtpVideoSender::~RtpVideoSender() { rtp_statistics_->Stop(); } + SSRCManager::Instance().DeleteSsrc(ssrc_); + #ifdef SAVE_RTP_SENT_STREAM if (file_rtp_sent_) { fflush(file_rtp_sent_); @@ -51,12 +54,26 @@ void RtpVideoSender::SetSendDataFunc( data_send_func_ = data_send_func; } +void RtpVideoSender::SetOnSentPacketFunc( + std::function on_sent_packet_func) { + on_sent_packet_func_ = on_sent_packet_func; +} + int RtpVideoSender::SendRtpPacket(RtpPacket& rtp_packet) { if (!data_send_func_) { LOG_ERROR("data_send_func_ is nullptr"); return -1; } + if (on_sent_packet_func_) { + webrtc::RtpPacketToSend rtp_packet_to_send; + rtp_packet_to_send.SetSequenceNumber(rtp_packet.SequenceNumber()); + rtp_packet_to_send.SetSsrc(rtp_packet.Ssrc()); + rtp_packet_to_send.set_transport_sequence_number(transport_seq_++); + rtp_packet_to_send.set_packet_type(webrtc::RtpPacketMediaType::kVideo); + on_sent_packet_func_(rtp_packet_to_send); + } + if (0 != data_send_func_((const char*)rtp_packet.Buffer().data(), rtp_packet.Size())) { // LOG_ERROR("Send rtp packet failed"); diff --git a/src/channel/rtp_channel/rtp_video_sender.h b/src/channel/rtp_channel/rtp_video_sender.h index f6b42a4..a4070ba 100644 --- a/src/channel/rtp_channel/rtp_video_sender.h +++ b/src/channel/rtp_channel/rtp_video_sender.h @@ -7,6 +7,7 @@ #include "ringbuffer.h" #include "rtcp_sender_report.h" #include "rtp_packet.h" +#include "rtp_packet_to_send.h" #include "rtp_statistics.h" #include "thread_base.h" @@ -19,6 +20,9 @@ class RtpVideoSender : public ThreadBase { public: void Enqueue(std::vector &rtp_packets); void SetSendDataFunc(std::function data_send_func); + void SetOnSentPacketFunc( + std::function on_sent_packet_func); + uint32_t GetSsrc() { return ssrc_; } private: int SendRtpPacket(RtpPacket &rtp_packet); @@ -31,9 +35,12 @@ class RtpVideoSender : public ThreadBase { private: std::function data_send_func_ = nullptr; + std::function on_sent_packet_func_ = + nullptr; RingBuffer rtp_packe_queue_; private: + uint32_t ssrc_ = 0; std::unique_ptr rtp_statistics_ = nullptr; std::shared_ptr io_statistics_ = nullptr; uint32_t last_send_bytes_ = 0; @@ -41,6 +48,9 @@ class RtpVideoSender : public ThreadBase { uint32_t total_rtp_payload_sent_ = 0; uint32_t total_rtp_packets_sent_ = 0; + private: + int64_t transport_seq_ = 0; + private: FILE *file_rtp_sent_ = nullptr; }; diff --git a/src/channel/video_channel_receive.cpp b/src/channel/video_channel_receive.cpp index dc187a7..f6dd0e0 100644 --- a/src/channel/video_channel_receive.cpp +++ b/src/channel/video_channel_receive.cpp @@ -5,17 +5,19 @@ VideoChannelReceive::VideoChannelReceive() {} VideoChannelReceive::VideoChannelReceive( - std::shared_ptr ice_agent, + std::shared_ptr clock, std::shared_ptr ice_agent, std::shared_ptr ice_io_statistics, std::function on_receive_complete_frame) : ice_agent_(ice_agent), ice_io_statistics_(ice_io_statistics), - on_receive_complete_frame_(on_receive_complete_frame) {} + on_receive_complete_frame_(on_receive_complete_frame), + clock_(clock) {} VideoChannelReceive::~VideoChannelReceive() {} void VideoChannelReceive::Initialize(rtp::PAYLOAD_TYPE payload_type) { - rtp_video_receiver_ = std::make_unique(ice_io_statistics_); + rtp_video_receiver_ = + std::make_unique(clock_, ice_io_statistics_); rtp_video_receiver_->SetOnReceiveCompleteFrame( [this](VideoFrame &video_frame) -> void { on_receive_complete_frame_(video_frame); diff --git a/src/channel/video_channel_receive.h b/src/channel/video_channel_receive.h index 8b9c5fd..d319556 100644 --- a/src/channel/video_channel_receive.h +++ b/src/channel/video_channel_receive.h @@ -7,6 +7,7 @@ #ifndef _VIDEO_CHANNEL_RECEIVE_H_ #define _VIDEO_CHANNEL_RECEIVE_H_ +#include "clock.h" #include "ice_agent.h" #include "rtp_video_receiver.h" @@ -14,7 +15,7 @@ class VideoChannelReceive { public: VideoChannelReceive(); VideoChannelReceive( - std::shared_ptr ice_agent, + std::shared_ptr clock, std::shared_ptr ice_agent, std::shared_ptr ice_io_statistics, std::function on_receive_complete_frame); @@ -31,6 +32,9 @@ class VideoChannelReceive { std::shared_ptr ice_io_statistics_ = nullptr; std::unique_ptr rtp_video_receiver_ = nullptr; std::function on_receive_complete_frame_ = nullptr; + + private: + std::shared_ptr clock_; }; #endif \ No newline at end of file diff --git a/src/channel/video_channel_send.cpp b/src/channel/video_channel_send.cpp index 396b144..85cb7fc 100644 --- a/src/channel/video_channel_send.cpp +++ b/src/channel/video_channel_send.cpp @@ -1,21 +1,25 @@ #include "video_channel_send.h" #include "log.h" +#include "rtc_base/network/sent_packet.h" VideoChannelSend::VideoChannelSend() {} VideoChannelSend::~VideoChannelSend() {} VideoChannelSend::VideoChannelSend( - std::shared_ptr ice_agent, + std::shared_ptr clock, std::shared_ptr ice_agent, std::shared_ptr ice_io_statistics) - : ice_agent_(ice_agent), ice_io_statistics_(ice_io_statistics){}; + : ice_agent_(ice_agent), + ice_io_statistics_(ice_io_statistics), + clock_(clock){}; void VideoChannelSend::Initialize(rtp::PAYLOAD_TYPE payload_type) { controller_ = std::make_unique(); - rtp_packetizer_ = RtpPacketizer::Create(payload_type); rtp_video_sender_ = std::make_unique(ice_io_statistics_); + rtp_packetizer_ = + RtpPacketizer::Create(payload_type, rtp_video_sender_->GetSsrc()); rtp_video_sender_->SetSendDataFunc( [this](const char* data, size_t size) -> int { if (!ice_agent_) { @@ -33,9 +37,31 @@ void VideoChannelSend::Initialize(rtp::PAYLOAD_TYPE payload_type) { } ice_io_statistics_->UpdateVideoOutboundBytes((uint32_t)size); + return ice_agent_->Send(data, size); }); + rtp_video_sender_->SetOnSentPacketFunc( + [this](const webrtc::RtpPacketToSend& packet) -> void { + webrtc::PacedPacketInfo pacing_info; + size_t transport_overhead_bytes_per_packet_ = 0; + webrtc::Timestamp creation_time = + webrtc::Timestamp::Millis(clock_->TimeInMilliseconds()); + transport_feedback_adapter_.AddPacket( + packet, pacing_info, transport_overhead_bytes_per_packet_, + creation_time); + + rtc::SentPacket sent_packet; + sent_packet.packet_id = packet.transport_sequence_number().value(); + sent_packet.send_time_ms = clock_->TimeInMilliseconds(); + sent_packet.info.included_in_feedback = true; + sent_packet.info.included_in_allocation = true; + sent_packet.info.packet_size_bytes = packet.size(); + sent_packet.info.packet_type = rtc::PacketType::kData; + + transport_feedback_adapter_.ProcessSentPacket(sent_packet); + }); + rtp_video_sender_->Start(); } @@ -71,7 +97,8 @@ void VideoChannelSend::HandleTransportPacketsFeedback( // if (transport_is_ecn_capable_) { // // If transport does not support ECN, packets should not be sent as // ECT(1). - // // TODO: bugs.webrtc.org/42225697 - adapt to ECN feedback and continue to + // // TODO: bugs.webrtc.org/42225697 - adapt to ECN feedback and + // continue to // // send packets as ECT(1) if transport is ECN capable. // transport_is_ecn_capable_ = false; // LOG_INFO("Transport is {} ECN capable. Stop sending ECT(1)", @@ -103,8 +130,8 @@ void VideoChannelSend::PostUpdates(webrtc::NetworkControlUpdate update) { } void VideoChannelSend::UpdateControlState() { - // std::optional update = control_handler_->GetUpdate(); - // if (!update) return; + // std::optional update = + // control_handler_->GetUpdate(); if (!update) return; // retransmission_rate_limiter_.SetMaxRate(update->target_rate.bps()); // observer_->OnTargetTransferRate(*update); } diff --git a/src/channel/video_channel_send.h b/src/channel/video_channel_send.h index 55f572a..2c3dc9e 100644 --- a/src/channel/video_channel_send.h +++ b/src/channel/video_channel_send.h @@ -8,6 +8,7 @@ #define _VIDEO_CHANNEL_SEND_H_ #include "api/transport/network_types.h" +#include "clock.h" #include "congestion_control.h" #include "congestion_control_feedback.h" #include "ice_agent.h" @@ -19,7 +20,8 @@ class VideoChannelSend { public: VideoChannelSend(); - VideoChannelSend(std::shared_ptr ice_agent, + VideoChannelSend(std::shared_ptr clock, + std::shared_ptr ice_agent, std::shared_ptr ice_io_statistics); ~VideoChannelSend(); @@ -47,6 +49,7 @@ class VideoChannelSend { std::unique_ptr rtp_video_sender_ = nullptr; private: + std::shared_ptr clock_; int64_t current_offset_ = std::numeric_limits::min(); // Used by RFC 8888 congestion control feedback to track base time. std::optional last_feedback_compact_ntp_time_; diff --git a/src/qos/congestion_control.cpp b/src/qos/congestion_control.cpp index bb3f147..c526845 100644 --- a/src/qos/congestion_control.cpp +++ b/src/qos/congestion_control.cpp @@ -114,6 +114,8 @@ NetworkControlUpdate CongestionControl::OnTransportPacketsFeedback( if (report.feedback_time > next_loss_update_) { next_loss_update_ = report.feedback_time + TimeDelta::Millis(kLossUpdateInterval); + LOG_WARN("lost_packets_since_last_loss_update_ = [{}]", + lost_packets_since_last_loss_update_); bandwidth_estimation_->UpdatePacketsLost( lost_packets_since_last_loss_update_, expected_packets_since_last_loss_update_, report.feedback_time); diff --git a/src/qos/congestion_control_feedback.cpp b/src/qos/congestion_control_feedback.cpp index 1784215..daf131b 100644 --- a/src/qos/congestion_control_feedback.cpp +++ b/src/qos/congestion_control_feedback.cpp @@ -297,6 +297,9 @@ bool CongestionControlFeedback::Parse(const rtcp::CommonHeader& packet) { uint16_t seq_no = base_seqno + i; bool received = (packet_info & 0x8000); + TimeDelta arrival_time_offset = AtoToTimeDelta(packet_info); + LOG_ERROR("received:{} = [{} {}]", received, + ToString(arrival_time_offset), arrival_time_offset.IsFinite()); packets_.push_back( {ssrc, seq_no, received ? AtoToTimeDelta(packet_info) : TimeDelta::MinusInfinity(), diff --git a/src/qos/congestion_control_feedback_generator.cc b/src/qos/congestion_control_feedback_generator.cc index 3942c18..c6b0d6f 100644 --- a/src/qos/congestion_control_feedback_generator.cc +++ b/src/qos/congestion_control_feedback_generator.cc @@ -94,6 +94,7 @@ void CongestionControlFeedbackGenerator::SendFeedback(Timestamp now) { for (auto& [unused, tracker] : feedback_trackers_) { tracker.AddPacketsToFeedback(now, rtcp_packet_info); } + marker_bit_seen_ = false; first_arrival_time_since_feedback_ = std::nullopt; diff --git a/src/qos/send_side_bandwidth_estimation.cc b/src/qos/send_side_bandwidth_estimation.cc index a58cf54..8c36be2 100644 --- a/src/qos/send_side_bandwidth_estimation.cc +++ b/src/qos/send_side_bandwidth_estimation.cc @@ -204,6 +204,7 @@ void SendSideBandwidthEstimation::SetBitrates( void SendSideBandwidthEstimation::SetSendBitrate(DataRate bitrate, Timestamp at_time) { + LOG_ERROR("3"); // Reset to avoid being capped by the estimate. delay_based_limit_ = DataRate::PlusInfinity(); UpdateTargetBitrate(bitrate, at_time); @@ -244,6 +245,7 @@ DataRate SendSideBandwidthEstimation::GetEstimatedLinkCapacity() const { void SendSideBandwidthEstimation::UpdateReceiverEstimate(Timestamp at_time, DataRate bandwidth) { + LOG_ERROR("6"); // TODO(srte): Ensure caller passes PlusInfinity, not zero, to represent no // limitation. receiver_limit_ = bandwidth.IsZero() ? DataRate::PlusInfinity() : bandwidth; @@ -252,6 +254,7 @@ void SendSideBandwidthEstimation::UpdateReceiverEstimate(Timestamp at_time, void SendSideBandwidthEstimation::UpdateDelayBasedEstimate(Timestamp at_time, DataRate bitrate) { + LOG_ERROR("7"); link_capacity_.UpdateDelayBasedEstimate(at_time, bitrate); // TODO(srte): Ensure caller passes PlusInfinity, not zero, to represent no // limitation. @@ -342,7 +345,9 @@ void SendSideBandwidthEstimation::UpdateRtt(TimeDelta rtt, Timestamp at_time) { } void SendSideBandwidthEstimation::UpdateEstimate(Timestamp at_time) { + LOG_ERROR("1"); if (rtt_backoff_.IsRttAboveLimit()) { + LOG_ERROR("11"); if (at_time - time_last_decrease_ >= rtt_backoff_.drop_interval_ && current_target_ > rtt_backoff_.bandwidth_floor_) { time_last_decrease_ = at_time; @@ -357,7 +362,7 @@ void SendSideBandwidthEstimation::UpdateEstimate(Timestamp at_time) { ApplyTargetLimits(at_time); return; } - + LOG_ERROR("111"); // We trust the REMB and/or delay-based estimate during the first 2 seconds if // we haven't had any packet loss reported, to allow startup bitrate probing. if (last_fraction_loss_ == 0 && IsInStartPhase(at_time)) { @@ -376,22 +381,28 @@ void SendSideBandwidthEstimation::UpdateEstimate(Timestamp at_time) { return; } } + LOG_ERROR("112"); UpdateMinHistory(at_time); if (last_loss_packet_report_.IsInfinite()) { // No feedback received. // TODO(srte): This is likely redundant in most cases. + LOG_ERROR("113"); ApplyTargetLimits(at_time); return; } TimeDelta time_since_loss_packet_report = at_time - last_loss_packet_report_; if (time_since_loss_packet_report < 1.2 * kMaxRtcpFeedbackInterval) { + LOG_ERROR("114"); // We only care about loss above a given bitrate threshold. float loss = last_fraction_loss_ / 256.0f; + LOG_ERROR("current_target_ = [{}], loss = [{}]", ToString(current_target_), + loss); // We only make decisions based on loss when the bitrate is above a // threshold. This is a crude way of handling loss which is uncorrelated // to congestion. if (current_target_ < bitrate_threshold_ || loss <= low_loss_threshold_) { + LOG_ERROR("115"); // Loss < 2%: Increase rate by 8% of the min bitrate in the last // kBweIncreaseInterval. // Note that by remembering the bitrate over the last second one can @@ -412,14 +423,18 @@ void SendSideBandwidthEstimation::UpdateEstimate(Timestamp at_time) { UpdateTargetBitrate(new_bitrate, at_time); return; } else if (current_target_ > bitrate_threshold_) { + LOG_ERROR("116"); if (loss <= high_loss_threshold_) { + LOG_ERROR("117"); // Loss between 2% - 10%: Do nothing. } else { + LOG_ERROR("118"); // Loss > 10%: Limit the rate decreases to once a kBweDecreaseInterval // + rtt. if (!has_decreased_since_last_fraction_loss_ && (at_time - time_last_decrease_) >= (kBweDecreaseInterval + last_round_trip_time_)) { + LOG_ERROR("119"); time_last_decrease_ = at_time; // Reduce rate: @@ -436,6 +451,7 @@ void SendSideBandwidthEstimation::UpdateEstimate(Timestamp at_time) { } } } + LOG_ERROR("120"); // TODO(srte): This is likely redundant in most cases. ApplyTargetLimits(at_time); } @@ -447,6 +463,7 @@ void SendSideBandwidthEstimation::UpdatePropagationRtt( void SendSideBandwidthEstimation::OnSentPacket(const SentPacket& sent_packet) { // Only feedback-triggering packets will be reported here. + LOG_ERROR("5"); rtt_backoff_.last_packet_sent_ = sent_packet.send_time; } @@ -495,6 +512,7 @@ void SendSideBandwidthEstimation::MaybeLogLowBitrateWarning(DataRate bitrate, void SendSideBandwidthEstimation::UpdateTargetBitrate(DataRate new_bitrate, Timestamp at_time) { new_bitrate = std::min(new_bitrate, GetUpperLimit()); + LOG_WARN("new_bitrate: [{}]", ToString(new_bitrate).c_str()); if (new_bitrate < min_bitrate_configured_) { MaybeLogLowBitrateWarning(new_bitrate, at_time); new_bitrate = min_bitrate_configured_; @@ -504,6 +522,7 @@ void SendSideBandwidthEstimation::UpdateTargetBitrate(DataRate new_bitrate, } void SendSideBandwidthEstimation::ApplyTargetLimits(Timestamp at_time) { + LOG_ERROR("2"); UpdateTargetBitrate(current_target_, at_time); } diff --git a/src/qos/transport_feedback_adapter.cc b/src/qos/transport_feedback_adapter.cc index 243d509..ff8f2fd 100644 --- a/src/qos/transport_feedback_adapter.cc +++ b/src/qos/transport_feedback_adapter.cc @@ -262,6 +262,7 @@ TransportFeedbackAdapter::ProcessCongestionControlFeedback( int failed_lookups = 0; bool supports_ecn = true; std::vector packet_result_vector; + LOG_ERROR("20"); for (const rtcp::CongestionControlFeedback::PacketInfo& packet_info : feedback.packets()) { std::optional packet_feedback = RetrievePacketFeedback( @@ -277,7 +278,9 @@ TransportFeedbackAdapter::ProcessCongestionControlFeedback( } PacketResult result; result.sent_packet = packet_feedback->sent; + LOG_ERROR("21"); if (packet_info.arrival_time_offset.IsFinite()) { + LOG_ERROR("22"); result.receive_time = current_offset_ - packet_info.arrival_time_offset; supports_ecn &= packet_info.ecn != EcnMarking::kNotEct; } diff --git a/src/rtcp/rtcp_sender/rtcp_sender.h b/src/rtcp/rtcp_sender/rtcp_sender.h index 1800ebc..736db63 100644 --- a/src/rtcp/rtcp_sender/rtcp_sender.h +++ b/src/rtcp/rtcp_sender/rtcp_sender.h @@ -19,12 +19,12 @@ class RTCPSender { RTCPSender(std::function callback, size_t max_packet_size) : callback_(callback), max_packet_size_(max_packet_size) { - if (max_packet_size > IP_PACKET_SIZE) { + if (max_packet_size >= IP_PACKET_SIZE) { LOG_ERROR("max_packet_size must be less than IP_PACKET_SIZE"); } } ~RTCPSender() { - if (index_ == 0) { + if (index_ != 0) { LOG_ERROR("Unsent rtcp packet"); } } diff --git a/src/rtp/rtp_packet/rtp_packet.hxx b/src/rtp/rtp_packet/rtp_packet.x similarity index 100% rename from src/rtp/rtp_packet/rtp_packet.hxx rename to src/rtp/rtp_packet/rtp_packet.x diff --git a/src/rtp/rtp_packetizer/rtp_packetizer.cpp b/src/rtp/rtp_packetizer/rtp_packetizer.cpp index 86cc341..473cf14 100644 --- a/src/rtp/rtp_packetizer/rtp_packetizer.cpp +++ b/src/rtp/rtp_packetizer/rtp_packetizer.cpp @@ -4,13 +4,14 @@ #include "rtp_packetizer_generic.h" #include "rtp_packetizer_h264.h" -std::unique_ptr RtpPacketizer::Create(uint32_t payload_type) { +std::unique_ptr RtpPacketizer::Create(uint32_t payload_type, + uint32_t ssrc) { switch (payload_type) { case rtp::PAYLOAD_TYPE::H264: - return std::make_unique(); + return std::make_unique(ssrc); case rtp::PAYLOAD_TYPE::AV1: - return std::make_unique(); + return std::make_unique(ssrc); default: - return std::make_unique(); + return std::make_unique(ssrc); } } \ No newline at end of file diff --git a/src/rtp/rtp_packetizer/rtp_packetizer.h b/src/rtp/rtp_packetizer/rtp_packetizer.h index a8ced94..32db74b 100644 --- a/src/rtp/rtp_packetizer/rtp_packetizer.h +++ b/src/rtp/rtp_packetizer/rtp_packetizer.h @@ -15,7 +15,8 @@ class RtpPacketizer { public: - static std::unique_ptr Create(uint32_t payload_type); + static std::unique_ptr Create(uint32_t payload_type, + uint32_t ssrc); virtual ~RtpPacketizer() = default; diff --git a/src/rtp/rtp_packetizer/rtp_packetizer_av1.cpp b/src/rtp/rtp_packetizer/rtp_packetizer_av1.cpp index 01f2a45..6e08889 100644 --- a/src/rtp/rtp_packetizer/rtp_packetizer_av1.cpp +++ b/src/rtp/rtp_packetizer/rtp_packetizer_av1.cpp @@ -1,6 +1,6 @@ #include "rtp_packetizer_av1.h" -RtpPacketizerAv1::RtpPacketizerAv1() {} +RtpPacketizerAv1::RtpPacketizerAv1(uint32_t ssrc) {} RtpPacketizerAv1::~RtpPacketizerAv1() {} diff --git a/src/rtp/rtp_packetizer/rtp_packetizer_av1.h b/src/rtp/rtp_packetizer/rtp_packetizer_av1.h index eeaf693..f0e6822 100644 --- a/src/rtp/rtp_packetizer/rtp_packetizer_av1.h +++ b/src/rtp/rtp_packetizer/rtp_packetizer_av1.h @@ -11,7 +11,7 @@ class RtpPacketizerAv1 : public RtpPacketizer { public: - RtpPacketizerAv1(); + RtpPacketizerAv1(uint32_t ssrc); virtual ~RtpPacketizerAv1(); diff --git a/src/rtp/rtp_packetizer/rtp_packetizer_generic.cpp b/src/rtp/rtp_packetizer/rtp_packetizer_generic.cpp index ef4b9eb..7d5ff2d 100644 --- a/src/rtp/rtp_packetizer/rtp_packetizer_generic.cpp +++ b/src/rtp/rtp_packetizer/rtp_packetizer_generic.cpp @@ -1,6 +1,6 @@ #include "rtp_packetizer_generic.h" -RtpPacketizerGeneric::RtpPacketizerGeneric() +RtpPacketizerGeneric::RtpPacketizerGeneric(uint32_t ssrc) : version_(kRtpVersion), has_padding_(false), has_extension_(true), @@ -9,7 +9,7 @@ RtpPacketizerGeneric::RtpPacketizerGeneric() payload_type_(rtp::PAYLOAD_TYPE::DATA), sequence_number_(0), timestamp_(0), - ssrc_(0), + ssrc_(ssrc), profile_(0), extension_profile_(0), extension_len_(0), diff --git a/src/rtp/rtp_packetizer/rtp_packetizer_generic.h b/src/rtp/rtp_packetizer/rtp_packetizer_generic.h index 481a122..f2ece73 100644 --- a/src/rtp/rtp_packetizer/rtp_packetizer_generic.h +++ b/src/rtp/rtp_packetizer/rtp_packetizer_generic.h @@ -11,7 +11,7 @@ class RtpPacketizerGeneric : public RtpPacketizer { public: - RtpPacketizerGeneric(); + RtpPacketizerGeneric(uint32_t ssrc); virtual ~RtpPacketizerGeneric(); diff --git a/src/rtp/rtp_packetizer/rtp_packetizer_h264.cpp b/src/rtp/rtp_packetizer/rtp_packetizer_h264.cpp index 761a75a..408123d 100644 --- a/src/rtp/rtp_packetizer/rtp_packetizer_h264.cpp +++ b/src/rtp/rtp_packetizer/rtp_packetizer_h264.cpp @@ -1,6 +1,6 @@ #include "rtp_packetizer_h264.h" -RtpPacketizerH264::RtpPacketizerH264() +RtpPacketizerH264::RtpPacketizerH264(uint32_t ssrc) : version_(kRtpVersion), has_padding_(false), has_extension_(true), @@ -9,7 +9,7 @@ RtpPacketizerH264::RtpPacketizerH264() payload_type_(rtp::PAYLOAD_TYPE::H264), sequence_number_(0), timestamp_(0), - ssrc_(0), + ssrc_(ssrc), profile_(0), extension_profile_(0), extension_len_(0), diff --git a/src/rtp/rtp_packetizer/rtp_packetizer_h264.h b/src/rtp/rtp_packetizer/rtp_packetizer_h264.h index 5aa37db..05441a1 100644 --- a/src/rtp/rtp_packetizer/rtp_packetizer_h264.h +++ b/src/rtp/rtp_packetizer/rtp_packetizer_h264.h @@ -11,7 +11,7 @@ class RtpPacketizerH264 : public RtpPacketizer { public: - RtpPacketizerH264(); + RtpPacketizerH264(uint32_t ssrc); virtual ~RtpPacketizerH264(); diff --git a/src/transport/ice_transport.cpp b/src/transport/ice_transport.cpp index 323d0fb..b22e5ba 100644 --- a/src/transport/ice_transport.cpp +++ b/src/transport/ice_transport.cpp @@ -25,7 +25,8 @@ IceTransport::IceTransport( remote_user_id_(remote_user_id), ice_ws_transport_(ice_ws_transmission), on_ice_status_change_(on_ice_status_change), - user_data_(user_data) {} + user_data_(user_data), + clock_(webrtc::Clock::GetRealTimeClockShared()) {} IceTransport::~IceTransport() { user_data_ = nullptr; @@ -119,8 +120,8 @@ void IceTransport::InitializeChannels( rtp::PAYLOAD_TYPE video_codec_payload_type) { video_codec_payload_type_ = video_codec_payload_type; - video_channel_send_ = - std::make_unique(ice_agent_, ice_io_statistics_); + video_channel_send_ = std::make_unique(clock_, ice_agent_, + ice_io_statistics_); audio_channel_send_ = std::make_unique(ice_agent_, ice_io_statistics_); data_channel_send_ = @@ -132,7 +133,7 @@ void IceTransport::InitializeChannels( std::weak_ptr weak_self = shared_from_this(); video_channel_receive_ = std::make_unique( - ice_agent_, ice_io_statistics_, + clock_, ice_agent_, ice_io_statistics_, [this, weak_self](VideoFrame &video_frame) { if (auto self = weak_self.lock()) { OnReceiveCompleteFrame(video_frame); diff --git a/src/transport/ice_transport.h b/src/transport/ice_transport.h index 7e39580..30f7c6f 100644 --- a/src/transport/ice_transport.h +++ b/src/transport/ice_transport.h @@ -14,6 +14,7 @@ // #include "congestion_control.h" #include "audio_channel_receive.h" #include "audio_channel_send.h" +#include "clock.h" #include "data_channel_receive.h" #include "data_channel_send.h" #include "ice_agent.h" @@ -219,6 +220,7 @@ class IceTransport : public std::enable_shared_from_this { on_receive_net_status_report_ = nullptr; private: + std::shared_ptr clock_; std::unique_ptr video_channel_send_ = nullptr; std::unique_ptr video_channel_receive_ = nullptr; std::unique_ptr audio_channel_send_ = nullptr; diff --git a/xmake.lua b/xmake.lua index ec7c0eb..3b2dbbd 100644 --- a/xmake.lua +++ b/xmake.lua @@ -44,6 +44,7 @@ target("common") add_deps("log") add_files("src/common/common.cpp", "src/common/rtc_base/*.cc", + "src/common/rtc_base/network/*.cc", "src/common/rtc_base/numerics/*.cc", "src/common/api/units/*.cc", "src/common/api/transport/*.cc")