#define MS_CLASS "RTC::RTCP::FeedbackRtp"
#include "RTC/RTCP/FeedbackRtp.hpp"
#include "Logger.hpp"
#include "RTC/RTCP/FeedbackRtpEcn.hpp"
#include "RTC/RTCP/FeedbackRtpNack.hpp"
#include "RTC/RTCP/FeedbackRtpTllei.hpp"
#include "RTC/RTCP/FeedbackRtpTmmb.hpp"
namespace RTC
{
namespace RTCP
{
template<typename Item>
FeedbackRtpItemsPacket<Item>* FeedbackRtpItemsPacket<Item>::Parse(const uint8_t* data, size_t len)
{
MS_TRACE();
if (len < Packet::CommonHeaderSize + FeedbackPacket::HeaderSize)
{
MS_WARN_TAG(rtcp, "not enough space for Feedback packet, discarded");
return nullptr;
}
auto* commonHeader = const_cast<CommonHeader*>(reinterpret_cast<const CommonHeader*>(data));
std::unique_ptr<FeedbackRtpItemsPacket<Item>> packet(
new FeedbackRtpItemsPacket<Item>(commonHeader));
size_t offset = Packet::CommonHeaderSize + FeedbackPacket::HeaderSize;
while (len > offset)
{
auto* item = FeedbackItem::Parse<Item>(data + offset, len - offset);
if (item)
{
packet->AddItem(item);
offset += item->GetSize();
}
else
{
break;
}
}
return packet.release();
}
template<typename Item>
size_t FeedbackRtpItemsPacket<Item>::Serialize(uint8_t* buffer)
{
MS_TRACE();
size_t offset = FeedbackPacket::Serialize(buffer);
for (auto* item : this->items)
{
offset += item->Serialize(buffer + offset);
}
return offset;
}
template<typename Item>
void FeedbackRtpItemsPacket<Item>::Dump(int indentation) const
{
MS_TRACE();
MS_DUMP_CLEAN(
indentation, "<%s>", FeedbackRtpPacket::MessageTypeToString(Item::MessageType).c_str());
FeedbackRtpPacket::Dump(indentation + 1);
for (auto* item : this->items)
{
item->Dump(indentation + 1);
}
MS_DUMP_CLEAN(
indentation, "</%s>", FeedbackRtpPacket::MessageTypeToString(Item::MessageType).c_str());
}
template class FeedbackRtpItemsPacket<FeedbackRtpNackItem>;
template class FeedbackRtpItemsPacket<FeedbackRtpTmmbrItem>;
template class FeedbackRtpItemsPacket<FeedbackRtpTmmbnItem>;
template class FeedbackRtpItemsPacket<FeedbackRtpTlleiItem>;
template class FeedbackRtpItemsPacket<FeedbackRtpEcnItem>;
} }