![]() 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 : /usr/local/lib/node_modules/mediasoup/worker/include/RTC/RTCP/ |
Upload File : |
#ifndef MS_RTC_RTCP_FEEDBACK_RTP_TRANSPORT_HPP #define MS_RTC_RTCP_FEEDBACK_RTP_TRANSPORT_HPP #include "common.hpp" #include "RTC/RTCP/FeedbackRtp.hpp" #include <vector> /* RTP Extensions for Transport-wide Congestion Control * draft-holmer-rmcat-transport-wide-cc-extensions-01 0 1 2 3 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |V=2|P| FMT=15 | PT=205 | length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | SSRC of packet sender | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | SSRC of media source | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | base sequence number | packet status count | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | reference time | fb pkt. count | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | packet chunk | packet chunk | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ . . . . +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | packet chunk | recv delta | recv delta | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ . . . . +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | recv delta | recv delta | zero padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ namespace RTC { namespace RTCP { class FeedbackRtpTransportPacket : public FeedbackRtpPacket { public: struct PacketResult { PacketResult(uint16_t sequenceNumber, bool received) : sequenceNumber(sequenceNumber), received(received) { } uint16_t sequenceNumber; // Wide sequence number. int16_t delta{ 0 }; // Delta. bool received{ false }; // Packet received or not. int64_t receivedAtMs{ 0 }; // Received time (ms) in remote timestamp reference. }; public: enum class AddPacketResult { SUCCESS = 0, MAX_SIZE_EXCEEDED = 1, FATAL }; private: enum Status : uint8_t { NotReceived = 0, SmallDelta, LargeDelta, Reserved, None }; private: struct Context { bool allSameStatus{ true }; Status currentStatus{ Status::None }; std::vector<Status> statuses; }; private: class Chunk { public: static Chunk* Parse(const uint8_t* data, size_t len, uint16_t count); public: Chunk() = default; virtual ~Chunk() = default; virtual bool AddDeltas( const uint8_t* data, size_t len, std::vector<int16_t>& deltas, size_t& offset) = 0; virtual void Dump() const = 0; virtual uint16_t GetCount() const = 0; virtual uint16_t GetReceivedStatusCount() const = 0; virtual void FillResults( std::vector<struct PacketResult>& packetResults, uint16_t& currentSequenceNumber) const = 0; virtual size_t Serialize(uint8_t* buffer) = 0; }; private: class RunLengthChunk : public Chunk { public: RunLengthChunk(Status status, uint16_t count) : status(status), count(count) { } explicit RunLengthChunk(uint16_t buffer); public: bool AddDeltas( const uint8_t* data, size_t len, std::vector<int16_t>& deltas, size_t& offset) override; Status GetStatus() const { return this->status; } void Dump() const override; uint16_t GetCount() const override { return this->count; } uint16_t GetReceivedStatusCount() const override; void FillResults( std::vector<struct PacketResult>& packetResults, uint16_t& currentSequenceNumber) const override; size_t Serialize(uint8_t* buffer) override; private: Status status{ Status::None }; uint16_t count{ 0u }; }; private: class OneBitVectorChunk : public Chunk { public: explicit OneBitVectorChunk(const std::vector<Status>& statuses) : statuses(statuses) { } OneBitVectorChunk(uint16_t buffer, uint16_t count); public: bool AddDeltas( const uint8_t* data, size_t len, std::vector<int16_t>& deltas, size_t& offset) override; void Dump() const override; uint16_t GetCount() const override { return this->statuses.size(); } uint16_t GetReceivedStatusCount() const override; void FillResults( std::vector<struct PacketResult>& packetResults, uint16_t& currentSequenceNumber) const override; size_t Serialize(uint8_t* buffer) override; private: std::vector<Status> statuses; }; private: class TwoBitVectorChunk : public Chunk { public: explicit TwoBitVectorChunk(const std::vector<Status>& statuses) : statuses(statuses) { } TwoBitVectorChunk(uint16_t buffer, uint16_t count); public: bool AddDeltas( const uint8_t* data, size_t len, std::vector<int16_t>& deltas, size_t& offset) override; void Dump() const override; uint16_t GetCount() const override { return this->statuses.size(); } uint16_t GetReceivedStatusCount() const override; void FillResults( std::vector<struct PacketResult>& packetResults, uint16_t& currentSequenceNumber) const override; size_t Serialize(uint8_t* buffer) override; private: std::vector<Status> statuses; }; public: static size_t fixedHeaderSize; static uint16_t maxMissingPackets; static uint16_t maxPacketStatusCount; static int16_t maxPacketDelta; public: static FeedbackRtpTransportPacket* Parse(const uint8_t* data, size_t len); private: static std::map<Status, std::string> status2String; public: FeedbackRtpTransportPacket(uint32_t senderSsrc, uint32_t mediaSsrc) : FeedbackRtpPacket(RTC::RTCP::FeedbackRtp::MessageType::TCC, senderSsrc, mediaSsrc) { } FeedbackRtpTransportPacket(CommonHeader* commonHeader, size_t availableLen); ~FeedbackRtpTransportPacket(); public: AddPacketResult AddPacket(uint16_t sequenceNumber, uint64_t timestamp, size_t maxRtcpPacketLen); void Finish(); // Just for locally generated packets. bool IsFull() { // NOTE: Since AddPendingChunks() is called at the end, we cannot track // the exact ongoing value of packetStatusCount. Hence, let's reserve 7 // packets just in case. return this->packetStatusCount >= FeedbackRtpTransportPacket::maxPacketStatusCount - 7; } bool IsSerializable() const { return this->deltas.size() > 0; } bool IsCorrect() const // Just for locally generated packets. { return this->isCorrect; } uint16_t GetBaseSequenceNumber() const { return this->baseSequenceNumber; } uint16_t GetPacketStatusCount() const { return this->packetStatusCount; } int32_t GetReferenceTime() const { return this->referenceTime; } int64_t GetReferenceTimestamp() const // Reference time in ms. { return static_cast<int64_t>(this->referenceTime) * 64; } uint8_t GetFeedbackPacketCount() const { return this->feedbackPacketCount; } void SetFeedbackPacketCount(uint8_t count) { this->feedbackPacketCount = count; } uint16_t GetLatestSequenceNumber() const // Just for locally generated packets. { return this->latestSequenceNumber; } uint64_t GetLatestTimestamp() const // Just for locally generated packets. { return this->latestTimestamp; } std::vector<struct PacketResult> GetPacketResults() const; uint8_t GetPacketFractionLost() const; /* Pure virtual methods inherited from Packet. */ public: void Dump() const override; size_t Serialize(uint8_t* buffer) override; size_t GetSize() const override { if (this->size) return this->size; // Fixed packet size. size_t size = FeedbackRtpPacket::GetSize(); size += FeedbackRtpTransportPacket::fixedHeaderSize; size += this->deltasAndChunksSize; // 32 bits padding. size += (-size) & 3; return size; } private: void FillChunk(uint16_t previousSequenceNumber, uint16_t sequenceNumber, int16_t delta); void CreateRunLengthChunk(Status status, uint16_t count); void CreateOneBitVectorChunk(std::vector<Status>& statuses); void CreateTwoBitVectorChunk(std::vector<Status>& statuses); void AddPendingChunks(); private: uint16_t baseSequenceNumber{ 0u }; int32_t referenceTime{ 0 }; uint16_t latestSequenceNumber{ 0u }; // Just for locally generated packets. uint64_t latestTimestamp{ 0u }; // Just for locally generated packets. uint16_t packetStatusCount{ 0u }; uint8_t feedbackPacketCount{ 0u }; std::vector<Chunk*> chunks; std::vector<int16_t> deltas; Context context; // Just for locally generated packets. size_t deltasAndChunksSize{ 0u }; size_t size{ 0 }; bool isCorrect{ true }; }; } // namespace RTCP } // namespace RTC #endif