mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-27 04:35:34 +08:00
[feat] introduce fraction lost into congestion control module
This commit is contained in:
@@ -299,6 +299,38 @@ bool IceTransport::ParseRtcpPacket(const uint8_t *buffer, size_t size,
|
||||
return true;
|
||||
}
|
||||
|
||||
void IceTransport::HandleReportBlock(const RtcpReportBlock &rtcp_report_block,
|
||||
RtcpPacketInfo *packet_information,
|
||||
uint32_t remote_ssrc) {
|
||||
int64_t now = clock_->CurrentTime();
|
||||
|
||||
RtcpReportBlock report_block_data;
|
||||
|
||||
int64_t now_ntp = clock_->ConvertToNtpTime(now);
|
||||
// Number of seconds since 1900 January 1 00:00 GMT (see
|
||||
// https://tools.ietf.org/html/rfc868).
|
||||
report_block_data.SetReportBlock(remote_ssrc, rtcp_report_block,
|
||||
clock_->NtpToUtc(now_ntp), now);
|
||||
|
||||
uint32_t send_time_ntp = rtcp_report_block.LastSr();
|
||||
if (send_time_ntp != 0) {
|
||||
uint32_t delay_ntp = rtcp_report_block.DelaySinceLastSr();
|
||||
// Local NTP time.
|
||||
constexpr uint64_t kNtpFractionalUnit = 0x100000000;
|
||||
uint32_t seconds = now_ntp / kNtpFractionalUnit;
|
||||
uint32_t fractions = now_ntp % kNtpFractionalUnit;
|
||||
uint32_t receive_time_ntp = (seconds << 16) | (fractions >> 16);
|
||||
// RTT in 1/(2^16) seconds.
|
||||
uint32_t rtt_ntp = receive_time_ntp - delay_ntp - send_time_ntp;
|
||||
// Convert to 1/1000 seconds (milliseconds).
|
||||
int64_t rtt = static_cast<int64_t>((rtt_ntp * 1000) / (1 << 16));
|
||||
report_block_data.AddRoundTripTimeSample(rtt);
|
||||
packet_information->rtt = rtt;
|
||||
}
|
||||
|
||||
packet_information->report_block_datas.push_back(report_block_data);
|
||||
}
|
||||
|
||||
bool IceTransport::HandleSenderReport(const RtcpCommonHeader &rtcp_block,
|
||||
RtcpPacketInfo *rtcp_packet_info) {
|
||||
SenderReport sender_report;
|
||||
@@ -319,8 +351,17 @@ bool IceTransport::HandleReceiverReport(const RtcpCommonHeader &rtcp_block,
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint32_t remote_ssrc = receiver_report.SenderSsrc();
|
||||
rtcp_packet_info->remote_ssrc = remote_ssrc;
|
||||
|
||||
for (const RtcpReportBlock &rtcp_report_block :
|
||||
receiver_report.GetReportBlocks()) {
|
||||
HandleReportBlock(rtcp_report_block, rtcp_packet_info, remote_ssrc);
|
||||
}
|
||||
|
||||
if (ice_transport_controller_) {
|
||||
ice_transport_controller_->OnReceiverReport(receiver_report);
|
||||
ice_transport_controller_->OnReceiverReport(
|
||||
rtcp_packet_info->report_block_datas);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -130,6 +130,10 @@ class IceTransport {
|
||||
bool ParseRtcpPacket(const uint8_t *buffer, size_t size,
|
||||
RtcpPacketInfo *rtcp_packet_info);
|
||||
|
||||
void HandleReportBlock(const RtcpReportBlock &rtcp_report_block,
|
||||
RtcpPacketInfo *packet_information,
|
||||
uint32_t remote_ssrc);
|
||||
|
||||
bool HandleSenderReport(const RtcpCommonHeader &rtcp_block,
|
||||
RtcpPacketInfo *rtcp_packet_info);
|
||||
|
||||
|
||||
@@ -6,14 +6,19 @@
|
||||
#include "nvcodec_api.h"
|
||||
#endif
|
||||
|
||||
#include "api/transport/network_types.h"
|
||||
|
||||
IceTransportController::IceTransportController(
|
||||
std::shared_ptr<SystemClock> clock)
|
||||
: clock_(clock),
|
||||
: last_report_block_time_(
|
||||
webrtc::Timestamp::Millis(webrtc_clock_->TimeInMilliseconds())),
|
||||
b_force_i_frame_(true),
|
||||
video_codec_inited_(false),
|
||||
audio_codec_inited_(false),
|
||||
load_nvcodec_dll_success_(false),
|
||||
hardware_acceleration_(false) {}
|
||||
hardware_acceleration_(false),
|
||||
clock_(clock),
|
||||
webrtc_clock_(webrtc::Clock::GetWebrtcClockShared(clock)) {}
|
||||
|
||||
IceTransportController::~IceTransportController() {
|
||||
user_data_ = nullptr;
|
||||
@@ -339,10 +344,48 @@ void IceTransportController::OnSenderReport(const SenderReport& sender_report) {
|
||||
}
|
||||
|
||||
void IceTransportController::OnReceiverReport(
|
||||
const ReceiverReport& receiver_report) {
|
||||
video_channel_send_->OnReceiverReport(receiver_report);
|
||||
audio_channel_send_->OnReceiverReport(receiver_report);
|
||||
data_channel_send_->OnReceiverReport(receiver_report);
|
||||
const std::vector<RtcpReportBlock>& report_block_datas) {
|
||||
webrtc::Timestamp now = webrtc_clock_->CurrentTime();
|
||||
if (report_block_datas.empty()) return;
|
||||
|
||||
int total_packets_lost_delta = 0;
|
||||
int total_packets_delta = 0;
|
||||
|
||||
for (const RtcpReportBlock& report_block : report_block_datas) {
|
||||
auto [it, inserted] =
|
||||
last_report_blocks_.try_emplace(report_block.SourceSsrc());
|
||||
LossReport& last_loss_report = it->second;
|
||||
if (!inserted) {
|
||||
total_packets_delta += report_block.ExtendedHighSeqNum() -
|
||||
last_loss_report.extended_highest_sequence_number;
|
||||
total_packets_lost_delta +=
|
||||
report_block.CumulativeLost() - last_loss_report.cumulative_lost;
|
||||
}
|
||||
last_loss_report.extended_highest_sequence_number =
|
||||
report_block.ExtendedHighSeqNum();
|
||||
last_loss_report.cumulative_lost = report_block.CumulativeLost();
|
||||
}
|
||||
// Can only compute delta if there has been previous blocks to compare to. If
|
||||
// not, total_packets_delta will be unchanged and there's nothing more to do.
|
||||
if (!total_packets_delta) return;
|
||||
int packets_received_delta = total_packets_delta - total_packets_lost_delta;
|
||||
// To detect lost packets, at least one packet has to be received. This check
|
||||
// is needed to avoid bandwith detection update in
|
||||
// VideoSendStreamTest.SuspendBelowMinBitrate
|
||||
|
||||
if (packets_received_delta < 1) {
|
||||
return;
|
||||
}
|
||||
webrtc::TransportLossReport msg;
|
||||
msg.packets_lost_delta = total_packets_lost_delta;
|
||||
msg.packets_received_delta = packets_received_delta;
|
||||
msg.receive_time = now;
|
||||
msg.start_time = last_report_block_time_;
|
||||
msg.end_time = now;
|
||||
if (controller_) {
|
||||
PostUpdates(controller_->OnTransportLossReport(msg));
|
||||
}
|
||||
last_report_block_time_ = now;
|
||||
}
|
||||
|
||||
void IceTransportController::OnCongestionControlFeedback(
|
||||
|
||||
@@ -62,7 +62,7 @@ class IceTransportController
|
||||
|
||||
public:
|
||||
void OnSenderReport(const SenderReport &sender_report);
|
||||
void OnReceiverReport(const ReceiverReport& receiver_report);
|
||||
void OnReceiverReport(const std::vector<RtcpReportBlock> &report_block_datas);
|
||||
void OnCongestionControlFeedback(
|
||||
const webrtc::rtcp::CongestionControlFeedback &feedback);
|
||||
|
||||
@@ -101,6 +101,7 @@ class IceTransportController
|
||||
|
||||
private:
|
||||
std::shared_ptr<SystemClock> clock_;
|
||||
std::shared_ptr<webrtc::Clock> webrtc_clock_ = nullptr;
|
||||
webrtc::TransportFeedbackAdapter transport_feedback_adapter_;
|
||||
std::unique_ptr<CongestionControl> controller_;
|
||||
|
||||
@@ -119,6 +120,13 @@ class IceTransportController
|
||||
|
||||
private:
|
||||
int64_t target_bitrate_ = 0;
|
||||
|
||||
struct LossReport {
|
||||
uint32_t extended_highest_sequence_number = 0;
|
||||
int cumulative_lost = 0;
|
||||
};
|
||||
std::map<uint32_t, LossReport> last_report_blocks_;
|
||||
webrtc::Timestamp last_report_block_time_;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user