Skip to content

Commit 0337b9c

Browse files
committed
B Fixed the same SSRC being used by multiple tracks #23
1 parent 6228fc3 commit 0337b9c

File tree

5 files changed

+59
-21
lines changed

5 files changed

+59
-21
lines changed

src/Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<Nullable>disable</Nullable>
66
<ImplicitUsings>disable</ImplicitUsings>
77
<Title>$(ProjectName)</Title>
8-
<Version>0.4.1</Version>
8+
<Version>0.4.2</Version>
99
<Authors>Lukas Volf</Authors>
1010
<Copyright>MIT</Copyright>
1111
<PackageProjectUrl>https://github.com/jimm98y/SharpRealTimeStreaming</PackageProjectUrl>

src/SharpRTSPServer/ITrack.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ namespace SharpRTSPServer
77
{
88
public interface ITrack
99
{
10+
uint SSRC { get; set; }
11+
1012
IRtpSender Sink { get; set; }
1113

1214
string StreamID { get; set; }

src/SharpRTSPServer/RTSPServer.cs

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,6 @@ public class RTSPServer : IRtpSender, IDisposable
4040

4141
private static readonly Random _rand = new Random();
4242

43-
/// <summary>
44-
/// SSRC.
45-
/// </summary>
46-
public uint SSRC { get; set; } = (uint)_rand.Next(0, int.MaxValue); // 8 hex digits
47-
4843
/// <summary>
4944
/// Session name.
5045
/// </summary>
@@ -116,7 +111,7 @@ public RTSPServer(int portNumber, string userName, string password, bool useHttp
116111
{
117112
const string realm = "SharpRTSPServer";
118113
_credentials = new NetworkCredential(userName, password);
119-
_authentication = new AuthenticationDigest(_credentials, realm, new Random().Next(100000000, 999999999).ToString(), string.Empty);
114+
_authentication = new AuthenticationDigest(_credentials, realm, _rand.Next(100000000, 999999999).ToString(), string.Empty);
120115
}
121116
else
122117
{
@@ -173,8 +168,7 @@ private async Task AcceptConnection(CancellationToken cancellationToken)
173168
{
174169
RTSPConnection newConnection = new RTSPConnection()
175170
{
176-
Listener = newListener,
177-
SSRC = SSRC,
171+
Listener = newListener
178172
};
179173
_connectionList.Add(newConnection);
180174
}
@@ -367,6 +361,34 @@ private void HandleSetup(RtspListener listener, RtspRequestSetup setupMessage)
367361
RtspTransport transportReply = null;
368362
IRtpTransport rtpTransport = null;
369363

364+
RTSPStreamSource streamSource = GetStreamSource(setupMessage.RtspUri);
365+
if (streamSource == null)
366+
{
367+
// track not found
368+
RtspResponse setupResponse = setupMessage.CreateResponse();
369+
setupResponse.ReturnCode = 404;
370+
listener.SendMessage(setupResponse);
371+
return;
372+
}
373+
374+
uint trackSSRC;
375+
if (streamSource.VideoTrack != null && setupMessage.RtspUri.AbsolutePath.EndsWith($"trackID={streamSource.VideoTrack.ID}"))
376+
{
377+
trackSSRC = streamSource.VideoTrack.SSRC;
378+
}
379+
else if (streamSource.AudioTrack != null && setupMessage.RtspUri.AbsolutePath.EndsWith($"trackID={streamSource.AudioTrack.ID}"))
380+
{
381+
trackSSRC = streamSource.AudioTrack.SSRC;
382+
}
383+
else
384+
{
385+
// track not found
386+
RtspResponse setupResponse = setupMessage.CreateResponse();
387+
setupResponse.ReturnCode = 404;
388+
listener.SendMessage(setupResponse);
389+
return;
390+
}
391+
370392
if (transport.LowerTransport == RtspTransport.LowerTransportType.TCP)
371393
{
372394
Debug.Assert(transport.Interleaved != null, "If transport.Interleaved is null here the program did not handle well connection problem");
@@ -378,7 +400,7 @@ private void HandleSetup(RtspListener listener, RtspRequestSetup setupMessage)
378400
// RTP over RTSP mode
379401
transportReply = new RtspTransport()
380402
{
381-
SSrc = SSRC.ToString("X8"), // Convert to Hex, padded to 8 characters
403+
SSrc = trackSSRC.ToString("X8"), // Convert to Hex, padded to 8 characters,
382404
LowerTransport = RtspTransport.LowerTransportType.TCP,
383405
Interleaved = new PortCouple(transport.Interleaved.First, transport.Interleaved.Second)
384406
};
@@ -405,7 +427,7 @@ private void HandleSetup(RtspListener listener, RtspRequestSetup setupMessage)
405427
// Pass the Port of the two sockets back in the reply
406428
transportReply = new RtspTransport()
407429
{
408-
SSrc = SSRC.ToString("X8"), // Convert to Hex, padded to 8 characters
430+
SSrc = trackSSRC.ToString("X8"), // Convert to Hex, padded to 8 characters,
409431
LowerTransport = RtspTransport.LowerTransportType.UDP,
410432
IsMulticast = false,
411433
ServerPort = new PortCouple(udpPair.DataPort, udpPair.ControlPort),
@@ -421,7 +443,7 @@ private void HandleSetup(RtspListener listener, RtspRequestSetup setupMessage)
421443
// Pass the Ports of the two sockets back in the reply
422444
transportReply = new RtspTransport()
423445
{
424-
SSrc = SSRC.ToString("X8"), // Convert to Hex, padded to 8 characters
446+
SSrc = trackSSRC.ToString("X8"), // Convert to Hex, padded to 8 characters,
425447
LowerTransport = RtspTransport.LowerTransportType.UDP,
426448
IsMulticast = true,
427449
Port = new PortCouple(7000, 7001) // FIX
@@ -436,6 +458,7 @@ private void HandleSetup(RtspListener listener, RtspRequestSetup setupMessage)
436458
// Update the stream within the session with transport information
437459
// If a Session ID is passed in we should match SessionID with other SessionIDs but we can match on RemoteAddress
438460
string copyOfSessionId = "";
461+
439462
lock (_connectionList)
440463
{
441464
foreach (var setupConnection in _connectionList.Where(connection => connection.Listener.RemoteEndPoint.Address == listener.RemoteEndPoint.Address))
@@ -444,13 +467,21 @@ private void HandleSetup(RtspListener listener, RtspRequestSetup setupMessage)
444467
// or a SETUP for an Audio Stream.
445468
// In the SDP the H264/H265 video track is TrackID 0
446469
// and the Audio Track is TrackID 1
447-
var streamSource = GetStreamSource(setupMessage.RtspUri);
448-
RTPStream stream;
449-
if (setupMessage.RtspUri.AbsolutePath.EndsWith($"trackID={streamSource.VideoTrack?.ID}")) stream = setupConnection.Video;
450-
else if (setupMessage.RtspUri.AbsolutePath.EndsWith($"trackID={streamSource.AudioTrack?.ID}")) stream = setupConnection.Audio;
451-
else continue;// error case - track unknown
452-
// found the connection
453-
// Add the transports to the stream
470+
RTPStream stream;
471+
if (setupMessage.RtspUri.AbsolutePath.EndsWith($"trackID={streamSource.VideoTrack?.ID}"))
472+
{
473+
stream = setupConnection.Video;
474+
}
475+
else if (setupMessage.RtspUri.AbsolutePath.EndsWith($"trackID={streamSource.AudioTrack?.ID}"))
476+
{
477+
stream = setupConnection.Audio;
478+
}
479+
else
480+
{
481+
continue;// error case - track unknown
482+
// found the connection
483+
// Add the transports to the stream
484+
}
454485
stream.RtpChannel = rtpTransport;
455486
// When there is Video and Audio there are two SETUP commands.
456487
// For the first SETUP command we will generate the connection.sessionId and return a SessionID in the Reply.

src/SharpRTSPServer/RTSPStreamSource.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ namespace SharpRTSPServer
77
{
88
public class RTSPStreamSource : IDisposable
99
{
10-
private static readonly Random _rand = new Random();
11-
1210
/// <summary>
1311
/// Stream ID.
1412
/// </summary>

src/SharpRTSPServer/Tracks/TrackBase.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ namespace SharpRTSPServer
77
{
88
public abstract class TrackBase : ITrack
99
{
10+
private static readonly Random _rand = new Random();
11+
12+
/// <summary>
13+
/// SSRC for this track.
14+
/// </summary>
15+
public uint SSRC { get; set; } = (uint)_rand.Next(0, int.MaxValue);
16+
1017
public IRtpSender Sink { get; set; } = null;
1118

1219
public string StreamID { get; set; } = null;

0 commit comments

Comments
 (0)