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