internal PreviewFrame(IntPtr ptr, ref PinnedPreviewBuffer <byte> buffers) { var unmanagedStruct = Marshal.PtrToStructure <CameraPreviewDataStruct>(ptr); Format = unmanagedStruct.Format; Resolution = new Size(unmanagedStruct.Width, unmanagedStruct.Height); TimeStamp = unmanagedStruct.TimeStamp; PlaneType = GetPlaneType(unmanagedStruct); CreatePlane(unmanagedStruct, ref buffers); }
internal void CreatePlane(CameraPreviewDataStruct unmanagedStruct, ref PinnedPreviewBuffer <byte> buffers) { switch (PlaneType) { case PlaneType.SinglePlane: var singlePlane = unmanagedStruct.Plane.SinglePlane; if (buffers == null || CheckReallocation(unmanagedStruct, ref buffers)) { buffers = new PinnedPreviewBuffer <byte>(singlePlane.DataLength); } Marshal.Copy(singlePlane.Data, buffers[0], 0, (int)singlePlane.DataLength); Plane = new SinglePlane(buffers[0]); break; case PlaneType.DoublePlane: var doublePlane = unmanagedStruct.Plane.DoublePlane; doublePlane.YLength = (uint)(Resolution.Width * Resolution.Height); doublePlane.UVLength = (uint)(Resolution.Width * Resolution.Height) / 2; if (buffers == null || CheckReallocation(unmanagedStruct, ref buffers)) { buffers = new PinnedPreviewBuffer <byte>(doublePlane.YLength, doublePlane.UVLength); } Marshal.Copy(doublePlane.Y, buffers[0], 0, (int)doublePlane.YLength); Marshal.Copy(doublePlane.UV, buffers[1], 0, (int)doublePlane.UVLength); Plane = new DoublePlane(buffers[0], buffers[1]); break; case PlaneType.TriplePlane: var triplePlane = unmanagedStruct.Plane.TriplePlane; if (buffers == null || CheckReallocation(unmanagedStruct, ref buffers)) { buffers = new PinnedPreviewBuffer <byte>(triplePlane.YLength, triplePlane.ULength, triplePlane.VLength); } Marshal.Copy(triplePlane.Y, buffers[0], 0, (int)triplePlane.YLength); Marshal.Copy(triplePlane.U, buffers[1], 0, (int)triplePlane.ULength); Marshal.Copy(triplePlane.V, buffers[2], 0, (int)triplePlane.VLength); Plane = new TriplePlane(buffers[0], buffers[1], buffers[2]); break; case PlaneType.EncodedPlane: var encodedPlane = unmanagedStruct.Plane.EncodedPlane; if (buffers == null || CheckReallocation(unmanagedStruct, ref buffers)) { // We take buffer margin to avoid reallocation as much as possible. buffers = new PinnedPreviewBuffer <byte>(encodedPlane.DataLength * _variableBufferMargin); } Marshal.Copy(encodedPlane.Data, buffers[0], 0, (int)encodedPlane.DataLength); Plane = new EncodedPlane(buffers[0], encodedPlane.IsDeltaFrame); break; case PlaneType.DepthPlane: var depthPlane = unmanagedStruct.Plane.DepthPlane; if (buffers == null || CheckReallocation(unmanagedStruct, ref buffers)) { buffers = new PinnedPreviewBuffer <byte>(depthPlane.DataLength); } Marshal.Copy(depthPlane.Data, buffers[0], 0, (int)depthPlane.DataLength); Plane = new DepthPlane(buffers[0]); break; case PlaneType.RgbPlane: var rgbPlane = unmanagedStruct.Plane.RgbPlane; if (buffers == null || CheckReallocation(unmanagedStruct, ref buffers)) { buffers = new PinnedPreviewBuffer <byte>(rgbPlane.DataLength); } Marshal.Copy(rgbPlane.Data, buffers[0], 0, (int)rgbPlane.DataLength); Plane = new RgbPlane(buffers[0]); break; default: Debug.Fail("Unknown preview data!"); break; } }
internal bool CheckReallocation(CameraPreviewDataStruct unmanagedStruct, ref PinnedPreviewBuffer <byte> buffers) { bool isReallocation = false; switch (PlaneType) { case PlaneType.SinglePlane: var singlePlane = unmanagedStruct.Plane.SinglePlane; if (buffers[0].Length < singlePlane.DataLength) { isReallocation = true; } break; case PlaneType.DoublePlane: var doublePlane = unmanagedStruct.Plane.DoublePlane; doublePlane.YLength = (uint)(Resolution.Width * Resolution.Height); doublePlane.UVLength = (uint)(Resolution.Width * Resolution.Height) / 2; if (buffers[0].Length < doublePlane.YLength || buffers[1].Length < doublePlane.UVLength) { isReallocation = true; } break; case PlaneType.TriplePlane: var triplePlane = unmanagedStruct.Plane.TriplePlane; if (buffers[0].Length < triplePlane.YLength || buffers[1].Length < triplePlane.ULength || buffers[2].Length < triplePlane.VLength) { isReallocation = true; } break; case PlaneType.EncodedPlane: var encodedPlane = unmanagedStruct.Plane.EncodedPlane; if (buffers[0].Length < encodedPlane.DataLength) { Log.Debug(CameraLog.Tag, $"Cur size:{buffers[0].Length} -> New size:{encodedPlane.DataLength * _variableBufferMargin}"); isReallocation = true; } break; case PlaneType.DepthPlane: var depthPlane = unmanagedStruct.Plane.DepthPlane; if (buffers[0].Length < depthPlane.DataLength) { isReallocation = true; } break; case PlaneType.RgbPlane: var rgbPlane = unmanagedStruct.Plane.RgbPlane; if (buffers[0].Length < rgbPlane.DataLength) { isReallocation = true; } break; default: Debug.Fail("Unknown preview data!"); break; } if (isReallocation) { Log.Debug(CameraLog.Tag, "Reallocate preview buffer."); // Dispose current buffer to free GCHandle. buffers.Dispose(); } return(isReallocation); }