![]() System : Linux absol.cf 5.4.0-198-generic #218-Ubuntu SMP Fri Sep 27 20:18:53 UTC 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.33 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, Directory : /proc/self/root/usr/local/lib/node_modules/mediasoup/worker/test/src/RTC/ |
Upload File : |
#include "common.hpp" #include "RTC/RtpPacket.hpp" #include "RTC/RtpStream.hpp" #include "RTC/RtpStreamRecv.hpp" #include <catch.hpp> #include <vector> using namespace RTC; // 17: 16 bit mask + the initial sequence number. static constexpr size_t MaxRequestedPackets{ 17 }; SCENARIO("receive RTP packets and trigger NACK", "[rtp][rtpstream]") { class RtpStreamRecvListener : public RtpStreamRecv::Listener { public: void OnRtpStreamScore(RtpStream* /*rtpStream*/, uint8_t /*score*/, uint8_t /*previousScore*/) override { } void OnRtpStreamSendRtcpPacket(RtpStreamRecv* rtpStream, RTCP::Packet* packet) override { switch (packet->GetType()) { case RTCP::Type::PSFB: { switch (dynamic_cast<RTCP::FeedbackPsPacket*>(packet)->GetMessageType()) { case RTCP::FeedbackPs::MessageType::PLI: { INFO("PLI required"); REQUIRE(this->shouldTriggerPLI == true); this->shouldTriggerPLI = false; this->nackedSeqNumbers.clear(); break; } case RTCP::FeedbackPs::MessageType::FIR: { INFO("FIR required"); REQUIRE(this->shouldTriggerFIR == true); this->shouldTriggerFIR = false; this->nackedSeqNumbers.clear(); break; } default:; } break; } case RTCP::Type::RTPFB: { switch (dynamic_cast<RTCP::FeedbackRtpPacket*>(packet)->GetMessageType()) { case RTCP::FeedbackRtp::MessageType::NACK: { INFO("NACK required"); REQUIRE(this->shouldTriggerNack == true); this->shouldTriggerNack = false; auto* nackPacket = dynamic_cast<RTCP::FeedbackRtpNackPacket*>(packet); for (auto it = nackPacket->Begin(); it != nackPacket->End(); ++it) { RTCP::FeedbackRtpNackItem* item = *it; uint16_t firstSeq = item->GetPacketId(); uint16_t bitmask = item->GetLostPacketBitmask(); this->nackedSeqNumbers.push_back(firstSeq); for (size_t i{ 1 }; i < MaxRequestedPackets; ++i) { if ((bitmask & 1) != 0) this->nackedSeqNumbers.push_back(firstSeq + i); bitmask >>= 1; } } break; } default:; } break; } default:; } } void OnRtpStreamNeedWorstRemoteFractionLost( RTC::RtpStreamRecv* /*rtpStream*/, uint8_t& /*worstRemoteFractionLost*/) override { } public: bool shouldTriggerNack = false; bool shouldTriggerPLI = false; bool shouldTriggerFIR = false; std::vector<uint16_t> nackedSeqNumbers; }; // clang-format off uint8_t buffer[] = { 0b10000000, 0b00000001, 0, 1, 0, 0, 0, 4, 0, 0, 0, 5 }; // clang-format on RtpPacket* packet = RtpPacket::Parse(buffer, sizeof(buffer)); if (!packet) FAIL("not a RTP packet"); RtpStream::Params params; params.ssrc = packet->GetSsrc(); params.clockRate = 90000; params.useNack = true; params.usePli = true; params.useFir = false; SECTION("NACK one packet") { RtpStreamRecvListener listener; RtpStreamRecv rtpStream(&listener, params); packet->SetSequenceNumber(1); rtpStream.ReceivePacket(packet); packet->SetSequenceNumber(3); listener.shouldTriggerNack = true; listener.shouldTriggerPLI = false; listener.shouldTriggerFIR = false; rtpStream.ReceivePacket(packet); REQUIRE(listener.nackedSeqNumbers.size() == 1); REQUIRE(listener.nackedSeqNumbers[0] == 2); listener.nackedSeqNumbers.clear(); packet->SetSequenceNumber(2); rtpStream.ReceivePacket(packet); REQUIRE(listener.nackedSeqNumbers.size() == 0); packet->SetSequenceNumber(4); rtpStream.ReceivePacket(packet); REQUIRE(listener.nackedSeqNumbers.size() == 0); } SECTION("wrapping sequence numbers") { RtpStreamRecvListener listener; RtpStreamRecv rtpStream(&listener, params); packet->SetSequenceNumber(0xfffe); rtpStream.ReceivePacket(packet); packet->SetSequenceNumber(1); listener.shouldTriggerNack = true; listener.shouldTriggerPLI = false; listener.shouldTriggerFIR = false; rtpStream.ReceivePacket(packet); REQUIRE(listener.nackedSeqNumbers.size() == 2); REQUIRE(listener.nackedSeqNumbers[0] == 0xffff); REQUIRE(listener.nackedSeqNumbers[1] == 0); listener.nackedSeqNumbers.clear(); } SECTION("require key frame") { RtpStreamRecvListener listener; RtpStreamRecv rtpStream(&listener, params); packet->SetSequenceNumber(1); rtpStream.ReceivePacket(packet); // Seq different is bigger than MaxNackPackets in NackGenerator, so it // triggers a key frame. packet->SetSequenceNumber(1003); listener.shouldTriggerPLI = true; listener.shouldTriggerFIR = false; rtpStream.ReceivePacket(packet); } delete packet; }