#define MS_CLASS "RTC::RTCP::FeedbackRtpTmmb"
#include "RTC/RTCP/FeedbackRtpTmmb.hpp"
#include "Logger.hpp"
#include "Utils.hpp"
#include <cstring>
namespace RTC
{
namespace RTCP
{
template<typename T>
FeedbackRtpTmmbItem<T>::FeedbackRtpTmmbItem(const Header* header)
: FeedbackRtpTmmbItem<T>(reinterpret_cast<const uint8_t*>(header))
{
}
template<typename T>
FeedbackRtpTmmbItem<T>::FeedbackRtpTmmbItem(const uint8_t* data)
{
this->ssrc = Utils::Byte::Get4Bytes(data, 0);
const uint32_t compact = Utils::Byte::Get4Bytes(data, 4);
const uint8_t exponent = compact >> 26; const uint64_t mantissa = (compact >> 9) & 0x1ffff;
this->overhead = compact & 0x1ff; this->bitrate = (mantissa << exponent);
if ((this->bitrate >> exponent) != mantissa)
{
MS_WARN_TAG(rtcp, "invalid TMMB bitrate value : %" PRIu64 " x 2^%" PRIu8, mantissa, exponent);
this->isCorrect = false;
}
}
template<typename T>
size_t FeedbackRtpTmmbItem<T>::Serialize(uint8_t* buffer)
{
static constexpr uint32_t MaxMantissa{ 0x1ffff };
uint64_t mantissa = this->bitrate;
uint32_t exponent{ 0 };
while (mantissa > MaxMantissa)
{
mantissa >>= 1;
++exponent;
}
Utils::Byte::Set4Bytes(buffer, 0, this->ssrc);
uint32_t compact = (exponent << 26) | (mantissa << 9) | this->overhead;
Utils::Byte::Set4Bytes(buffer, 4, compact);
return HeaderSize;
}
template<typename T>
void FeedbackRtpTmmbItem<T>::Dump() const
{
MS_TRACE();
MS_DUMP("<FeedbackRtpTmmbItem>");
MS_DUMP(" ssrc : %" PRIu32, this->GetSsrc());
MS_DUMP(" bitrate : %" PRIu64, this->GetBitrate());
MS_DUMP(" overhead : %" PRIu16, this->GetOverhead());
MS_DUMP("</FeedbackRtpTmmbItem>");
}
template<>
const FeedbackRtp::MessageType FeedbackRtpTmmbItem<FeedbackRtpTmmbr>::messageType =
FeedbackRtp::MessageType::TMMBR;
template<>
const FeedbackRtp::MessageType FeedbackRtpTmmbItem<FeedbackRtpTmmbn>::messageType =
FeedbackRtp::MessageType::TMMBN;
template class FeedbackRtpTmmbItem<FeedbackRtpTmmbr>;
template class FeedbackRtpTmmbItem<FeedbackRtpTmmbn>;
} }