[feat] implementation for nack generator module

This commit is contained in:
dijunkun
2025-02-13 17:24:18 +08:00
parent 1db57bfc76
commit 7b4bba4166
14 changed files with 303 additions and 88 deletions

View File

@@ -2,6 +2,7 @@
#include "common.h"
#include "log.h"
#include "nack.h"
#include "rtcp_sender.h"
// #define SAVE_RTP_RECV_STREAM
@@ -21,9 +22,12 @@ RtpVideoReceiver::RtpVideoReceiver(std::shared_ptr<Clock> clock)
SendRemb(bitrate_bps, ssrcs);
}),
clock_(clock),
rtcp_feedback_buffer_(this, this, this),
nack_(std::make_unique<NackRequester>(clock, &rtcp_feedback_buffer_,
&rtcp_feedback_buffer_)) {
rtcp_sender_(std::make_unique<RtcpSender>(
[this](const uint8_t* buffer, size_t size) -> int {
return data_send_func_((const char*)buffer, size);
},
1200)),
nack_(std::make_unique<NackRequester>(clock, this, this)) {
SetPeriod(std::chrono::milliseconds(5));
// rtcp_thread_ = std::thread(&RtpVideoReceiver::RtcpThread, this);
}
@@ -41,9 +45,12 @@ RtpVideoReceiver::RtpVideoReceiver(std::shared_ptr<Clock> clock,
SendRemb(bitrate_bps, ssrcs);
}),
clock_(clock),
rtcp_feedback_buffer_(this, this, this),
nack_(std::make_unique<NackRequester>(clock, &rtcp_feedback_buffer_,
&rtcp_feedback_buffer_)) {
rtcp_sender_(std::make_unique<RtcpSender>(
[this](const uint8_t* buffer, size_t size) -> int {
return data_send_func_((const char*)buffer, size);
},
1200)),
nack_(std::make_unique<NackRequester>(clock, this, this)) {
SetPeriod(std::chrono::milliseconds(5));
// rtcp_thread_ = std::thread(&RtpVideoReceiver::RtcpThread, this);
@@ -83,6 +90,8 @@ void RtpVideoReceiver::InsertRtpPacket(RtpPacket& rtp_packet) {
rtp_statistics_->Start();
}
remote_ssrc_ = rtp_packet.Ssrc();
#ifdef SAVE_RTP_RECV_STREAM
fwrite((unsigned char*)rtp_packet.Payload(), 1, rtp_packet.PayloadSize(),
file_rtp_recv_);
@@ -90,7 +99,6 @@ void RtpVideoReceiver::InsertRtpPacket(RtpPacket& rtp_packet) {
webrtc::RtpPacketReceived rtp_packet_received;
rtp_packet_received.Build(rtp_packet.Buffer().data(), rtp_packet.Size());
rtp_packet_received.set_arrival_time(clock_->CurrentTime());
rtp_packet_received.set_ecn(EcnMarking::kEct0);
rtp_packet_received.set_recovered(false);
@@ -98,6 +106,8 @@ void RtpVideoReceiver::InsertRtpPacket(RtpPacket& rtp_packet) {
receive_side_congestion_controller_.OnReceivedPacket(rtp_packet_received,
MediaType::VIDEO);
nack_->OnReceivedPacket(rtp_packet.SequenceNumber());
last_recv_bytes_ = (uint32_t)rtp_packet.PayloadSize();
total_rtp_payload_recv_ += (uint32_t)rtp_packet.PayloadSize();
total_rtp_packets_recv_++;
@@ -434,16 +444,10 @@ void RtpVideoReceiver::SendCombinedRtcpPacket(
// LOG_ERROR("Send combined rtcp packet");
RTCPSender rtcp_sender(
[this](const uint8_t* buffer, size_t size) -> int {
return data_send_func_((const char*)buffer, size);
},
1200);
for (auto& rtcp_packet : rtcp_packets) {
rtcp_packet->SetSenderSsrc(feedback_ssrc_);
rtcp_sender.AppendPacket(*rtcp_packet);
rtcp_sender.Send();
rtcp_sender_->AppendPacket(*rtcp_packet);
rtcp_sender_->Send();
}
}
@@ -517,4 +521,26 @@ void RtpVideoReceiver::RtcpThread() {
}
}
}
}
}
/******************************************************************************/
void RtpVideoReceiver::SendNack(const std::vector<uint16_t>& nack_list,
bool buffering_allowed) {
if (!nack_list.empty()) {
webrtc::rtcp::Nack nack;
nack.SetSenderSsrc(feedback_ssrc_);
nack.SetMediaSsrc(remote_ssrc_);
nack.SetPacketIds(std::move(nack_list));
rtcp_sender_->AppendPacket(nack);
rtcp_sender_->Send();
}
}
void RtpVideoReceiver::RequestKeyFrame() {}
void RtpVideoReceiver::SendLossNotification(uint16_t last_decoded_seq_num,
uint16_t last_received_seq_num,
bool decodability_flag,
bool buffering_allowed) {}

View File

@@ -13,6 +13,7 @@
#include "receive_side_congestion_controller.h"
#include "ringbuffer.h"
#include "rtcp_receiver_report.h"
#include "rtcp_sender.h"
#include "rtp_packet_av1.h"
#include "rtp_packet_h264.h"
#include "rtp_rtcp_defines.h"
@@ -63,6 +64,15 @@ class RtpVideoReceiver : public ThreadBase,
bool Process() override;
void RtcpThread();
private:
void SendNack(const std::vector<uint16_t>& nack_list, bool buffering_allowed);
void RequestKeyFrame();
void SendLossNotification(uint16_t last_decoded_seq_num,
uint16_t last_received_seq_num,
bool decodability_flag, bool buffering_allowed);
private:
std::map<uint16_t, RtpPacketH264> incomplete_h264_frame_list_;
std::map<uint16_t, RtpPacketAv1> incomplete_av1_frame_list_;
@@ -107,66 +117,11 @@ class RtpVideoReceiver : public ThreadBase,
ReceiveSideCongestionController receive_side_congestion_controller_;
RtcpFeedbackSenderInterface* active_remb_module_;
uint32_t feedback_ssrc_ = 0;
uint32_t remote_ssrc_ = 0;
std::unique_ptr<RtcpSender> rtcp_sender_;
std::unique_ptr<NackRequester> nack_;
private:
class RtcpFeedbackBuffer : public KeyFrameRequestSender,
public NackSender,
public LossNotificationSender {
public:
RtcpFeedbackBuffer(KeyFrameRequestSender* key_frame_request_sender,
NackSender* nack_sender,
LossNotificationSender* loss_notification_sender);
~RtcpFeedbackBuffer() override = default;
// KeyFrameRequestSender implementation.
void RequestKeyFrame() override;
// NackSender implementation.
void SendNack(const std::vector<uint16_t>& sequence_numbers,
bool buffering_allowed) override;
// LossNotificationSender implementation.
void SendLossNotification(uint16_t last_decoded_seq_num,
uint16_t last_received_seq_num,
bool decodability_flag,
bool buffering_allowed) override;
// Send all RTCP feedback messages buffered thus far.
void SendBufferedRtcpFeedback();
void ClearLossNotificationState();
private:
// LNTF-related state.
struct LossNotificationState {
LossNotificationState(uint16_t last_decoded_seq_num,
uint16_t last_received_seq_num,
bool decodability_flag)
: last_decoded_seq_num(last_decoded_seq_num),
last_received_seq_num(last_received_seq_num),
decodability_flag(decodability_flag) {}
uint16_t last_decoded_seq_num;
uint16_t last_received_seq_num;
bool decodability_flag;
};
KeyFrameRequestSender* const key_frame_request_sender_;
NackSender* const nack_sender_;
LossNotificationSender* const loss_notification_sender_;
// Key-frame-request-related state.
bool request_key_frame_;
// NACK-related state.
std::vector<uint16_t> nack_sequence_numbers_;
std::optional<LossNotificationState> lntf_state_;
};
RtcpFeedbackBuffer rtcp_feedback_buffer_;
private:
FILE* file_rtp_recv_ = nullptr;
};