From d99373b94d096f051a31087c6101a95afa6fbf2f Mon Sep 17 00:00:00 2001 From: Dominik Zipperle Date: Thu, 15 Dec 2016 12:17:46 +0100 Subject: [PATCH] Add function in DirectShow D3DRenderer to get the current video frame as thread-safe image --- Source/DirectShow/Controls/D3DRenderer.cs | 50 +++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/Source/DirectShow/Controls/D3DRenderer.cs b/Source/DirectShow/Controls/D3DRenderer.cs index 32f70a0..3c050a2 100644 --- a/Source/DirectShow/Controls/D3DRenderer.cs +++ b/Source/DirectShow/Controls/D3DRenderer.cs @@ -601,5 +601,55 @@ public D3DRenderer CloneD3DRenderer() renderer.SetBackBuffer(m_pBackBuffer); return renderer; } + + /// + /// Creates a cloned image of the current video frame. + /// The image can be used thread-safe. + /// + /// + public Image CloneSingleFrameImage() + { + // create new image and it's D3D source + Image img = new Image(); + D3DImage d3dSource = new D3DImage(); + + // add the D3D source + img.Source = d3dSource; + + // set default stretch + img.Stretch = (Stretch)StretchProperty.DefaultMetadata.DefaultValue; + img.StretchDirection = (StretchDirection)StretchProperty.DefaultMetadata.DefaultValue; + + // store pixel width and height + int pxWidth = 0; + int pxHeight = 0; + + /* We have this around a try/catch just in case we + * lose the device and our Surface is invalid. The + * try/catch may not be needed, but testing needs + * to take place before it's removed */ + try + { + // assign surface as back buffer + d3dSource.Lock(); + d3dSource.SetBackBuffer(D3DResourceType.IDirect3DSurface9, m_pBackBuffer); + d3dSource.Unlock(); + + // update pixel width and height + pxWidth = d3dSource.PixelWidth; + pxHeight = d3dSource.PixelHeight; + } + catch (Exception ex) + { + return null; + } + + // UIElement Layout Update + img.Measure(new Size(pxWidth, pxHeight)); + img.Arrange(new Rect(new Size(pxWidth, pxHeight))); + img.UpdateLayout(); + + return img; + } } }