Beispiel #1
0
    // Shut down capture
    private void CloseInterfaces()
    {
        int hr;

        lock (this)
        {
            if (m_State != GraphState.Exiting)
            {
                m_State = GraphState.Exiting;

                // Release the thread (if the thread was started)
                if (m_mre != null)
                {
                    m_mre.Set();
                }
            }

            if (m_mediaCtrl != null)
            {
                // Stop the graph
                hr          = m_mediaCtrl.Stop();
                m_mediaCtrl = null;
            }

            if (m_sampGrabber != null)
            {
                Marshal.ReleaseComObject(m_sampGrabber);
                m_sampGrabber = null;
            }

#if DEBUG
            if (m_DsRot != null)
            {
                m_DsRot.Dispose();
            }
#endif

            if (m_graphBuilder != null)
            {
                Marshal.ReleaseComObject(m_graphBuilder);
                m_graphBuilder = null;
            }
        }
        GC.Collect();
    }
Beispiel #2
0
    /// <summary> Shut down capture </summary>
    private void CloseInterfaces()
    {
        int hr;

        try
        {
            if (m_mediaCtrl != null)
            {
                // Stop the graph
                hr         = m_mediaCtrl.Stop();
                m_bRunning = false;
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex);
        }

        if (m_graphBuilder != null)
        {
            Marshal.ReleaseComObject(m_graphBuilder);
            m_graphBuilder = null;
        }
    }
Beispiel #3
0
    // Shut down capture
    private void CloseInterfaces()
    {
        int hr;

        lock (this)
        {
            if (m_State != GraphState.Exiting)
            {
                m_State = GraphState.Exiting;

                // Release the thread (if the thread was started)
                if (m_mre != null)
                {
                    m_mre.Set();
                }
            }

            if( m_mediaCtrl != null )
            {
                // Stop the graph
                hr = m_mediaCtrl.Stop();
                m_mediaCtrl = null;
            }

            if (m_sampGrabber != null)
            {
                Marshal.ReleaseComObject(m_sampGrabber);
                m_sampGrabber = null;
            }

#if DEBUG
            if (m_DsRot != null)
            {
                m_DsRot.Dispose();
            }
#endif

            if (m_graphBuilder != null)
            {
                Marshal.ReleaseComObject(m_graphBuilder);
                m_graphBuilder = null;
            }
        }
        GC.Collect();
    }
Beispiel #4
0
	// Build the capture graph for grabber and renderer.</summary>
	// (Control to show video in, Filename to play)
	private void SetupGraph(string FileName)
	{
		int hr;

		// Get the graphbuilder object
		m_graphBuilder = new DirectShowLib.FilterGraph() as DirectShowLib.IFilterGraph2;

		// Get a ICaptureGraphBuilder2 to help build the graph
		DirectShowLib.ICaptureGraphBuilder2 icgb2 = new DirectShowLib.CaptureGraphBuilder2() as DirectShowLib.ICaptureGraphBuilder2;

		try
		{
			// Link the ICaptureGraphBuilder2 to the IFilterGraph2
			hr = icgb2.SetFiltergraph(m_graphBuilder);
			DsError.ThrowExceptionForHR( hr );

#if DEBUG
			// Allows you to view the graph with GraphEdit File/Connect
			m_DsRot = new DsROTEntry(m_graphBuilder);
#endif

			// Add the filters necessary to render the file.  This function will
			// work with a number of different file types.
			IBaseFilter	sourceFilter = null;
			hr = m_graphBuilder.AddSourceFilter(FileName, FileName, out sourceFilter);
			DsError.ThrowExceptionForHR( hr );

			// Get the SampleGrabber interface
			m_sampGrabber = (DirectShowLib.ISampleGrabber) new DirectShowLib.SampleGrabber();
			DirectShowLib.IBaseFilter baseGrabFlt = (DirectShowLib.IBaseFilter)	m_sampGrabber;

			// Configure the Sample Grabber
			ConfigureSampleGrabber(m_sampGrabber);

			// Add it to the filter
			hr = m_graphBuilder.AddFilter( baseGrabFlt, "Ds.NET Grabber" );
			DsError.ThrowExceptionForHR( hr );

			// System.Windows.Forms.MessageBox.Show(Width.ToString(), Height.ToString(), System.Windows.Forms.MessageBoxButtons.OK);

			// A Null Renderer does not display the video
			// But it allows the Sample Grabber to run
			// And it will keep proper playback timing
			// Unless specified otherwise.
			DirectShowLib.NullRenderer nullRenderer = new DirectShowLib.NullRenderer();

			m_graphBuilder.AddFilter((DirectShowLib.IBaseFilter) nullRenderer, "Null Renderer");

			// Connect the pieces together, use the default renderer
			hr = icgb2.RenderStream(null, null, sourceFilter, baseGrabFlt, (DirectShowLib.IBaseFilter) nullRenderer);
			DsError.ThrowExceptionForHR( hr );

			// Now that the graph is built, read the dimensions of the bitmaps we'll be getting
			SaveSizeInfo(m_sampGrabber);

			// Configure the Video Window
			//DirectShowLib.IVideoWindow videoWindow = m_graphBuilder as DirectShowLib.IVideoWindow;
			//ConfigureVideoWindow(videoWindow, hWin);

			// Grab some other interfaces
			m_mediaEvent = m_graphBuilder as DirectShowLib.IMediaEvent;
			m_mediaCtrl = m_graphBuilder as DirectShowLib.IMediaControl;
		}
		finally
		{
			if (icgb2 != null)
			{
				Marshal.ReleaseComObject(icgb2);
				icgb2 = null;
			}
		}
#if DEBUG
		// Double check to make sure we aren't releasing something
		// important.
		GC.Collect();
		GC.WaitForPendingFinalizers();
#endif
	}
Beispiel #5
0
    /// <summary> Shut down capture </summary>
    private void CloseInterfaces()
    {
        int hr;

        try
        {
            if( m_mediaCtrl != null )
            {
                // Stop the graph
                hr = m_mediaCtrl.Stop();
                m_bRunning = false;
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex);
        }

        if (m_graphBuilder != null)
        {
            Marshal.ReleaseComObject(m_graphBuilder);
            m_graphBuilder = null;
        }
    }
Beispiel #6
0
    /// <summary> build the capture graph for grabber. </summary>
    private void SetupGraph(DsDevice dev, int iFrameRate, int iWidth, int iHeight, Control hControl)
    {
        int hr;

        DirectShowLib.ISampleGrabber sampGrabber = null;
        DirectShowLib.IBaseFilter capFilter = null;
        DirectShowLib.ICaptureGraphBuilder2 capGraph = null;

        // Get the graphbuilder object
        m_graphBuilder = (DirectShowLib.IFilterGraph2) new FilterGraph();
        m_mediaCtrl = m_graphBuilder as DirectShowLib.IMediaControl;
        try
        {
            // Get the ICaptureGraphBuilder2
            capGraph = (DirectShowLib.ICaptureGraphBuilder2) new DirectShowLib.CaptureGraphBuilder2();

            // Get the SampleGrabber interface
            sampGrabber = (DirectShowLib.ISampleGrabber) new DirectShowLib.SampleGrabber();

            // Start building the graph
            hr = capGraph.SetFiltergraph( m_graphBuilder );
            DsError.ThrowExceptionForHR( hr );

            // Add the video device
            hr = m_graphBuilder.AddSourceFilterForMoniker(dev.Mon, null, "Video input", out capFilter);
            DsError.ThrowExceptionForHR( hr );

            DirectShowLib.IBaseFilter baseGrabFlt = (DirectShowLib.IBaseFilter)	sampGrabber;
            ConfigureSampleGrabber(sampGrabber);

            // Add the frame grabber to the graph
            hr = m_graphBuilder.AddFilter( baseGrabFlt, "Ds.NET Grabber" );
            DsError.ThrowExceptionForHR( hr );

            // If any of the default config items are set
            if (iFrameRate + iHeight + iWidth > 0)
            {
                SetConfigParms(capGraph, capFilter, iFrameRate, iWidth, iHeight);
            }

			// ------------------------------------

			if (false) 
			{
				if (false)
				{
					hr = capGraph.RenderStream(DirectShowLib.PinCategory.Preview, DirectShowLib.MediaType.Video, capFilter, null, baseGrabFlt);
					DsError.ThrowExceptionForHR(hr);
				}
				theCompressor = CreateFilter(FilterCategory.VideoCompressorCategory, "Microsoft MPEG-4 Video Codec V2");

				// Add the Video compressor filter to the graph
				if (theCompressor != null)
				{
					hr = m_graphBuilder.AddFilter(theCompressor, "Compressor Filter");
					DsError.ThrowExceptionForHR(hr);
				}

				// Create the file writer part of the graph. SetOutputFileName does this for us, and returns the mux and sink
				DirectShowLib.IBaseFilter mux;
				DirectShowLib.IFileSinkFilter sink;
				hr = capGraph.SetOutputFileName(DirectShowLib.MediaSubType.Avi, "C:\\Test.avi", out mux, out sink);
				DsError.ThrowExceptionForHR(hr);

				hr = capGraph.RenderStream(DirectShowLib.PinCategory.Capture, DirectShowLib.MediaType.Video, capFilter, theCompressor, mux);
				DsError.ThrowExceptionForHR(hr);

				Marshal.ReleaseComObject(mux);
				Marshal.ReleaseComObject(sink);

				hr = capGraph.RenderStream(DirectShowLib.PinCategory.Preview, DirectShowLib.MediaType.Video, capFilter, null, null);
				DsError.ThrowExceptionForHR(hr);

				//ShowVideoWindow(hControl);
			}
			else
			{
				hr = capGraph.RenderStream(DirectShowLib.PinCategory.Capture, DirectShowLib.MediaType.Video, capFilter, null, baseGrabFlt);
				DsError.ThrowExceptionForHR(hr);

				//hr = capGraph.RenderStream(DirectShowLib.PinCategory.Preview, DirectShowLib.MediaType.Video, capFilter, null, null);
				//DsError.ThrowExceptionForHR(hr);

				//ShowVideoWindow(hControl);
			}

            // --------------------------------------

            //hr = capGraph.RenderStream( DirectShowLib.PinCategory.Capture, DirectShowLib.MediaType.Video, capFilter, null, baseGrabFlt );
            //DsError.ThrowExceptionForHR( hr );

            SaveSizeInfo(sampGrabber);
        }
        finally
        {
            if (capFilter != null)
            {
                Marshal.ReleaseComObject(capFilter);
                capFilter = null;
            }
            if (sampGrabber != null)
            {
                Marshal.ReleaseComObject(sampGrabber);
                sampGrabber = null;
            }
            if (capGraph != null)
            {
                Marshal.ReleaseComObject(capGraph);
                capGraph = null;
            }
        }
    }
Beispiel #7
0
    /// <summary> build the capture graph for grabber. </summary>
    private void SetupGraph(DsDevice dev, int iFrameRate, int iWidth, int iHeight, Control hControl)
    {
        int hr;

        DirectShowLib.ISampleGrabber        sampGrabber = null;
        DirectShowLib.IBaseFilter           capFilter   = null;
        DirectShowLib.ICaptureGraphBuilder2 capGraph    = null;

        // Get the graphbuilder object
        m_graphBuilder = (DirectShowLib.IFilterGraph2) new FilterGraph();
        m_mediaCtrl    = m_graphBuilder as DirectShowLib.IMediaControl;
        try
        {
            // Get the ICaptureGraphBuilder2
            capGraph = (DirectShowLib.ICaptureGraphBuilder2) new DirectShowLib.CaptureGraphBuilder2();

            // Get the SampleGrabber interface
            sampGrabber = (DirectShowLib.ISampleGrabber) new DirectShowLib.SampleGrabber();

            // Start building the graph
            hr = capGraph.SetFiltergraph(m_graphBuilder);
            DsError.ThrowExceptionForHR(hr);

            // Add the video device
            hr = m_graphBuilder.AddSourceFilterForMoniker(dev.Mon, null, "Video input", out capFilter);
            DsError.ThrowExceptionForHR(hr);

            DirectShowLib.IBaseFilter baseGrabFlt = (DirectShowLib.IBaseFilter)sampGrabber;
            ConfigureSampleGrabber(sampGrabber);

            // Add the frame grabber to the graph
            hr = m_graphBuilder.AddFilter(baseGrabFlt, "Ds.NET Grabber");
            DsError.ThrowExceptionForHR(hr);

            // If any of the default config items are set
            if (iFrameRate + iHeight + iWidth > 0)
            {
                SetConfigParms(capGraph, capFilter, iFrameRate, iWidth, iHeight);
            }

            // ------------------------------------

            if (false)
            {
                if (false)
                {
                    hr = capGraph.RenderStream(DirectShowLib.PinCategory.Preview, DirectShowLib.MediaType.Video, capFilter, null, baseGrabFlt);
                    DsError.ThrowExceptionForHR(hr);
                }
                theCompressor = CreateFilter(FilterCategory.VideoCompressorCategory, "Microsoft MPEG-4 Video Codec V2");

                // Add the Video compressor filter to the graph
                if (theCompressor != null)
                {
                    hr = m_graphBuilder.AddFilter(theCompressor, "Compressor Filter");
                    DsError.ThrowExceptionForHR(hr);
                }

                // Create the file writer part of the graph. SetOutputFileName does this for us, and returns the mux and sink
                DirectShowLib.IBaseFilter     mux;
                DirectShowLib.IFileSinkFilter sink;
                hr = capGraph.SetOutputFileName(DirectShowLib.MediaSubType.Avi, "C:\\Test.avi", out mux, out sink);
                DsError.ThrowExceptionForHR(hr);

                hr = capGraph.RenderStream(DirectShowLib.PinCategory.Capture, DirectShowLib.MediaType.Video, capFilter, theCompressor, mux);
                DsError.ThrowExceptionForHR(hr);

                Marshal.ReleaseComObject(mux);
                Marshal.ReleaseComObject(sink);

                hr = capGraph.RenderStream(DirectShowLib.PinCategory.Preview, DirectShowLib.MediaType.Video, capFilter, null, null);
                DsError.ThrowExceptionForHR(hr);

                //ShowVideoWindow(hControl);
            }
            else
            {
                hr = capGraph.RenderStream(DirectShowLib.PinCategory.Capture, DirectShowLib.MediaType.Video, capFilter, null, baseGrabFlt);
                DsError.ThrowExceptionForHR(hr);

                //hr = capGraph.RenderStream(DirectShowLib.PinCategory.Preview, DirectShowLib.MediaType.Video, capFilter, null, null);
                //DsError.ThrowExceptionForHR(hr);

                //ShowVideoWindow(hControl);
            }

            // --------------------------------------

            //hr = capGraph.RenderStream( DirectShowLib.PinCategory.Capture, DirectShowLib.MediaType.Video, capFilter, null, baseGrabFlt );
            //DsError.ThrowExceptionForHR( hr );

            SaveSizeInfo(sampGrabber);
        }
        finally
        {
            if (capFilter != null)
            {
                Marshal.ReleaseComObject(capFilter);
                capFilter = null;
            }
            if (sampGrabber != null)
            {
                Marshal.ReleaseComObject(sampGrabber);
                sampGrabber = null;
            }
            if (capGraph != null)
            {
                Marshal.ReleaseComObject(capGraph);
                capGraph = null;
            }
        }
    }
        private void CloseInterfaces()
        {
            _hiddenWindow.SizeChanged -= _hiddenWindow_SizeChanged;

            int hr;

            if (_defaultAudioRenderer != null)
            {
                m_graph.RemoveFilter(_defaultAudioRenderer as DirectShowLib.IBaseFilter);

                Marshal.ReleaseComObject(_defaultAudioRenderer);
                _defaultAudioRenderer = null;
            }

            if (_reclockAudioRenderer != null)
            {
                m_graph.RemoveFilter(_reclockAudioRenderer as DirectShowLib.IBaseFilter);

                Marshal.ReleaseComObject(_reclockAudioRenderer);
                _reclockAudioRenderer = null;
            }

            if (_lavaudio != null)
            {
                m_graph.RemoveFilter(_lavaudio as DirectShowLib.IBaseFilter);

                Marshal.ReleaseComObject(_lavaudio);
                _lavaudio = null;
            }

            if (_xyVsFilter != null)
            {
                m_graph.RemoveFilter(_xyVsFilter as DirectShowLib.IBaseFilter);

                Marshal.ReleaseComObject(_xyVsFilter);
                _xyVsFilter = null;
            }

            if (_xySubFilter != null)
            {
                m_graph.RemoveFilter(_xySubFilter as DirectShowLib.IBaseFilter);

                Marshal.ReleaseComObject(_xySubFilter);
                _xySubFilter = null;
            }

            if (_lavvideo != null)
            {
                m_graph.RemoveFilter(_lavvideo as DirectShowLib.IBaseFilter);

                Marshal.ReleaseComObject(_lavvideo);
                _lavvideo = null;
            }

            if (_madvr != null)
            {
                m_graph.RemoveFilter(_madvr as DirectShowLib.IBaseFilter);

                Marshal.ReleaseComObject(_madvr);
                _madvr = null;
            }

            if (_videoWindow != null)
            {
                // Relinquish ownership (IMPORTANT!) after hiding video window
                hr = _videoWindow.put_Visible(OABool.False);

                hr = _videoWindow.put_Owner(IntPtr.Zero);
            }

            if (_mediaEventEx != null)
            {
                hr = _mediaEventEx.SetNotifyWindow(IntPtr.Zero, 0, IntPtr.Zero);
                Marshal.ReleaseComObject(_mediaEventEx);
                _mediaEventEx = null;
            }

            if (_dvdNav != null)
            {
                Marshal.ReleaseComObject(_dvdNav);
                _dvdNav = null;
            }

            if (_mDvdInfo != null)
            {
                Marshal.ReleaseComObject(_mDvdInfo);
                _mDvdInfo = null;
            }

            if (_mDvdControl != null)
            {
                Marshal.ReleaseComObject(_mDvdControl);
                _mDvdControl = null;
            }

            if (_mPDisplay != null)
            {
                Marshal.ReleaseComObject(_mPDisplay);
                _mPDisplay = null;
            }

            if (_filterGraph != null)
            {
                Marshal.ReleaseComObject(_filterGraph);
                _filterGraph = null;
            }

            if (_mPEvr != null)
            {
                Marshal.ReleaseComObject(_mPEvr);
                _mPEvr = null;
            }

            if (_mediaEventEx != null)
            {
                Marshal.ReleaseComObject(_mediaEventEx);
                _mediaEventEx = null;
            }

            if (_mediaSeeking != null)
            {
                Marshal.ReleaseComObject(_mediaSeeking);
                _mediaSeeking = null;
            }

            if (_mediaPosition != null)
            {
                Marshal.ReleaseComObject(_mediaPosition);
                _mediaPosition = null;
            }

            if (_mediaControl != null)
            {
                Marshal.ReleaseComObject(_mediaControl);
                _mediaControl = null;
            }

            if (_basicAudio != null)
            {
                Marshal.ReleaseComObject(_basicAudio);
                _basicAudio = null;
            }

            if (_basicVideo != null)
            {
                Marshal.ReleaseComObject(_basicVideo);
                _basicVideo = null;
            }

            if (_sourceFilter != null)
            {
                Marshal.ReleaseComObject(_sourceFilter);
                _sourceFilter = null;
            }

            if (m_graph != null)
            {
                Marshal.ReleaseComObject(m_graph);
                m_graph = null;
            }

            if (_videoWindow != null)
            {
                Marshal.ReleaseComObject(_videoWindow);
                _videoWindow = null;
            }

            _mSeekCaps = 0;

            _streams = null;

            GC.Collect();
        }
Beispiel #9
0
        private void CloseInterfaces()
        {
            _hiddenWindow.SizeChanged -= _hiddenWindow_SizeChanged;

            int hr;

            if (_defaultAudioRenderer != null)
            {
                m_graph.RemoveFilter(_defaultAudioRenderer as DirectShowLib.IBaseFilter);

                Marshal.ReleaseComObject(_defaultAudioRenderer);
                _defaultAudioRenderer = null;
            }

            if (_reclockAudioRenderer != null)
            {
                m_graph.RemoveFilter(_reclockAudioRenderer as DirectShowLib.IBaseFilter);

                Marshal.ReleaseComObject(_reclockAudioRenderer);
                _reclockAudioRenderer = null;
            }

            if (_lavaudio != null)
            {
                m_graph.RemoveFilter(_lavaudio as DirectShowLib.IBaseFilter);

                Marshal.ReleaseComObject(_lavaudio);
                _lavaudio = null;
            }

            if (_xyVsFilter != null)
            {
                m_graph.RemoveFilter(_xyVsFilter as DirectShowLib.IBaseFilter);

                Marshal.ReleaseComObject(_xyVsFilter);
                _xyVsFilter = null;
            }

            if (_xySubFilter != null)
            {
                m_graph.RemoveFilter(_xySubFilter as DirectShowLib.IBaseFilter);

                Marshal.ReleaseComObject(_xySubFilter);
                _xySubFilter = null;
            }

            if (_lavvideo != null)
            {
                m_graph.RemoveFilter(_lavvideo as DirectShowLib.IBaseFilter);

                Marshal.ReleaseComObject(_lavvideo);
                _lavvideo = null;
            }

            if (_madvr != null)
            {
                m_graph.RemoveFilter(_madvr as DirectShowLib.IBaseFilter);

                Marshal.ReleaseComObject(_madvr);
                _madvr = null;
            }

            if (_videoWindow != null)
            {
                // Relinquish ownership (IMPORTANT!) after hiding video window
                hr = _videoWindow.put_Visible(OABool.False);

                hr = _videoWindow.put_Owner(IntPtr.Zero);
            }

            if (_mediaEventEx != null)
            {
                hr = _mediaEventEx.SetNotifyWindow(IntPtr.Zero, 0, IntPtr.Zero);
                Marshal.ReleaseComObject(_mediaEventEx);
                _mediaEventEx = null;
            }

            if (_dvdNav != null)
            {
                Marshal.ReleaseComObject(_dvdNav);
                _dvdNav = null;
            }

            if (_mDvdInfo != null)
            {
                Marshal.ReleaseComObject(_mDvdInfo);
                _mDvdInfo = null;
            }

            if (_mDvdControl != null)
            {
                Marshal.ReleaseComObject(_mDvdControl);
                _mDvdControl = null;
            }

            if (_mPDisplay != null)
            {
                Marshal.ReleaseComObject(_mPDisplay);
                _mPDisplay = null;
            }

            if (_filterGraph != null)
            {
                Marshal.ReleaseComObject(_filterGraph);
                _filterGraph = null;
            }

            if (_mPEvr != null)
            {
                Marshal.ReleaseComObject(_mPEvr);
                _mPEvr = null;
            }

            if (_mediaEventEx != null)
            {
                Marshal.ReleaseComObject(_mediaEventEx);
                _mediaEventEx = null;
            }

            if (_mediaSeeking != null)
            {
                Marshal.ReleaseComObject(_mediaSeeking);
                _mediaSeeking = null;
            }

            if (_mediaPosition != null)
            {
                Marshal.ReleaseComObject(_mediaPosition);
                _mediaPosition = null;
            }

            if (_mediaControl != null)
            {
                Marshal.ReleaseComObject(_mediaControl);
                _mediaControl = null;
            }

            if (_basicAudio != null)
            {
                Marshal.ReleaseComObject(_basicAudio);
                _basicAudio = null;
            }

            if (_basicVideo != null)
            {
                Marshal.ReleaseComObject(_basicVideo);
                _basicVideo = null;
            }

            if (_sourceFilter != null)
            {
                Marshal.ReleaseComObject(_sourceFilter);
                _sourceFilter = null;
            }

            if (m_graph != null)
            {
                Marshal.ReleaseComObject(m_graph);
                m_graph = null;
            }

            if (_videoWindow != null)
            {
                Marshal.ReleaseComObject(_videoWindow);
                _videoWindow = null;
            }

            _mSeekCaps = 0;

            _streams = null;

            GC.Collect();
        }
        private void RenderStreams(DirectShowLib.IBaseFilter pSource, bool enableReclock, bool enableMadvr, bool enableXySubFilter)
        {
            int hr;

            _filterGraph = m_graph as DirectShowLib.IFilterGraph2;
            if (_filterGraph == null)
            {
                throw new Exception("Could not QueryInterface for the IFilterGraph2");
            }

            // Add video renderer
            if (_item.IsVideo)
            {
                _mPEvr = (DirectShowLib.IBaseFilter)new EnhancedVideoRenderer();
                hr = m_graph.AddFilter(_mPEvr, "Enhanced Video Renderer");
                DsError.ThrowExceptionForHR(hr);

                InitializeEvr(_mPEvr, 1);
            }

            // Add audio renderer
            var useDefaultRenderer = true;

            if (enableReclock)
            {
                try
                {
                    _reclockAudioRenderer = new ReclockAudioRenderer();
                    var aRenderer = _reclockAudioRenderer as DirectShowLib.IBaseFilter;
                    if (aRenderer != null)
                    {
                        hr = m_graph.AddFilter(aRenderer, "Reclock Audio Renderer");
                        DsError.ThrowExceptionForHR(hr);
                        useDefaultRenderer = false;
                    }
                }
                catch (Exception ex)
                {
                    _logger.ErrorException("Error adding reclock filter", ex);
                }
            }

            if (useDefaultRenderer)
            {
                _defaultAudioRenderer = new DefaultAudioRenderer();
                var aRenderer = _defaultAudioRenderer as DirectShowLib.IBaseFilter;
                if (aRenderer != null)
                {
                    m_graph.AddFilter(aRenderer, "Default Audio Renderer");
                }
            }

            if (_item.IsVideo)
            {
                try
                {
                    _lavvideo = new LAVVideo();
                    var vlavvideo = _lavvideo as DirectShowLib.IBaseFilter;
                    if (vlavvideo != null)
                    {
                        hr = m_graph.AddFilter(vlavvideo, "LAV Video Decoder");
                        DsError.ThrowExceptionForHR(hr);
                    }
                }
                catch (Exception ex)
                {
                    _logger.ErrorException("Error adding LAV Video filter", ex);
                }

                try
                {
                    _lavaudio = new LAVAudio();
                    var vlavaudio = _lavaudio as DirectShowLib.IBaseFilter;
                    if (vlavaudio != null)
                    {
                        hr = m_graph.AddFilter(vlavaudio, "LAV Audio Decoder");
                        DsError.ThrowExceptionForHR(hr);
                    }
                }
                catch (Exception ex)
                {
                    _logger.ErrorException("Error adding LAV Audio filter", ex);
                }

                if (_item.IsVideo)
                {
                    var xySubFilterSucceeded = false;

                    if (enableMadvr)
                    {
                        var madVrSucceded = false;

                        try
                        {
                            _madvr = new MadVR();
                            var vmadvr = _madvr as DirectShowLib.IBaseFilter;
                            if (vmadvr != null)
                            {
                                hr = m_graph.AddFilter(vmadvr, "MadVR Video Renderer");
                                DsError.ThrowExceptionForHR(hr);
                            }

                            madVrSucceded = true;
                        }
                        catch (Exception ex)
                        {
                            _logger.ErrorException("Error adding MadVR filter", ex);
                        }

                        // Load xySubFilter if configured and if madvr succeeded
                        if (enableXySubFilter && madVrSucceded)
                        {
                            try
                            {
                                _xySubFilter = new XySubFilter();
                                var vxySubFilter = _xySubFilter as DirectShowLib.IBaseFilter;
                                if (vxySubFilter != null)
                                {
                                    hr = m_graph.AddFilter(vxySubFilter, "xy-SubFilter");
                                    DsError.ThrowExceptionForHR(hr);
                                }

                                xySubFilterSucceeded = true;
                            }
                            catch (Exception ex)
                            {
                                _logger.ErrorException("Error adding xy-SubFilter filter", ex);
                            }
                        }
                    }

                    // Fallback to xyVsFilter
                    if (!xySubFilterSucceeded)
                    {
                        try
                        {
                            _xyVsFilter = new XYVSFilter();
                            var vxyVsFilter = _xyVsFilter as DirectShowLib.IBaseFilter;
                            if (vxyVsFilter != null)
                            {
                                hr = m_graph.AddFilter(vxyVsFilter, "xy-VSFilter");
                                DsError.ThrowExceptionForHR(hr);
                            }
                        }
                        catch (Exception ex)
                        {
                            _logger.ErrorException("Error adding xy-VSFilter filter", ex);
                        }
                    }
                }
            }

            DirectShowLib.IEnumPins pEnum;
            hr = pSource.EnumPins(out pEnum);
            DsError.ThrowExceptionForHR(hr);

            DirectShowLib.IPin[] pins = { null };

            /* Counter for how many pins successfully rendered */
            var pinsRendered = 0;
            /* Loop over each pin of the source filter */
            while (pEnum.Next(1, pins, IntPtr.Zero) == 0)
            {
                if (_filterGraph.RenderEx(pins[0], AMRenderExFlags.RenderToExistingRenderers, IntPtr.Zero) >= 0)
                    pinsRendered++;

                Marshal.ReleaseComObject(pins[0]);
            }

            Marshal.ReleaseComObject(pEnum);

            if (pinsRendered == 0)
            {
                throw new Exception("Could not render any streams from the source Uri");
            }

            _logger.Info("Completed RenderStreams with {0} pins.", pinsRendered);

            if (_item.IsVideo)
            {
                SetVideoWindow();
            }
        }
Beispiel #11
0
        private void RenderStreams(DirectShowLib.IBaseFilter pSource, bool enableReclock, bool enableMadvr, bool enableXySubFilter)
        {
            int hr;

            _filterGraph = m_graph as DirectShowLib.IFilterGraph2;
            if (_filterGraph == null)
            {
                throw new Exception("Could not QueryInterface for the IFilterGraph2");
            }

            // Add video renderer
            if (_item.IsVideo)
            {
                _mPEvr = (DirectShowLib.IBaseFilter) new EnhancedVideoRenderer();
                hr     = m_graph.AddFilter(_mPEvr, "Enhanced Video Renderer");
                DsError.ThrowExceptionForHR(hr);

                InitializeEvr(_mPEvr, 1);
            }

            // Add audio renderer
            var useDefaultRenderer = true;

            if (enableReclock)
            {
                try
                {
                    _reclockAudioRenderer = new ReclockAudioRenderer();
                    var aRenderer = _reclockAudioRenderer as DirectShowLib.IBaseFilter;
                    if (aRenderer != null)
                    {
                        hr = m_graph.AddFilter(aRenderer, "Reclock Audio Renderer");
                        DsError.ThrowExceptionForHR(hr);
                        useDefaultRenderer = false;
                    }
                }
                catch (Exception ex)
                {
                    _logger.ErrorException("Error adding reclock filter", ex);
                }
            }

            if (useDefaultRenderer)
            {
                _defaultAudioRenderer = new DefaultAudioRenderer();
                var aRenderer = _defaultAudioRenderer as DirectShowLib.IBaseFilter;
                if (aRenderer != null)
                {
                    m_graph.AddFilter(aRenderer, "Default Audio Renderer");
                }
            }

            if (_item.IsVideo)
            {
                try
                {
                    _lavvideo = new LAVVideo();
                    var vlavvideo = _lavvideo as DirectShowLib.IBaseFilter;
                    if (vlavvideo != null)
                    {
                        hr = m_graph.AddFilter(vlavvideo, "LAV Video Decoder");
                        DsError.ThrowExceptionForHR(hr);
                    }
                }
                catch (Exception ex)
                {
                    _logger.ErrorException("Error adding LAV Video filter", ex);
                }

                try
                {
                    _lavaudio = new LAVAudio();
                    var vlavaudio = _lavaudio as DirectShowLib.IBaseFilter;
                    if (vlavaudio != null)
                    {
                        hr = m_graph.AddFilter(vlavaudio, "LAV Audio Decoder");
                        DsError.ThrowExceptionForHR(hr);
                    }
                }
                catch (Exception ex)
                {
                    _logger.ErrorException("Error adding LAV Audio filter", ex);
                }

                if (_item.IsVideo)
                {
                    var xySubFilterSucceeded = false;

                    if (enableMadvr)
                    {
                        var madVrSucceded = false;

                        try
                        {
                            _madvr = new MadVR();
                            var vmadvr = _madvr as DirectShowLib.IBaseFilter;
                            if (vmadvr != null)
                            {
                                hr = m_graph.AddFilter(vmadvr, "MadVR Video Renderer");
                                DsError.ThrowExceptionForHR(hr);
                            }

                            madVrSucceded = true;
                        }
                        catch (Exception ex)
                        {
                            _logger.ErrorException("Error adding MadVR filter", ex);
                        }

                        // Load xySubFilter if configured and if madvr succeeded
                        if (enableXySubFilter && madVrSucceded)
                        {
                            try
                            {
                                _xySubFilter = new XySubFilter();
                                var vxySubFilter = _xySubFilter as DirectShowLib.IBaseFilter;
                                if (vxySubFilter != null)
                                {
                                    hr = m_graph.AddFilter(vxySubFilter, "xy-SubFilter");
                                    DsError.ThrowExceptionForHR(hr);
                                }

                                xySubFilterSucceeded = true;
                            }
                            catch (Exception ex)
                            {
                                _logger.ErrorException("Error adding xy-SubFilter filter", ex);
                            }
                        }
                    }

                    // Fallback to xyVsFilter
                    if (!xySubFilterSucceeded)
                    {
                        try
                        {
                            _xyVsFilter = new XYVSFilter();
                            var vxyVsFilter = _xyVsFilter as DirectShowLib.IBaseFilter;
                            if (vxyVsFilter != null)
                            {
                                hr = m_graph.AddFilter(vxyVsFilter, "xy-VSFilter");
                                DsError.ThrowExceptionForHR(hr);
                            }
                        }
                        catch (Exception ex)
                        {
                            _logger.ErrorException("Error adding xy-VSFilter filter", ex);
                        }
                    }
                }
            }

            DirectShowLib.IEnumPins pEnum;
            hr = pSource.EnumPins(out pEnum);
            DsError.ThrowExceptionForHR(hr);

            DirectShowLib.IPin[] pins = { null };

            /* Counter for how many pins successfully rendered */
            var pinsRendered = 0;

            /* Loop over each pin of the source filter */
            while (pEnum.Next(1, pins, IntPtr.Zero) == 0)
            {
                if (_filterGraph.RenderEx(pins[0], AMRenderExFlags.RenderToExistingRenderers, IntPtr.Zero) >= 0)
                {
                    pinsRendered++;
                }

                Marshal.ReleaseComObject(pins[0]);
            }

            Marshal.ReleaseComObject(pEnum);

            if (pinsRendered == 0)
            {
                throw new Exception("Could not render any streams from the source Uri");
            }

            _logger.Info("Completed RenderStreams with {0} pins.", pinsRendered);

            if (_item.IsVideo)
            {
                SetVideoWindow();
            }
        }
        private void InitializeGraph(bool isDvd)
        {
            int hr = 0;
            _isDvd = isDvd;
            if (isDvd)
            {
                _dvdGraphBuilder = new DvdGraphBuilder() as IDvdGraphBuilder;
                hr = _dvdGraphBuilder.GetFiltergraph(out _graph);
                DsError.ThrowExceptionForHR(hr);
                _filterGraph = _graph as IFilterGraph2;
            }
            else
            {
                _filterGraphNT = new FilterGraphNoThread();
                _graph = (_filterGraphNT as DirectShowLib.IGraphBuilder);
            }
            // QueryInterface for DirectShow interfaces
            _mediaControl = (DirectShowLib.IMediaControl)_graph;
            _mediaEventEx = (DirectShowLib.IMediaEventEx)_graph;
            _mediaSeeking = (DirectShowLib.IMediaSeeking)_graph;
            _mediaPosition = (DirectShowLib.IMediaPosition)_graph;

            // Query for video interfaces, which may not be relevant for audio files
            _videoWindow = _graph as DirectShowLib.IVideoWindow;
            _basicVideo = _graph as DirectShowLib.IBasicVideo;

            // Query for audio interfaces, which may not be relevant for video-only files
            _basicAudio = _graph as DirectShowLib.IBasicAudio;

            // Set up event notification.
            if (isDvd)
                hr = _mediaEventEx.SetNotifyWindow(VideoWindowHandle, WM_DVD_EVENT, IntPtr.Zero);
            else
                hr = _mediaEventEx.SetNotifyWindow(VideoWindowHandle, WM_GRAPHNOTIFY, IntPtr.Zero);
            DsError.ThrowExceptionForHR(hr);

            if (_mbtConfig.Configuration.InternalPlayerConfiguration.PublishGraph)
                m_dsRot = new DsROTEntry(_graph as IFilterGraph);
        }
        private void RenderStreams(DirectShowLib.IBaseFilter pSource, bool enableMadvr,
            bool enableMadvrExclusiveMode, bool enableXySubFilter)
        {
            int hr;

            _filterGraph = _graph as DirectShowLib.IFilterGraph2;
            if (_filterGraph == null)
            {
                throw new Exception("Could not QueryInterface for the IFilterGraph2");
            }
            
            DirectShowLib.IEnumPins pEnum;
            hr = pSource.EnumPins(out pEnum);
            DsError.ThrowExceptionForHR(hr);

            DirectShowLib.IPin[] pins = { null };

            /* Counter for how many pins successfully rendered */
            var pinsRendered = 0;
            /* Loop over each pin of the source filter */
            while (pEnum.Next(1, pins, IntPtr.Zero) == 0)
            {
                //explicitly build graph to avoid unwanted filters worming their way in
                List<Guid> mediaTypes = GetPinMediaTypes(pins[0]);
                bool needsRender = true;

                for (int m = 0; m < mediaTypes.Count; m++)
                {
                    DirectShowLib.IPin decIn = null;
                    DirectShowLib.IPin decOut = null;
                    DirectShowLib.IPin rendIn = null;

                    try
                    {
                        if (mediaTypes[m] == DirectShowLib.MediaType.Video)
                        {
                            #region Video

                            //add the video renderer first so we know whether to enable DXVA2 in "Auto" mode.
                            if (enableMadvr)
                            {
                                AddMadVr();
                            }
                            else // Add default video renderer
                            {
                                _mPEvr = (DirectShowLib.IBaseFilter)new EnhancedVideoRenderer();
                                hr = _graph.AddFilter(_mPEvr, "EVR");
                                DsError.ThrowExceptionForHR(hr);

                                //we only need 2 input pins on the EVR if LAV Video isn't used for DVDs, but it doesn't hurt to have them
                                InitializeEvr(_mPEvr, _isDvd ? 2 : 1);
                            }

                            try
                            {
                                AddVideoDecoder();

                                decIn = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_lavvideo, PinDirection.Input, 0);
                                if (decIn != null)
                                {
                                    hr = _filterGraph.ConnectDirect(pins[0], decIn, null);
                                    DsError.ThrowExceptionForHR(hr);
                                    decOut = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_lavvideo,
                                        PinDirection.Output, 0);

                                    if (enableXySubFilter) //this flag indicates whether we should handle subtitle rendering
                                    {
                                        var xySubFilterSucceeded = false;

                                        // Load xySubFilter if configured and if madvr succeeded
                                        if (enableMadvr || _customEvrPresenterLoaded)
                                        {
                                            try
                                            {
                                                _xySubFilter = URCOMLoader.Instance.GetObject(typeof(XySubFilter).GUID, true); //new XySubFilter();
                                                var vxySubFilter = _xySubFilter as DirectShowLib.IBaseFilter;
                                                if (vxySubFilter != null)
                                                {
                                                    hr = _graph.AddFilter(vxySubFilter, "xy-SubFilter");
                                                    DsError.ThrowExceptionForHR(hr);
                                                }

                                                xySubFilterSucceeded = true;
                                            }
                                            catch (Exception ex)
                                            {
                                                _logger.ErrorException("Error adding xy-SubFilter filter", ex);
                                            }
                                        }

                                        // Fallback to xyVsFilter
                                        if (!xySubFilterSucceeded)
                                        {
                                            try
                                            {
                                                _xyVsFilter = URCOMLoader.Instance.GetObject(typeof(XYVSFilter).GUID, true); //new XYVSFilter();
                                                var vxyVsFilter = _xyVsFilter as DirectShowLib.IBaseFilter;
                                                if (vxyVsFilter != null)
                                                {
                                                    hr = _graph.AddFilter(vxyVsFilter, "xy-VSFilter");
                                                    DsError.ThrowExceptionForHR(hr);
                                                }
                                            }
                                            catch (Exception ex)
                                            {
                                                _logger.ErrorException("Error adding xy-VSFilter filter", ex);
                                            }
                                        }

                                        if (_xyVsFilter != null) //If using VSFilter
                                        {
                                            //insert xyVsFilter b/w LAV Video and the renderer
                                            rendIn = DsFindPin.ByName((DirectShowLib.IBaseFilter)_xyVsFilter, "Video");

                                            //connect it to VSFilter
                                            if (decOut != null && rendIn != null)
                                            {
                                                hr = _filterGraph.ConnectDirect(decOut, rendIn, null);
                                                DsError.ThrowExceptionForHR(hr);

                                                CleanUpInterface(rendIn);
                                                CleanUpInterface(decOut);
                                                rendIn = null;
                                                decOut = null;
                                            }

                                            //grab xyVsFilter's output pin so it can be connected to the renderer
                                            decOut = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_xyVsFilter,
                                                    PinDirection.Output, 0);
                                        }
                                    }

                                    if (_madvr != null)
                                    {
                                        rendIn = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_madvr,
                                            PinDirection.Input, 0);
                                    }
                                    else
                                    {
                                        rendIn = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_mPEvr,
                                            PinDirection.Input, 0);
                                    }

                                    if (decOut != null && rendIn != null)
                                    {
                                        hr = _filterGraph.ConnectDirect(decOut, rendIn, null);
                                        DsError.ThrowExceptionForHR(hr);

                                        needsRender = false;
                                        break;
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                _logger.ErrorException("Error adding LAV Video filter", ex);
                            }

                            #endregion
                        }
                        else if (mediaTypes[m] == DirectShowLib.MediaType.Audio)
                        {
                            #region Audio
                            //we have an audio pin so add a renderer and decoder
                            
                            if (!AddAudioRenderer())
                            {
                                AddDefaultAudioRenderer();
                            }

                            AddAudioDecoder();

                            decIn = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_lavaudio, PinDirection.Input, 0);
                            if (decIn != null)
                            {
                                hr = _filterGraph.ConnectDirect(pins[0], decIn, null);
                                if (hr < 0) //LAV cannot handle this audio type
                                {
                                    _logger.Warn("LAV Audio could not decode audio media type.");
                                }
                                else
                                {
                                    //DsError.ThrowExceptionForHR(hr);
                                    decOut = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_lavaudio,
                                        PinDirection.Output, 0);
                                }

                                rendIn = DsFindPin.ByDirection(AudioRenderer, PinDirection.Input, 0);

                                if (decOut != null && rendIn != null)
                                {
                                    hr = _filterGraph.ConnectDirect(decOut, rendIn, null);
                                    if (hr == -2004287474 && _wasapiAR != null) //AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED
                                    {
                                        IMPAudioRendererConfig arSett = _wasapiAR as IMPAudioRendererConfig;
                                        if (arSett != null)
                                        {
                                            arSett.SetInt(MPARSetting.WASAPI_MODE, (int)AUDCLNT_SHAREMODE.SHARED);
                                            _logger.Warn("WASAPI AR failed to connected in exclusive mode, check device properties");
                                            hr = _filterGraph.ConnectDirect(decOut, rendIn, null);
                                        }
                                    }
                                    DsError.ThrowExceptionForHR(hr);

                                    needsRender = false;
                                    break;
                                }
                            }
                            #endregion
                        }
                        else if (mediaTypes[m] == SubtitleMediaType
                            /*DirectShowLib.MediaType.Subtitle*/)
                        {
                            #region subtitles

                            if (_xySubFilter != null)
                            {
                                rendIn = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_xySubFilter,
                                    PinDirection.Input, 0);
                            }
                            else if (_xyVsFilter != null)
                            {
                                rendIn = DsFindPin.ByName((DirectShowLib.IBaseFilter)_xyVsFilter, "Input");
                            }

                            if (rendIn != null)
                            {
                                hr = _filterGraph.ConnectDirect(pins[0], rendIn, null);
                                DsError.ThrowExceptionForHR(hr);

                                needsRender = false;
                                break;
                            }
                            #endregion
                        }
                        else if (mediaTypes[m] == DvdSubpictureMediaType)
                        {
                            #region DVD Subpicture
                            if (_lavvideo != null)
                            {
                                rendIn = DsFindPin.ByName((DirectShowLib.IBaseFilter)_lavvideo, "Subtitle Input");
                                if (rendIn != null)
                                {
                                    hr = _filterGraph.ConnectDirect(pins[0], rendIn, null);
                                    DsError.ThrowExceptionForHR(hr);

                                    needsRender = false;
                                    break;
                                }
                            }
                            #endregion
                        }
                    }
                    finally
                    {
                        CleanUpInterface(decIn);
                        CleanUpInterface(decOut);
                        CleanUpInterface(rendIn);
                    }
                }

                if (needsRender)
                {
                    if (_filterGraph.RenderEx(pins[0], AMRenderExFlags.RenderToExistingRenderers, IntPtr.Zero) >= 0)
                        pinsRendered++;
                }
                else
                    pinsRendered++;

                Marshal.ReleaseComObject(pins[0]);
            }

            Marshal.ReleaseComObject(pEnum);

            if (pinsRendered == 0)
            {
                throw new Exception("Could not render any streams from the source Uri");
            }

            _logger.Debug("Completed RenderStreams with {0} pins.", pinsRendered);

            if (_item.IsVideo)
            {
                SetVideoWindow(enableMadvrExclusiveMode);
                if (_mPEvr != null)
                    SetEvrVppMode(_mPEvr);
            }
        }
        private void CloseInterfaces()
        {
            int hr;

            if (m_adecOut != null)
            {
                CleanUpInterface(m_adecOut);
                m_adecOut = null;
            }

            if (_defaultAudioRenderer != null)
            {
                m_graph.RemoveFilter(_defaultAudioRenderer as DirectShowLib.IBaseFilter);

                CleanUpInterface(_defaultAudioRenderer);
                _defaultAudioRenderer = null;
            }

            if (_reclockAudioRenderer != null)
            {
                m_graph.RemoveFilter(_reclockAudioRenderer as DirectShowLib.IBaseFilter);

                CleanUpInterface(_reclockAudioRenderer);
                _reclockAudioRenderer = null;
            }

            if (_wasapiAR != null)
            {
                m_graph.RemoveFilter(_wasapiAR as DirectShowLib.IBaseFilter);

                CleanUpInterface(_wasapiAR);
                _wasapiAR = null;
            }

            if (_lavaudio != null)
            {
                m_graph.RemoveFilter(_lavaudio as DirectShowLib.IBaseFilter);

                CleanUpInterface(_lavaudio);
                _lavaudio = null;
            }

            if (_xyVsFilter != null)
            {
                m_graph.RemoveFilter(_xyVsFilter as DirectShowLib.IBaseFilter);

                CleanUpInterface(_xyVsFilter);
                _xyVsFilter = null;
            }

            if (_xySubFilter != null)
            {
                m_graph.RemoveFilter(_xySubFilter as DirectShowLib.IBaseFilter);

                CleanUpInterface(_xySubFilter);
                _xySubFilter = null;
            }

            if (_lavvideo != null)
            {
                m_graph.RemoveFilter(_lavvideo as DirectShowLib.IBaseFilter);

                CleanUpInterface(_lavvideo);
                _lavvideo = null;
            }

            if (_madvr != null)
            {
                m_graph.RemoveFilter(_madvr as DirectShowLib.IBaseFilter);

                CleanUpInterface(_madvr);
                _madvr = null;
            }

            if (_videoWindow != null)
            {
                // Relinquish ownership (IMPORTANT!) after hiding video window
                hr = _videoWindow.put_Visible(OABool.False);

                hr = _videoWindow.put_Owner(IntPtr.Zero);
            }

            if (_mediaEventEx != null)
            {
                hr = _mediaEventEx.SetNotifyWindow(IntPtr.Zero, 0, IntPtr.Zero);
                //Marshal.ReleaseComObject(_mediaEventEx);
                //_mediaEventEx = null;
            }

            //if (_dvdNav != null)
            //{
            //    Marshal.ReleaseComObject(_dvdNav);
            //    _dvdNav = null;
            //}
            /* //this will double release the source filter
            if (dvdInfo != null)
            {
                Marshal.ReleaseComObject(dvdInfo);
                dvdInfo = null;
            }

            if (_mDvdControl != null)
            {
                Marshal.ReleaseComObject(_mDvdControl);                
            }
            */
            _mDvdControl = null;

            CleanUpInterface(_mPDisplay);
            _mPDisplay = null;
            CleanUpInterface(_sourceFilter);
            _sourceFilter = null;
            CleanUpInterface(_mPEvr);
            _mPEvr = null;
            CleanUpInterface(m_filterGraph);
            m_filterGraph = null;

            m_filterGraph = null;
            _mediaEventEx = null;
            _mediaSeeking = null;
            _mediaPosition = null;
            _mediaControl = null;
            _basicAudio = null;
            _basicVideo = null;
            m_graph = null;
            _videoWindow = null;
            _filterGraph = null;

            if (m_dsRot != null)
                m_dsRot.Dispose();
            m_dsRot = null;

            _mSeekCaps = 0;

            _streams = null;

            GC.Collect();
        }
        private void RenderStreams(DirectShowLib.IBaseFilter pSource, bool enableReclock, bool enableMadvr, bool enableMadvrExclusiveMode, bool enableXySubFilter)
        {
            int hr;

            _filterGraph = m_graph as DirectShowLib.IFilterGraph2;
            if (_filterGraph == null)
            {
                throw new Exception("Could not QueryInterface for the IFilterGraph2");
            }

            // Add audio renderer
            var useDefaultRenderer = true;

            if (enableReclock)
            {
                try
                {
                    _reclockAudioRenderer = new ReclockAudioRenderer();
                    var aRenderer = _reclockAudioRenderer as DirectShowLib.IBaseFilter;
                    if (aRenderer != null)
                    {
                        hr = m_graph.AddFilter(aRenderer, "Reclock Audio Renderer");
                        DsError.ThrowExceptionForHR(hr);
                        useDefaultRenderer = false;
                    }
                }
                catch (Exception ex)
                {
                    _logger.ErrorException("Error adding reclock filter", ex);
                }
            }

            if (useDefaultRenderer)
            {
                _defaultAudioRenderer = new DefaultAudioRenderer();
                var aRenderer = _defaultAudioRenderer as DirectShowLib.IBaseFilter;
                if (aRenderer != null)
                {
                    m_graph.AddFilter(aRenderer, "Default Audio Renderer");                    
                }
            }

            if (_item.IsVideo)
            {
                var xySubFilterSucceeded = false;
                var madVrSucceded = false;
                //add the video renderer first so we know whether to enable DXVA2 in "Auto" mode.
                if (enableMadvr)
                {

                    try
                    {
                        _madvr = _urCom.GetObject(typeof(MadVR).GUID, true);// new MadVR();
                        var vmadvr = _madvr as DirectShowLib.IBaseFilter;
                        if (vmadvr != null)
                        {
                            hr = m_graph.AddFilter(vmadvr, "MadVR Video Renderer");
                            DsError.ThrowExceptionForHR(hr);

                            try
                            {
                                MadVRSettings msett = new MadVRSettings(_madvr);

                                bool smoothMotion = msett.GetBool("smoothMotionEnabled");

                                if (smoothMotion != _mbtConfig.Configuration.InternalPlayerConfiguration.VideoConfig.UseMadVrSmoothMotion)
                                    msett.SetBool("smoothMotionEnabled", _mbtConfig.Configuration.InternalPlayerConfiguration.VideoConfig.UseMadVrSmoothMotion);

                                if (string.Compare(msett.GetString("smoothMotionMode"), _mbtConfig.Configuration.InternalPlayerConfiguration.VideoConfig.MadVrSmoothMotionMode, true) != 0)
                                {
                                    bool success = msett.SetString("smoothMotionMode", _mbtConfig.Configuration.InternalPlayerConfiguration.VideoConfig.MadVrSmoothMotionMode);
                                }
                            }
                            catch (Exception ex)
                            {
                                _logger.ErrorException("Error configuring madVR", ex);
                            }

                            madVrSucceded = true;
                        }
                    }
                    catch (Exception ex)
                    {
                        _logger.ErrorException("Error adding MadVR filter", ex);
                    }
                }

                // Add video renderer
                if (!madVrSucceded)
                {
                    _mPEvr = (DirectShowLib.IBaseFilter)new EnhancedVideoRenderer();
                    hr = m_graph.AddFilter(_mPEvr, "EVR");
                    DsError.ThrowExceptionForHR(hr);

                    //we only need 2 input pins on the EVR if LAV Video isn't used for DVDs, but it doesn't hurt to have them
                    InitializeEvr(_mPEvr, _isDvd ? 2 : 1);
                }

                // Load xySubFilter if configured and if madvr succeeded
                if (enableXySubFilter && (madVrSucceded || _customEvrPresenterLoaded))
                {
                    try
                    {
                        _xySubFilter = _urCom.GetObject(typeof(XySubFilter).GUID, true);//new XySubFilter();
                        var vxySubFilter = _xySubFilter as DirectShowLib.IBaseFilter;
                        if (vxySubFilter != null)
                        {
                            hr = m_graph.AddFilter(vxySubFilter, "xy-SubFilter");
                            DsError.ThrowExceptionForHR(hr);
                        }

                        xySubFilterSucceeded = true;
                    }
                    catch (Exception ex)
                    {
                        _logger.ErrorException("Error adding xy-SubFilter filter", ex);
                    }
                }

                // Fallback to xyVsFilter
                if (!xySubFilterSucceeded && enableXySubFilter)
                {
                    try
                    {
                        _xyVsFilter = new XYVSFilter();
                        var vxyVsFilter = _xyVsFilter as DirectShowLib.IBaseFilter;
                        if (vxyVsFilter != null)
                        {
                            hr = m_graph.AddFilter(vxyVsFilter, "xy-VSFilter");
                            DsError.ThrowExceptionForHR(hr);
                        }
                    }
                    catch (Exception ex)
                    {
                        _logger.ErrorException("Error adding xy-VSFilter filter", ex);
                    }
                }

                try
                {
                    _lavvideo = _urCom.GetObject(typeof(LAVVideo).GUID, true);//new LAVVideo();
                    var vlavvideo = _lavvideo as DirectShowLib.IBaseFilter;
                    if (vlavvideo != null)
                    {
                        hr = m_graph.AddFilter(vlavvideo, "LAV Video Decoder");
                        DsError.ThrowExceptionForHR(hr);

                        ILAVVideoSettings vsett = vlavvideo as ILAVVideoSettings;
                        if (vsett != null)
                        {
                            //we only want to set it for MB
                            hr = vsett.SetRuntimeConfig(true);
                            DsError.ThrowExceptionForHR(hr);

                            LAVHWAccel configuredMode = VideoConfigurationUtils.GetHwaMode(_mbtConfig.Configuration.InternalPlayerConfiguration.VideoConfig, _customEvrPresenterLoaded);

                            LAVHWAccel testme = vsett.GetHWAccel();
                            if (testme != configuredMode)
                            {
                                hr = vsett.SetHWAccel(configuredMode);
                                DsError.ThrowExceptionForHR(hr);
                            }

                            foreach (string c in DirectShowPlayer.GetLAVVideoCodecs())
                            {
                                LAVVideoCodec codec = (LAVVideoCodec)Enum.Parse(typeof(LAVVideoCodec), c);

                                bool isEnabled = vsett.GetFormatConfiguration(codec);
                                if (_mbtConfig.Configuration.InternalPlayerConfiguration.VideoConfig.EnabledCodecs.Contains(c))
                                {
                                    if (!isEnabled)
                                    {
                                        _logger.Debug("Enable support for: {0}", c);
                                        hr = vsett.SetFormatConfiguration(codec, true);
                                        DsError.ThrowExceptionForHR(hr);
                                    }
                                }
                                else if (isEnabled)
                                {
                                    _logger.Debug("Disable support for: {0}", c);
                                    hr = vsett.SetFormatConfiguration(codec, false);
                                    DsError.ThrowExceptionForHR(hr);
                                }
                            }

                            foreach (string hwaCodec in DirectShowPlayer.GetLAVVideoHwaCodecs())
                            {
                                LAVVideoHWCodec codec = (LAVVideoHWCodec)Enum.Parse(typeof(LAVVideoHWCodec), hwaCodec);
                                bool hwaIsEnabled = vsett.GetHWAccelCodec(codec);

                                if (_mbtConfig.Configuration.InternalPlayerConfiguration.VideoConfig.HwaEnabledCodecs.Contains(hwaCodec))
                                {
                                    if (!hwaIsEnabled)
                                    {
                                        _logger.Debug("Enable HWA support for: {0}", hwaCodec);
                                        hr = vsett.SetHWAccelCodec(codec, true);
                                        DsError.ThrowExceptionForHR(hr);
                                    }
                                }
                                else if (hwaIsEnabled)
                                {
                                    _logger.Debug("Disable HWA support for: {0}", hwaCodec);
                                    hr = vsett.SetHWAccelCodec(codec, false);
                                    DsError.ThrowExceptionForHR(hr);
                                }
                            }

                            if (!vsett.GetDVDVideoSupport())
                            {
                                _logger.Debug("Enable DVD support.");
                                hr = vsett.SetDVDVideoSupport(true);
                                DsError.ThrowExceptionForHR(hr);
                            }

                            int hwaRes = vsett.GetHWAccelResolutionFlags();
                            if (hwaRes != _mbtConfig.Configuration.InternalPlayerConfiguration.VideoConfig.HwaResolution)
                            {
                                _logger.Debug("Change HWA resolution support from {0} to {1}.", hwaRes, _mbtConfig.Configuration.InternalPlayerConfiguration.VideoConfig.HwaResolution);
                                hr = vsett.SetHWAccelResolutionFlags(VideoConfigurationUtils.GetHwaResolutions(_mbtConfig.Configuration.InternalPlayerConfiguration.VideoConfig));
                                DsError.ThrowExceptionForHR(hr);
                            }

                            hr = vsett.SetTrayIcon(_mbtConfig.Configuration.InternalPlayerConfiguration.VideoConfig.ShowTrayIcon);
                            DsError.ThrowExceptionForHR(hr);
                        }
                    }
                }
                catch (Exception ex)
                {
                    _logger.ErrorException("Error adding LAV Video filter", ex);
                }
            }

            try
            {
                _lavaudio = _urCom.GetObject(typeof(LAVAudio).GUID, true);// new LAVAudio();
                var vlavaudio = _lavaudio as DirectShowLib.IBaseFilter;
                if (vlavaudio != null)
                {
                    _logger.Debug("Add LAVAudio to the graph.");

                    hr = m_graph.AddFilter(vlavaudio, "LAV Audio Decoder");
                    DsError.ThrowExceptionForHR(hr);

                    ILAVAudioSettings asett = vlavaudio as ILAVAudioSettings;
                    if (asett != null)
                    {
                        _logger.Debug("Enable LAVAudio Runtime Config");

                        //we only want to set it for MB
                        hr = asett.SetRuntimeConfig(true);
                        DsError.ThrowExceptionForHR(hr);

                        foreach (string c in DirectShowPlayer.GetLAVAudioCodecs())
                        {
                            LAVAudioCodec codec = (LAVAudioCodec)Enum.Parse(typeof(LAVAudioCodec), c);

                            bool isEnabled = asett.GetFormatConfiguration(codec);
                            if (_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.EnabledCodecs.Contains(c))
                            {
                                if (!isEnabled)
                                {
                                    _logger.Debug("Enable support for: {0}", c);
                                    hr = asett.SetFormatConfiguration(codec, true);
                                    DsError.ThrowExceptionForHR(hr);
                                }
                            }
                            else if (isEnabled)
                            {
                                _logger.Debug("Disable support for: {0}", c);
                                hr = asett.SetFormatConfiguration(codec, false);
                                DsError.ThrowExceptionForHR(hr);
                            }
                        }

                        //enable/disable bitstreaming
                        if ((_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.AudioBitstreaming & BitstreamChoice.SPDIF) == BitstreamChoice.SPDIF)
                        {
                            _logger.Debug("Enable LAVAudio S/PDIF bitstreaming");

                            hr = asett.SetBitstreamConfig(LAVBitstreamCodec.AC3, true);
                            DsError.ThrowExceptionForHR(hr);

                            hr = asett.SetBitstreamConfig(LAVBitstreamCodec.DTS, true);
                            DsError.ThrowExceptionForHR(hr);
                        }

                        if ((_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.AudioBitstreaming & BitstreamChoice.HDMI) == BitstreamChoice.HDMI)
                        {
                            _logger.Debug("Enable LAVAudio HDMI bitstreaming");

                            hr = asett.SetBitstreamConfig(LAVBitstreamCodec.EAC3, true);
                            DsError.ThrowExceptionForHR(hr);

                            hr = asett.SetBitstreamConfig(LAVBitstreamCodec.TRUEHD, true);
                            DsError.ThrowExceptionForHR(hr);

                            hr = asett.SetBitstreamConfig(LAVBitstreamCodec.DTSHD, true);
                            DsError.ThrowExceptionForHR(hr);

                        }

                        if (_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.Delay > 0)
                        {
                            _logger.Debug("Set LAVAudio audio delay: {0}", _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.Delay);

                            hr = asett.SetAudioDelay(true, _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.Delay);
                            DsError.ThrowExceptionForHR(hr);
                        }

                        _logger.Debug("Set LAVAudio auto AV Sync: {0}", _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.EnableAutoSync);
                        hr = asett.SetAutoAVSync(_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.EnableAutoSync);
                        DsError.ThrowExceptionForHR(hr);

                        _logger.Debug("Set LAVAudio Expand61: {0}", _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.Expand61);
                        hr = asett.SetExpand61(_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.Expand61);
                        DsError.ThrowExceptionForHR(hr);

                        _logger.Debug("Set LAVAudio ExpandMono: {0}", _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.ExpandMono);
                        hr = asett.SetExpandMono(_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.ExpandMono);
                        DsError.ThrowExceptionForHR(hr);

                        _logger.Debug("Set LAVAudio ConvertToStandardLayout: {0}", _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.ConvertToStandardLayout);
                        hr = asett.SetOutputStandardLayout(_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.ConvertToStandardLayout);
                        DsError.ThrowExceptionForHR(hr);

                        _logger.Debug("Set LAVAudio audio EnableDRC: {0}", _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.EnableDRC);
                        hr = asett.SetDRC(_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.EnableDRC, _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.DRCLevel);
                        DsError.ThrowExceptionForHR(hr);

                        _logger.Debug("Set LAVAudio audio ShowTrayIcon: {0}", _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.ShowTrayIcon);
                        hr = asett.SetTrayIcon(_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.ShowTrayIcon);
                        DsError.ThrowExceptionForHR(hr);

                        bool mixingEnabled = asett.GetMixingEnabled();
                        if (mixingEnabled != _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.EnablePCMMixing)
                        {
                            _logger.Debug("Set LAVAudio EnablePCMMixing: {0}", _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.EnablePCMMixing);
                            hr = asett.SetMixingEnabled(!mixingEnabled);
                            DsError.ThrowExceptionForHR(hr);
                        }

                        if (_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.EnablePCMMixing)
                        {
                            _logger.Debug("Set LAVAudio MixingSetting: {0}", _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.MixingSetting);
                            LAVAudioMixingFlag amf = (LAVAudioMixingFlag)_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.MixingSetting;
                            hr = asett.SetMixingFlags(amf);
                            DsError.ThrowExceptionForHR(hr);

                            _logger.Debug("Set LAVAudio MixingEncoding: {0}", _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.MixingEncoding);
                            LAVAudioMixingMode amm = (LAVAudioMixingMode)Enum.Parse(typeof(LAVAudioMixingMode), _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.MixingEncoding);
                            hr = asett.SetMixingMode(amm);
                            DsError.ThrowExceptionForHR(hr);

                            _logger.Debug("Set LAVAudio MixingLayout: {0}", _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.MixingLayout);
                            LAVAudioMixingLayout aml = (LAVAudioMixingLayout)Enum.Parse(typeof(LAVAudioMixingLayout), _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.MixingLayout);
                            hr = asett.SetMixingLayout(aml);
                            DsError.ThrowExceptionForHR(hr);

                            _logger.Debug("Set LAVAudio LfeMixingLevel: {0} CenterMixingLevel: {1} SurroundMixingLevel: {2}", _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.LfeMixingLevel, _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.CenterMixingLevel, _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.SurroundMixingLevel);
                            int lfe, center, surround;
                            //convert to the # that LAV Audio expects
                            lfe = (int)(_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.LfeMixingLevel * 10000.01);
                            center = (int)(_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.CenterMixingLevel * 10000.01);
                            surround = (int)(_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.SurroundMixingLevel * 10000.01);

                            hr = asett.SetMixingLevels(center, surround, lfe);
                            DsError.ThrowExceptionForHR(hr);
                        }

                        for (int i = 0; i < (int)LAVBitstreamCodec.NB; i++)
                        {
                            LAVBitstreamCodec codec = (LAVBitstreamCodec)i;
                            bool isEnabled = asett.GetBitstreamConfig(codec);
                            _logger.Log(LogSeverity.Debug, "{0} bitstreaming: {1}", codec, isEnabled);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.ErrorException("Error adding LAV Audio filter", ex);
            }

            DirectShowLib.IEnumPins pEnum;
            hr = pSource.EnumPins(out pEnum);
            DsError.ThrowExceptionForHR(hr);

            DirectShowLib.IPin[] pins = { null };

            /* Counter for how many pins successfully rendered */
            var pinsRendered = 0;
            /* Loop over each pin of the source filter */
            while (pEnum.Next(1, pins, IntPtr.Zero) == 0)
            {
                //explicitly build graph to avoid unwanted filters worming their way in
                List<Guid> mediaTypes = GetPinMediaTypes(pins[0]);
                bool needsRender = true;

                for (int m = 0; m < mediaTypes.Count; m++)
                {
                    DirectShowLib.IPin decIn = null;
                    DirectShowLib.IPin decOut = null;
                    DirectShowLib.IPin rendIn = null;

                    try
                    {
                        if (mediaTypes[m] == DirectShowLib.MediaType.Video && _lavvideo != null)
                        {
                            decIn = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_lavvideo, PinDirection.Input, 0);
                            if (decIn != null)
                            {
                                hr = _filterGraph.ConnectDirect(pins[0], decIn, null);
                                DsError.ThrowExceptionForHR(hr);
                                decOut = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_lavvideo, PinDirection.Output, 0);

                                if (_xyVsFilter != null)
                                {
                                    //insert xyVsFilter b/w LAV Video and the renderer
                                    rendIn = DsFindPin.ByName((DirectShowLib.IBaseFilter)_xyVsFilter, "Video");
                                    if (decOut != null && rendIn != null)
                                    {
                                        hr = _filterGraph.ConnectDirect(decOut, rendIn, null);
                                        DsError.ThrowExceptionForHR(hr);
                                        CleanUpInterface(decOut);
                                        CleanUpInterface(rendIn);
                                        //grab xyVsFilter's output pin so it can be connected to the renderer
                                        decOut = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_xyVsFilter, PinDirection.Output, 0);
                                    }
                                }

                                if (_madvr != null)
                                {
                                    rendIn = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_madvr, PinDirection.Input, 0);
                                }
                                else
                                {
                                    rendIn = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_mPEvr, PinDirection.Input, 0);
                                }

                                if (decOut != null && rendIn != null)
                                {
                                    hr = _filterGraph.ConnectDirect(decOut, rendIn, null);
                                    DsError.ThrowExceptionForHR(hr);

                                    needsRender = false;
                                    break;
                                }
                            }
                        }
                        else if (mediaTypes[m] == DirectShowLib.MediaType.Audio && _lavaudio != null)
                        {
                            decIn = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_lavaudio, PinDirection.Input, 0);
                            if (decIn != null)
                            {
                                hr = _filterGraph.ConnectDirect(pins[0], decIn, null);
                                DsError.ThrowExceptionForHR(hr);
                                decOut = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_lavaudio, PinDirection.Output, 0);

                                if (_reclockAudioRenderer != null)
                                {
                                    rendIn = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_reclockAudioRenderer, PinDirection.Input, 0);
                                }
                                else
                                {
                                    rendIn = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_defaultAudioRenderer, PinDirection.Input, 0);
                                }

                                if (decOut != null && rendIn != null)
                                {
                                    hr = _filterGraph.ConnectDirect(decOut, rendIn, null);
                                    DsError.ThrowExceptionForHR(hr);

                                    needsRender = false;
                                    break;
                                }
                            }
                        }
                        else if (mediaTypes[m] == new Guid("E487EB08-6B26-4be9-9DD3-993434D313FD") /*DirectShowLib.MediaType.Subtitle*/
                            && (_xySubFilter != null || _xyVsFilter != null))
                        {

                            if (_xySubFilter != null)
                            {
                                rendIn = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_xySubFilter, PinDirection.Input, 0);
                            }
                            else
                            {
                                rendIn = DsFindPin.ByName((DirectShowLib.IBaseFilter)_xyVsFilter, "Input");
                            }

                            if (rendIn != null)
                            {
                                hr = _filterGraph.ConnectDirect(pins[0], rendIn, null);
                                DsError.ThrowExceptionForHR(hr);

                                needsRender = false;
                                break;
                            }
                        }
                    }
                    finally
                    {
                        CleanUpInterface(decIn);
                        CleanUpInterface(decOut);
                        CleanUpInterface(rendIn);
                    }
                }

                if (needsRender)
                {
                    if (_filterGraph.RenderEx(pins[0], AMRenderExFlags.RenderToExistingRenderers, IntPtr.Zero) >= 0)
                        pinsRendered++;
                }
                else
                    pinsRendered++;

                Marshal.ReleaseComObject(pins[0]);
            }

            Marshal.ReleaseComObject(pEnum);

            if (pinsRendered == 0)
            {
                throw new Exception("Could not render any streams from the source Uri");
            }

            _logger.Debug("Completed RenderStreams with {0} pins.", pinsRendered);

            if (_item.IsVideo)
            {
                SetVideoWindow(enableMadvrExclusiveMode);
                if(_mPEvr != null)
                    SetEvrVppMode(_mPEvr);
            }
        }
        private void RenderStreams(DirectShowLib.IBaseFilter pSource,
            string forcedVideoRenderer,
            bool enableXySubFilter)
        {
            int hr;

            _filterGraph = m_graph as DirectShowLib.IFilterGraph2;
            if (_filterGraph == null)
            {
                throw new Exception("Could not QueryInterface for the IFilterGraph2");
            }

            var useDefaultRenderer = true;

            DirectShowLib.IEnumPins pEnum;
            hr = pSource.EnumPins(out pEnum);
            DsError.ThrowExceptionForHR(hr);

            DirectShowLib.IPin[] pins = { null };

            /* Counter for how many pins successfully rendered */
            var pinsRendered = 0;
            /* Loop over each pin of the source filter */
            while (pEnum.Next(1, pins, IntPtr.Zero) == 0)
            {
                //explicitly build graph to avoid unwanted filters worming their way in
                List<Guid> mediaTypes = GetPinMediaTypes(pins[0]);
                bool needsRender = true;

                for (int m = 0; m < mediaTypes.Count; m++)
                {
                    DirectShowLib.IPin decIn = null;
                    DirectShowLib.IPin decOut = null;
                    DirectShowLib.IPin rendIn = null;

                    var enableMadvr = _config.VideoConfig.EnableMadvr && (string.IsNullOrWhiteSpace(forcedVideoRenderer) || string.Equals(forcedVideoRenderer, "madvr", StringComparison.OrdinalIgnoreCase));

                    try
                    {
                        if (mediaTypes[m] == DirectShowLib.MediaType.Video)
                        {
                            #region Video

                            //add the video renderer first so we know whether to enable DXVA2 in "Auto" mode.
                            if (enableMadvr)
                            {
                                try
                                {
                                    _madvr = URCOMLoader.Instance.GetObject(typeof(MadVR).GUID, true); // new MadVR();
                                    var vmadvr = _madvr as DirectShowLib.IBaseFilter;
                                    if (vmadvr != null)
                                    {
                                        hr = m_graph.AddFilter(vmadvr, "MadVR Video Renderer");
                                        DsError.ThrowExceptionForHR(hr);

                                        try
                                        {
                                            MadVRSettings msett = new MadVRSettings(_madvr);

                                            bool smoothMotion = msett.GetBool("smoothMotionEnabled");

                                            if (smoothMotion !=
                                                _config.VideoConfig
                                                    .UseMadVrSmoothMotion)
                                                msett.SetBool("smoothMotionEnabled",
                                                    _config.VideoConfig
                                                        .UseMadVrSmoothMotion);

                                            if (
                                                string.Compare(msett.GetString("smoothMotionMode"),
                                                    _config.VideoConfig
                                                        .MadVrSmoothMotionMode, true) != 0)
                                            {
                                                bool success = msett.SetString("smoothMotionMode",
                                                    _config.VideoConfig
                                                        .MadVrSmoothMotionMode);
                                            }
                                            MFNominalRange levels = (MFNominalRange)_config.VideoConfig.NominalRange;
                                            //string madVrLevelInitial = msett.GetString("levels");
                                            //switch (levels)
                                            //{
                                            //    case MFNominalRange.MFNominalRange_0_255:
                                            //        msett.SetString("levels", "PC Levels");
                                            //        break;
                                            //    case MFNominalRange.MFNominalRange_16_235:
                                            //        msett.SetString("levels", "TV Levels");
                                            //        break;
                                            //}
                                            //string madVrLevel = msett.GetString("levels");

                                            //if (string.Compare(madVrLevel, madVrLevelInitial, false) != 0)
                                            //    _logger.Debug("Changed madVR levels from {0} to {1}", madVrLevelInitial, madVrLevel);
                                        }
                                        catch (Exception ex)
                                        {
                                            _logger.ErrorException("Error configuring madVR", ex);
                                        }

                                    }
                                }
                                catch (Exception ex)
                                {
                                    _logger.ErrorException("Error adding MadVR filter", ex);
                                }
                            }
                            else // Add default video renderer
                            {
                                _mPEvr = (DirectShowLib.IBaseFilter)new EnhancedVideoRenderer();
                                hr = m_graph.AddFilter(_mPEvr, "EVR");
                                DsError.ThrowExceptionForHR(hr);

                                //we only need 2 input pins on the EVR if LAV Video isn't used for DVDs, but it doesn't hurt to have them
                                InitializeEvr(_mPEvr, _isDvd ? 2 : 1, forcedVideoRenderer);
                            }

                            try
                            {
                                _lavvideo = URCOMLoader.Instance.GetObject(typeof(LAVVideo).GUID, true); //new LAVVideo();
                                var vlavvideo = _lavvideo as DirectShowLib.IBaseFilter;
                                if (vlavvideo != null)
                                {
                                    hr = m_graph.AddFilter(vlavvideo, "LAV Video Decoder");
                                    DsError.ThrowExceptionForHR(hr);

                                    ILAVVideoSettings vsett = vlavvideo as ILAVVideoSettings;
                                    if (vsett != null)
                                    {
                                        //we only want to set it for MB
                                        hr = vsett.SetRuntimeConfig(true);
                                        DsError.ThrowExceptionForHR(hr);

                                        _logger.Debug("GPU Model: {0}", VideoConfiguration.GpuModel);

                                        LAVHWAccel configuredMode =
                                            VideoConfigurationUtils.GetHwaMode(
                                                _config.VideoConfig,
                                                _customEvrPresenterLoaded);

                                        LAVHWAccel testme = vsett.GetHWAccel();
                                        _logger.Debug("Current HWA Mode: {0} Desired Mode: {1}", testme, configuredMode);
                                        if (testme != configuredMode)
                                        {
                                            hr = vsett.SetHWAccel(configuredMode);
                                            DsError.ThrowExceptionForHR(hr);
                                        }

                                        foreach (string c in DirectShowPlayer.GetLAVVideoCodecs())
                                        {
                                            LAVVideoCodec codec = (LAVVideoCodec)Enum.Parse(typeof(LAVVideoCodec), c);

                                            bool isEnabled = vsett.GetFormatConfiguration(codec);
                                            if (
                                                _config.VideoConfig.EnabledCodecs
                                                    .Contains(c))
                                            {
                                                if (!isEnabled)
                                                {
                                                    _logger.Debug("Enable support for: {0}", c);
                                                    hr = vsett.SetFormatConfiguration(codec, true);
                                                    DsError.ThrowExceptionForHR(hr);
                                                }
                                            }
                                            else if (isEnabled)
                                            {
                                                _logger.Debug("Disable support for: {0}", c);
                                                hr = vsett.SetFormatConfiguration(codec, false);
                                                DsError.ThrowExceptionForHR(hr);
                                            }
                                        }

                                        foreach (string hwaCodec in DirectShowPlayer.GetLAVVideoHwaCodecs())
                                        {
                                            LAVVideoHWCodec codec = (LAVVideoHWCodec)Enum.Parse(typeof(LAVVideoHWCodec), hwaCodec);
                                            bool hwaIsEnabled = vsett.GetHWAccelCodec(codec);

                                            if (
                                                _config.VideoConfig.HwaEnabledCodecs
                                                    .Contains(hwaCodec))
                                            {
                                                if (!hwaIsEnabled)
                                                {
                                                    _logger.Debug("Enable HWA support for: {0}", hwaCodec);
                                                    hr = vsett.SetHWAccelCodec(codec, true);
                                                    DsError.ThrowExceptionForHR(hr);
                                                }
                                            }
                                            else if (hwaIsEnabled)
                                            {
                                                _logger.Debug("Disable HWA support for: {0}", hwaCodec);
                                                hr = vsett.SetHWAccelCodec(codec, false);
                                                DsError.ThrowExceptionForHR(hr);
                                            }
                                        }

                                        if (!vsett.GetDVDVideoSupport())
                                        {
                                            _logger.Debug("Enable DVD support.");
                                            hr = vsett.SetDVDVideoSupport(true);
                                            DsError.ThrowExceptionForHR(hr);
                                        }

                                        int hwaRes = vsett.GetHWAccelResolutionFlags();
                                        if (hwaRes != _config.VideoConfig.HwaResolution
                                            && _config.VideoConfig.HwaResolution > 0)
                                        {
                                            _logger.Debug("Change HWA resolution support from {0} to {1}.", hwaRes,
                                                _config.VideoConfig.HwaResolution);
                                            hr =
                                                vsett.SetHWAccelResolutionFlags(
                                                    VideoConfigurationUtils.GetHwaResolutions(
                                                        _config.VideoConfig));
                                            DsError.ThrowExceptionForHR(hr);
                                        }

                                        hr =
                                            vsett.SetTrayIcon(
                                                _config.VideoConfig.ShowTrayIcon);
                                        DsError.ThrowExceptionForHR(hr);
                                    }
                                }

                                decIn = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_lavvideo, PinDirection.Input, 0);
                                if (decIn != null)
                                {
                                    hr = _filterGraph.ConnectDirect(pins[0], decIn, null);
                                    DsError.ThrowExceptionForHR(hr);
                                    decOut = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_lavvideo,
                                        PinDirection.Output, 0);

                                    if (enableXySubFilter) //this flag indicates whether we should handle subtitle rendering
                                    {
                                        var xySubFilterSucceeded = false;

                                        // Load xySubFilter if configured and if madvr succeeded
                                        if (_madvr != null || _customEvrPresenterLoaded)
                                        {
                                            try
                                            {
                                                _xySubFilter = URCOMLoader.Instance.GetObject(typeof(XySubFilter).GUID, true); //new XySubFilter();
                                                var vxySubFilter = _xySubFilter as DirectShowLib.IBaseFilter;
                                                if (vxySubFilter != null)
                                                {
                                                    hr = m_graph.AddFilter(vxySubFilter, "xy-SubFilter");
                                                    DsError.ThrowExceptionForHR(hr);
                                                }

                                                xySubFilterSucceeded = true;
                                            }
                                            catch (Exception ex)
                                            {
                                                _logger.ErrorException("Error adding xy-SubFilter filter", ex);
                                            }
                                        }

                                        // Fallback to xyVsFilter
                                        if (!xySubFilterSucceeded)
                                        {
                                            try
                                            {
                                                _xyVsFilter = URCOMLoader.Instance.GetObject(typeof(XYVSFilter).GUID, true); //new XYVSFilter();
                                                var vxyVsFilter = _xyVsFilter as DirectShowLib.IBaseFilter;
                                                if (vxyVsFilter != null)
                                                {
                                                    hr = m_graph.AddFilter(vxyVsFilter, "xy-VSFilter");
                                                    DsError.ThrowExceptionForHR(hr);
                                                }
                                            }
                                            catch (Exception ex)
                                            {
                                                _logger.ErrorException("Error adding xy-VSFilter filter", ex);
                                            }
                                        }

                                        if (_xyVsFilter != null) //If using VSFilter
                                        {
                                            //insert xyVsFilter b/w LAV Video and the renderer
                                            rendIn = DsFindPin.ByName((DirectShowLib.IBaseFilter)_xyVsFilter, "Video");

                                            //connect it to VSFilter
                                            if (decOut != null && rendIn != null)
                                            {
                                                hr = _filterGraph.ConnectDirect(decOut, rendIn, null);
                                                DsError.ThrowExceptionForHR(hr);

                                                CleanUpInterface(rendIn);
                                                CleanUpInterface(decOut);
                                                rendIn = null;
                                                decOut = null;
                                            }

                                            //grab xyVsFilter's output pin so it can be connected to the renderer
                                            decOut = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_xyVsFilter,
                                                    PinDirection.Output, 0);
                                        }
                                    }

                                    if (_madvr != null)
                                    {
                                        rendIn = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_madvr,
                                            PinDirection.Input, 0);
                                    }
                                    else
                                    {
                                        rendIn = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_mPEvr,
                                            PinDirection.Input, 0);
                                    }

                                    if (decOut != null && rendIn != null)
                                    {
                                        hr = _filterGraph.ConnectDirect(decOut, rendIn, null);
                                        DsError.ThrowExceptionForHR(hr);

                                        needsRender = false;
                                        break;
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                _logger.ErrorException("Error adding LAV Video filter", ex);
                            }

                            #endregion
                        }
                        else if (mediaTypes[m] == DirectShowLib.MediaType.Audio)
                        {
                            #region Audio
                            //we have an audio pin so add a renderer and decoder
                            switch (_config.AudioConfig.Renderer)
                            {
                                case AudioRendererChoice.Reclock:
                                    try
                                    {
                                        _reclockAudioRenderer = new ReclockAudioRenderer();
                                        var aRenderer = _reclockAudioRenderer as DirectShowLib.IBaseFilter;
                                        if (aRenderer != null)
                                        {
                                            hr = m_graph.AddFilter(aRenderer, "Reclock Audio Renderer");
                                            DsError.ThrowExceptionForHR(hr);
                                            useDefaultRenderer = false;

                                            _logger.Debug("Added reclock audio renderer");
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        _logger.ErrorException("Error adding reclock filter", ex);
                                    }
                                    break;
                                case AudioRendererChoice.WASAPI:
                                    try
                                    {
                                        _wasapiAR = URCOMLoader.Instance.GetObject(typeof(MPAudioFilter).GUID, true);
                                        var aRenderer = _wasapiAR as DirectShowLib.IBaseFilter;
                                        if (aRenderer != null)
                                        {
                                            hr = m_graph.AddFilter(aRenderer, "WASAPI Audio Renderer");
                                            DsError.ThrowExceptionForHR(hr);
                                            useDefaultRenderer = false;
                                            _logger.Debug("Added WASAPI audio renderer");

                                            IMPAudioRendererConfig arSett = aRenderer as IMPAudioRendererConfig;
                                            if (arSett != null)
                                            {
                                                arSett.SetInt(MPARSetting.WASAPI_MODE, (int)AUDCLNT_SHAREMODE.EXCLUSIVE);
                                                arSett.SetBool(MPARSetting.WASAPI_EVENT_DRIVEN, _config.AudioConfig.UseWasapiEventMode);
                                                _logger.Debug("Set WASAPI use event mode: {0}", _config.AudioConfig.UseWasapiEventMode);
                                                arSett.SetString(MPARSetting.SETTING_AUDIO_DEVICE, _config.AudioConfig.AudioDevice);
                                                _logger.Debug("Set WASAPI audio device: {0}", _config.AudioConfig.AudioDevice);
                                                SpeakerConfig sc = SpeakerConfig.Stereo; //use stereo for maxium compat
                                                Enum.TryParse<SpeakerConfig>(_config.AudioConfig.SpeakerLayout, out sc);
                                                arSett.SetInt(MPARSetting.SPEAKER_CONFIG, (int)sc);
                                                _logger.Debug("Set WASAPI speaker config: {0}", sc);
                                                //audSett.SetSpeakerMatchOutput(true);
                                                arSett.SetBool(MPARSetting.ALLOW_BITSTREAMING, true);
                                                arSett.SetInt(MPARSetting.USE_FILTERS, _config.AudioConfig.WasapiARFilters);
                                                _logger.Debug("Set WASAPI filter config: {0}", _config.AudioConfig.WasapiARFilters);
                                                AC3Encoding a3 = (AC3Encoding)_config.AudioConfig.Ac3EncodingMode;
                                                arSett.SetInt(MPARSetting.AC3_ENCODING, (int)a3);
                                                _logger.Debug("Set WASAPI AC3 encoding: {0}", a3);
                                                arSett.SetBool(MPARSetting.ENABLE_TIME_STRETCHING, _config.AudioConfig.EnableTimeStretching);
                                                _logger.Debug("Set WASAPI use time stretching: {0}", _config.AudioConfig.EnableTimeStretching);
                                                arSett.SetInt(MPARSetting.OUTPUT_BUFFER_LENGTH, _config.AudioConfig.OutputBufferSize);
                                                _logger.Debug("Set WASAPI buffer: {0}", _config.AudioConfig.OutputBufferSize);
                                            }
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        _logger.ErrorException("Error adding WASAPI audio filter", ex);
                                    }
                                    break;
                            }

                            if (useDefaultRenderer)
                            {
                                AddDefaultAudioRenderer();
                            }

                            try
                            {
                                _lavaudio = URCOMLoader.Instance.GetObject(typeof(LAVAudio).GUID, true); // new LAVAudio();
                                var vlavaudio = _lavaudio as DirectShowLib.IBaseFilter;
                                if (vlavaudio != null)
                                {
                                    _logger.Debug("Add LAVAudio to the graph.");

                                    hr = m_graph.AddFilter(vlavaudio, "LAV Audio Decoder");
                                    DsError.ThrowExceptionForHR(hr);

                                    ILAVAudioSettings asett = vlavaudio as ILAVAudioSettings;
                                    if (asett != null)
                                    {
                                        _logger.Debug("Enable LAVAudio Runtime Config");

                                        //we only want to set it for MB
                                        hr = asett.SetRuntimeConfig(true);
                                        DsError.ThrowExceptionForHR(hr);

                                        foreach (string c in DirectShowPlayer.GetLAVAudioCodecs())
                                        {
                                            LAVAudioCodec codec = (LAVAudioCodec)Enum.Parse(typeof(LAVAudioCodec), c);

                                            bool isEnabled = asett.GetFormatConfiguration(codec);
                                            if (
                                                _config.AudioConfig.EnabledCodecs.Contains(
                                                    c))
                                            {
                                                if (!isEnabled)
                                                {
                                                    _logger.Debug("Enable support for: {0}", c);
                                                    hr = asett.SetFormatConfiguration(codec, true);
                                                    DsError.ThrowExceptionForHR(hr);
                                                }
                                            }
                                            else if (isEnabled)
                                            {
                                                _logger.Debug("Disable support for: {0}", c);
                                                hr = asett.SetFormatConfiguration(codec, false);
                                                DsError.ThrowExceptionForHR(hr);
                                            }
                                        }

                                        //enable/disable bitstreaming
                                        if ((_config.AudioConfig.AudioBitstreaming &
                                             BitstreamChoice.SPDIF) == BitstreamChoice.SPDIF)
                                        {
                                            _logger.Debug("Enable LAVAudio S/PDIF bitstreaming");

                                            hr = asett.SetBitstreamConfig(LAVBitstreamCodec.AC3, true);
                                            DsError.ThrowExceptionForHR(hr);

                                            hr = asett.SetBitstreamConfig(LAVBitstreamCodec.DTS, true);
                                            DsError.ThrowExceptionForHR(hr);
                                        }

                                        if ((_config.AudioConfig.AudioBitstreaming &
                                             BitstreamChoice.HDMI) == BitstreamChoice.HDMI)
                                        {
                                            _logger.Debug("Enable LAVAudio HDMI bitstreaming");

                                            hr = asett.SetBitstreamConfig(LAVBitstreamCodec.EAC3, true);
                                            DsError.ThrowExceptionForHR(hr);

                                            hr = asett.SetBitstreamConfig(LAVBitstreamCodec.TRUEHD, true);
                                            DsError.ThrowExceptionForHR(hr);

                                            hr = asett.SetBitstreamConfig(LAVBitstreamCodec.DTSHD, true);
                                            DsError.ThrowExceptionForHR(hr);

                                        }

                                        if (_config.AudioConfig.Delay > 0)
                                        {
                                            _logger.Debug("Set LAVAudio audio delay: {0}",
                                                _config.AudioConfig.Delay);

                                            hr = asett.SetAudioDelay(true,
                                                _config.AudioConfig.Delay);
                                            DsError.ThrowExceptionForHR(hr);
                                        }

                                        _logger.Debug("Set LAVAudio auto AV Sync: {0}",
                                            _config.AudioConfig.EnableAutoSync);
                                        hr =
                                            asett.SetAutoAVSync(
                                                _config.AudioConfig.EnableAutoSync);
                                        DsError.ThrowExceptionForHR(hr);

                                        _logger.Debug("Set LAVAudio Expand61: {0}",
                                            _config.AudioConfig.Expand61);
                                        hr = asett.SetExpand61(_config.AudioConfig.Expand61);
                                        DsError.ThrowExceptionForHR(hr);

                                        _logger.Debug("Set LAVAudio ExpandMono: {0}",
                                            _config.AudioConfig.ExpandMono);
                                        hr =
                                            asett.SetExpandMono(
                                                _config.AudioConfig.ExpandMono);
                                        DsError.ThrowExceptionForHR(hr);

                                        _logger.Debug("Set LAVAudio ConvertToStandardLayout: {0}",
                                            _config.AudioConfig.ConvertToStandardLayout);
                                        hr =
                                            asett.SetOutputStandardLayout(
                                                _config.AudioConfig.ConvertToStandardLayout);
                                        DsError.ThrowExceptionForHR(hr);

                                        _logger.Debug("Set LAVAudio audio EnableDRC: {0}",
                                            _config.AudioConfig.EnableDRC);
                                        hr = asett.SetDRC(_config.AudioConfig.EnableDRC,
                                            _config.AudioConfig.DRCLevel);
                                        DsError.ThrowExceptionForHR(hr);

                                        _logger.Debug("Set LAVAudio audio ShowTrayIcon: {0}",
                                            _config.AudioConfig.ShowTrayIcon);
                                        hr =
                                            asett.SetTrayIcon(
                                                _config.AudioConfig.ShowTrayIcon);
                                        DsError.ThrowExceptionForHR(hr);

                                        bool mixingEnabled = asett.GetMixingEnabled();
                                        if (mixingEnabled !=
                                            _config.AudioConfig.EnablePCMMixing)
                                        {
                                            _logger.Debug("Set LAVAudio EnablePCMMixing: {0}",
                                                _config.AudioConfig.EnablePCMMixing);
                                            hr = asett.SetMixingEnabled(!mixingEnabled);
                                            DsError.ThrowExceptionForHR(hr);
                                        }

                                        if (_config.AudioConfig.EnablePCMMixing)
                                        {
                                            _logger.Debug("Set LAVAudio MixingSetting: {0}",
                                                _config.AudioConfig.MixingSetting);
                                            LAVAudioMixingFlag amf =
                                                (LAVAudioMixingFlag)
                                                    _config.AudioConfig.MixingSetting;
                                            hr = asett.SetMixingFlags(amf);
                                            DsError.ThrowExceptionForHR(hr);

                                            _logger.Debug("Set LAVAudio MixingEncoding: {0}",
                                                _config.AudioConfig.MixingEncoding);
                                            LAVAudioMixingMode amm =
                                                (LAVAudioMixingMode)
                                                    Enum.Parse(typeof(LAVAudioMixingMode),
                                                        _config.AudioConfig.MixingEncoding);
                                            hr = asett.SetMixingMode(amm);
                                            DsError.ThrowExceptionForHR(hr);

                                            _logger.Debug("Set LAVAudio MixingLayout: {0}",
                                                _config.AudioConfig.MixingLayout);
                                            LAVAudioMixingLayout aml =
                                                (LAVAudioMixingLayout)
                                                    Enum.Parse(typeof(LAVAudioMixingLayout),
                                                        _config.AudioConfig.MixingLayout);
                                            hr = asett.SetMixingLayout(aml);
                                            DsError.ThrowExceptionForHR(hr);

                                            _logger.Debug(
                                                "Set LAVAudio LfeMixingLevel: {0} CenterMixingLevel: {1} SurroundMixingLevel: {2}",
                                                _config.AudioConfig.LfeMixingLevel,
                                                _config.AudioConfig.CenterMixingLevel,
                                                _config.AudioConfig.SurroundMixingLevel);
                                            int lfe, center, surround;
                                            //convert to the # that LAV Audio expects
                                            lfe =
                                                (int)
                                                    (_config.AudioConfig.LfeMixingLevel *
                                                     10000.01);
                                            center =
                                                (int)
                                                    (_config.AudioConfig.CenterMixingLevel *
                                                     10000.01);
                                            surround =
                                                (int)
                                                    (_config.AudioConfig
                                                        .SurroundMixingLevel * 10000.01);

                                            hr = asett.SetMixingLevels(center, surround, lfe);
                                            DsError.ThrowExceptionForHR(hr);
                                        }

                                        for (int i = 0; i < (int)LAVBitstreamCodec.NB; i++)
                                        {
                                            LAVBitstreamCodec codec = (LAVBitstreamCodec)i;
                                            bool isEnabled = asett.GetBitstreamConfig(codec);
                                            _logger.Log(LogSeverity.Debug, "{0} bitstreaming: {1}", codec, isEnabled);
                                        }
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                _logger.ErrorException("Error adding LAV Audio filter", ex);
                            }

                            decIn = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_lavaudio, PinDirection.Input, 0);
                            if (decIn != null)
                            {
                                hr = _filterGraph.ConnectDirect(pins[0], decIn, null);
                                if (hr < 0) //LAV cannot handle this audio type
                                {
                                    _logger.Warn("LAV Audio could not decode audio media type.");
                                }
                                else
                                {
                                    //DsError.ThrowExceptionForHR(hr);
                                    decOut = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_lavaudio,
                                        PinDirection.Output, 0);
                                }

                                rendIn = DsFindPin.ByDirection(AudioRenderer, PinDirection.Input, 0);

                                if (decOut != null && rendIn != null)
                                {
                                    hr = _filterGraph.ConnectDirect(decOut, rendIn, null);
                                    if (hr == -2004287474 && _wasapiAR != null) //AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED
                                    {
                                        IMPAudioRendererConfig arSett = _wasapiAR as IMPAudioRendererConfig;
                                        if (arSett != null)
                                        {
                                            arSett.SetInt(MPARSetting.WASAPI_MODE, (int)AUDCLNT_SHAREMODE.SHARED);
                                            _logger.Warn("WASAPI AR failed to connected in exclusive mode, check device properties");
                                            hr = _filterGraph.ConnectDirect(decOut, rendIn, null);
                                        }
                                    }
                                    DsError.ThrowExceptionForHR(hr);

                                    needsRender = false;
                                    break;
                                }
                            }
                            #endregion
                        }
                        else if (mediaTypes[m] == SubtitleMediaType
                            /*DirectShowLib.MediaType.Subtitle*/)
                        {
                            #region subtitles

                            if (_xySubFilter != null)
                            {
                                rendIn = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_xySubFilter,
                                    PinDirection.Input, 0);
                            }
                            else if (_xyVsFilter != null)
                            {
                                rendIn = DsFindPin.ByName((DirectShowLib.IBaseFilter)_xyVsFilter, "Input");
                            }

                            if (rendIn != null)
                            {
                                hr = _filterGraph.ConnectDirect(pins[0], rendIn, null);
                                DsError.ThrowExceptionForHR(hr);

                                needsRender = false;
                                break;
                            }
                            #endregion
                        }
                        else if (mediaTypes[m] == DvdSubpictureMediaType)
                        {
                            #region DVD Subpicture
                            if (_lavvideo != null)
                            {
                                rendIn = DsFindPin.ByName((DirectShowLib.IBaseFilter)_lavvideo, "Subtitle Input");
                                if (rendIn != null)
                                {
                                    hr = _filterGraph.ConnectDirect(pins[0], rendIn, null);
                                    DsError.ThrowExceptionForHR(hr);

                                    needsRender = false;
                                    break;
                                }
                            }
                            #endregion
                        }
                    }
                    finally
                    {
                        CleanUpInterface(decIn);
                        CleanUpInterface(decOut);
                        CleanUpInterface(rendIn);
                    }
                }

                if (needsRender)
                {
                    if (_filterGraph.RenderEx(pins[0], AMRenderExFlags.RenderToExistingRenderers, IntPtr.Zero) >= 0)
                        pinsRendered++;
                }
                else
                    pinsRendered++;

                Marshal.ReleaseComObject(pins[0]);
            }

            Marshal.ReleaseComObject(pEnum);

            if (pinsRendered == 0)
            {
                throw new Exception("Could not render any streams from the source Uri");
            }

            _logger.Debug("Completed RenderStreams with {0} pins.", pinsRendered);

            if (_item.IsVideo)
            {
                SetVideoWindow();
                if (_mPEvr != null)
                    SetEvrVppMode(_mPEvr);
            }
        }
Beispiel #17
0
    // Build the capture graph for grabber and renderer.</summary>
    // (Control to show video in, Filename to play)
    private void SetupGraph(string FileName)
    {
        int hr;

        // Get the graphbuilder object
        m_graphBuilder = new DirectShowLib.FilterGraph() as DirectShowLib.IFilterGraph2;

        // Get a ICaptureGraphBuilder2 to help build the graph
        DirectShowLib.ICaptureGraphBuilder2 icgb2 = new DirectShowLib.CaptureGraphBuilder2() as DirectShowLib.ICaptureGraphBuilder2;

        try
        {
            // Link the ICaptureGraphBuilder2 to the IFilterGraph2
            hr = icgb2.SetFiltergraph(m_graphBuilder);
            DsError.ThrowExceptionForHR(hr);

#if DEBUG
            // Allows you to view the graph with GraphEdit File/Connect
            m_DsRot = new DsROTEntry(m_graphBuilder);
#endif

            // Add the filters necessary to render the file.  This function will
            // work with a number of different file types.
            IBaseFilter sourceFilter = null;
            hr = m_graphBuilder.AddSourceFilter(FileName, FileName, out sourceFilter);
            DsError.ThrowExceptionForHR(hr);

            // Get the SampleGrabber interface
            m_sampGrabber = (DirectShowLib.ISampleGrabber) new DirectShowLib.SampleGrabber();
            DirectShowLib.IBaseFilter baseGrabFlt = (DirectShowLib.IBaseFilter)m_sampGrabber;

            // Configure the Sample Grabber
            ConfigureSampleGrabber(m_sampGrabber);

            // Add it to the filter
            hr = m_graphBuilder.AddFilter(baseGrabFlt, "Ds.NET Grabber");
            DsError.ThrowExceptionForHR(hr);

            // System.Windows.Forms.MessageBox.Show(Width.ToString(), Height.ToString(), System.Windows.Forms.MessageBoxButtons.OK);

            // A Null Renderer does not display the video
            // But it allows the Sample Grabber to run
            // And it will keep proper playback timing
            // Unless specified otherwise.
            DirectShowLib.NullRenderer nullRenderer = new DirectShowLib.NullRenderer();

            m_graphBuilder.AddFilter((DirectShowLib.IBaseFilter)nullRenderer, "Null Renderer");

            // Connect the pieces together, use the default renderer
            hr = icgb2.RenderStream(null, null, sourceFilter, baseGrabFlt, (DirectShowLib.IBaseFilter)nullRenderer);
            DsError.ThrowExceptionForHR(hr);

            // Now that the graph is built, read the dimensions of the bitmaps we'll be getting
            SaveSizeInfo(m_sampGrabber);

            // Configure the Video Window
            //DirectShowLib.IVideoWindow videoWindow = m_graphBuilder as DirectShowLib.IVideoWindow;
            //ConfigureVideoWindow(videoWindow, hWin);

            // Grab some other interfaces
            m_mediaEvent = m_graphBuilder as DirectShowLib.IMediaEvent;
            m_mediaCtrl  = m_graphBuilder as DirectShowLib.IMediaControl;
        }
        finally
        {
            if (icgb2 != null)
            {
                Marshal.ReleaseComObject(icgb2);
                icgb2 = null;
            }
        }
#if DEBUG
        // Double check to make sure we aren't releasing something
        // important.
        GC.Collect();
        GC.WaitForPendingFinalizers();
#endif
    }