/// <summary> /// Ends the videocall. /// </summary> public void StopCalling(bool isForcedByPeer) { if (isForcedByPeer) { udpMaster.SendMessage(new byte[0]); } udpMaster.Kill(); OwnFootage.Stop(); dimensionsEstablished = false; OnCallEnded.SafeInvoke(); AudioSource.Stop(); Microphone.StopRecording(); dimensionsEstablished = false; }
/// <summary> /// Collects the own video footage, reduces resolution, /// and sends it across the network. /// </summary> private IEnumerator <YieldInstruction> SendFootage() { while (OwnFootage.width == 0 || OwnFootage.height == 0) { yield return(new WaitForEndOfFrame()); } int ownFootageWidth = OwnFootage.width; int ownFootageHeight = OwnFootage.height; // Converts the width and height to byte array and sends it across the network. List <byte> resolutionByteList = new List <byte>(); resolutionByteList.Add(VIDEORES_ID); int videoWidth = (int)(ownFootageWidth * resolutionScale); int videoHeight = (int)(ownFootageHeight * resolutionScale); resolutionByteList.AddRange(videoWidth.ToByteArray()); resolutionByteList.AddRange(videoHeight.ToByteArray()); byte[] resolutionByteArray = resolutionByteList.ToArray(); while (!dimensionsEstablished) { udpMaster.SendMessage(resolutionByteList.ToArray()); yield return(new WaitForSeconds(1)); } // TODO: Do this on a different thread (framerate and such)? // TODO: Merge the lowering of resolution and the sending of the message in one loop. That will significantly improve performance (as you go through it once instead of twice). // TODO: Do this backwards? When you take the last message first, you can reuse the lowresframe list (less garbage). while (true) { // Lowers the resolution of the video frame. Color32[] frame = OwnFootage.GetPixels32(); List <Color32> lowResFrame = new List <Color32>(); for (float i = 0; i < videoHeight; i++) { for (float j = 0; j < videoWidth; j++) { int x = (int)(j / resolutionScale); int y = (int)(i / resolutionScale); int k = y * ownFootageWidth + x; Color32 pixel = frame[k]; lowResFrame.Add(pixel); } } // Sends the low resolution frame in chunks across the network. // Color32 contains 3 byte values (RGB). Therefore, everything is done in 3s. int colorBufferSize = (int)(udpMaster.MessageBufferSize / 3f); int chunkCount = Mathf.CeilToInt((float)lowResFrame.Count / colorBufferSize); for (int i = 0; i < chunkCount; i++) { // Establishes the message size. int j = i * colorBufferSize; int length = i == chunkCount - 1 // Is the last chunk. ? lowResFrame.Count - j : colorBufferSize; // Creates the message. List <byte> byteList = new List <byte>(); byteList.Add(VIDEO_ID); byteList.Add((byte)i); for (int k = 0; k < length; k++) { Color32 color = lowResFrame[k]; byteList.Add(color.r); byteList.Add(color.g); byteList.Add(color.b); } udpMaster.SendMessage(byteList.ToArray()); yield return(new WaitForEndOfFrame()); } yield return(new WaitForEndOfFrame()); } }