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;
        }
Example #2
0
        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");
        }