#define MS_CLASS "RTC::RTP::SharedPacket"
#include "RTC/RTP/SharedPacket.hpp"
#include "Logger.hpp"
#include "RTC/Serializable.hpp"
#include <new>
namespace RTC
{
namespace RTP
{
static constexpr size_t PacketBufferLengthIncrement{ 100 };
static thread_local Serializable::BufferReleasedListener PacketBufferReleasedListener =
[](const Serializable* packet, uint8_t* buffer)
{
::operator delete[](buffer, std::align_val_t{ 4 });
#ifdef MS_DUMP_RTP_SHARED_PACKET_MEMORY_USAGE
SharedPacket::allocatedMemory -= packet->GetBufferLength();
MS_DUMP_CLEAN(
0,
"[worker.pid:%" PRIu64
"] [RTC::RTP::SharedPacket] memory deallocated [packet buffer:%zu, total allocated memory:%" PRIu64
"]",
Logger::Pid,
packet->GetBufferLength(),
SharedPacket::allocatedMemory);
#endif
};
#ifdef MS_DUMP_RTP_SHARED_PACKET_MEMORY_USAGE
thread_local uint64_t SharedPacket::allocatedMemory{ 0 };
#endif
SharedPacket::SharedPacket()
: sharedPtr(std::make_shared<std::unique_ptr<RTP::Packet>>(nullptr))
{
MS_TRACE();
}
SharedPacket::SharedPacket(RTP::Packet* packet)
: sharedPtr(std::make_shared<std::unique_ptr<RTP::Packet>>(nullptr))
{
MS_TRACE();
if (packet)
{
StorePacket(packet);
}
}
void SharedPacket::Dump(int indentation) const
{
MS_TRACE();
MS_DUMP_CLEAN(indentation, "<SharedPacket>");
MS_DUMP_CLEAN(indentation, " has packet: %s", HasPacket() ? "yes" : "no");
if (HasPacket())
{
const auto* packet = GetPacket();
packet->Dump(indentation + 1);
}
MS_DUMP_CLEAN(indentation, "</SharedPacket>");
}
void SharedPacket::Assign(RTP::Packet* packet)
{
MS_TRACE();
if (packet)
{
StorePacket(packet);
}
else
{
this->sharedPtr->reset(nullptr);
}
}
void SharedPacket::Reset()
{
MS_TRACE();
this->sharedPtr->reset(nullptr);
}
void SharedPacket::AssertSamePacket(const RTP::Packet* otherPacket) const
{
MS_TRACE();
const auto* packet = GetPacket();
if (!packet && !otherPacket)
{
return;
}
else if (packet && !otherPacket)
{
MS_ABORT("there is a packet in sharedPacket but given otherPacket doesn't have value");
}
else if (!packet && otherPacket)
{
MS_ABORT("there is no packet in sharedPacket but given otherPacket has value");
}
else
{
MS_ASSERT(
packet->GetSsrc() == otherPacket->GetSsrc(),
"SSRC %" PRIu32 " in packet in sharedPacket != SSRC %" PRIu32 " in otherPacket",
packet->GetSsrc(),
otherPacket->GetSsrc());
MS_ASSERT(
packet->GetSequenceNumber() == otherPacket->GetSequenceNumber(),
"seq %" PRIu16 " in packet in sharedPacket != seq %" PRIu16 " in otherPacket",
packet->GetSequenceNumber(),
otherPacket->GetSequenceNumber());
MS_ASSERT(
packet->GetTimestamp() == otherPacket->GetTimestamp(),
"timestamp %" PRIu16 " in packet in sharedPacket != timestamp %" PRIu16 " in otherPacket",
packet->GetTimestamp(),
otherPacket->GetTimestamp());
MS_ASSERT(
packet->GetLength() == otherPacket->GetLength(),
"length %zu of packet in sharedPacket != length %zu of otherPacket",
packet->GetLength(),
otherPacket->GetLength());
}
}
void SharedPacket::StorePacket(RTP::Packet* packet)
{
MS_TRACE();
const size_t bufferLength = packet->GetLength() + PacketBufferLengthIncrement;
auto* buffer = static_cast<uint8_t*>(::operator new[](bufferLength, std::align_val_t{ 4 }));
auto* clonedPacket = packet->Clone(buffer, bufferLength);
clonedPacket->SetBufferReleasedListener(std::addressof(PacketBufferReleasedListener));
this->sharedPtr->reset(clonedPacket);
#ifdef MS_DUMP_RTP_SHARED_PACKET_MEMORY_USAGE
SharedPacket::allocatedMemory += bufferLength;
MS_DUMP_CLEAN(
0,
"[worker.pid:%" PRIu64
"] [RTC::RTP::SharedPacket] memory allocated [packet buffer:%zu, total allocated memory:%" PRIu64
"]",
Logger::Pid,
clonedPacket->GetBufferLength(),
SharedPacket::allocatedMemory);
#endif
}
} }