Skip to content

Improve buffer allocation for RTP Packets #1694

@ibc

Description

@ibc

In RTP/SharedPacket.cpp we do:

/* Static. */

// When cloning a RTP packet, a buffer is allocated for it and its length is
// the length of the Packet plus this value (in bytes).
static constexpr size_t PacketBufferLengthIncrement{ 100 };
// Callback to pass to every cloned RTP Packet to deallocate its buffer once
// the Packet releases its buffer (for example when the Packet is destroyed).
static thread_local Serializable::BufferReleasedListener PacketBufferReleasedListener =
  [](const Serializable* packet, uint8_t* buffer)
{
	delete[] buffer;

#ifdef MS_DUMP_RTP_SHARED_PACKET_MEMORY_USAGE
	SharedPacket::allocatedMemory -= packet->GetBufferLength();

	MS_DUMP_CLEAN(
	  0,
	  "[RTC::RTP::SharedPacket] memory deallocated [packet buffer:%zu, total allocated memory:%" PRIu64
	  "]",
	  packet->GetBufferLength(),
	  SharedPacket::allocatedMemory);
#endif
};

void SharedPacket::StorePacket(RTC::RTP::Packet* packet)
{
	MS_TRACE();

	const size_t bufferLength = packet->GetLength() + PacketBufferLengthIncrement;
	auto* buffer              = new uint8_t[bufferLength];
	auto* clonedPacket        = packet->Clone(buffer, bufferLength);

	// Set a listener in the Packet to deallocate its buffer once the Packet
	// is destroyed or releases its internal buffer.
	clonedPacket->SetBufferReleasedListener(std::addressof(PacketBufferReleasedListener));

	this->sharedPtr->reset(clonedPacket);

#ifdef MS_DUMP_RTP_SHARED_PACKET_MEMORY_USAGE
	SharedPacket::allocatedMemory += bufferLength;

	MS_DUMP_CLEAN(
	  0,
	  "[RTC::RTP::SharedPacket] memory allocated [packet buffer:%zu, total allocated memory:%" PRIu64
	  "]",
	  clonedPacket->GetBufferLength(),
	  SharedPacket::allocatedMemory);
#endif
}

This means that for each received RTP packet we are allocating a buffer of bufferLength = packet->GetLength() + 100 bytes.

While nothing is wrong here, we could make it better by having a pre-allocated big buffer in which we could use free regions of it to clone packets. It would be more efficient than calling new uint8_t[bufferLength] for each packet.

Of course, any allocator mechanism consists on having chunks of fixed size (aligned to 8 bytes for efficiency). This means that we should decide a max valid length of RTP packet and should discard those received packets that are bigger than that, but that shouldn't be a problem.

Existing stuff

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions