Exemple #1
0
        //-----------------------------------------------------------------------------
        // PresentSwapChain
        //
        // Presents a swap chain that contains a video frame.
        //
        // pSwapChain: Pointer to the swap chain.
        // pSurface: Pointer to the swap chain's back buffer surface.

        //
        // Note: This method simply calls IDirect3DSwapChain9::Present, but a derived
        // class could do something fancier.
        //-----------------------------------------------------------------------------

        protected void PresentSwapChain(IDirect3DSwapChain9 pSwapChain, IDirect3DSurface9 pSurface)
        {
            if (m_hwnd == IntPtr.Zero)
            {
                throw new COMException("D3DPresentEngine::PresentSwapChain", (int)HResult.MF_E_INVALIDREQUEST);
            }

            pSwapChain.Present(null, m_rcDestRect, m_hwnd, null, 0);
            m_iFrames++;
        }
Exemple #2
0
        //-----------------------------------------------------------------------------
        // CreateD3DSample
        //
        // Creates an sample object (IMFSample) to hold a Direct3D swap chain.
        //-----------------------------------------------------------------------------

        protected void CreateD3DSample(IDirect3DSwapChain9 pSwapChain, out IMFSample ppVideoSample)
        {
            HResult           hr;
            IDirect3DSurface9 pSurface = null;

            // Caller holds the object lock.
            try
            {
                // Get the back buffer surface.
                pSwapChain.GetBackBuffer(0, D3DBACKBUFFER_TYPE.Mono, out pSurface);

                // Create the sample.
                hr = MFExtern.MFCreateVideoSampleFromSurface(pSurface, out ppVideoSample);
                MFError.ThrowExceptionForHR(hr);
            }
            finally
            {
                SafeRelease(pSurface); pSurface = null;
            }
        }
Exemple #3
0
        //-----------------------------------------------------------------------------
        // PresentSample
        //
        // Presents a video frame.
        //
        // pSample:  Pointer to the sample that contains the surface to present. If
        //           this parameter is NULL, the method paints a black rectangle.
        // llTarget: Target presentation time.
        //
        // This method is called by the scheduler and/or the presenter.
        //-----------------------------------------------------------------------------

        public void PresentSample(IMFSample pSample, long llTarget)
        {
            HResult             hr;
            IMFMediaBuffer      pBuffer    = null;
            IDirect3DSurface9   pSurface   = null;
            IDirect3DSwapChain9 pSwapChain = null;
            object o;

            try
            {
                if (pSample != null)
                {
                    // Get the buffer from the sample.
                    hr = pSample.GetBufferByIndex(0, out pBuffer);
                    MFError.ThrowExceptionForHR(hr);

                    // Get the surface from the buffer.
                    hr = MFExtern.MFGetService(pBuffer, MFServices.MR_BUFFER_SERVICE, typeof(IDirect3DSurface9).GUID, out o);
                    MFError.ThrowExceptionForHR(hr);
                    pSurface = o as IDirect3DSurface9;
                }
                else if (m_pSurfaceRepaint != null)
                {
                    // Redraw from the last surface.
                    pSurface = m_pSurfaceRepaint;
                }

                if (pSurface != null)
                {
                    // Get the swap chain from the surface.
                    pSurface.GetContainer(typeof(IDirect3DSwapChain9).GUID, out o);
                    pSwapChain = o as IDirect3DSwapChain9;

                    // Present the swap chain.
                    PresentSwapChain(pSwapChain, pSurface);

                    // Store this pointer in case we need to repaint the surface.
                    if (m_pSurfaceRepaint != pSurface)
                    {
                        SafeRelease(m_pSurfaceRepaint);
                        m_pSurfaceRepaint = pSurface;
                    }
                }
                else
                {
                    // No surface. All we can do is paint a black rectangle.
                    PaintFrameWithGDI();
                }
            }
            catch (Exception e)
            {
                hr = (HResult)Marshal.GetHRForException(e);
                if (hr == (HResult)D3DError.DeviceLost || hr == (HResult)D3DError.DeviceNotReset || hr == (HResult)D3DError.DeviceHung)
                {
                    // We failed because the device was lost. Fill the destination rectangle.
                    PaintFrameWithGDI();

                    // Ignore. We need to reset or re-create the device, but this method
                    // is probably being called from the scheduler thread, which is not the
                    // same thread that created the device. The Reset(Ex) method must be
                    // called from the thread that created the device.

                    // The presenter will detect the state when it calls CheckDeviceState()
                    // on the next sample.
                }
            }
            finally
            {
                SafeRelease(pSwapChain); pSwapChain = null;
                //SafeRelease(pSurface); pSurface = null;
                SafeRelease(pBuffer); pBuffer = null;
            }
        }
Exemple #4
0
        //-----------------------------------------------------------------------------
        // CreateVideoSamples
        //
        // Creates video samples based on a specified media type.
        //
        // pFormat: Media type that describes the video format.
        // videoSampleQueue: List that will contain the video samples.
        //
        // Note: For each video sample, the method creates a swap chain with a
        // single back buffer. The video sample object holds a pointer to the swap
        // chain's back buffer surface. The mixer renders to this surface, and the
        // D3DPresentEngine renders the video frame by presenting the swap chain.
        //-----------------------------------------------------------------------------

        public void CreateVideoSamples(
            IMFMediaType pFormat,
            Queue <IMFSample> videoSampleQueue
            )
        {
            if (m_hwnd == IntPtr.Zero)
            {
                throw new COMException("D3DPresentEngine::CreateVideoSamples", (int)HResult.MF_E_INVALIDREQUEST);
            }

            if (pFormat == null)
            {
                throw new COMException("D3DPresentEngine::CreateVideoSamples", (int)HResult.MF_E_UNEXPECTED);
            }

            HResult hr;
            D3DPRESENT_PARAMETERS pp;

            IDirect3DSwapChain9 pSwapChain   = null;  // Swap chain
            IMFSample           pVideoSample = null;  // Sampl

            lock (this)
            {
                ReleaseResources();

                try
                {
                    // Get the swap chain parameters from the media type.
                    GetSwapChainPresentParameters(pFormat, out pp);

                    UpdateDestRect();

                    // Create the video samples.
                    for (int i = 0; i < PRESENTER_BUFFER_COUNT; i++)
                    {
                        // Create a new swap chain.
                        m_pDevice.CreateAdditionalSwapChain(pp, out pSwapChain);

                        // Create the video sample from the swap chain.
                        CreateD3DSample(pSwapChain, out pVideoSample);

                        // Add it to the list.
                        videoSampleQueue.Enqueue(pVideoSample);

                        // Set the swap chain pointer as a custom attribute on the sample. This keeps
                        // a reference count on the swap chain, so that the swap chain is kept alive
                        // for the duration of the sample's lifetime.
                        hr = pVideoSample.SetUnknown(EVRCustomPresenter.MFSamplePresenter_SampleSwapChain, pSwapChain);
                        MFError.ThrowExceptionForHR(hr);

                        //SafeRelease(pVideoSample);
                        SafeRelease(pSwapChain); pSwapChain = null;
                    }
                }
                catch
                {
                    ReleaseResources();
                }
                finally
                {
                    SafeRelease(pSwapChain); pSwapChain = null;
                    //SafeRelease(pVideoSample);
                }
            }
        }
Exemple #5
0
        //-----------------------------------------------------------------------------
        // PresentSwapChain
        //
        // Presents a swap chain that contains a video frame.
        //
        // pSwapChain: Pointer to the swap chain.
        // pSurface: Pointer to the swap chain's back buffer surface.
        //
        // Note: This method simply calls IDirect3DSwapChain9::Present, but a derived
        // class could do something fancier.
        //-----------------------------------------------------------------------------
        protected void PresentSwapChain(IDirect3DSwapChain9 pSwapChain, IDirect3DSurface9 pSurface)
        {
            if (m_hwnd == IntPtr.Zero)
            {
                throw new COMException("D3DPresentEngine::PresentSwapChain", MFError.MF_E_INVALIDREQUEST);
            }

            pSwapChain.Present(null, m_rcDestRect, m_hwnd, null, 0);
            m_iFrames++;
        }
Exemple #6
0
        //-----------------------------------------------------------------------------
        // CreateD3DSample
        //
        // Creates an sample object (IMFSample) to hold a Direct3D swap chain.
        //-----------------------------------------------------------------------------
        protected void CreateD3DSample(IDirect3DSwapChain9 pSwapChain, out IMFSample ppVideoSample)
        {
            int hr;
            IDirect3DSurface9 pSurface = null;

            // Caller holds the object lock.
            try
            {
                // Get the back buffer surface.
                pSwapChain.GetBackBuffer(0, D3DBACKBUFFER_TYPE.Mono, out pSurface);

                // Create the sample.
                hr = MFExtern.MFCreateVideoSampleFromSurface(pSurface, out ppVideoSample);
                MFError.ThrowExceptionForHR(hr);
            }
            finally
            {
                SafeRelease(pSurface); pSurface = null;
            }
        }