private void EncodingThreadEntry() { // Wait for an initial voice packet _waitHandle.WaitOne(); Debug.Log("Starting encoder thread"); bool isLastPacket = false; while (true) { try { // Keep running until a stop has been requested and we've encoded the rest of the buffer // Then wait for a new voice packet while (_stopSendingRequested && isLastPacket) { _waitHandle.WaitOne(); } bool isEmpty; ArraySegment <byte> packet = _encodingBuffer.Encode(_encoder, out isLastPacket, out isEmpty); if (isEmpty && !isLastPacket) { Thread.Sleep(Mumble.MumbleConstants.FRAME_SIZE_MS); //Debug.LogWarning("Empty Packet"); continue; } if (isLastPacket) { Debug.Log("Will send last packet"); } //Make the header byte type = (byte)4; //originally [type = codec_type_id << 5 | whistep_chanel_id]. now we can talk only to normal chanel type = (byte)(type << 5); byte[] sequence = Var64.writeVarint64_alternative((UInt64)sequenceIndex); //Write header to show how long the encoded data is ulong opusHeaderNum = isEmpty ? 0 : (UInt64)packet.Count; //Mark the leftmost bit if this is the last packet if (isLastPacket) { opusHeaderNum += 8192; Debug.Log("Adding end flag"); } byte[] opusHeader = Var64.writeVarint64_alternative(opusHeaderNum); //Packet: //[type/target] [sequence] [opus length header] [packet data] byte[] finalPacket = new byte[1 + sequence.Length + opusHeader.Length + packet.Count]; finalPacket[0] = type; Array.Copy(sequence, 0, finalPacket, 1, sequence.Length); Array.Copy(opusHeader, 0, finalPacket, 1 + sequence.Length, opusHeader.Length); Array.Copy(packet.Array, packet.Offset, finalPacket, 1 + sequence.Length + opusHeader.Length, packet.Count); while (_udpConnection._isSending) { //Debug.Log("waiting"); Thread.Sleep(1); } //Debug.Log("seq: " + sequenceIndex + " | " + finalPacket.Length); _udpConnection.SendVoicePacket(finalPacket); sequenceIndex += MumbleConstants.NUM_FRAMES_PER_OUTGOING_PACKET; //If we've hit a stop packet, then reset the seq number if (isLastPacket) { sequenceIndex = 0; } } catch (Exception e) { if (e is System.Threading.ThreadAbortException) { // This is ok break; } else { Debug.LogError("Error: " + e); } } } Debug.Log("Terminated encoding thread"); _encodingThread = null; }
private void EncodingThreadEntry() { while (true) { try { bool isLastPacket; bool isEmpty; ArraySegment <byte> packet = _encodingBuffer.Encode(_codec, out isLastPacket, out isEmpty); if (isEmpty) { Thread.Sleep(Mumble.MumbleConstants.FRAME_SIZE_MS); //Debug.LogWarning("Empty Packet"); continue; } if (isLastPacket) { Debug.Log("Will send last packet"); } if (packet.Array.Length == 0 || packet.Count == 0) { Debug.LogError("Empty packet?"); } //Make the header byte type = (byte)4; //originally [type = codec_type_id << 5 | whistep_chanel_id]. now we can talk only to normal chanel type = (byte)(type << 5); byte[] sequence = Var64.writeVarint64_alternative((UInt64)sequenceIndex); //Write header to show how long the encoded data is byte[] opusHeader = Var64.writeVarint64_alternative((UInt64)packet.Count); //Mark the leftmost bit if this is the last packet if (isLastPacket) { opusHeader[0] = (byte)(opusHeader[0] | 128); Debug.LogWarning("Adding end flag"); } //Packet: //[type/target] [sequence] [opus length header] [packet data] byte[] finalPacket = new byte[1 + sequence.Length + opusHeader.Length + packet.Count]; finalPacket[0] = type; Array.Copy(sequence, 0, finalPacket, 1, sequence.Length); Array.Copy(opusHeader, 0, finalPacket, 1 + sequence.Length, opusHeader.Length); Array.Copy(packet.Array, packet.Offset, finalPacket, 1 + sequence.Length + opusHeader.Length, packet.Count); while (_udpConnection._isSending) { //Debug.Log("waiting"); Thread.Sleep(1); } //Debug.Log("seq: " + sequenceIndex + " | " + finalPacket.Length); _udpConnection.SendVoicePacket(finalPacket); sequenceIndex += MumbleConstants.NUM_FRAMES_PER_OUTGOING_PACKET; //If we've hit a stop packet, then reset the seq number if (isLastPacket) { sequenceIndex = 0; } } catch (Exception e) { if (e is System.Threading.ThreadAbortException) { // This is ok } else { Debug.LogError("Error: " + e); } } } }
private void EncodingThreadEntry() { // Wait for an initial voice packet _waitHandle.WaitOne(); //Debug.Log("Starting encoder thread"); bool isLastPacket = false; System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch(); stopwatch.Start(); while (true) { if (!_isRunning) { return; } try { // Keep running until a stop has been requested and we've encoded the rest of the buffer // Then wait for a new voice packet while (_stopSendingRequested && isLastPacket) { _waitHandle.WaitOne(); } if (!_isRunning) { return; } bool isEmpty; AudioEncodingBuffer.CompressedBuffer buff = _encodingBuffer.Encode(_encoder, out isLastPacket, out isEmpty); if (isEmpty && !isLastPacket) { // This should not normally occur Thread.Sleep(Mumble.MumbleConstants.FRAME_SIZE_MS); Debug.LogWarning("Empty Packet"); continue; } if (isLastPacket) { Debug.Log("Will send last packet"); } ArraySegment <byte> packet = buff.EncodedData; //Make the header byte type = (byte)4; //originally [type = codec_type_id << 5 | whistep_chanel_id]. now we can talk only to normal chanel type = (byte)(type << 5); byte[] sequence = Var64.writeVarint64_alternative((UInt64)sequenceIndex); //Write header to show how long the encoded data is ulong opusHeaderNum = isEmpty ? 0 : (UInt64)packet.Count; //Mark the leftmost bit if this is the last packet if (isLastPacket) { opusHeaderNum += 8192; Debug.Log("Adding end flag"); } byte[] opusHeader = Var64.writeVarint64_alternative(opusHeaderNum); //Packet: //[type/target] [sequence] [opus length header] [packet data] byte[] finalPacket = new byte[1 + sequence.Length + opusHeader.Length + packet.Count + buff.PositionalDataLength]; finalPacket[0] = type; int finalOffset = 1; Array.Copy(sequence, 0, finalPacket, finalOffset, sequence.Length); finalOffset += sequence.Length; Array.Copy(opusHeader, 0, finalPacket, finalOffset, opusHeader.Length); finalOffset += opusHeader.Length; Array.Copy(packet.Array, packet.Offset, finalPacket, finalOffset, packet.Count); finalOffset += packet.Count; // Append positional data, if it exists if (buff.PositionalDataLength > 0) { Array.Copy(buff.PositionalData, 0, finalPacket, finalOffset, buff.PositionalDataLength); } //Debug.Log("seq: " + sequenceIndex + " final len: " + finalPacket.Length + " pos: " + buff.PositionalDataLength); //Debug.Log("seq: " + sequenceIndex + " | " + finalPacket.Length); stopwatch.Stop(); long timeSinceLastSend = stopwatch.ElapsedMilliseconds; //Debug.Log("Elapsed: " + timeSinceLastSend + " pending: " + _encodingBuffer.GetNumUncompressedPending()); if (timeSinceLastSend < MinSendingElapsedMilliseconds && _encodingBuffer.GetNumUncompressedPending() < MaxPendingBuffersForSleep) { Thread.Sleep((int)(MinSendingElapsedMilliseconds - timeSinceLastSend)); //Debug.Log("Slept: " + stopwatch.ElapsedMilliseconds); } _udpConnection.SendVoicePacket(finalPacket); sequenceIndex += MumbleConstants.NUM_FRAMES_PER_OUTGOING_PACKET; //If we've hit a stop packet, then reset the seq number if (isLastPacket) { sequenceIndex = 0; } stopwatch.Reset(); stopwatch.Start(); } catch (Exception e) { if (e is System.Threading.ThreadAbortException) { // This is ok break; } else { Debug.LogError("Error: " + e); } } } Debug.Log("Terminated encoding thread"); }