using System; using System.Collections; using System.Collections.Generic; using System.IO.MemoryMappedFiles; using System.Linq; using UnityEngine; using UnityEngine.UI; public class CameraReceiverMemory : MonoBehaviour { public ReceiverData[] Cameras; public string StreamFileName = "CameraReceiveStream"; public float ScanTime = 0.04f; private MemoryMappedViewAccessor mapView; private MemoryMappedFile mapFile; private List grabbedImages = new List(); private Texture2D checkTexture; private List imagePointers = new List(); private List imageSizes = new List(); private int HeaderSize; private bool isStreamingEnable = true; //--------------------------------------------------------------------------------- void Start() { int totalimagesize = 0; checkTexture = new Texture2D(2, 2,TextureFormat.ARGB32,false); for (int i = 0; i < Cameras.Length; i++) { grabbedImages.Add(new Texture2D(Cameras[i].CameraSize.x, Cameras[i].CameraSize.y, TextureFormat.ARGB32, false)); Cameras[i].CameraSources.texture = grabbedImages[i]; imagePointers.Add(totalimagesize); var imagesize = 3 * Cameras[i].CameraSize.x * Cameras[i].CameraSize.y; imageSizes.Add(imagesize); totalimagesize += imagesize; } HeaderSize = sizeof(Int32) + sizeof(Int32) * 2 * Cameras.Length; mapFile = MemoryMappedFile.CreateOrOpen(StreamFileName, totalimagesize + HeaderSize); mapView = mapFile.CreateViewAccessor(0, totalimagesize + HeaderSize); mapView.Write(0, Cameras.Length); for (int i = 0; i < Cameras.Length; i++) { mapView.Write(4 + 8 * i, Cameras[i].CameraSize.x); //width mapView.Write(8 + 8 * i, Cameras[i].CameraSize.y);//height } StartCoroutine(Cameraframeloop()); } //--------------------------------------------------------------------------------- IEnumerator Cameraframeloop() { int i = 0; while (Application.isPlaying) { if (ScanTime > 0) yield return new WaitForSecondsRealtime(ScanTime); else yield return new WaitForEndOfFrame(); if (!this.isStreamingEnable) continue; //READ MEMORY FILE CAMERA [I] //LOAD CameraSources[i].texture byte[] pixelValues = new byte[imageSizes[i]]; mapView.ReadArray( HeaderSize + imagePointers[i], pixelValues, 0, imageSizes[i] ); //Debug.Log($"{Cameras[i].CameraSources.gameObject.name} pointer={HeaderSize + imagePointers[i]} pixels={pixelValues.Length} RGB:({pixelValues[0]}, {pixelValues[1]}, {pixelValues[2]}) - ({pixelValues[pixelValues.Length-3]}, {pixelValues[pixelValues.Length - 2]}, {pixelValues[pixelValues.Length - 1]})"); //VERSION ORIGINAL: //Texture2D texture = new Texture2D(2,2,TextureFormat.RGB24,false); //texture.LoadImage(pixelValues); //Cameras[i].CameraSources.texture = texture; //VERSION 1-13 //Texture2D texture = new Texture2D(Cameras[i].CameraSize.x, Cameras[i].CameraSize.y,TextureFormat.RGB24,false); //texture.LoadRawTextureData(pixelValues); //texture.Apply(); //Cameras[i].CameraSources.texture = texture; //Version 1-14 //if (Cameras[i].Protocol.ToUpper().Trim()=="RTSP") // grabbedImages[i].LoadRawTextureData(pixelValues); //else // grabbedImages[i].LoadImage(pixelValues); //grabbedImages[i].Apply(); //Version 1-15 //Texture will be uploaded to the GPU automatically; there's no need to call Apply. //https://docs.unity3d.com/ScriptReference/ImageConversion.LoadImage.html ////CHECK IF IS A PNG IMAGE ////https://stackoverflow.com/questions/55869/determine-file-type-of-an-image/12451102#12451102 //var png = new byte[] { 137, 80, 78, 71 }; // PNG //byte[] check = new byte[4]; //Array.Copy(pixelValues, 0, check, 0, 4); //if (!check.SequenceEqual(png)) //{ // Debug.Log("PNG ERROR"); //} checkTexture.LoadImage(pixelValues); if (Cameras[i].CameraSize.x != checkTexture.width || Cameras[i].CameraSize.y != checkTexture.height) { //Debug.Log($"format={checkTexture.format} graphicsFormat={checkTexture.graphicsFormat} Size=({checkTexture.width},{checkTexture.height})"); } else { if (checkTexture.format != grabbedImages[i].format) { grabbedImages[i] = new Texture2D(Cameras[i].CameraSize.x, Cameras[i].CameraSize.y, checkTexture.format, false); Cameras[i].CameraSources.texture = grabbedImages[i]; Debug.Log($"Texture Format changed to {checkTexture.format}"); } Graphics.CopyTexture(checkTexture, grabbedImages[i]); } i++; if (i == Cameras.Length) i = 0; } } }