Ejemplo n.º 1
0
        private void CloseInterface()
        {
            //그래프와 콘트롤 해제
            if (pMediaControl != null)
            {
                pMediaControl.StopWhenReady();
            }
            if (pVideoWindow != null)
            {
                pVideoWindow.put_Visible(OABool.False);
                pVideoWindow.put_Owner(IntPtr.Zero);
            }

            Marshal.ReleaseComObject(pSampleGrabber);
            pSampleGrabber = null;
            Marshal.ReleaseComObject(pSampleGrabberFilter);
            pSampleGrabberFilter = null;
            Marshal.ReleaseComObject(pGraphBuilder);
            pGraphBuilder = null;
            Marshal.ReleaseComObject(pMediaControl);
            pMediaControl = null;
            Marshal.ReleaseComObject(pVideoWindow);
            pVideoWindow = null;
            Marshal.ReleaseComObject(pMediaPosition);
            pMediaPosition = null;
            //this.Close(); //close this program
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Load a video to setup DirectShow. This also initally creates an instance of the DirectX3D Device
        /// </summary>
        public static void StartGraph()
        {
            int hr = 0;

            //CloseGraph();

            string path = @"opensebj.wmv";

            try
            {
                graph  = (DirectShowLib.IGraphBuilder) new DirectShowLib.FilterGraph();
                filter = (DirectShowLib.IBaseFilter) new DirectShowLib.VideoMixingRenderer9();

                DirectShowLib.IVMRFilterConfig9 filterConfig = (DirectShowLib.IVMRFilterConfig9)filter;

                hr = filterConfig.SetRenderingMode(VMR9Mode.Renderless);
                DsError.ThrowExceptionForHR(hr);

                hr = filterConfig.SetNumberOfStreams(2);
                DsError.ThrowExceptionForHR(hr);

                SetAllocatorPresenter();

                hr = graph.AddFilter(filter, "Video Mixing Renderer 9");
                DsError.ThrowExceptionForHR(hr);

                hr = graph.RenderFile(path, null);
                DsError.ThrowExceptionForHR(hr);

                mediaControl = (DirectShowLib.IMediaControl)graph;
            }
            catch
            {
            }
        }
Ejemplo n.º 3
0
        private void Initialize(string path, bool enableReclock, bool enableMadvr, bool enableXySubFilter, bool isDvd)
        {
            InitializeGraph();

            int hr = 0;

            if (!isDvd)
            {
                hr = m_graph.AddSourceFilter(path, path, out _pSource);
                DsError.ThrowExceptionForHR(hr);

                // Try to render the streams.
                RenderStreams(_pSource, enableReclock, enableMadvr, enableXySubFilter);
            }
            else
            {
                _logger.Debug("Initializing dvd player to play {0}", path);

                /* Create a new DVD Navigator. */
                _dvdNav = (DirectShowLib.IBaseFilter) new DVDNavigator();

                InitializeDvd(path);

                // Try to render the streams.
                RenderStreams(_dvdNav, enableReclock, enableMadvr, enableXySubFilter);
            }

            // Get the seeking capabilities.
            hr = _mediaSeeking.GetCapabilities(out _mSeekCaps);
            DsError.ThrowExceptionForHR(hr);
        }
Ejemplo n.º 4
0
        public static void startSecond()
        {
            initDSArrays();



            filter1 = (DirectShowLib.IBaseFilter) new DirectShowLib.VideoMixingRenderer9();
            DirectShowLib.IVMRFilterConfig9 filterConfig = (DirectShowLib.IVMRFilterConfig9)filter1;
            filterConfig.SetRenderingMode(VMR9Mode.Renderless);
            filterConfig.SetNumberOfStreams(2);


            DirectShowLib.IVMRSurfaceAllocatorNotify9 vmrSurfAllocNotify = (DirectShowLib.IVMRSurfaceAllocatorNotify9)filter1;

            try
            {
                int hr = vmrSurfAllocNotify.AdviseSurfaceAllocator(userId1, allocator);
                DsError.ThrowExceptionForHR(hr);

                hr = allocator.AdviseNotify(vmrSurfAllocNotify);
                DsError.ThrowExceptionForHR(hr);
            }
            catch { }



            graph1 = (DirectShowLib.IGraphBuilder) new DirectShowLib.FilterGraph();
            graph1.AddFilter(filter1, "Video Mixing Renderer 9");

            graph1.RenderFile(@"C:\Download\workmates.wmv", null);
            mediaControl1 = (DirectShowLib.IMediaControl)graph1;
            mediaControl1.Run();
        }
Ejemplo n.º 5
0
        public static void RemoveAllFilters()
        {
            int hr = 0;

            DirectShowLib.IEnumFilters   enumFilters;
            System.Collections.ArrayList filtersArray = new System.Collections.ArrayList();

            hr = graph.EnumFilters(out enumFilters);
            DsError.ThrowExceptionForHR(hr);

            DirectShowLib.IBaseFilter[] filters = new DirectShowLib.IBaseFilter[1];
            int fetched;

            while (enumFilters.Next(filters.Length, filters, out fetched) == 0)
            {
                filtersArray.Add(filters[0]);
            }

            foreach (DirectShowLib.IBaseFilter filter in filtersArray)
            {
                hr = graph.RemoveFilter(filter);
                while (System.Runtime.InteropServices.Marshal.ReleaseComObject(filter) > 0)
                {
                    ;
                }
            }
        }
Ejemplo n.º 6
0
    // Set the Framerate, and video size
    private void SetConfigParms(DirectShowLib.ICaptureGraphBuilder2 capGraph, DirectShowLib.IBaseFilter capFilter, int iFrameRate, int iWidth, int iHeight)
    {
        int    hr;
        object o;

        DirectShowLib.AMMediaType media;

        // Find the stream config interface
        hr = capGraph.FindInterface(
            DirectShowLib.PinCategory.Capture, DirectShowLib.MediaType.Video, capFilter, typeof(DirectShowLib.IAMStreamConfig).GUID, out o);

        DirectShowLib.IAMStreamConfig videoStreamConfig = o as DirectShowLib.IAMStreamConfig;
        if (videoStreamConfig == null)
        {
            throw new Exception("Failed to get IAMStreamConfig");
        }

        // Get the existing format block
        hr = videoStreamConfig.GetFormat(out media);
        DsError.ThrowExceptionForHR(hr);

        // copy out the videoinfoheader
        DirectShowLib.VideoInfoHeader v = new DirectShowLib.VideoInfoHeader();
        Marshal.PtrToStructure(media.formatPtr, v);

        // if overriding the framerate, set the frame rate
        if (iFrameRate > 0)
        {
            v.AvgTimePerFrame = 10000000 / iFrameRate;
        }

        // if overriding the width, set the width
        if (iWidth > 0)
        {
            v.BmiHeader.Width = iWidth;
        }

        // if overriding the Height, set the Height
        if (iHeight > 0)
        {
            v.BmiHeader.Height = iHeight;
        }

        // Copy the media structure back
        Marshal.StructureToPtr(v, media.formatPtr, false);

        // Set the new format
        hr = videoStreamConfig.SetFormat(media);
        DsError.ThrowExceptionForHR(hr);

        DirectShowLib.DsUtils.FreeAMMediaType(media);
        media = null;
    }
Ejemplo n.º 7
0
        private void SetStream(SelectableMediaStream stream)
        {
            IEnumFilters enumFilters;
            var          hr = m_graph.EnumFilters(out enumFilters);

            DsError.ThrowExceptionForHR(hr);

            var filters = new DirectShowLib.IBaseFilter[1];

            while (enumFilters.Next(filters.Length, filters, IntPtr.Zero) == 0)
            {
                FilterInfo filterInfo;

                hr = filters[0].QueryFilterInfo(out filterInfo);
                DsError.ThrowExceptionForHR(hr);

                Guid cl;
                filters[0].GetClassID(out cl);

                if (stream.Type == MediaStreamType.Audio)
                {
                    if (cl != _audioSelector)
                    {
                        continue;
                    }
                }
                else if (stream.Type == MediaStreamType.Subtitle)
                {
                    if (cl != _grp2Selector && cl != _vobsubSelector)
                    {
                        continue;
                    }
                }

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

                var iss = filters[0] as IAMStreamSelect;

                iss.Enable(stream.Index, AMStreamSelectEnableFlags.Enable);

                Marshal.ReleaseComObject(filters[0]);
            }

            Marshal.ReleaseComObject(enumFilters);

            foreach (var i in GetSelectableStreams().Where(s => s.Type == stream.Type))
            {
                i.IsActive = i.Index == stream.Index;
            }
        }
Ejemplo n.º 8
0
        private void InitializeEvr(DirectShowLib.IBaseFilter pEvr, int dwStreams)
        {
            IMFVideoDisplayControl pDisplay;

            // Continue with the rest of the set-up.

            // Set the video window.
            object o;
            var    pGetService = (IMFGetService)pEvr;
            var    hr          = pGetService.GetService(MFServices.MR_VIDEO_RENDER_SERVICE, typeof(IMFVideoDisplayControl).GUID, out o);

            DsError.ThrowExceptionForHR(hr);

            try
            {
                pDisplay = (IMFVideoDisplayControl)o;
            }
            catch
            {
                Marshal.ReleaseComObject(o);
                throw;
            }

            // Set the number of streams.
            hr = pDisplay.SetVideoWindow(VideoWindowHandle);
            DsError.ThrowExceptionForHR(hr);

            if (dwStreams > 1)
            {
                var pConfig = (IEVRFilterConfig)pEvr;
                hr = pConfig.SetNumberOfStreams(dwStreams);
                DsError.ThrowExceptionForHR(hr);
            }

            // Return the IMFVideoDisplayControl pointer to the caller.
            _mPDisplay = pDisplay;
        }
Ejemplo n.º 9
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 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);
            }
        }
Ejemplo n.º 11
0
        private void RenderDvdStreams(bool enableMadvr, bool enableMadvrExclusiveMode)
        {
            int hr;

            AMDvdGraphFlags buildFlags = AMDvdGraphFlags.DoNotClear;

            #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
            {
                buildFlags = AMDvdGraphFlags.EvrOnly | buildFlags;
                object objEvr;
                hr = _dvdGraphBuilder.GetDvdInterface(typeof(IMFVideoRenderer).GUID, out objEvr);
                DsError.ThrowExceptionForHR(hr);
                _mPEvr = objEvr as IBaseFilter;

                //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);
            }

            AddVideoDecoder();

            #endregion

            #region Audio

            AddAudioRenderer();

            AddAudioDecoder();

            #endregion

            if (string.Compare(_filePath, "video_ts", true) < 0)
                _filePath = Path.Combine(_filePath, "video_ts");

            AMDvdRenderStatus buildStatus;
            hr = _dvdGraphBuilder.RenderDvdVideoVolume(_filePath, buildFlags, out buildStatus);
            DsError.ThrowExceptionForHR(hr);

            //The DVD Graph Builder won't connect LAV to the VR
            IPin lavOut = null;
            IPin vrIn = null;
            if (_lavvideo != null)
            {
                try
                {
                    lavOut = DsFindPin.ByDirection((_lavvideo as IBaseFilter), PinDirection.Output, 0);
                    if (lavOut != null)
                    {
                        hr = lavOut.ConnectedTo(out vrIn);
                        //DsError.ThrowExceptionForHR(hr);

                        if (vrIn == null)
                        {
                            if (_madvr != null)
                                vrIn = DsFindPin.ByDirection((_madvr as IBaseFilter), PinDirection.Input, 0);
                            else
                                vrIn = DsFindPin.ByDirection(_mPEvr, PinDirection.Input, 0);
                            hr = _graph.ConnectDirect(lavOut, vrIn, null);
                            DsError.ThrowExceptionForHR(hr);
                        }
                    }
                }
                finally
                {
                    if (lavOut != null)
                        Marshal.ReleaseComObject(lavOut);
                    if (vrIn != null)
                        Marshal.ReleaseComObject(vrIn);
                }
            }

            //see if we need to remove the DS renderer
            if (AudioRenderer != null)
            {
                IBaseFilter defAR = FilterGraphTools.FindFilterByClsid(_graph, typeof(DefaultAudioRenderer).GUID);
                if (defAR != null)
                {
                    try
                    {
                        hr = _graph.RemoveFilter(defAR);
                        DsError.ThrowExceptionForHR(hr);

                        DirectShowLib.IPin decOut = null;
                        DirectShowLib.IPin rendIn = null;

                        try
                        {
                            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);
                            }

                        }
                        finally
                        {
                            CleanUpInterface(decOut);
                            CleanUpInterface(rendIn);
                        }
                    }
                    finally
                    {
                        CleanUpInterface(defAR);
                        defAR = null;
                    }
                }
            }

            object comobj = null;
            hr = _dvdGraphBuilder.GetDvdInterface(typeof(IDvdInfo2).GUID, out comobj);
            //DsError.ThrowExceptionForHR(hr);
            if (comobj != null)
            {
                m_DvdInfo = (IDvdInfo2)comobj;
                comobj = null;
            }

            //hr = m_dvdGraphBuilder.GetDvdInterface(typeof(IAMLine21Decoder).GUID, out comobj);
            ////DsError.ThrowExceptionForHR(hr);
            //if (comobj != null)
            //{
            //    m_DvdSubtitle = (IAMLine21Decoder)comobj;
            //    comobj = null;
            //}

            hr = _dvdGraphBuilder.GetDvdInterface(typeof(IDvdControl2).GUID, out comobj);
            //DsError.ThrowExceptionForHR(hr);
            if (comobj != null)
            {
                m_DvdControl = (IDvdControl2)comobj;
                comobj = null;
            }

            hr = m_DvdControl.SetOption(DvdOptionFlag.HMSFTimeCodeEvents, true);	// use new HMSF timecode format
            DsError.ThrowExceptionForHR(hr);

            hr = m_DvdControl.SetOption(DvdOptionFlag.ResetOnStop, false);
            DsError.ThrowExceptionForHR(hr);

            //hr = m_DvdControl.SetDVDDirectory(_filePath);
            //DsError.ThrowExceptionForHR(hr);

            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);
            }
        }
        private void SetInternalStream(SelectableMediaStream stream)
        {
            _logger.Debug("SetInternalStream {0} {1} {2}", stream.Index, stream.Type, stream.Name);

            // if we are already playing an external subtitle, we have to clear it first or
            // we wont be able to swicth subtitles
            var activeExternalSub = GetActiveExternalSubtitleStream();
            if (activeExternalSub != null)
            {
                ClearExternalSubtitles();
            }

            IEnumFilters enumFilters;
            var hr = m_graph.EnumFilters(out enumFilters);

            DsError.ThrowExceptionForHR(hr);

            var filters = new DirectShowLib.IBaseFilter[1];

            while (enumFilters.Next(filters.Length, filters, IntPtr.Zero) == 0)
            {
                FilterInfo filterInfo;

                hr = filters[0].QueryFilterInfo(out filterInfo);
                DsError.ThrowExceptionForHR(hr);

                Guid cl;
                filters[0].GetClassID(out cl);

                if (stream.Type == MediaStreamType.Audio)
                {
                    if (cl != _audioSelector)
                    {
                        continue;
                    }
                }
                else if (stream.Type == MediaStreamType.Subtitle)
                {
                    if (cl != _grp2Selector && cl != _vobsubSelector)
                    {
                        continue;
                    }
                }

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

                var iss = filters[0] as IAMStreamSelect;

                if (iss != null)
                    iss.Enable(stream.Index, AMStreamSelectEnableFlags.Enable);

                Marshal.ReleaseComObject(filters[0]);
            }

            Marshal.ReleaseComObject(enumFilters);

            UpdateStreamActiveSetting(stream.Name, stream.Type);
        }
Ejemplo n.º 14
0
        private void SetupGraph(Control hWin, string filename)
        {
            pGraphBuilder   = (DirectShowLib.IGraphBuilder) new FilterGraph();
            pMediaControl   = (DirectShowLib.IMediaControl)pGraphBuilder;
            pVideoWindow    = (DirectShowLib.IVideoWindow)pGraphBuilder;
            pVideoFrameStep = (DirectShowLib.IVideoFrameStep)pGraphBuilder; // video frame...
            pMediaPosition  = (DirectShowLib.IMediaPosition)pGraphBuilder;
            //DirectShowLib.IBaseFilter pBaseFilter = (DirectShowLib.IBaseFilter)pGraphBuilder;

            //pMediaSeeking = (DirectShowLib.IMediaSeeking)pGraphBuilder;
            //pMediaSeeking.SetPositions(5000, AMSeekingSeekingFlags.AbsolutePositioning, 6000, AMSeekingSeekingFlags.AbsolutePositioning);

            //test
            DirectShowLib.ICaptureGraphBuilder2  pCaptureGraphBuilder2;
            DirectShowLib.IBaseFilter            pRenderer;
            DirectShowLib.IVMRFilterConfig9      pIVMRFilterConfig9;
            DirectShowLib.IVMRWindowlessControl9 pVMRWC9;

            pCaptureGraphBuilder2 = (DirectShowLib.ICaptureGraphBuilder2) new CaptureGraphBuilder2();
            pCaptureGraphBuilder2.SetFiltergraph(pGraphBuilder);     // CaptureGraph를  GraphBuilder에 붙인다.

            //pGraphBuilder.AddFilter(pMediaControl "SDZ 375 Source");  // GraphBuilder에 영상장치필터를 추가한다.
            pRenderer          = (DirectShowLib.IBaseFilter) new DirectShowLib.VideoMixingRenderer9(); // 믹서 필터를 생성 한다.
            pIVMRFilterConfig9 = (DirectShowLib.IVMRFilterConfig9)pRenderer;                           // 믹서 필터의 속성을 설정한다.
            pIVMRFilterConfig9.SetRenderingMode(VMR9Mode.Windowless);
            pIVMRFilterConfig9.SetNumberOfStreams(2);

            pVMRWC9 = (DirectShowLib.IVMRWindowlessControl9)pRenderer;              // 오버레이 평면의 속성을 설정한다.
            pVMRWC9.SetVideoClippingWindow(hWin.Handle);
            pVMRWC9.SetBorderColor(0);
            pVMRWC9.SetVideoPosition(null, hWin.ClientRectangle);
            pGraphBuilder.AddFilter(pRenderer, "Video Mixing Renderer");                               // GraphBuilder에 믹스 필터를 추가한다.
            pCaptureGraphBuilder2.RenderStream(null, MediaType.Video, pGraphBuilder, null, pRenderer); // 영상표시를 위한 필터를 설정한다.
            ///test

            //sampleGrabber
            AMMediaType am_media_type = new AMMediaType();

            pSampleGrabber           = (DirectShowLib.ISampleGrabber) new SampleGrabber();
            pSampleGrabberFilter     = (DirectShowLib.IBaseFilter)pSampleGrabber;
            am_media_type.majorType  = MediaType.Video;
            am_media_type.subType    = MediaSubType.RGB24;
            am_media_type.formatType = FormatType.VideoInfo;
            pSampleGrabber.SetMediaType(am_media_type);
            //Graph에 sampleGrabber filter를 추가
            pGraphBuilder.AddFilter(pSampleGrabberFilter, "Sample Grabber");

            pMediaControl.RenderFile(filename);

            pVideoWindow.put_Owner(hWin.Handle);
            pVideoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipSiblings);
            Rectangle rect = hWin.ClientRectangle;

            pVideoWindow.SetWindowPosition(0, 0, rect.Right, rect.Bottom);

            //sampleGrabber2
            pSampleGrabber.GetConnectedMediaType(am_media_type);
            DirectShowLib.VideoInfoHeader pVideoInfoHeader = (DirectShowLib.VideoInfoHeader)Marshal.PtrToStructure(am_media_type.formatPtr, typeof(VideoInfoHeader));
            String str = string.Format("size = {0} x {1}", pVideoInfoHeader.BmiHeader.Width, pVideoInfoHeader.BmiHeader.Height);

            Video_Width   = pVideoInfoHeader.BmiHeader.Width;
            Video_Height  = pVideoInfoHeader.BmiHeader.Height;
            str          += string.Format("sample size = {0}", am_media_type.sampleSize);
            textBox1.Text = str;
            DsUtils.FreeAMMediaType(am_media_type);
            //SetBufferSamples를 실행하지 않으면 버퍼로부터 데이터를 얻을 수 없다.
            //불필요하게 부하를 주고싶지 않은경우 false, 데이터를 얻고싶으면 true
            pSampleGrabber.SetBufferSamples(true);

            //play time
            pMediaPosition = (DirectShowLib.IMediaPosition)pGraphBuilder;
            double Length;

            pMediaPosition.get_Duration(out Length);
            String str2 = string.Format("play time: {0}", Length);

            textBox1.Text = str2;
            pMediaPosition.put_CurrentPosition(5.0); //set current Position



            //2017.05.08
            DirectShowLib.IVMRWindowlessControl9 windowlessCtrl = (DirectShowLib.IVMRWindowlessControl9)pRenderer;
            windowlessCtrl.SetVideoClippingWindow(hWin.Handle);
            IntPtr lpDib;

            windowlessCtrl.GetCurrentImage(out lpDib);
            BitmapInfoHeader head;

            head = (BitmapInfoHeader)Marshal.PtrToStructure(lpDib, typeof(BitmapInfoHeader));
            int         width       = head.Width;
            int         height      = head.Height;
            int         stride      = width * (head.BitCount / 8);
            PixelFormat pixelFormat = PixelFormat.Format24bppRgb;

            switch (head.BitCount)
            {
            case 24: pixelFormat = PixelFormat.Format24bppRgb; break;

            case 32: pixelFormat = PixelFormat.Format32bppRgb; break;

            case 48: pixelFormat = PixelFormat.Format48bppRgb; break;

            default: throw new Exception("Unknown BitCount");
            }

            Bitmap Cap = new Bitmap(width, height, stride, pixelFormat, lpDib);

            Cap.RotateFlip(RotateFlipType.RotateNoneFlipY);
            pictureBox1.Image = Cap;
        }
Ejemplo n.º 15
0
        private List <SelectableMediaStream> GetStreams()
        {
            var streams = new List <SelectableMediaStream>();

            IEnumFilters enumFilters;
            var          hr = m_graph.EnumFilters(out enumFilters);

            DsError.ThrowExceptionForHR(hr);

            var filters = new DirectShowLib.IBaseFilter[1];

            while (enumFilters.Next(filters.Length, filters, IntPtr.Zero) == 0)
            {
                FilterInfo filterInfo;

                hr = filters[0].QueryFilterInfo(out filterInfo);
                DsError.ThrowExceptionForHR(hr);

                Guid cl;
                filters[0].GetClassID(out cl);

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

                var iss = filters[0] as IAMStreamSelect;

                if (iss != null)
                {
                    int count;

                    hr = iss.Count(out count);
                    DsError.ThrowExceptionForHR(hr);

                    for (int i = 0; i < count; i++)
                    {
                        DirectShowLib.AMMediaType type;
                        AMStreamSelectInfoFlags   flags;
                        int    plcid, pwdGrp; // language
                        String pzname;

                        object ppobject, ppunk;

                        hr = iss.Info(i, out type, out flags, out plcid, out pwdGrp, out pzname, out ppobject, out ppunk);
                        DsError.ThrowExceptionForHR(hr);

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

                        if (type != null)
                        {
                            DsUtils.FreeAMMediaType(type);
                        }

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

                        if (pwdGrp == 2)
                        {
                            if (_grp2Selector == Guid.Empty)
                            {
                                filters[0].GetClassID(out _grp2Selector);
                            }

                            var stream = new SelectableMediaStream
                            {
                                Index = i,
                                Name  = pzname,
                                Type  = MediaStreamType.Subtitle
                            };

                            if ((AMStreamSelectInfoFlags.Enabled & flags) == AMStreamSelectInfoFlags.Enabled)
                            {
                                stream.IsActive = true;
                            }
                            streams.Add(stream);
                        }

                        if (pwdGrp == 1)
                        {
                            if (_audioSelector == Guid.Empty)
                            {
                                filters[0].GetClassID(out _audioSelector);
                            }
                            var stream = new SelectableMediaStream
                            {
                                Index = i,
                                Name  = pzname,
                                Type  = MediaStreamType.Audio
                            };
                            if ((AMStreamSelectInfoFlags.Enabled & flags) == AMStreamSelectInfoFlags.Enabled)
                            {
                                stream.IsActive = true;
                            }
                            streams.Add(stream);
                        }

                        if (pwdGrp == 6590033)
                        {
                            if (_vobsubSelector == Guid.Empty)
                            {
                                filters[0].GetClassID(out _vobsubSelector);
                            }

                            var stream = new SelectableMediaStream
                            {
                                Index      = i,
                                Name       = pzname,
                                Type       = MediaStreamType.Subtitle,
                                Identifier = "Vobsub"
                            };

                            if ((AMStreamSelectInfoFlags.Enabled & flags) == AMStreamSelectInfoFlags.Enabled)
                            {
                                stream.IsActive = true;
                            }
                            streams.Add(stream);
                        }
                    }
                }

                Marshal.ReleaseComObject(filters[0]);
            }

            Marshal.ReleaseComObject(enumFilters);

            return(streams);
        }
Ejemplo n.º 16
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();
        }
Ejemplo n.º 17
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 Initialize(string path, bool enableMadvr, bool enableMadvrExclusiveMode,
            bool enableXySubFilter, bool isDvd)
        {
            _filePath = path;

            InitializeGraph(isDvd);

            int hr = 0;

            if (isDvd)
            {
                _logger.Debug("Initializing dvd player to play {0}", path);

                /* Create a new DVD Navigator. */
                _sourceFilter = (DirectShowLib.IBaseFilter) new DVDNavigator();

                InitializeDvd(path);

                // Try to render the streams.
                RenderStreams(_sourceFilter, enableMadvr, enableMadvrExclusiveMode, false);
                    //we don't need XySubFilter for DVD 
            }
            else
            {
                //prefer LAV Spliter Source
                bool loadSource = true;
                object objLavSource = _playerWrapper.PrivateCom.GetObject(typeof(LAVSplitterSource).GUID, true);
                _sourceFilter = objLavSource as IBaseFilter;
                    //Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("{B98D13E7-55DB-4385-A33D-09FD1BA26338}"))) as DirectShowLib.IBaseFilter;
                if (_sourceFilter != null)
                {
                    hr = m_graph.AddFilter(_sourceFilter, "LAV Splitter Source");
                    DsError.ThrowExceptionForHR(hr);

                    if (_sourceFilter != null)
                    {
                        hr = ((IFileSourceFilter) _sourceFilter).Load(path, null);
                        if (hr < 0)
                        {
                            //LAV can't load this file type
                            hr = m_graph.RemoveFilter(_sourceFilter);
                            Marshal.ReleaseComObject(_sourceFilter);
                            _sourceFilter = null;
                            DsError.ThrowExceptionForHR(hr);
                        }
                        else
                            loadSource = false;
                    }
                }

                if (loadSource)
                {
                    hr = m_graph.AddSourceFilter(path, path, out _sourceFilter);
                    DsError.ThrowExceptionForHR(hr);
                }
                // Try to render the streams.
                RenderStreams(_sourceFilter, enableMadvr, enableMadvrExclusiveMode, enableXySubFilter);
            }

            // Get the seeking capabilities.
            hr = _mediaSeeking.GetCapabilities(out _mSeekCaps);
            DsError.ThrowExceptionForHR(hr);
        }
        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();
        }
Ejemplo n.º 20
0
        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 Initialize(string path, bool enableReclock, bool enableMadvr, bool enableXySubFilter, bool isDvd)
        {
            InitializeGraph();

            int hr = 0;

            if (!isDvd)
            {
                hr = m_graph.AddSourceFilter(path, path, out _pSource);
                DsError.ThrowExceptionForHR(hr);

                // Try to render the streams.
                RenderStreams(_pSource, enableReclock, enableMadvr, enableXySubFilter);
            }
            else
            {
                _logger.Debug("Initializing dvd player to play {0}", path);

                /* Create a new DVD Navigator. */
                _dvdNav = (DirectShowLib.IBaseFilter)new DVDNavigator();

                InitializeDvd(path);

                // Try to render the streams.
                RenderStreams(_dvdNav, enableReclock, enableMadvr, enableXySubFilter);
            }

            // Get the seeking capabilities.
            hr = _mediaSeeking.GetCapabilities(out _mSeekCaps);
            DsError.ThrowExceptionForHR(hr);
        }
        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 List<SelectableMediaStream> GetInternalStreams()
        {
            _logger.Debug("GetInternalStreams");

            var streams = new List<SelectableMediaStream>();

            IEnumFilters enumFilters = null;
            try
            {
                var hr = m_graph.EnumFilters(out enumFilters);

                DsError.ThrowExceptionForHR(hr);

                var filters = new DirectShowLib.IBaseFilter[1];

                while (enumFilters.Next(filters.Length, filters, IntPtr.Zero) == 0)
                {
                    FilterInfo filterInfo;

                    hr = filters[0].QueryFilterInfo(out filterInfo);
                    DsError.ThrowExceptionForHR(hr);

                    Guid cl;
                    filters[0].GetClassID(out cl);

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

                    var iss = filters[0] as IAMStreamSelect;

                    if (iss != null)
                    {
                        int count;

                        hr = iss.Count(out count);
                        DsError.ThrowExceptionForHR(hr);

                        for (int i = 0; i < count; i++)
                        {
                            DirectShowLib.AMMediaType type;
                            AMStreamSelectInfoFlags flags;
                            int plcid, pwdGrp; // language
                            String pzname;

                            object ppobject, ppunk;

                            hr = iss.Info(i, out type, out flags, out plcid, out pwdGrp, out pzname, out ppobject, out ppunk);
                            DsError.ThrowExceptionForHR(hr);

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

                            if (type != null)
                            {
                                DsUtils.FreeAMMediaType(type);
                            }

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

                            if (pwdGrp == 2)
                            {
                                if (_grp2Selector == Guid.Empty)
                                {
                                    filters[0].GetClassID(out _grp2Selector);
                                }

                                var stream = new SelectableMediaStream
                                {
                                    Index = i,
                                    Name = pzname,
                                    Type = MediaStreamType.Subtitle
                                };

                                if ((AMStreamSelectInfoFlags.Enabled & flags) == AMStreamSelectInfoFlags.Enabled)
                                {
                                    stream.IsActive = true;
                                }
                                streams.Add(stream);
                            }

                            if (pwdGrp == 1)
                            {
                                if (_audioSelector == Guid.Empty)
                                {
                                    filters[0].GetClassID(out _audioSelector);
                                }
                                var stream = new SelectableMediaStream
                                {
                                    Index = i,
                                    Name = pzname,
                                    Type = MediaStreamType.Audio
                                };
                                if ((AMStreamSelectInfoFlags.Enabled & flags) == AMStreamSelectInfoFlags.Enabled)
                                {
                                    stream.IsActive = true;
                                }
                                streams.Add(stream);
                            }

                            if (pwdGrp == 6590033)
                            {
                                if (_vobsubSelector == Guid.Empty)
                                {
                                    filters[0].GetClassID(out _vobsubSelector);
                                }

                                var stream = new SelectableMediaStream
                                {
                                    Index = i,
                                    Name = pzname,
                                    Type = MediaStreamType.Subtitle,
                                    Identifier = "Vobsub"
                                };

                                if ((AMStreamSelectInfoFlags.Enabled & flags) == AMStreamSelectInfoFlags.Enabled)
                                {
                                    stream.IsActive = true;
                                }
                                streams.Add(stream);
                            }
                        }
                    }

                    Marshal.ReleaseComObject(filters[0]);
                }
            }
            finally
            {
                if (enumFilters != null)
                    Marshal.ReleaseComObject(enumFilters);
            }

            _logger.Debug("Return InternalStreamCount: {0}", streams.Count);
            return streams;
        }
        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 Initialize(string path,
            bool isDvd, string forcedVideoRenderer)
        {
            _filePath = path;

            InitializeGraph(isDvd);

            int hr = 0;

            if (isDvd)
            {
                _logger.Debug("Initializing dvd player to play {0}", path);

                /* Create a new DVD Navigator. */
                _sourceFilter = (DirectShowLib.IBaseFilter)new DVDNavigator();

                InitializeDvd(path);

                // Try to render the streams.
                RenderStreams(_sourceFilter, forcedVideoRenderer, false);
                //we don't need XySubFilter for DVD 
            }
            else
            {
                //prefer LAV Spliter Source
                bool loadSource = true;
                object objLavSource = URCOMLoader.Instance.GetObject(typeof(LAVSplitterSource).GUID, true);
                _sourceFilter = objLavSource as IBaseFilter;

                if (_sourceFilter != null)
                {
                    hr = m_graph.AddFilter(_sourceFilter, "LAV Splitter Source");
                    DsError.ThrowExceptionForHR(hr);

                    if (_sourceFilter != null)
                    {
                        ILAVSplitterSettings lss = _sourceFilter as ILAVSplitterSettings;
                        if (lss != null)
                        {
                            _logger.Debug("Configure LAV Splitter");

                            hr = lss.SetRuntimeConfig(true);
                            DsError.ThrowExceptionForHR(hr);

                            if (!string.IsNullOrWhiteSpace(_config.SplitterConfig.PreferredAudioLanguages))
                            {
                                _logger.Debug("Set preferred audio lang: {0}", _config.SplitterConfig.PreferredAudioLanguages);
                                hr = lss.SetPreferredLanguages(_config.SplitterConfig.PreferredAudioLanguages);
                                DsError.ThrowExceptionForHR(hr);
                            }

                            if (!string.IsNullOrWhiteSpace(_config.SplitterConfig.PreferredSubtitleLanguages))
                            {
                                _logger.Debug("Set preferred subs lang: {0}", _config.SplitterConfig.PreferredSubtitleLanguages);
                                hr = lss.SetPreferredSubtitleLanguages(_config.SplitterConfig.PreferredSubtitleLanguages);
                                DsError.ThrowExceptionForHR(hr);
                            }

                            if (!string.IsNullOrWhiteSpace(_config.SplitterConfig.AdvancedSubtitleConfig))
                            {
                                _logger.Debug("Set preferred subs lang: {0}", _config.SplitterConfig.AdvancedSubtitleConfig);
                                hr = lss.SetAdvancedSubtitleConfig(_config.SplitterConfig.AdvancedSubtitleConfig);
                                DsError.ThrowExceptionForHR(hr);
                            }

                            _logger.Debug("SetSubtitleMode: {0}", _config.SplitterConfig.PreferredSubtitleLanguages);
                            hr = lss.SetSubtitleMode((LAVSubtitleMode)Enum.Parse(typeof(LAVSubtitleMode), _config.SplitterConfig.SubtitleMode));
                            DsError.ThrowExceptionForHR(hr);

                            _logger.Debug("SetPGSForcedStream: {0}", _config.SplitterConfig.PGSForcedStream);
                            //hr = lss.SetPGSForcedStream(_config.SplitterConfig.PGSForcedStream);
                            hr = lss.SetPGSForcedStream(false);
                            DsError.ThrowExceptionForHR(hr);

                            _logger.Debug("SetPGSOnlyForced: {0}", _config.SplitterConfig.PGSOnlyForced);
                            hr = lss.SetPGSOnlyForced(_config.SplitterConfig.PGSOnlyForced);
                            DsError.ThrowExceptionForHR(hr);

                            _logger.Debug("SetVC1TimestampMode: {0}", _config.SplitterConfig.VC1TimestampMode);
                            hr = lss.SetVC1TimestampMode((short)Enum.Parse(typeof(VC1TimestampMode), _config.SplitterConfig.VC1TimestampMode));
                            DsError.ThrowExceptionForHR(hr);

                            _logger.Debug("SetSubstreamsEnabled: {0}", _config.SplitterConfig.SubstreamsEnabled);
                            hr = lss.SetSubstreamsEnabled(_config.SplitterConfig.SubstreamsEnabled);
                            DsError.ThrowExceptionForHR(hr);

                            _logger.Debug("SetStreamSwitchRemoveAudio: {0}", _config.SplitterConfig.StreamSwitchRemoveAudio);
                            hr = lss.SetStreamSwitchRemoveAudio(_config.SplitterConfig.StreamSwitchRemoveAudio);
                            DsError.ThrowExceptionForHR(hr);

                            _logger.Debug("SetUseAudioForHearingVisuallyImpaired: {0}", _config.SplitterConfig.UseAudioForHearingVisuallyImpaired);
                            hr = lss.SetUseAudioForHearingVisuallyImpaired(_config.SplitterConfig.UseAudioForHearingVisuallyImpaired);
                            DsError.ThrowExceptionForHR(hr);

                            _logger.Debug("SetMaxQueueMemSize: {0}", _config.SplitterConfig.MaxQueueMemSize);
                            hr = lss.SetMaxQueueMemSize(_config.SplitterConfig.MaxQueueMemSize);
                            DsError.ThrowExceptionForHR(hr);

                            _logger.Debug("SetTrayIcon: {0}", _config.SplitterConfig.ShowTrayIcon);
                            hr = lss.SetTrayIcon(_config.SplitterConfig.ShowTrayIcon);
                            DsError.ThrowExceptionForHR(hr);

                            _logger.Debug("SetPreferHighQualityAudioStreams: {0}", _config.SplitterConfig.PreferHighQualityAudioStreams);
                            hr = lss.SetPreferHighQualityAudioStreams(_config.SplitterConfig.PreferHighQualityAudioStreams);
                            DsError.ThrowExceptionForHR(hr);

                            _logger.Debug("SetLoadMatroskaExternalSegments: {0}", _config.SplitterConfig.LoadMatroskaExternalSegments);
                            hr = lss.SetLoadMatroskaExternalSegments(_config.SplitterConfig.LoadMatroskaExternalSegments);
                            DsError.ThrowExceptionForHR(hr);

                            _logger.Debug("SetNetworkStreamAnalysisDuration: {0}", _config.SplitterConfig.NetworkStreamAnalysisDuration);
                            hr = lss.SetNetworkStreamAnalysisDuration(_config.SplitterConfig.NetworkStreamAnalysisDuration);
                            DsError.ThrowExceptionForHR(hr);
                        }

                        hr = ((IFileSourceFilter)_sourceFilter).Load(path, null);
                        if (hr < 0)
                        {
                            //LAV can't load this file type
                            hr = m_graph.RemoveFilter(_sourceFilter);
                            Marshal.ReleaseComObject(_sourceFilter);
                            _sourceFilter = null;
                            DsError.ThrowExceptionForHR(hr);
                        }
                        else
                            loadSource = false;
                    }
                }

                if (loadSource)
                {
                    hr = m_graph.AddSourceFilter(path, path, out _sourceFilter);
                    DsError.ThrowExceptionForHR(hr);
                }
                // Try to render the streams.
                RenderStreams(_sourceFilter, forcedVideoRenderer, true);
            }

            // Get the seeking capabilities.
            hr = _mediaSeeking.GetCapabilities(out _mSeekCaps);
            DsError.ThrowExceptionForHR(hr);

            _logger.Debug("Retrieved seeking capabilities: {0}", _mSeekCaps);
        }
        private void SetInternalStream(SelectableMediaStream stream)
        {
            IEnumFilters enumFilters;
            var hr = m_graph.EnumFilters(out enumFilters);

            DsError.ThrowExceptionForHR(hr);

            var filters = new DirectShowLib.IBaseFilter[1];

            while (enumFilters.Next(filters.Length, filters, IntPtr.Zero) == 0)
            {
                FilterInfo filterInfo;

                hr = filters[0].QueryFilterInfo(out filterInfo);
                DsError.ThrowExceptionForHR(hr);

                Guid cl;
                filters[0].GetClassID(out cl);

                if (stream.Type == MediaStreamType.Audio)
                {
                    if (cl != _audioSelector)
                    {
                        continue;
                    }
                }
                else if (stream.Type == MediaStreamType.Subtitle)
                {
                    if (cl != _grp2Selector && cl != _vobsubSelector)
                    {
                        continue;
                    }
                }

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

                var iss = filters[0] as IAMStreamSelect;

                iss.Enable(stream.Index, AMStreamSelectEnableFlags.Enable);

                Marshal.ReleaseComObject(filters[0]);
            }

            Marshal.ReleaseComObject(enumFilters);

            UpdateStreamActiveSetting(stream.Index, stream.Type);
        }
Ejemplo n.º 27
0
 private static extern int SetWmvProfile(DirectShowLib.IBaseFilter filter, int bitrate, int fps, int screenX,
                                         int screenY);
Ejemplo n.º 28
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
    }