|
@@ -1,5 +1,5 @@
|
|
/**
|
|
/**
|
|
- * Copyright (c) 2020 Staz M
|
|
|
|
|
|
+ * Copyright (c) 2020 Staz Modrzynski
|
|
* Copyright (c) 2020 Paul-Louis Ageneau
|
|
* Copyright (c) 2020 Paul-Louis Ageneau
|
|
*
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* This library is free software; you can redistribute it and/or
|
|
@@ -21,6 +21,7 @@
|
|
|
|
|
|
#include <cmath>
|
|
#include <cmath>
|
|
#include <utility>
|
|
#include <utility>
|
|
|
|
+#include "track.hpp"
|
|
|
|
|
|
#ifdef _WIN32
|
|
#ifdef _WIN32
|
|
#include <winsock2.h>
|
|
#include <winsock2.h>
|
|
@@ -28,310 +29,14 @@
|
|
#include <arpa/inet.h>
|
|
#include <arpa/inet.h>
|
|
#endif
|
|
#endif
|
|
|
|
|
|
-#ifndef htonll
|
|
|
|
-#define htonll(x) \
|
|
|
|
- ((uint64_t)htonl(((uint64_t)(x)&0xFFFFFFFF) << 32) | (uint64_t)htonl((uint64_t)(x) >> 32))
|
|
|
|
-#endif
|
|
|
|
-#ifndef ntohll
|
|
|
|
-#define ntohll(x) htonll(x)
|
|
|
|
-#endif
|
|
|
|
|
|
|
|
namespace rtc {
|
|
namespace rtc {
|
|
|
|
|
|
-#pragma pack(push, 1)
|
|
|
|
-
|
|
|
|
-struct RTP {
|
|
|
|
-private:
|
|
|
|
- uint8_t _first;
|
|
|
|
- uint8_t _payloadType;
|
|
|
|
- uint16_t _seqNumber;
|
|
|
|
- uint32_t _timestamp;
|
|
|
|
-
|
|
|
|
-public:
|
|
|
|
- SSRC ssrc;
|
|
|
|
- SSRC csrc[16];
|
|
|
|
-
|
|
|
|
- inline uint8_t version() const { return _first >> 6; }
|
|
|
|
- inline bool padding() const { return (_first >> 5) & 0x01; }
|
|
|
|
- inline uint8_t csrcCount() const { return _first & 0x0F; }
|
|
|
|
- inline uint8_t payloadType() const { return _payloadType; }
|
|
|
|
- inline uint16_t seqNumber() const { return ntohs(_seqNumber); }
|
|
|
|
- inline uint32_t timestamp() const { return ntohl(_timestamp); }
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-struct RTCP_ReportBlock {
|
|
|
|
- SSRC ssrc;
|
|
|
|
-
|
|
|
|
-private:
|
|
|
|
- uint32_t _fractionLostAndPacketsLost; // fraction lost is 8-bit, packets lost is 24-bit
|
|
|
|
- uint16_t _seqNoCycles;
|
|
|
|
- uint16_t _highestSeqNo;
|
|
|
|
- uint32_t _jitter;
|
|
|
|
- uint32_t _lastReport;
|
|
|
|
- uint32_t _delaySinceLastReport;
|
|
|
|
-
|
|
|
|
-public:
|
|
|
|
- inline void preparePacket(SSRC ssrc_, [[maybe_unused]] unsigned int packetsLost,
|
|
|
|
- [[maybe_unused]] unsigned int totalPackets, uint16_t highestSeqNo,
|
|
|
|
- uint16_t seqNoCycles, uint32_t jitter, uint64_t lastSR_NTP,
|
|
|
|
- uint64_t lastSR_DELAY) {
|
|
|
|
- setSeqNo(highestSeqNo, seqNoCycles);
|
|
|
|
- setJitter(jitter);
|
|
|
|
- setSSRC(ssrc_);
|
|
|
|
-
|
|
|
|
- // Middle 32 bits of NTP Timestamp
|
|
|
|
- // _lastReport = lastSR_NTP >> 16u;
|
|
|
|
- setNTPOfSR(uint32_t(lastSR_NTP));
|
|
|
|
- setDelaySinceSR(uint32_t(lastSR_DELAY));
|
|
|
|
-
|
|
|
|
- // The delay, expressed in units of 1/65536 seconds
|
|
|
|
- // _delaySinceLastReport = lastSR_DELAY;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- inline void setSSRC(SSRC ssrc_) { ssrc = htonl(ssrc_); }
|
|
|
|
- inline SSRC getSSRC() const { return ntohl(ssrc); }
|
|
|
|
-
|
|
|
|
- inline void setPacketsLost([[maybe_unused]] unsigned int packetsLost,
|
|
|
|
- [[maybe_unused]] unsigned int totalPackets) {
|
|
|
|
- // TODO Implement loss percentages.
|
|
|
|
- _fractionLostAndPacketsLost = 0;
|
|
|
|
- }
|
|
|
|
- inline unsigned int getLossPercentage() const {
|
|
|
|
- // TODO Implement loss percentages.
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
- inline unsigned int getPacketLostCount() const {
|
|
|
|
- // TODO Implement total packets lost.
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- inline uint16_t seqNoCycles() const { return ntohs(_seqNoCycles); }
|
|
|
|
- inline uint16_t highestSeqNo() const { return ntohs(_highestSeqNo); }
|
|
|
|
- inline uint32_t jitter() const { return ntohl(_jitter); }
|
|
|
|
-
|
|
|
|
- inline void setSeqNo(uint16_t highestSeqNo, uint16_t seqNoCycles) {
|
|
|
|
- _highestSeqNo = htons(highestSeqNo);
|
|
|
|
- _seqNoCycles = htons(seqNoCycles);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- inline void setJitter(uint32_t jitter) { _jitter = htonl(jitter); }
|
|
|
|
-
|
|
|
|
- inline void setNTPOfSR(uint32_t ntp) { _lastReport = htonl(ntp >> 16u); }
|
|
|
|
- inline uint32_t getNTPOfSR() const { return ntohl(_lastReport) << 16u; }
|
|
|
|
-
|
|
|
|
- inline void setDelaySinceSR(uint32_t sr) {
|
|
|
|
- // The delay, expressed in units of 1/65536 seconds
|
|
|
|
- _delaySinceLastReport = htonl(sr);
|
|
|
|
- }
|
|
|
|
- inline uint32_t getDelaySinceSR() const { return ntohl(_delaySinceLastReport); }
|
|
|
|
-
|
|
|
|
- inline void log() const {
|
|
|
|
- PLOG_DEBUG << "RTCP report block: "
|
|
|
|
- << "ssrc="
|
|
|
|
- << ntohl(ssrc)
|
|
|
|
- // TODO: Implement these reports
|
|
|
|
- // << ", fractionLost=" << fractionLost
|
|
|
|
- // << ", packetsLost=" << packetsLost
|
|
|
|
- << ", highestSeqNo=" << highestSeqNo() << ", seqNoCycles=" << seqNoCycles()
|
|
|
|
- << ", jitter=" << jitter() << ", lastSR=" << getNTPOfSR()
|
|
|
|
- << ", lastSRDelay=" << getDelaySinceSR();
|
|
|
|
- }
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-struct RTCP_HEADER {
|
|
|
|
-private:
|
|
|
|
- uint8_t _first;
|
|
|
|
- uint8_t _payloadType;
|
|
|
|
- uint16_t _length;
|
|
|
|
-
|
|
|
|
-public:
|
|
|
|
- inline uint8_t version() const { return _first >> 6; }
|
|
|
|
- inline bool padding() const { return (_first >> 5) & 0x01; }
|
|
|
|
- inline uint8_t reportCount() const { return _first & 0x0F; }
|
|
|
|
- inline uint8_t payloadType() const { return _payloadType; }
|
|
|
|
- inline uint16_t length() const { return ntohs(_length); }
|
|
|
|
-
|
|
|
|
- inline void setPayloadType(uint8_t type) { _payloadType = type; }
|
|
|
|
- inline void setReportCount(uint8_t count) { _first = (_first & 0xF0) | (count & 0x0F); }
|
|
|
|
- inline void setLength(uint16_t length) { _length = htons(length); }
|
|
|
|
-
|
|
|
|
- inline void prepareHeader(uint8_t payloadType, uint8_t reportCount, uint16_t length) {
|
|
|
|
- _first = 0x02 << 6; // version 2, no padding
|
|
|
|
- setReportCount(reportCount);
|
|
|
|
- setPayloadType(payloadType);
|
|
|
|
- setLength(length);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- inline void log() const {
|
|
|
|
- PLOG_DEBUG << "RTCP header: "
|
|
|
|
- << "version=" << unsigned(version()) << ", padding=" << padding()
|
|
|
|
- << ", reportCount=" << unsigned(reportCount())
|
|
|
|
- << ", payloadType=" << unsigned(payloadType()) << ", length=" << length();
|
|
|
|
- }
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-struct RTCP_SR {
|
|
|
|
- RTCP_HEADER header;
|
|
|
|
- SSRC senderSsrc;
|
|
|
|
-
|
|
|
|
-private:
|
|
|
|
- uint64_t _ntpTimestamp;
|
|
|
|
- uint32_t _rtpTimestamp;
|
|
|
|
- uint32_t _packetCount;
|
|
|
|
- uint32_t _octetCount;
|
|
|
|
-
|
|
|
|
- RTCP_ReportBlock _reportBlocks;
|
|
|
|
-
|
|
|
|
-public:
|
|
|
|
- inline void preparePacket(SSRC senderSsrc_, uint8_t reportCount) {
|
|
|
|
- unsigned int length =
|
|
|
|
- ((sizeof(header) + 24 + reportCount * sizeof(RTCP_ReportBlock)) / 4) - 1;
|
|
|
|
- header.prepareHeader(200, reportCount, uint16_t(length));
|
|
|
|
- senderSsrc = htonl(senderSsrc_);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- inline RTCP_ReportBlock *getReportBlock(int num) { return &_reportBlocks + num; }
|
|
|
|
- inline const RTCP_ReportBlock *getReportBlock(int num) const { return &_reportBlocks + num; }
|
|
|
|
-
|
|
|
|
- [[nodiscard]] inline size_t getSize() const {
|
|
|
|
- // "length" in packet is one less than the number of 32 bit words in the packet.
|
|
|
|
- return sizeof(uint32_t) * (1 + size_t(header.length()));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- inline uint32_t ntpTimestamp() const { return ntohll(_ntpTimestamp); }
|
|
|
|
- inline uint32_t rtpTimestamp() const { return ntohl(_rtpTimestamp); }
|
|
|
|
- inline uint32_t packetCount() const { return ntohl(_packetCount); }
|
|
|
|
- inline uint32_t octetCount() const { return ntohl(_octetCount); }
|
|
|
|
-
|
|
|
|
- inline void setNtpTimestamp(uint32_t ts) { _ntpTimestamp = htonll(ts); }
|
|
|
|
- inline void setRtpTimestamp(uint32_t ts) { _rtpTimestamp = htonl(ts); }
|
|
|
|
-
|
|
|
|
- inline void log() const {
|
|
|
|
- header.log();
|
|
|
|
- PLOG_DEBUG << "RTCP SR: "
|
|
|
|
- << " SSRC=" << ntohl(senderSsrc) << ", NTP_TS=" << ntpTimestamp()
|
|
|
|
- << ", RTP_TS=" << rtpTimestamp() << ", packetCount=" << packetCount()
|
|
|
|
- << ", octetCount=" << octetCount();
|
|
|
|
-
|
|
|
|
- for (unsigned i = 0; i < unsigned(header.reportCount()); i++) {
|
|
|
|
- getReportBlock(i)->log();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-struct RTCP_RR {
|
|
|
|
- RTCP_HEADER header;
|
|
|
|
- SSRC senderSsrc;
|
|
|
|
-
|
|
|
|
-private:
|
|
|
|
- RTCP_ReportBlock _reportBlocks;
|
|
|
|
-
|
|
|
|
-public:
|
|
|
|
- inline RTCP_ReportBlock *getReportBlock(int num) { return &_reportBlocks + num; }
|
|
|
|
- inline const RTCP_ReportBlock *getReportBlock(int num) const { return &_reportBlocks + num; }
|
|
|
|
-
|
|
|
|
- inline SSRC getSenderSSRC() const { return ntohl(senderSsrc); }
|
|
|
|
- inline void setSenderSSRC(SSRC ssrc) { senderSsrc = htonl(ssrc); }
|
|
|
|
-
|
|
|
|
- [[nodiscard]] inline size_t getSize() const {
|
|
|
|
- // "length" in packet is one less than the number of 32 bit words in the packet.
|
|
|
|
- return sizeof(uint32_t) * (1 + size_t(header.length()));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- inline void preparePacket(SSRC ssrc, uint8_t reportCount) {
|
|
|
|
- // "length" in packet is one less than the number of 32 bit words in the packet.
|
|
|
|
- size_t length = (sizeWithReportBlocks(reportCount) / 4) - 1;
|
|
|
|
- header.prepareHeader(201, reportCount, uint16_t(length));
|
|
|
|
- senderSsrc = htonl(ssrc);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- inline static size_t sizeWithReportBlocks(uint8_t reportCount) {
|
|
|
|
- return sizeof(header) + 4 + size_t(reportCount) * sizeof(RTCP_ReportBlock);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- inline void log() const {
|
|
|
|
- header.log();
|
|
|
|
- PLOG_DEBUG << "RTCP RR: "
|
|
|
|
- << " SSRC=" << ntohl(senderSsrc);
|
|
|
|
-
|
|
|
|
- for (unsigned i = 0; i < unsigned(header.reportCount()); i++) {
|
|
|
|
- getReportBlock(i)->log();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-struct RTCP_REMB {
|
|
|
|
- RTCP_HEADER header;
|
|
|
|
- SSRC senderSsrc;
|
|
|
|
- SSRC mediaSourceSSRC;
|
|
|
|
-
|
|
|
|
- // Unique identifier
|
|
|
|
- const char id[4] = {'R', 'E', 'M', 'B'};
|
|
|
|
-
|
|
|
|
- // Num SSRC, Br Exp, Br Mantissa (bit mask)
|
|
|
|
- uint32_t bitrate;
|
|
|
|
-
|
|
|
|
- SSRC ssrc[1];
|
|
|
|
-
|
|
|
|
- [[nodiscard]] inline size_t getSize() const {
|
|
|
|
- // "length" in packet is one less than the number of 32 bit words in the packet.
|
|
|
|
- return sizeof(uint32_t) * (1 + size_t(header.length()));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- inline void preparePacket(SSRC senderSsrc_, unsigned int numSSRC, unsigned int br) {
|
|
|
|
- // Report Count becomes the format here.
|
|
|
|
- header.prepareHeader(206, 15, 0);
|
|
|
|
-
|
|
|
|
- // Always zero.
|
|
|
|
- mediaSourceSSRC = 0;
|
|
|
|
-
|
|
|
|
- senderSsrc = htonl(senderSsrc_);
|
|
|
|
- setBitrate(numSSRC, br);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- inline void setBitrate(unsigned int numSSRC, unsigned int br) {
|
|
|
|
- unsigned int exp = 0;
|
|
|
|
- while (br > pow(2, 18) - 1) {
|
|
|
|
- exp++;
|
|
|
|
- br /= 2;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // "length" in packet is one less than the number of 32 bit words in the packet.
|
|
|
|
- header.setLength(uint16_t(((sizeof(header) + 4 * 2 + 4 + 4) / 4) - 1 + numSSRC));
|
|
|
|
-
|
|
|
|
- bitrate = htonl((numSSRC << (32u - 8u)) | (exp << (32u - 8u - 6u)) | br);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // TODO Make this work
|
|
|
|
- // uint64_t getBitrate() const{
|
|
|
|
- // uint32_t ntohed = ntohl(bitrate);
|
|
|
|
- // uint64_t bitrate = ntohed & (unsigned int)(pow(2, 18)-1);
|
|
|
|
- // unsigned int exp = ntohed & ((unsigned int)( (pow(2, 6)-1)) << (32u-8u-6u));
|
|
|
|
- // return bitrate * pow(2,exp);
|
|
|
|
- // }
|
|
|
|
- //
|
|
|
|
- // uint8_t getNumSSRCS() const {
|
|
|
|
- // return ntohl(bitrate) & (((unsigned int) pow(2,8)-1) << (32u-8u));
|
|
|
|
- // }
|
|
|
|
-
|
|
|
|
- inline void setSSRC(uint8_t iterator, SSRC ssrc_) { ssrc[iterator] = htonl(ssrc_); }
|
|
|
|
-
|
|
|
|
- inline void log() const {
|
|
|
|
- header.log();
|
|
|
|
- PLOG_DEBUG << "RTCP REMB: "
|
|
|
|
- << " SSRC=" << ntohl(senderSsrc);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- static unsigned int sizeWithSSRCs(int numSSRC) {
|
|
|
|
- return (sizeof(header) + 4 * 2 + 4 + 4) + sizeof(SSRC) * numSSRC;
|
|
|
|
- }
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-#pragma pack(pop)
|
|
|
|
-
|
|
|
|
-void RtcpSession::onOutgoing(std::function<void(rtc::message_ptr)> cb) { mTxCallback = cb; }
|
|
|
|
|
|
+rtc::message_ptr RtcpReceivingSession::outgoing(rtc::message_ptr ptr) {
|
|
|
|
+ return ptr;
|
|
|
|
+}
|
|
|
|
|
|
-std::optional<rtc::message_ptr> RtcpSession::incoming(rtc::message_ptr ptr) {
|
|
|
|
|
|
+rtc::message_ptr RtcpReceivingSession::incoming(rtc::message_ptr ptr) {
|
|
if (ptr->type == rtc::Message::Type::Binary) {
|
|
if (ptr->type == rtc::Message::Type::Binary) {
|
|
auto rtp = reinterpret_cast<const RTP *>(ptr->data());
|
|
auto rtp = reinterpret_cast<const RTP *>(ptr->data());
|
|
|
|
|
|
@@ -339,12 +44,12 @@ std::optional<rtc::message_ptr> RtcpSession::incoming(rtc::message_ptr ptr) {
|
|
if (rtp->version() != 2) {
|
|
if (rtp->version() != 2) {
|
|
PLOG_WARNING << "RTP packet is not version 2";
|
|
PLOG_WARNING << "RTP packet is not version 2";
|
|
|
|
|
|
- return std::nullopt;
|
|
|
|
|
|
+ return nullptr;
|
|
}
|
|
}
|
|
if (rtp->payloadType() == 201 || rtp->payloadType() == 200) {
|
|
if (rtp->payloadType() == 201 || rtp->payloadType() == 200) {
|
|
PLOG_WARNING << "RTP packet has a payload type indicating RR/SR";
|
|
PLOG_WARNING << "RTP packet has a payload type indicating RR/SR";
|
|
|
|
|
|
- return std::nullopt;
|
|
|
|
|
|
+ return nullptr;
|
|
}
|
|
}
|
|
|
|
|
|
// TODO Implement the padding bit
|
|
// TODO Implement the padding bit
|
|
@@ -352,13 +57,7 @@ std::optional<rtc::message_ptr> RtcpSession::incoming(rtc::message_ptr ptr) {
|
|
PLOG_WARNING << "Padding processing not implemented";
|
|
PLOG_WARNING << "Padding processing not implemented";
|
|
}
|
|
}
|
|
|
|
|
|
- mSsrc = ntohl(rtp->ssrc);
|
|
|
|
-
|
|
|
|
- uint32_t seqNo = rtp->seqNumber();
|
|
|
|
- // uint32_t rtpTS = rtp->getTS();
|
|
|
|
-
|
|
|
|
- if (mGreatestSeqNo < seqNo)
|
|
|
|
- mGreatestSeqNo = seqNo;
|
|
|
|
|
|
+ mSsrc = rtp->ssrc();
|
|
|
|
|
|
return ptr;
|
|
return ptr;
|
|
}
|
|
}
|
|
@@ -367,11 +66,11 @@ std::optional<rtc::message_ptr> RtcpSession::incoming(rtc::message_ptr ptr) {
|
|
auto rr = reinterpret_cast<const RTCP_RR *>(ptr->data());
|
|
auto rr = reinterpret_cast<const RTCP_RR *>(ptr->data());
|
|
if (rr->header.payloadType() == 201) {
|
|
if (rr->header.payloadType() == 201) {
|
|
// RR
|
|
// RR
|
|
- mSsrc = rr->getSenderSSRC();
|
|
|
|
|
|
+ mSsrc = rr->senderSSRC();
|
|
rr->log();
|
|
rr->log();
|
|
} else if (rr->header.payloadType() == 200) {
|
|
} else if (rr->header.payloadType() == 200) {
|
|
// SR
|
|
// SR
|
|
- mSsrc = rr->getSenderSSRC();
|
|
|
|
|
|
+ mSsrc = rr->senderSSRC();
|
|
auto sr = reinterpret_cast<const RTCP_SR *>(ptr->data());
|
|
auto sr = reinterpret_cast<const RTCP_SR *>(ptr->data());
|
|
mSyncRTPTS = sr->rtpTimestamp();
|
|
mSyncRTPTS = sr->rtpTimestamp();
|
|
mSyncNTPTS = sr->ntpTimestamp();
|
|
mSyncNTPTS = sr->ntpTimestamp();
|
|
@@ -382,28 +81,27 @@ std::optional<rtc::message_ptr> RtcpSession::incoming(rtc::message_ptr ptr) {
|
|
if (mRequestedBitrate > 0)
|
|
if (mRequestedBitrate > 0)
|
|
pushREMB(mRequestedBitrate);
|
|
pushREMB(mRequestedBitrate);
|
|
}
|
|
}
|
|
- return std::nullopt;
|
|
|
|
|
|
+ return nullptr;
|
|
}
|
|
}
|
|
|
|
|
|
-void RtcpSession::requestBitrate(unsigned int newBitrate) {
|
|
|
|
|
|
+void RtcpReceivingSession::requestBitrate(unsigned int newBitrate) {
|
|
mRequestedBitrate = newBitrate;
|
|
mRequestedBitrate = newBitrate;
|
|
|
|
|
|
PLOG_DEBUG << "[GOOG-REMB] Requesting bitrate: " << newBitrate << std::endl;
|
|
PLOG_DEBUG << "[GOOG-REMB] Requesting bitrate: " << newBitrate << std::endl;
|
|
pushREMB(newBitrate);
|
|
pushREMB(newBitrate);
|
|
}
|
|
}
|
|
|
|
|
|
-void RtcpSession::pushREMB(unsigned int bitrate) {
|
|
|
|
|
|
+void RtcpReceivingSession::pushREMB(unsigned int bitrate) {
|
|
rtc::message_ptr msg =
|
|
rtc::message_ptr msg =
|
|
rtc::make_message(RTCP_REMB::sizeWithSSRCs(1), rtc::Message::Type::Control);
|
|
rtc::make_message(RTCP_REMB::sizeWithSSRCs(1), rtc::Message::Type::Control);
|
|
auto remb = reinterpret_cast<RTCP_REMB *>(msg->data());
|
|
auto remb = reinterpret_cast<RTCP_REMB *>(msg->data());
|
|
remb->preparePacket(mSsrc, 1, bitrate);
|
|
remb->preparePacket(mSsrc, 1, bitrate);
|
|
- remb->setSSRC(0, mSsrc);
|
|
|
|
- remb->log();
|
|
|
|
|
|
+ remb->setSsrc(0, mSsrc);
|
|
|
|
|
|
- tx(msg);
|
|
|
|
|
|
+ send(msg);
|
|
}
|
|
}
|
|
|
|
|
|
-void RtcpSession::pushRR(unsigned int lastSR_delay) {
|
|
|
|
|
|
+void RtcpReceivingSession::pushRR(unsigned int lastSR_delay) {
|
|
auto msg = rtc::make_message(RTCP_RR::sizeWithReportBlocks(1), rtc::Message::Type::Control);
|
|
auto msg = rtc::make_message(RTCP_RR::sizeWithReportBlocks(1), rtc::Message::Type::Control);
|
|
auto rr = reinterpret_cast<RTCP_RR *>(msg->data());
|
|
auto rr = reinterpret_cast<RTCP_RR *>(msg->data());
|
|
rr->preparePacket(mSsrc, 1);
|
|
rr->preparePacket(mSsrc, 1);
|
|
@@ -411,16 +109,33 @@ void RtcpSession::pushRR(unsigned int lastSR_delay) {
|
|
lastSR_delay);
|
|
lastSR_delay);
|
|
rr->log();
|
|
rr->log();
|
|
|
|
|
|
- tx(msg);
|
|
|
|
|
|
+ send(msg);
|
|
}
|
|
}
|
|
|
|
|
|
-void RtcpSession::tx(message_ptr msg) {
|
|
|
|
|
|
+bool RtcpReceivingSession::send(message_ptr msg) {
|
|
try {
|
|
try {
|
|
- mTxCallback(msg);
|
|
|
|
|
|
+ outgoingCallback(std::move(msg));
|
|
|
|
+ return true;
|
|
} catch (const std::exception &e) {
|
|
} catch (const std::exception &e) {
|
|
LOG_DEBUG << "RTCP tx failed: " << e.what();
|
|
LOG_DEBUG << "RTCP tx failed: " << e.what();
|
|
}
|
|
}
|
|
|
|
+ return false;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+bool RtcpReceivingSession::requestKeyframe() {
|
|
|
|
+ pushPLI();
|
|
|
|
+ return true; // TODO Make this false when it is impossible (i.e. Opus).
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void RtcpReceivingSession::pushPLI() {
|
|
|
|
+ auto msg = rtc::make_message(rtc::RTCP_PLI::size(), rtc::Message::Type::Control);
|
|
|
|
+ auto *pli = (rtc::RTCP_PLI *) msg->data();
|
|
|
|
+ pli->preparePacket(mSsrc);
|
|
|
|
+ send(msg);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void RtcpHandler::onOutgoing(const std::function<void(rtc::message_ptr)>& cb) {
|
|
|
|
+ this->outgoingCallback = synchronized_callback<rtc::message_ptr>(cb);
|
|
|
|
+}
|
|
} // namespace rtc
|
|
} // namespace rtc
|
|
|
|
|