private Task CreateScreenCaptureTask() { Logger.Debug("Screen", "CreateScreenCaptureTask"); return(new Task(() => { if (null == customVideoCapturer) { return; } while (true) { using (var frame = screenCaptureQueue.Take()) { if (null == frame) { return; } if ((frame.ContentSize.Width != lastSize.Width) || (frame.ContentSize.Height != lastSize.Height)) { lastSize = frame.ContentSize; ResetFramePool(frame.ContentSize, false); } try { var canvasBitmap = CanvasBitmap.CreateFromDirect3D11Surface(canvasDevice, frame.Surface); uint actualBitmapWidth = canvasBitmap.SizeInPixels.Width; uint actualBitmapHeight = canvasBitmap.SizeInPixels.Height; uint bitmapWidth = actualBitmapWidth; uint bitmapHeight = actualBitmapHeight; if (bitmapWidth % 2 != 0) { bitmapWidth += 1; } if (bitmapHeight % 2 != 0) { bitmapHeight += 1; } VideoData rgbData = new VideoData((ulong)(bitmapWidth * bitmapHeight * 4)); var pixels = canvasBitmap.GetPixelBytes(); if (bitmapWidth != actualBitmapWidth) { var tmpPixels = new byte[bitmapWidth * bitmapHeight * 4]; Int64 indexSource = 0; Int64 indexDest = 0; Int64 strideSource = actualBitmapWidth * 4; Int64 strideDest = bitmapWidth * 4; for (uint y = 0; y < actualBitmapHeight; ++y) { Array.Copy(pixels, indexSource, tmpPixels, indexDest, strideSource); indexSource += strideSource; indexDest += strideDest; } pixels = tmpPixels; } rgbData.SetData8bit(pixels); var buffer = VideoFrameBuffer.CreateFromARGB( (int)bitmapWidth, (int)bitmapHeight, (int)(4 * bitmapWidth), rgbData); customVideoCapturer.NotifyFrame( buffer, (ulong)(DateTimeOffset.Now.ToUnixTimeMilliseconds()), VideoRotation.Rotation0); } catch (Exception e) when(canvasDevice.IsDeviceLost(e.HResult)) { ResetFramePool(frame.ContentSize, true); } } } })); }