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 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); | |||