#if RTC_ENABLE_MEDIA
#include "rtcpreceivingsession.hpp"
#include "logcounter.hpp"
#include "track.hpp"
#include <cmath>
#include <utility>
#ifdef _WIN32
#include <winsock2.h>
#else
#include <arpa/inet.h>
#endif
namespace rtc {
static LogCounter COUNTER_BAD_RTP_HEADER(plog::warning, "Number of malformed RTP headers");
static LogCounter COUNTER_UNKNOWN_PPID(plog::warning, "Number of Unknown PPID messages");
static LogCounter COUNTER_BAD_NOTIF_LEN(plog::warning, "Number of Bad-Lengthed notifications");
static LogCounter COUNTER_BAD_SCTP_STATUS(plog::warning, "Number of unknown SCTP_STATUS errors");
message_ptr RtcpReceivingSession::outgoing(message_ptr ptr) { return ptr; }
message_ptr RtcpReceivingSession::incoming(message_ptr ptr) {
if (ptr->type == Message::Type::Binary) {
auto rtp = reinterpret_cast<const RTP *>(ptr->data());
if (rtp->version() != 2) {
COUNTER_BAD_RTP_HEADER++;
PLOG_VERBOSE << "RTP packet is not version 2";
return nullptr;
}
if (rtp->payloadType() == 201 || rtp->payloadType() == 200) {
COUNTER_BAD_RTP_HEADER++;
PLOG_VERBOSE << "RTP packet has a payload type indicating RR/SR";
return nullptr;
}
mSsrc = rtp->ssrc();
return ptr;
}
assert(ptr->type == Message::Type::Control);
auto rr = reinterpret_cast<const RTCP_RR *>(ptr->data());
if (rr->header.payloadType() == 201) {
mSsrc = rr->senderSSRC();
rr->log();
} else if (rr->header.payloadType() == 200) {
mSsrc = rr->senderSSRC();
auto sr = reinterpret_cast<const RTCP_SR *>(ptr->data());
mSyncRTPTS = sr->rtpTimestamp();
mSyncNTPTS = sr->ntpTimestamp();
sr->log();
pushRR(0);
if (mRequestedBitrate > 0)
pushREMB(mRequestedBitrate);
}
return nullptr;
}
void RtcpReceivingSession::requestBitrate(unsigned int newBitrate) {
mRequestedBitrate = newBitrate;
PLOG_DEBUG << "[GOOG-REMB] Requesting bitrate: " << newBitrate << std::endl;
pushREMB(newBitrate);
}
void RtcpReceivingSession::pushREMB(unsigned int bitrate) {
message_ptr msg = make_message(RTCP_REMB::sizeWithSSRCs(1), Message::Type::Control);
auto remb = reinterpret_cast<RTCP_REMB *>(msg->data());
remb->preparePacket(mSsrc, 1, bitrate);
remb->setSsrc(0, mSsrc);
send(msg);
}
void RtcpReceivingSession::pushRR(unsigned int lastSR_delay) {
auto msg = make_message(RTCP_RR::sizeWithReportBlocks(1), Message::Type::Control);
auto rr = reinterpret_cast<RTCP_RR *>(msg->data());
rr->preparePacket(mSsrc, 1);
rr->getReportBlock(0)->preparePacket(mSsrc, 0, 0, uint16_t(mGreatestSeqNo), 0, 0, mSyncNTPTS,
lastSR_delay);
rr->log();
send(msg);
}
bool RtcpReceivingSession::send(message_ptr msg) {
try {
outgoingCallback(std::move(msg));
return true;
} catch (const std::exception &e) {
LOG_DEBUG << "RTCP tx failed: " << e.what();
}
return false;
}
bool RtcpReceivingSession::requestKeyframe() {
pushPLI();
return true; }
void RtcpReceivingSession::pushPLI() {
auto msg = make_message(RTCP_PLI::size(), Message::Type::Control);
auto *pli = reinterpret_cast<RTCP_PLI *>(msg->data());
pli->preparePacket(mSsrc);
send(msg);
}
}
#endif