/// <summary> /// Renders an object and sends the image to the XSplit plugin. /// This method must be called on the same thread as the owner of the Visual, in most cases the UI (main) thread. /// </summary> /// <param name="obj"> /// Visual object to render and send to XSplit. /// </param> /// <param name="width"> /// Desired output width, in pixels. /// </param> /// <param name="height"> /// Desired output height, in pixels. /// </param> /// <returns> /// Returns whether the call was successful and the object was rendered. If obj is null, false will always be returned. /// </returns> public bool RenderVisual(Bitmap img) { if (img == null) { return(false); } if (ConnectionIsReady) { // The remaining work (format conversion, sending to xsplit) can be done on a seperate thread) Task.Factory.StartNew( () => { using (var stream = new MemoryStream()) { img.Save(stream, ImageFormat.Bmp); stream.Position = 0; byte[] bytes = stream.ToArray(); // Length of output data we're going to send. int length = img.Width * img.Height * 4; // Allocate memory for bitmap transfer to COM IntPtr dataptr = Marshal.AllocCoTaskMem(length); Marshal.Copy(bytes, bytes.Length - length, dataptr, length); xsplit.SendFrame((uint)img.Width, (uint)img.Height, dataptr.ToInt32()); // Send to broadcaster Marshal.FreeCoTaskMem(dataptr); } }); return(true); } return(false); }