Author | SHA1 | Message | Date |
---|---|---|---|
|
de1a41eae0 |
Make some tweaks to dispose impls on streams
Make them a little more consistent, and actually dispose where appropriate |
6 years ago |
@@ -38,7 +38,7 @@ namespace Discord.Audio.Streams | |||||
private bool _isPreloaded; | private bool _isPreloaded; | ||||
private int _silenceFrames; | private int _silenceFrames; | ||||
public BufferedWriteStream(AudioStream next, IAudioClient client, int bufferMillis, CancellationToken cancelToken, int maxFrameSize = 1500) | |||||
internal BufferedWriteStream(AudioStream next, IAudioClient client, int bufferMillis, CancellationToken cancelToken, int maxFrameSize = 1500) | |||||
: this(next, client as AudioClient, bufferMillis, cancelToken, null, maxFrameSize) { } | : this(next, client as AudioClient, bufferMillis, cancelToken, null, maxFrameSize) { } | ||||
internal BufferedWriteStream(AudioStream next, AudioClient client, int bufferMillis, CancellationToken cancelToken, Logger logger, int maxFrameSize = 1500) | internal BufferedWriteStream(AudioStream next, AudioClient client, int bufferMillis, CancellationToken cancelToken, Logger logger, int maxFrameSize = 1500) | ||||
{ | { | ||||
@@ -69,6 +69,13 @@ namespace Discord.Audio.Streams | |||||
_disposeTokenSource?.Dispose(); | _disposeTokenSource?.Dispose(); | ||||
_cancelTokenSource?.Dispose(); | _cancelTokenSource?.Dispose(); | ||||
_queueLock?.Dispose(); | _queueLock?.Dispose(); | ||||
try | |||||
{ | |||||
_task.GetAwaiter().GetResult(); | |||||
} | |||||
catch (OperationCanceledException) | |||||
{ /* no-op */ } | |||||
_next?.Dispose(); | |||||
} | } | ||||
base.Dispose(disposing); | base.Dispose(disposing); | ||||
} | } | ||||
@@ -23,7 +23,7 @@ namespace Discord.Audio.Streams | |||||
public override bool CanWrite => false; | public override bool CanWrite => false; | ||||
public override int AvailableFrames => _signal.CurrentCount; | public override int AvailableFrames => _signal.CurrentCount; | ||||
public InputStream() | |||||
internal InputStream() | |||||
{ | { | ||||
_frames = new ConcurrentQueue<RTPFrame>(); | _frames = new ConcurrentQueue<RTPFrame>(); | ||||
_signal = new SemaphoreSlim(0, MaxFrames); | _signal = new SemaphoreSlim(0, MaxFrames); | ||||
@@ -15,7 +15,7 @@ namespace Discord.Audio.Streams | |||||
private bool _nextMissed; | private bool _nextMissed; | ||||
private bool _hasHeader; | private bool _hasHeader; | ||||
public OpusDecodeStream(AudioStream next) | |||||
internal OpusDecodeStream(AudioStream next) | |||||
{ | { | ||||
_next = next; | _next = next; | ||||
_buffer = new byte[OpusConverter.FrameBytes]; | _buffer = new byte[OpusConverter.FrameBytes]; | ||||
@@ -26,7 +26,7 @@ namespace Discord.Audio.Streams | |||||
public override void WriteHeader(ushort seq, uint timestamp, bool missed) | public override void WriteHeader(ushort seq, uint timestamp, bool missed) | ||||
{ | { | ||||
if (_hasHeader) | if (_hasHeader) | ||||
throw new InvalidOperationException("Header received with no payload."); | |||||
throw new InvalidOperationException("Header received with no payload."); | |||||
_hasHeader = true; | _hasHeader = true; | ||||
_nextMissed = missed; | _nextMissed = missed; | ||||
@@ -15,13 +15,22 @@ namespace Discord.Audio.Streams | |||||
private int _partialFramePos; | private int _partialFramePos; | ||||
private ushort _seq; | private ushort _seq; | ||||
private uint _timestamp; | private uint _timestamp; | ||||
public OpusEncodeStream(AudioStream next, int bitrate, AudioApplication application, int packetLoss) | |||||
internal OpusEncodeStream(AudioStream next, int bitrate, AudioApplication application, int packetLoss) | |||||
{ | { | ||||
_next = next; | _next = next; | ||||
_encoder = new OpusEncoder(bitrate, application, packetLoss); | _encoder = new OpusEncoder(bitrate, application, packetLoss); | ||||
_buffer = new byte[OpusConverter.FrameBytes]; | _buffer = new byte[OpusConverter.FrameBytes]; | ||||
} | } | ||||
protected override void Dispose(bool disposing) | |||||
{ | |||||
if (disposing) | |||||
{ | |||||
_encoder.Dispose(); | |||||
_next.Dispose(); | |||||
} | |||||
base.Dispose(disposing); | |||||
} | |||||
public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancelToken) | public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancelToken) | ||||
{ | { | ||||
@@ -86,13 +95,5 @@ namespace Discord.Audio.Streams | |||||
{ | { | ||||
await _next.ClearAsync(cancelToken).ConfigureAwait(false); | await _next.ClearAsync(cancelToken).ConfigureAwait(false); | ||||
} | } | ||||
protected override void Dispose(bool disposing) | |||||
{ | |||||
base.Dispose(disposing); | |||||
if (disposing) | |||||
_encoder.Dispose(); | |||||
} | |||||
} | } | ||||
} | } |
@@ -7,13 +7,13 @@ namespace Discord.Audio.Streams | |||||
public class OutputStream : AudioOutStream | public class OutputStream : AudioOutStream | ||||
{ | { | ||||
private readonly DiscordVoiceAPIClient _client; | private readonly DiscordVoiceAPIClient _client; | ||||
public OutputStream(IAudioClient client) | |||||
internal OutputStream(IAudioClient client) | |||||
: this((client as AudioClient).ApiClient) { } | : this((client as AudioClient).ApiClient) { } | ||||
internal OutputStream(DiscordVoiceAPIClient client) | internal OutputStream(DiscordVoiceAPIClient client) | ||||
{ | { | ||||
_client = client; | _client = client; | ||||
} | } | ||||
public override void WriteHeader(ushort seq, uint timestamp, bool missed) { } //Ignore | public override void WriteHeader(ushort seq, uint timestamp, bool missed) { } //Ignore | ||||
public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancelToken) | public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancelToken) | ||||
{ | { | ||||
@@ -21,4 +21,4 @@ namespace Discord.Audio.Streams | |||||
await _client.SendAsync(buffer, offset, count).ConfigureAwait(false); | await _client.SendAsync(buffer, offset, count).ConfigureAwait(false); | ||||
} | } | ||||
} | } | ||||
} | |||||
} |
@@ -14,7 +14,7 @@ namespace Discord.Audio.Streams | |||||
public override bool CanSeek => false; | public override bool CanSeek => false; | ||||
public override bool CanWrite => true; | public override bool CanWrite => true; | ||||
public RTPReadStream(AudioStream next, int bufferSize = 4000) | |||||
internal RTPReadStream(AudioStream next, int bufferSize = 4000) | |||||
{ | { | ||||
_next = next; | _next = next; | ||||
_buffer = new byte[bufferSize]; | _buffer = new byte[bufferSize]; | ||||
@@ -46,7 +46,7 @@ namespace Discord.Audio.Streams | |||||
ssrc = 0; | ssrc = 0; | ||||
if (buffer.Length - offset < 12) | if (buffer.Length - offset < 12) | ||||
return false; | return false; | ||||
int version = (buffer[offset + 0] & 0b1100_0000) >> 6; | int version = (buffer[offset + 0] & 0b1100_0000) >> 6; | ||||
if (version != 2) | if (version != 2) | ||||
return false; | return false; | ||||
@@ -71,8 +71,8 @@ namespace Discord.Audio.Streams | |||||
return 12 + csics * 4; | return 12 + csics * 4; | ||||
int extensionOffset = offset + 12 + (csics * 4); | int extensionOffset = offset + 12 + (csics * 4); | ||||
int extensionLength = | |||||
(buffer[extensionOffset + 2] << 8) | | |||||
int extensionLength = | |||||
(buffer[extensionOffset + 2] << 8) | | |||||
(buffer[extensionOffset + 3]); | (buffer[extensionOffset + 3]); | ||||
return extensionOffset + 4 + (extensionLength * 4); | return extensionOffset + 4 + (extensionLength * 4); | ||||
} | } | ||||
@@ -15,7 +15,7 @@ namespace Discord.Audio.Streams | |||||
private uint _nextTimestamp; | private uint _nextTimestamp; | ||||
private bool _hasHeader; | private bool _hasHeader; | ||||
public RTPWriteStream(AudioStream next, uint ssrc, int bufferSize = 4000) | |||||
internal RTPWriteStream(AudioStream next, uint ssrc, int bufferSize = 4000) | |||||
{ | { | ||||
_next = next; | _next = next; | ||||
_ssrc = ssrc; | _ssrc = ssrc; | ||||
@@ -28,12 +28,20 @@ namespace Discord.Audio.Streams | |||||
_header[10] = (byte)(_ssrc >> 8); | _header[10] = (byte)(_ssrc >> 8); | ||||
_header[11] = (byte)(_ssrc >> 0); | _header[11] = (byte)(_ssrc >> 0); | ||||
} | } | ||||
protected override void Dispose(bool disposing) | |||||
{ | |||||
if (disposing) | |||||
{ | |||||
_next?.Dispose(); | |||||
} | |||||
base.Dispose(disposing); | |||||
} | |||||
public override void WriteHeader(ushort seq, uint timestamp, bool missed) | public override void WriteHeader(ushort seq, uint timestamp, bool missed) | ||||
{ | { | ||||
if (_hasHeader) | if (_hasHeader) | ||||
throw new InvalidOperationException("Header received with no payload"); | throw new InvalidOperationException("Header received with no payload"); | ||||
_hasHeader = true; | _hasHeader = true; | ||||
_nextSeq = seq; | _nextSeq = seq; | ||||
_nextTimestamp = timestamp; | _nextTimestamp = timestamp; | ||||
@@ -17,7 +17,7 @@ namespace Discord.Audio.Streams | |||||
public override bool CanSeek => false; | public override bool CanSeek => false; | ||||
public override bool CanWrite => true; | public override bool CanWrite => true; | ||||
public SodiumDecryptStream(AudioStream next, IAudioClient client) | |||||
internal SodiumDecryptStream(AudioStream next, IAudioClient client) | |||||
{ | { | ||||
_next = next; | _next = next; | ||||
_client = (AudioClient)client; | _client = (AudioClient)client; | ||||
@@ -16,12 +16,20 @@ namespace Discord.Audio.Streams | |||||
private ushort _nextSeq; | private ushort _nextSeq; | ||||
private uint _nextTimestamp; | private uint _nextTimestamp; | ||||
public SodiumEncryptStream(AudioStream next, IAudioClient client) | |||||
internal SodiumEncryptStream(AudioStream next, IAudioClient client) | |||||
{ | { | ||||
_next = next; | _next = next; | ||||
_client = (AudioClient)client; | _client = (AudioClient)client; | ||||
_nonce = new byte[24]; | _nonce = new byte[24]; | ||||
} | } | ||||
protected override void Dispose(bool disposing) | |||||
{ | |||||
if (disposing) | |||||
{ | |||||
_next?.Dispose(); | |||||
} | |||||
base.Dispose(disposing); | |||||
} | |||||
/// <exception cref="InvalidOperationException">Header received with no payload.</exception> | /// <exception cref="InvalidOperationException">Header received with no payload.</exception> | ||||
public override void WriteHeader(ushort seq, uint timestamp, bool missed) | public override void WriteHeader(ushort seq, uint timestamp, bool missed) | ||||
@@ -45,7 +53,7 @@ namespace Discord.Audio.Streams | |||||
if (_client.SecretKey == null) | if (_client.SecretKey == null) | ||||
return; | return; | ||||
Buffer.BlockCopy(buffer, offset, _nonce, 0, 12); //Copy nonce from RTP header | Buffer.BlockCopy(buffer, offset, _nonce, 0, 12); //Copy nonce from RTP header | ||||
count = SecretBox.Encrypt(buffer, offset + 12, count - 12, buffer, 12, _nonce, _client.SecretKey); | count = SecretBox.Encrypt(buffer, offset + 12, count - 12, buffer, 12, _nonce, _client.SecretKey); | ||||
_next.WriteHeader(_nextSeq, _nextTimestamp, false); | _next.WriteHeader(_nextSeq, _nextTimestamp, false); | ||||