Skip to content

Commit bfe25ba

Browse files
committed
R Moved FeedInRawSamples into the tracks
1 parent 4617980 commit bfe25ba

7 files changed

Lines changed: 132 additions & 98 deletions

File tree

src/RTSPServerApp/Program.cs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
TrakBox videoTrackBox = null;
2424
double videoFrameRate = 0;
2525

26+
ITrack rtspVideoTrack = null;
27+
ITrack rtspAudioTrack = null;
28+
2629
// frag_bunny.mp4 audio is not playable in VLC on Windows 11 (works on MacOS)
2730
using (Stream fs = new BufferedStream(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)))
2831
{
@@ -42,14 +45,16 @@
4245
if (h264VisualSample != null)
4346
{
4447
var avcC = (h264VisualSample.Children.First(x => x.Type == AvcConfigurationBox.TYPE) as AvcConfigurationBox).AvcDecoderConfigurationRecord;
45-
server.VideoTrack = new SharpRTSPServer.H264Track(avcC.AvcProfileIndication, 0, avcC.AvcLevelIndication);
48+
rtspVideoTrack = new SharpRTSPServer.H264Track(avcC.AvcProfileIndication, 0, avcC.AvcLevelIndication);
49+
server.AddVideoTrack(rtspVideoTrack);
4650
}
4751
else
4852
{
4953
var h265VisualSample = videoTrackBox.GetMdia().GetMinf().GetStbl().GetStsd().Children.FirstOrDefault(x => x.Type == VisualSampleEntryBox.TYPE6 || x.Type == VisualSampleEntryBox.TYPE7) as VisualSampleEntryBox;
5054
if(h265VisualSample != null)
5155
{
52-
server.VideoTrack = new SharpRTSPServer.H265Track();
56+
rtspVideoTrack = new SharpRTSPServer.H265Track();
57+
server.AddVideoTrack(rtspVideoTrack);
5358
}
5459
else
5560
{
@@ -67,7 +72,8 @@
6772
{
6873
var audioConfigDescriptor = audioSampleEntry.GetAudioSpecificConfigDescriptor();
6974
int audioSamplingRate = audioConfigDescriptor.GetSamplingFrequency();
70-
server.AudioTrack = new SharpRTSPServer.AACTrack(await audioConfigDescriptor.ToBytes(), audioSamplingRate, audioConfigDescriptor.ChannelConfiguration);
75+
rtspAudioTrack = new SharpRTSPServer.AACTrack(await audioConfigDescriptor.ToBytes(), audioSamplingRate, audioConfigDescriptor.ChannelConfiguration);
76+
server.AddAudioTrack(rtspAudioTrack);
7177
}
7278
else
7379
{
@@ -92,18 +98,18 @@
9298
{
9399
if (videoIndex == 0)
94100
{
95-
if (server.VideoTrack is SharpRTSPServer.H264Track h264VideoTrack)
101+
if (rtspVideoTrack is SharpRTSPServer.H264Track h264VideoTrack)
96102
{
97103
h264VideoTrack.SetParameterSets(videoTrack[0][0], videoTrack[0][1]);
98104
}
99-
else if (server.VideoTrack is SharpRTSPServer.H265Track h265VideoTrack)
105+
else if (rtspVideoTrack is SharpRTSPServer.H265Track h265VideoTrack)
100106
{
101107
h265VideoTrack.SetParameterSets(videoTrack[0][0], videoTrack[0][1], videoTrack[0][2]);
102108
}
103109
videoIndex++;
104110
}
105111

106-
server.FeedInRawVideoSamples((uint)(videoIndex * videoSampleDuration), (List<byte[]>)videoTrack[videoIndex++ % videoTrack.Count]);
112+
rtspVideoTrack.FeedInRawSamples((uint)(videoIndex * videoSampleDuration), (List<byte[]>)videoTrack[videoIndex++ % videoTrack.Count]);
107113

108114
if (videoIndex % videoTrack.Count == 0)
109115
{
@@ -116,10 +122,10 @@
116122
{
117123
var audioSampleDuration = SharpMp4.AACTrack.AAC_SAMPLE_SIZE;
118124
var audioTrack = parsedMDAT[audioTrackId];
119-
audioTimer = new Timer(audioSampleDuration * 1000 / (server.AudioTrack as SharpRTSPServer.AACTrack).SamplingRate);
125+
audioTimer = new Timer(audioSampleDuration * 1000 / (rtspAudioTrack as SharpRTSPServer.AACTrack).SamplingRate);
120126
audioTimer.Elapsed += (s, e) =>
121127
{
122-
server.FeedInRawAudioSamples((uint)(audioIndex * audioSampleDuration), new List<byte[]>() { audioTrack[0][audioIndex++ % audioTrack[0].Count] });
128+
rtspAudioTrack.FeedInRawSamples((uint)(audioIndex * audioSampleDuration), new List<byte[]>() { audioTrack[0][audioIndex++ % audioTrack[0].Count] });
123129

124130
if (audioIndex % audioTrack[0].Count == 0)
125131
{

src/SharpRTSPServer/AACTrack.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,17 @@ namespace SharpRTSPServer
99
/// <summary>
1010
/// AAC track.
1111
/// </summary>
12-
public class AACTrack : ITrack
12+
public class AACTrack : TrackBase
1313
{
1414
/// <summary>
1515
/// AAC Audio Codec name.
1616
/// </summary>
17-
public string Codec => "mpeg4-generic";
17+
public override string Codec => "mpeg4-generic";
1818

1919
/// <summary>
2020
/// Track ID. Used to identify the track in the SDP.
2121
/// </summary>
22-
public int ID { get; set; } = 1;
22+
public override int ID { get; set; } = 1;
2323

2424
/// <summary>
2525
/// Sampling rate.
@@ -39,14 +39,14 @@ public class AACTrack : ITrack
3939
/// <summary>
4040
/// Is the track ready?
4141
/// </summary>
42-
public bool IsReady { get { return ConfigDescriptor != null && ConfigDescriptor.Length > 0; } }
42+
public override bool IsReady { get { return ConfigDescriptor != null && ConfigDescriptor.Length > 0; } }
4343

4444
private int _payloadType = -1;
4545

4646
/// <summary>
4747
/// Payload type. AAC uses a dynamic payload type, which by default we calculate as 96 + track ID.
4848
/// </summary>
49-
public int PayloadType
49+
public override int PayloadType
5050
{
5151
get
5252
{
@@ -101,7 +101,7 @@ public void SetConfigDescriptor(byte[] configDescriptor)
101101
/// </summary>
102102
/// <param name="sdp">SDP <see cref="StringBuilder"/>.</param>
103103
/// <returns><see cref="StringBuilder"/>.</returns>
104-
public StringBuilder BuildSDP(StringBuilder sdp)
104+
public override StringBuilder BuildSDP(StringBuilder sdp)
105105
{
106106
sdp.Append($"m=audio 0 RTP/AVP {PayloadType}\n"); // <---- Payload Type 0 means G711 ULAW, 96+ means dynamic payload type
107107
sdp.Append($"a=control:trackID={ID}\n");
@@ -117,7 +117,7 @@ public StringBuilder BuildSDP(StringBuilder sdp)
117117
/// <param name="samples">An array of AAC fragments. By default single fragment is expected.</param>
118118
/// <param name="rtpTimestamp">RTP timestamp in the timescale of the track.</param>
119119
/// <returns>RTP packets.</returns>
120-
public (List<Memory<byte>>, List<IMemoryOwner<byte>>) CreateRtpPackets(List<byte[]> samples, uint rtpTimestamp)
120+
public override (List<Memory<byte>>, List<IMemoryOwner<byte>>) CreateRtpPackets(List<byte[]> samples, uint rtpTimestamp)
121121
{
122122
List<Memory<byte>> rtpPackets = new List<Memory<byte>>();
123123
List<IMemoryOwner<byte>> memoryOwners = new List<IMemoryOwner<byte>>();

src/SharpRTSPServer/G711Track.cs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,17 @@ namespace SharpRTSPServer
88
/// <summary>
99
/// G711 PCMU (U-LAW) track.
1010
/// </summary>
11-
public class PCMUTrack : ITrack
11+
public class PCMUTrack : TrackBase
1212
{
1313
/// <summary>
1414
/// PCMU Audio Codec name.
1515
/// </summary>
16-
public string Codec => "PCMU";
16+
public override string Codec => "PCMU";
1717

1818
/// <summary>
1919
/// Track ID. Used to identify the track in the SDP.
2020
/// </summary>
21-
public int ID { get; set; } = 1;
21+
public override int ID { get; set; } = 1;
2222

2323
/// <summary>
2424
/// Sampling rate.
@@ -33,19 +33,19 @@ public class PCMUTrack : ITrack
3333
/// <summary>
3434
/// Is the track ready?
3535
/// </summary>
36-
public bool IsReady { get { return true; } }
36+
public override bool IsReady { get { return true; } }
3737

3838
/// <summary>
3939
/// Payload type. PCMU uses static payload type 0.
4040
/// </summary>
41-
public int PayloadType { get; set; } = 0;
41+
public override int PayloadType { get; set; } = 0;
4242

4343
/// <summary>
4444
/// Build the SDP for this track.
4545
/// </summary>
4646
/// <param name="sdp">SDP <see cref="StringBuilder"/>.</param>
4747
/// <returns><see cref="StringBuilder"/>.</returns>
48-
public StringBuilder BuildSDP(StringBuilder sdp)
48+
public override StringBuilder BuildSDP(StringBuilder sdp)
4949
{
5050
sdp.Append($"m=audio 0 RTP/AVP {PayloadType}\n");
5151
sdp.Append($"a=control:trackID={ID}\n");
@@ -59,7 +59,7 @@ public StringBuilder BuildSDP(StringBuilder sdp)
5959
/// <param name="samples">An array of PCMU fragments. By default single fragment is expected.</param>
6060
/// <param name="rtpTimestamp">RTP timestamp in the timescale of the track.</param>
6161
/// <returns>RTP packets.</returns>
62-
public (List<Memory<byte>>, List<IMemoryOwner<byte>>) CreateRtpPackets(List<byte[]> samples, uint rtpTimestamp)
62+
public override (List<Memory<byte>>, List<IMemoryOwner<byte>>) CreateRtpPackets(List<byte[]> samples, uint rtpTimestamp)
6363
{
6464
List<Memory<byte>> rtpPackets = new List<Memory<byte>>();
6565
List<IMemoryOwner<byte>> memoryOwners = new List<IMemoryOwner<byte>>();
@@ -93,17 +93,17 @@ public StringBuilder BuildSDP(StringBuilder sdp)
9393
/// <summary>
9494
/// G711 PCMA (A-LAW) track.
9595
/// </summary>
96-
public class PCMATrack : ITrack
96+
public class PCMATrack : TrackBase
9797
{
9898
/// <summary>
9999
/// PCMA Audio Codec name.
100100
/// </summary>
101-
public string Codec => "PCMA";
101+
public override string Codec => "PCMA";
102102

103103
/// <summary>
104104
/// Track ID. Used to identify the track in the SDP.
105105
/// </summary>
106-
public int ID { get; set; } = 1;
106+
public override int ID { get; set; } = 1;
107107

108108
/// <summary>
109109
/// Sampling rate.
@@ -118,19 +118,19 @@ public class PCMATrack : ITrack
118118
/// <summary>
119119
/// Is the track ready?
120120
/// </summary>
121-
public bool IsReady { get { return true; } }
121+
public override bool IsReady { get { return true; } }
122122

123123
/// <summary>
124124
/// Payload type. PCMA uses static payload type 8.
125125
/// </summary>
126-
public int PayloadType { get; set; } = 8;
126+
public override int PayloadType { get; set; } = 8;
127127

128128
/// <summary>
129129
/// Build the SDP for this track.
130130
/// </summary>
131131
/// <param name="sdp">SDP <see cref="StringBuilder"/>.</param>
132132
/// <returns><see cref="StringBuilder"/>.</returns>
133-
public StringBuilder BuildSDP(StringBuilder sdp)
133+
public override StringBuilder BuildSDP(StringBuilder sdp)
134134
{
135135
sdp.Append($"m=audio 0 RTP/AVP {PayloadType}\n");
136136
sdp.Append($"a=control:trackID={ID}\n");
@@ -144,7 +144,7 @@ public StringBuilder BuildSDP(StringBuilder sdp)
144144
/// <param name="samples">An array of PCMA fragments. By default single fragment is expected.</param>
145145
/// <param name="rtpTimestamp">RTP timestamp in the timescale of the track.</param>
146146
/// <returns>RTP packets.</returns>
147-
public (List<Memory<byte>>, List<IMemoryOwner<byte>>) CreateRtpPackets(List<byte[]> samples, uint rtpTimestamp)
147+
public override (List<Memory<byte>>, List<IMemoryOwner<byte>>) CreateRtpPackets(List<byte[]> samples, uint rtpTimestamp)
148148
{
149149
List<Memory<byte>> rtpPackets = new List<Memory<byte>>();
150150
List<IMemoryOwner<byte>> memoryOwners = new List<IMemoryOwner<byte>>();

src/SharpRTSPServer/H264Track.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ namespace SharpRTSPServer
88
/// <summary>
99
/// H264 video track.
1010
/// </summary>
11-
public class H264Track : ITrack
11+
public class H264Track : TrackBase
1212
{
1313
/// <summary>
1414
/// H264 Video Codec name.
1515
/// </summary>
16-
public string Codec => "H264";
16+
public override string Codec => "H264";
1717

1818
/// <summary>
1919
/// Default video track clock rate.
@@ -23,7 +23,7 @@ public class H264Track : ITrack
2323
/// <summary>
2424
/// Track ID. Used to identify the track in the SDP.
2525
/// </summary>
26-
public int ID { get; set; } = 0;
26+
public override int ID { get; set; } = 0;
2727

2828
/// <summary>
2929
/// H264 Profile IDC. Default value is 77 (Main Profile).
@@ -63,14 +63,14 @@ public class H264Track : ITrack
6363
/// <summary>
6464
/// Is the track ready?
6565
/// </summary>
66-
public bool IsReady { get { return SPS != null && PPS != null; } }
66+
public override bool IsReady { get { return SPS != null && PPS != null; } }
6767

6868
private int _payloadType = -1;
6969

7070
/// <summary>
7171
/// Payload type. H264 uses a dynamic payload type, which by default we calculate as 96 + track ID.
7272
/// </summary>
73-
public int PayloadType
73+
public override int PayloadType
7474
{
7575
get
7676
{
@@ -134,7 +134,7 @@ public void SetParameterSets(byte[] sps, byte[] pps)
134134
/// </summary>
135135
/// <param name="sdp">SDP <see cref="StringBuilder"/>.</param>
136136
/// <returns><see cref="StringBuilder"/>.</returns>
137-
public StringBuilder BuildSDP(StringBuilder sdp)
137+
public override StringBuilder BuildSDP(StringBuilder sdp)
138138
{
139139
// Make the profile-level-id
140140
// Eg a string of profile-level-id=42A01E is
@@ -160,7 +160,7 @@ public StringBuilder BuildSDP(StringBuilder sdp)
160160
/// <param name="samples">An array of H264 NALUs.</param>
161161
/// <param name="rtpTimestamp">RTP timestamp in the timescale of the track.</param>
162162
/// <returns>RTP packets.</returns>
163-
public (List<Memory<byte>>, List<IMemoryOwner<byte>>) CreateRtpPackets(List<byte[]> samples, uint rtpTimestamp)
163+
public override (List<Memory<byte>>, List<IMemoryOwner<byte>>) CreateRtpPackets(List<byte[]> samples, uint rtpTimestamp)
164164
{
165165
List<Memory<byte>> rtpPackets = new List<Memory<byte>>();
166166
List<IMemoryOwner<byte>> memoryOwners = new List<IMemoryOwner<byte>>();

src/SharpRTSPServer/H265Track.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ namespace SharpRTSPServer
88
/// <summary>
99
/// H265 video track.
1010
/// </summary>
11-
public class H265Track : ITrack
11+
public class H265Track : TrackBase
1212
{
1313
/// <summary>
1414
/// H265 Video Codec name.
1515
/// </summary>
16-
public string Codec => "H265";
16+
public override string Codec => "H265";
1717

1818
/// <summary>
1919
/// Default video track clock rate.
@@ -23,7 +23,7 @@ public class H265Track : ITrack
2323
/// <summary>
2424
/// Track ID. Used to identify the track in the SDP.
2525
/// </summary>
26-
public int ID { get; set; } = 0;
26+
public override int ID { get; set; } = 0;
2727

2828
/// <summary>
2929
/// Video clock rate. Default value is 90000.
@@ -53,14 +53,14 @@ public class H265Track : ITrack
5353
/// <summary>
5454
/// Is the track ready?
5555
/// </summary>
56-
public bool IsReady { get { return VPS != null && SPS != null && PPS != null; } }
56+
public override bool IsReady { get { return VPS != null && SPS != null && PPS != null; } }
5757

5858
private int _payloadType = -1;
5959

6060
/// <summary>
6161
/// Payload type. H264 uses a dynamic payload type, which by default we calculate as 96 + track ID.
6262
/// </summary>
63-
public int PayloadType
63+
public override int PayloadType
6464
{
6565
get
6666
{
@@ -113,7 +113,7 @@ public void SetParameterSets(byte[] vps, byte[] sps, byte[] pps)
113113
this.PPS = pps;
114114
}
115115

116-
public StringBuilder BuildSDP(StringBuilder sdp)
116+
public override StringBuilder BuildSDP(StringBuilder sdp)
117117
{
118118
string vps_str = Convert.ToBase64String(VPS);
119119
string sps_str = Convert.ToBase64String(SPS);
@@ -132,7 +132,7 @@ public StringBuilder BuildSDP(StringBuilder sdp)
132132
/// <param name="samples">An array of H265 NALUs.</param>
133133
/// <param name="rtpTimestamp">RTP timestamp in the timescale of the track.</param>
134134
/// <returns>RTP packets.</returns>
135-
public (List<Memory<byte>>, List<IMemoryOwner<byte>>) CreateRtpPackets(List<byte[]> samples, uint rtpTimestamp)
135+
public override (List<Memory<byte>>, List<IMemoryOwner<byte>>) CreateRtpPackets(List<byte[]> samples, uint rtpTimestamp)
136136
{
137137
List<Memory<byte>> rtpPackets = new List<Memory<byte>>();
138138
List<IMemoryOwner<byte>> memoryOwners = new List<IMemoryOwner<byte>>();

0 commit comments

Comments
 (0)