#define MS_CLASS "RTC::RTCP::XrDelaySinceLastRr"
#include "RTC/RTCP/XrDelaySinceLastRr.hpp"
#include "Logger.hpp"
#include <cstring>
namespace RTC
{
namespace RTCP
{
DelaySinceLastRr::SsrcInfo* DelaySinceLastRr::SsrcInfo::Parse(const uint8_t* data, size_t len)
{
MS_TRACE();
if (len < BodySize)
{
MS_WARN_TAG(rtcp, "not enough space for a extended DSLR sub-block, sub-block discarded");
return nullptr;
}
auto* body = const_cast<SsrcInfo::Body*>(reinterpret_cast<const SsrcInfo::Body*>(data));
auto* ssrcInfo = new DelaySinceLastRr::SsrcInfo(body);
return ssrcInfo;
}
void DelaySinceLastRr::SsrcInfo::Dump(int indentation) const
{
MS_TRACE();
MS_DUMP_CLEAN(indentation, "<SsrcInfo>");
MS_DUMP_CLEAN(indentation, " ssrc: %" PRIu32, GetSsrc());
MS_DUMP_CLEAN(indentation, " lrr: %" PRIu32, GetLastReceiverReport());
MS_DUMP_CLEAN(indentation, " dlrr: %" PRIu32, GetDelaySinceLastReceiverReport());
MS_DUMP_CLEAN(indentation, "<SsrcInfo>");
}
size_t DelaySinceLastRr::SsrcInfo::Serialize(uint8_t* buffer)
{
MS_TRACE();
std::memcpy(buffer, this->body, DelaySinceLastRr::SsrcInfo::BodySize);
return DelaySinceLastRr::SsrcInfo::BodySize;
}
DelaySinceLastRr* DelaySinceLastRr::Parse(const uint8_t* data, size_t len)
{
MS_TRACE();
auto* header = const_cast<ExtendedReportBlock::CommonHeader*>(
reinterpret_cast<const ExtendedReportBlock::CommonHeader*>(data));
std::unique_ptr<DelaySinceLastRr> report(new DelaySinceLastRr(header));
size_t offset{ ExtendedReportBlock::CommonHeaderSize };
uint16_t reportLength = ntohs(header->length) * 4;
while (len > offset && reportLength >= DelaySinceLastRr::SsrcInfo::BodySize)
{
DelaySinceLastRr::SsrcInfo* ssrcInfo =
DelaySinceLastRr::SsrcInfo::Parse(data + offset, len - offset);
if (ssrcInfo)
{
report->AddSsrcInfo(ssrcInfo);
offset += ssrcInfo->GetSize();
reportLength -= ssrcInfo->GetSize();
}
else
{
return report.release();
}
}
return report.release();
}
size_t DelaySinceLastRr::Serialize(uint8_t* buffer)
{
MS_TRACE();
const size_t length = static_cast<uint16_t>((SsrcInfo::BodySize * this->ssrcInfos.size() / 4));
this->header->blockType = static_cast<uint8_t>(this->type);
this->header->reserved = 0;
this->header->length = htons(length);
std::memcpy(buffer, this->header, ExtendedReportBlock::CommonHeaderSize);
size_t offset{ ExtendedReportBlock::CommonHeaderSize };
for (auto* ssrcInfo : this->ssrcInfos)
{
offset += ssrcInfo->Serialize(buffer + offset);
}
return offset;
}
void DelaySinceLastRr::Dump(int indentation) const
{
MS_TRACE();
MS_DUMP_CLEAN(indentation, "<DelaySinceLastRr>");
MS_DUMP_CLEAN(indentation, " block type: %" PRIu8, (uint8_t)this->type);
MS_DUMP_CLEAN(indentation, " reserved: 0");
MS_DUMP_CLEAN(
indentation,
" length: %" PRIu16,
static_cast<uint16_t>((SsrcInfo::BodySize * this->ssrcInfos.size() / 4)));
for (auto* ssrcInfo : this->ssrcInfos)
{
ssrcInfo->Dump(indentation + 1);
}
MS_DUMP_CLEAN(indentation, "</DelaySinceLastRr>");
}
} }