Skip to content

Commit 7a5abea

Browse files
authored
Reduce Memory allocations (#1190)
* Reduce Memory allocations Reduce Memory allocations on H264 Sender HotPath by reusing byte[] and using ArrayPool<byte> * Keep SendH264Frame compatible * Fix NAL Parser * Keep Some old method signatures for compatibility Keep signatures in SrtpHandler and DtlsSrtpTransport. * Keep Some old method signatures for compatibility - Part 2 * reduce web stateupdates, no flickering in webrtc * Missing impl in SrtpTransformer.cs * Fix RTPPacket Constructor
1 parent f560fbc commit 7a5abea

14 files changed

+635
-259
lines changed

src/net/DtlsSrtp/DtlsSrtpTransport.cs

+68-19
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
//-----------------------------------------------------------------------------
1818

1919
using System;
20+
using System.Buffers;
2021
using System.Collections.Concurrent;
22+
using System.Linq;
2123
using Microsoft.Extensions.Logging;
2224
using Org.BouncyCastle.Crypto.Tls;
2325
using Org.BouncyCastle.Security;
@@ -398,27 +400,51 @@ public int UnprotectRTP(byte[] payload, int length, out int outLength)
398400
}
399401

400402
public byte[] ProtectRTP(byte[] packet, int offset, int length)
403+
{
404+
var buffer=ArrayPool<byte>.Shared.Rent(packet.Length * 2);
405+
try
406+
{
407+
var resultLength = ProtectRTP(packet, offset, length, buffer, packet.Length * 2);
408+
var segment=new ArraySegment<byte>(buffer, 0, resultLength);
409+
return segment.ToArray();
410+
}
411+
finally
412+
{
413+
ArrayPool<byte>.Shared.Return(buffer);
414+
}
415+
416+
}
417+
public int ProtectRTP(byte[] packet, int offset, int length,byte[] buffer,int bufferLength)
401418
{
402419
lock (this.srtpEncoder)
403420
{
404-
return this.srtpEncoder.Transform(packet, offset, length);
421+
return this.srtpEncoder.Transform(packet, offset, length,buffer,bufferLength);
405422
}
406423
}
407424

408425
public int ProtectRTP(byte[] payload, int length, out int outLength)
409426
{
410-
var result = ProtectRTP(payload, 0, length);
411-
412-
if (result == null)
427+
var resultBuf=ArrayPool<byte>.Shared.Rent(length * 2);
428+
try
413429
{
414-
outLength = 0;
415-
return -1;
416-
}
430+
var resultSize = ProtectRTP(payload, 0, length,resultBuf,length * 2);
417431

418-
System.Buffer.BlockCopy(result, 0, payload, 0, result.Length);
419-
outLength = result.Length;
432+
if (resultSize <1)
433+
{
434+
outLength = 0;
435+
return -1;
436+
}
420437

421-
return 0; //No Errors
438+
System.Buffer.BlockCopy(resultBuf, 0, payload, 0, resultSize);
439+
outLength = resultSize;
440+
441+
return 0; //No Errors
442+
}
443+
finally
444+
{
445+
ArrayPool<byte>.Shared.Return(resultBuf);
446+
}
447+
422448
}
423449

424450
public byte[] UnprotectRTCP(byte[] packet, int offset, int length)
@@ -445,26 +471,49 @@ public int UnprotectRTCP(byte[] payload, int length, out int outLength)
445471
}
446472

447473
public byte[] ProtectRTCP(byte[] packet, int offset, int length)
474+
{
475+
var buffer=ArrayPool<byte>.Shared.Rent(packet.Length * 2);
476+
try
477+
{
478+
var resultLength = ProtectRTCP(packet, offset, length, buffer, packet.Length * 2);
479+
var segment=new ArraySegment<byte>(buffer, 0, resultLength);
480+
return segment.ToArray();
481+
}
482+
finally
483+
{
484+
ArrayPool<byte>.Shared.Return(buffer);
485+
}
486+
}
487+
public int ProtectRTCP(byte[] packet, int offset, int length,byte[] buffer,int bufferLength)
448488
{
449489
lock (this.srtcpEncoder)
450490
{
451-
return this.srtcpEncoder.Transform(packet, offset, length);
491+
return this.srtcpEncoder.Transform(packet, offset, length,buffer,bufferLength);
452492
}
453493
}
454494

455495
public int ProtectRTCP(byte[] payload, int length, out int outLength)
456496
{
457-
var result = ProtectRTCP(payload, 0, length);
458-
if (result == null)
497+
var buff=ArrayPool<byte>.Shared.Rent(length * 2);
498+
try
459499
{
460-
outLength = 0;
461-
return -1;
462-
}
500+
var resultSize = ProtectRTCP(payload, 0, length,buff,length * 2);
501+
if (resultSize<0)
502+
{
503+
outLength = 0;
504+
return -1;
505+
}
463506

464-
System.Buffer.BlockCopy(result, 0, payload, 0, result.Length);
465-
outLength = result.Length;
507+
System.Buffer.BlockCopy(buff, 0, payload, 0, resultSize);
508+
outLength = resultSize;
466509

467-
return 0; //No Errors
510+
return 0; //No Errors
511+
}
512+
finally
513+
{
514+
ArrayPool<byte>.Shared.Return(buff);
515+
}
516+
468517
}
469518

470519
/// <summary>

src/net/DtlsSrtp/SrtpHandler.cs

+70-20
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
//-----------------------------------------------------------------------------
1515

1616
using System;
17+
using System.Buffers;
1718
using System.Collections.Generic;
1819
using System.Linq;
1920
using Microsoft.Extensions.Logging;
@@ -189,29 +190,53 @@ public int UnprotectRTP(byte[] payload, int length, out int outLength)
189190

190191
return 0; //No Errors
191192
}
192-
193+
193194
public byte[] ProtectRTP(byte[] packet, int offset, int length)
194195
{
195-
lock (SrtpEncoder)
196+
var buffer=ArrayPool<byte>.Shared.Rent(packet.Length * 2);
197+
try
198+
{
199+
var resultLength = ProtectRTP(packet, offset, length, buffer, packet.Length * 2);
200+
var segment=new ArraySegment<byte>(buffer, 0, resultLength);
201+
return segment.ToArray();
202+
}
203+
finally
196204
{
197-
return SrtpEncoder.Transform(packet, offset, length);
205+
ArrayPool<byte>.Shared.Return(buffer);
206+
}
207+
}
208+
209+
public int ProtectRTP(byte[] packet, int offset, int length,byte[] buffer,int bufferLength)
210+
{
211+
lock (this.SrtpEncoder)
212+
{
213+
return this.SrtpEncoder.Transform(packet, offset, length,buffer,bufferLength);
198214
}
199215
}
200216

201217
public int ProtectRTP(byte[] payload, int length, out int outLength)
202218
{
203-
var result = ProtectRTP(payload, 0, length);
219+
var resultBuf=ArrayPool<byte>.Shared.Rent(length * 2);
220+
try
221+
{
222+
var resultSize = ProtectRTP(payload, 0, length,resultBuf,length * 2);
204223

205-
if (result == null)
224+
if (resultSize <1)
225+
{
226+
outLength = 0;
227+
return -1;
228+
}
229+
230+
System.Buffer.BlockCopy(resultBuf, 0, payload, 0, resultSize);
231+
outLength = resultSize;
232+
233+
return 0; //No Errors
234+
}
235+
finally
206236
{
207-
outLength = 0;
208-
return -1;
237+
ArrayPool<byte>.Shared.Return(resultBuf);
209238
}
210239

211-
System.Buffer.BlockCopy(result, 0, payload, 0, result.Length);
212-
outLength = result.Length;
213-
214-
return 0; //No Errors
215240
}
216241

217242
public byte[] UnprotectRTCP(byte[] packet, int offset, int length)
@@ -238,26 +263,51 @@ public int UnprotectRTCP(byte[] payload, int length, out int outLength)
238263
}
239264

240265
public byte[] ProtectRTCP(byte[] packet, int offset, int length)
266+
{
267+
var buffer=ArrayPool<byte>.Shared.Rent(packet.Length * 2);
268+
try
269+
{
270+
var resultLength = ProtectRTCP(packet, offset, length, buffer, packet.Length * 2);
271+
var segment=new ArraySegment<byte>(buffer, 0, resultLength);
272+
return segment.ToArray();
273+
}
274+
finally
275+
{
276+
ArrayPool<byte>.Shared.Return(buffer);
277+
}
278+
}
279+
public int ProtectRTCP(byte[] packet, int offset, int length, byte[] buffer,int bufferLength)
241280
{
242281
lock (SrtcpEncoder)
243282
{
244-
return SrtcpEncoder.Transform(packet, offset, length);
283+
return SrtcpEncoder.Transform(packet, offset, length,buffer,bufferLength);
245284
}
246285
}
247286

248287
public int ProtectRTCP(byte[] payload, int length, out int outLength)
249288
{
250-
var result = ProtectRTCP(payload, 0, length);
251-
if (result == null)
289+
var resultBuf=ArrayPool<byte>.Shared.Rent(length * 2);
290+
try
252291
{
253-
outLength = 0;
254-
return -1;
255-
}
292+
var resultSize = ProtectRTCP(payload, 0, length,resultBuf,length * 2);
256293

257-
System.Buffer.BlockCopy(result, 0, payload, 0, result.Length);
258-
outLength = result.Length;
294+
if (resultSize <1)
295+
{
296+
outLength = 0;
297+
return -1;
298+
}
259299

260-
return 0; //No Errors
300+
System.Buffer.BlockCopy(resultBuf, 0, payload, 0, resultSize);
301+
outLength = resultSize;
302+
303+
return 0; //No Errors
304+
}
305+
finally
306+
{
307+
ArrayPool<byte>.Shared.Return(resultBuf);
308+
}
309+
310+
261311
}
262312
}
263313
}

src/net/DtlsSrtp/Transform/IPackerTransformer.cs

+21-18
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
1-
//-----------------------------------------------------------------------------
2-
// Filename: IPacketTransformer.cs
3-
//
1+
//-----------------------------------------------------------------------------
2+
// Filename: IPacketTransformer.cs
3+
//
44
// Description: Encapsulate the concept of packet transformation. Given a packet,
55
// PacketTransformer can either transform it or reverse the
6-
// transformation.
7-
//
8-
// Derived From:
9-
// https://github.com/RestComm/media-core/blob/master/rtp/src/main/java/org/restcomm/media/core/rtp/crypto/PacketTransformer.java
10-
//
11-
// Author(s):
12-
// Rafael Soares ([email protected])
13-
//
14-
// History:
15-
// 01 Jul 2020 Rafael Soares Created.
16-
//
17-
// License:
18-
// BSD 3-Clause "New" or "Revised" License, see included LICENSE.md file.
19-
// Original Source: AGPL-3.0 License
20-
//-----------------------------------------------------------------------------
6+
// transformation.
7+
//
8+
// Derived From:
9+
// https://github.com/RestComm/media-core/blob/master/rtp/src/main/java/org/restcomm/media/core/rtp/crypto/PacketTransformer.java
10+
//
11+
// Author(s):
12+
// Rafael Soares ([email protected])
13+
//
14+
// History:
15+
// 01 Jul 2020 Rafael Soares Created.
16+
//
17+
// License:
18+
// BSD 3-Clause "New" or "Revised" License, see included LICENSE.md file.
19+
// Original Source: AGPL-3.0 License
20+
//-----------------------------------------------------------------------------
2121

2222
namespace SIPSorcery.Net
2323
{
@@ -31,6 +31,7 @@ public interface IPacketTransformer
3131
* @return The transformed packet. Returns null if the packet cannot be transformed.
3232
*/
3333
byte[] Transform(byte[] pkt);
34+
int Transform(byte[] pkt,byte[] resultBuffer,int resultBufferLength);
3435

3536
/**
3637
* Transforms a specific non-secure packet.
@@ -44,7 +45,9 @@ public interface IPacketTransformer
4445
* @return The transformed packet. Returns null if the packet cannot be
4546
* transformed.
4647
*/
48+
4749
byte[] Transform(byte[] pkt, int offset, int length);
50+
int Transform(byte[] pkt, int offset, int length,byte[] resultBuffer,int resultBufferLength);
4851

4952
/**
5053
* Reverse-transforms a specific packet (i.e. transforms a transformed

0 commit comments

Comments
 (0)