From 37bc343dd71fe16be698466f26829c12c369368c Mon Sep 17 00:00:00 2001 From: Juliusz Chroboczek Date: Tue, 16 Apr 2024 00:32:22 +0200 Subject: [PATCH] Add SetZeroAllocation SetZeroAllocation enables a higher performance depacketizer, with a reduced feature set. Currently only enabled for H264. By default, the H264Packet.Unmarshal performs reassembly of FU-A NALUs. Not only is this ineficient, it also assumes that no packet reordering or packet loss ever happens. --- codecs/common.go | 12 +++++++++++- codecs/h264_packet.go | 8 ++++++++ depacketizer.go | 4 ++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/codecs/common.go b/codecs/common.go index 5da8aaf6..e807a0ac 100644 --- a/codecs/common.go +++ b/codecs/common.go @@ -22,8 +22,18 @@ func (d *audioDepacketizer) IsPartitionHead(_ []byte) bool { } // videoDepacketizer is a mixin for video codec depacketizers -type videoDepacketizer struct{} +type videoDepacketizer struct { + zeroAllocation bool +} func (d *videoDepacketizer) IsPartitionTail(marker bool, _ []byte) bool { return marker } + +// SetZeroAllocation enables Zero Allocation mode for the depacketizer +// By default the Depacketizers will allocate as they parse. These allocations +// are needed for Metadata and other optional values. If you don't need this information +// enabling SetZeroAllocation gives you higher performance at a reduced feature set. +func (d *videoDepacketizer) SetZeroAllocation(zeroAllocation bool) { + d.zeroAllocation = zeroAllocation +} diff --git a/codecs/h264_packet.go b/codecs/h264_packet.go index 49c37da6..3021fc0f 100644 --- a/codecs/h264_packet.go +++ b/codecs/h264_packet.go @@ -208,6 +208,14 @@ func (p *H264Packet) IsDetectedFinalPacketInSequence(rtpPacketMarketBit bool) bo // Unmarshal parses the passed byte slice and stores the result in the H264Packet this method is called upon func (p *H264Packet) Unmarshal(payload []byte) ([]byte, error) { + if p.zeroAllocation { + return payload, nil + } + + return p.parseBody(payload) +} + +func (p *H264Packet) parseBody(payload []byte) ([]byte, error) { if len(payload) == 0 { return nil, fmt.Errorf("%w: %d <=0", errShortPacket, len(payload)) } diff --git a/depacketizer.go b/depacketizer.go index 0439a531..d10ad89b 100644 --- a/depacketizer.go +++ b/depacketizer.go @@ -5,11 +5,15 @@ package rtp // Depacketizer depacketizes a RTP payload, removing any RTP specific data from the payload type Depacketizer interface { + // Unmarshal parses the RTP payload and returns media. + // Metadata may be stored on the Depacketizer itself Unmarshal(packet []byte) ([]byte, error) + // Checks if the packet is at the beginning of a partition. This // should return false if the result could not be determined, in // which case the caller will detect timestamp discontinuities. IsPartitionHead(payload []byte) bool + // Checks if the packet is at the end of a partition. This should // return false if the result could not be determined. IsPartitionTail(marker bool, payload []byte) bool