/// <summary> /// This is a prototype! Do not use except for testing! /// Will update the texture based based on IDirectMemoryFrame. /// Only i420p supported! /// Note that this method can easily cause crashes if the memory /// isn't structured as expected. /// </summary> /// <param name="frame"></param> /// <param name="yplane"></param> /// <param name="uplane"></param> /// <param name="vplane"></param> /// <returns></returns> public static bool UpdateTexture(IDirectMemoryFrame frame, ref Texture2D yplane, ref Texture2D uplane, ref Texture2D vplane) { if (frame.Format == FramePixelFormat.I420p) { var dframe = frame as IDirectMemoryFrame; int width = frame.Width; int height = frame.Height; int hwidth = frame.Width / 2; int hheight = frame.Height / 2; TextureFormat texFormat = TextureFormat.R8; bool newTextureCreated = EnsureTex(width, height, texFormat, ref yplane); newTextureCreated |= EnsureTex(hwidth, hheight, texFormat, ref uplane); newTextureCreated |= EnsureTex(hwidth, hheight, texFormat, ref vplane); IntPtr ystart = dframe.GetIntPtr(); long ylength = width * height; IntPtr ustart = new IntPtr(ystart.ToInt64() + ylength); long ulength = (hwidth * hheight); IntPtr vstart = new IntPtr(ustart.ToInt64() + ulength); yplane.LoadRawTextureData(ystart, (int)ylength); uplane.LoadRawTextureData(ustart, (int)ulength); vplane.LoadRawTextureData(vstart, (int)ulength); yplane.Apply(); uplane.Apply(); vplane.Apply(); return(newTextureCreated); } else { Debug.LogError("Format not supported"); return(false); } }
/// <summary> /// Helper to update a RawImage based on IFrame. /// /// Watch out this method might change the material and textures /// used for the RawImage. /// /// This method can be used in the future to support i420p using /// a specific shader / material / texture combination. /// /// </summary> /// <param name="target"></param> /// <param name="frame"></param> /// <returns></returns> public static bool UpdateRawImage(RawImage target, IFrame frame) { if (target == null || frame == null) { return(false); } if (frame.Format == FramePixelFormat.I420p && frame is IDirectMemoryFrame) { if (target.material.name != I420_MAT_NAME) { Material mat = Resources.Load <Material>(I420_MAT_NAME); target.material = new Material(mat); } //using the texture references in the shader if possible //makes it easier reusable Texture2D mainTex = target.texture as Texture2D; Texture2D uTex = target.material.GetTexture(I420_MAT_UPLANE) as Texture2D; Texture2D vTex = target.material.GetTexture(I420_MAT_VPLANE) as Texture2D; IDirectMemoryFrame dframe = frame as IDirectMemoryFrame; //update existing textures or create new ones bool textureCreated = UnityMediaHelper.UpdateTexture(dframe, ref mainTex, ref uTex, ref vTex); dframe.Dispose(); dframe = null; if (textureCreated) { //new textures where creates (e.g. due to resolution change) //update the UI target.texture = mainTex; target.material.SetTexture(I420_MAT_UPLANE, uTex); target.material.SetTexture(I420_MAT_VPLANE, vTex); } return(textureCreated); } else { if (target.material != target.defaultMaterial) { target.material = target.defaultMaterial; } Texture2D mainTex = target.texture as Texture2D; bool textureCreated = UnityMediaHelper.UpdateTexture(frame, ref mainTex); if (textureCreated) { //helper had to create a new texture object -> refresh ui target.texture = mainTex; } return(textureCreated); } }