private void AddDefaultAudioRenderer() { _defaultAudioRenderer = new DefaultAudioRenderer(); var aRenderer = _defaultAudioRenderer as DirectShowLib.IBaseFilter; if (aRenderer != null) { m_graph.AddFilter(aRenderer, "Default Audio Renderer"); _logger.Debug("Added default audio renderer"); } }
private void CloseInterfaces() { int hr; if (m_adecOut != null) { CleanUpInterface(m_adecOut); m_adecOut = null; } if (_defaultAudioRenderer != null) { m_graph.RemoveFilter(_defaultAudioRenderer as DirectShowLib.IBaseFilter); CleanUpInterface(_defaultAudioRenderer); _defaultAudioRenderer = null; } if (_reclockAudioRenderer != null) { m_graph.RemoveFilter(_reclockAudioRenderer as DirectShowLib.IBaseFilter); CleanUpInterface(_reclockAudioRenderer); _reclockAudioRenderer = null; } if (_wasapiAR != null) { m_graph.RemoveFilter(_wasapiAR as DirectShowLib.IBaseFilter); CleanUpInterface(_wasapiAR); _wasapiAR = null; } if (_lavaudio != null) { m_graph.RemoveFilter(_lavaudio as DirectShowLib.IBaseFilter); CleanUpInterface(_lavaudio); _lavaudio = null; } if (_xyVsFilter != null) { m_graph.RemoveFilter(_xyVsFilter as DirectShowLib.IBaseFilter); CleanUpInterface(_xyVsFilter); _xyVsFilter = null; } if (_xySubFilter != null) { m_graph.RemoveFilter(_xySubFilter as DirectShowLib.IBaseFilter); CleanUpInterface(_xySubFilter); _xySubFilter = null; } if (_lavvideo != null) { m_graph.RemoveFilter(_lavvideo as DirectShowLib.IBaseFilter); CleanUpInterface(_lavvideo); _lavvideo = null; } if (_madvr != null) { m_graph.RemoveFilter(_madvr as DirectShowLib.IBaseFilter); CleanUpInterface(_madvr); _madvr = null; } if (_videoWindow != null) { // Relinquish ownership (IMPORTANT!) after hiding video window hr = _videoWindow.put_Visible(OABool.False); hr = _videoWindow.put_Owner(IntPtr.Zero); } if (_mediaEventEx != null) { hr = _mediaEventEx.SetNotifyWindow(IntPtr.Zero, 0, IntPtr.Zero); //Marshal.ReleaseComObject(_mediaEventEx); //_mediaEventEx = null; } //if (_dvdNav != null) //{ // Marshal.ReleaseComObject(_dvdNav); // _dvdNav = null; //} /* //this will double release the source filter if (dvdInfo != null) { Marshal.ReleaseComObject(dvdInfo); dvdInfo = null; } if (_mDvdControl != null) { Marshal.ReleaseComObject(_mDvdControl); } */ _mDvdControl = null; CleanUpInterface(_mPDisplay); _mPDisplay = null; CleanUpInterface(_sourceFilter); _sourceFilter = null; CleanUpInterface(_mPEvr); _mPEvr = null; CleanUpInterface(m_filterGraph); m_filterGraph = null; m_filterGraph = null; _mediaEventEx = null; _mediaSeeking = null; _mediaPosition = null; _mediaControl = null; _basicAudio = null; _basicVideo = null; m_graph = null; _videoWindow = null; _filterGraph = null; if (m_dsRot != null) m_dsRot.Dispose(); m_dsRot = null; _mSeekCaps = 0; _streams = null; GC.Collect(); }
private void RenderStreams(DirectShowLib.IBaseFilter pSource, bool enableReclock, bool enableMadvr, bool enableMadvrExclusiveMode, bool enableXySubFilter) { int hr; _filterGraph = m_graph as DirectShowLib.IFilterGraph2; if (_filterGraph == null) { throw new Exception("Could not QueryInterface for the IFilterGraph2"); } // Add audio renderer var useDefaultRenderer = true; if (enableReclock) { try { _reclockAudioRenderer = new ReclockAudioRenderer(); var aRenderer = _reclockAudioRenderer as DirectShowLib.IBaseFilter; if (aRenderer != null) { hr = m_graph.AddFilter(aRenderer, "Reclock Audio Renderer"); DsError.ThrowExceptionForHR(hr); useDefaultRenderer = false; } } catch (Exception ex) { _logger.ErrorException("Error adding reclock filter", ex); } } if (useDefaultRenderer) { _defaultAudioRenderer = new DefaultAudioRenderer(); var aRenderer = _defaultAudioRenderer as DirectShowLib.IBaseFilter; if (aRenderer != null) { m_graph.AddFilter(aRenderer, "Default Audio Renderer"); } } if (_item.IsVideo) { var xySubFilterSucceeded = false; var madVrSucceded = false; //add the video renderer first so we know whether to enable DXVA2 in "Auto" mode. if (enableMadvr) { try { _madvr = _urCom.GetObject(typeof(MadVR).GUID, true);// new MadVR(); var vmadvr = _madvr as DirectShowLib.IBaseFilter; if (vmadvr != null) { hr = m_graph.AddFilter(vmadvr, "MadVR Video Renderer"); DsError.ThrowExceptionForHR(hr); try { MadVRSettings msett = new MadVRSettings(_madvr); bool smoothMotion = msett.GetBool("smoothMotionEnabled"); if (smoothMotion != _mbtConfig.Configuration.InternalPlayerConfiguration.VideoConfig.UseMadVrSmoothMotion) msett.SetBool("smoothMotionEnabled", _mbtConfig.Configuration.InternalPlayerConfiguration.VideoConfig.UseMadVrSmoothMotion); if (string.Compare(msett.GetString("smoothMotionMode"), _mbtConfig.Configuration.InternalPlayerConfiguration.VideoConfig.MadVrSmoothMotionMode, true) != 0) { bool success = msett.SetString("smoothMotionMode", _mbtConfig.Configuration.InternalPlayerConfiguration.VideoConfig.MadVrSmoothMotionMode); } } catch (Exception ex) { _logger.ErrorException("Error configuring madVR", ex); } madVrSucceded = true; } } catch (Exception ex) { _logger.ErrorException("Error adding MadVR filter", ex); } } // Add video renderer if (!madVrSucceded) { _mPEvr = (DirectShowLib.IBaseFilter)new EnhancedVideoRenderer(); hr = m_graph.AddFilter(_mPEvr, "EVR"); DsError.ThrowExceptionForHR(hr); //we only need 2 input pins on the EVR if LAV Video isn't used for DVDs, but it doesn't hurt to have them InitializeEvr(_mPEvr, _isDvd ? 2 : 1); } // Load xySubFilter if configured and if madvr succeeded if (enableXySubFilter && (madVrSucceded || _customEvrPresenterLoaded)) { try { _xySubFilter = _urCom.GetObject(typeof(XySubFilter).GUID, true);//new XySubFilter(); var vxySubFilter = _xySubFilter as DirectShowLib.IBaseFilter; if (vxySubFilter != null) { hr = m_graph.AddFilter(vxySubFilter, "xy-SubFilter"); DsError.ThrowExceptionForHR(hr); } xySubFilterSucceeded = true; } catch (Exception ex) { _logger.ErrorException("Error adding xy-SubFilter filter", ex); } } // Fallback to xyVsFilter if (!xySubFilterSucceeded && enableXySubFilter) { try { _xyVsFilter = new XYVSFilter(); var vxyVsFilter = _xyVsFilter as DirectShowLib.IBaseFilter; if (vxyVsFilter != null) { hr = m_graph.AddFilter(vxyVsFilter, "xy-VSFilter"); DsError.ThrowExceptionForHR(hr); } } catch (Exception ex) { _logger.ErrorException("Error adding xy-VSFilter filter", ex); } } try { _lavvideo = _urCom.GetObject(typeof(LAVVideo).GUID, true);//new LAVVideo(); var vlavvideo = _lavvideo as DirectShowLib.IBaseFilter; if (vlavvideo != null) { hr = m_graph.AddFilter(vlavvideo, "LAV Video Decoder"); DsError.ThrowExceptionForHR(hr); ILAVVideoSettings vsett = vlavvideo as ILAVVideoSettings; if (vsett != null) { //we only want to set it for MB hr = vsett.SetRuntimeConfig(true); DsError.ThrowExceptionForHR(hr); LAVHWAccel configuredMode = VideoConfigurationUtils.GetHwaMode(_mbtConfig.Configuration.InternalPlayerConfiguration.VideoConfig, _customEvrPresenterLoaded); LAVHWAccel testme = vsett.GetHWAccel(); if (testme != configuredMode) { hr = vsett.SetHWAccel(configuredMode); DsError.ThrowExceptionForHR(hr); } foreach (string c in DirectShowPlayer.GetLAVVideoCodecs()) { LAVVideoCodec codec = (LAVVideoCodec)Enum.Parse(typeof(LAVVideoCodec), c); bool isEnabled = vsett.GetFormatConfiguration(codec); if (_mbtConfig.Configuration.InternalPlayerConfiguration.VideoConfig.EnabledCodecs.Contains(c)) { if (!isEnabled) { _logger.Debug("Enable support for: {0}", c); hr = vsett.SetFormatConfiguration(codec, true); DsError.ThrowExceptionForHR(hr); } } else if (isEnabled) { _logger.Debug("Disable support for: {0}", c); hr = vsett.SetFormatConfiguration(codec, false); DsError.ThrowExceptionForHR(hr); } } foreach (string hwaCodec in DirectShowPlayer.GetLAVVideoHwaCodecs()) { LAVVideoHWCodec codec = (LAVVideoHWCodec)Enum.Parse(typeof(LAVVideoHWCodec), hwaCodec); bool hwaIsEnabled = vsett.GetHWAccelCodec(codec); if (_mbtConfig.Configuration.InternalPlayerConfiguration.VideoConfig.HwaEnabledCodecs.Contains(hwaCodec)) { if (!hwaIsEnabled) { _logger.Debug("Enable HWA support for: {0}", hwaCodec); hr = vsett.SetHWAccelCodec(codec, true); DsError.ThrowExceptionForHR(hr); } } else if (hwaIsEnabled) { _logger.Debug("Disable HWA support for: {0}", hwaCodec); hr = vsett.SetHWAccelCodec(codec, false); DsError.ThrowExceptionForHR(hr); } } if (!vsett.GetDVDVideoSupport()) { _logger.Debug("Enable DVD support."); hr = vsett.SetDVDVideoSupport(true); DsError.ThrowExceptionForHR(hr); } int hwaRes = vsett.GetHWAccelResolutionFlags(); if (hwaRes != _mbtConfig.Configuration.InternalPlayerConfiguration.VideoConfig.HwaResolution) { _logger.Debug("Change HWA resolution support from {0} to {1}.", hwaRes, _mbtConfig.Configuration.InternalPlayerConfiguration.VideoConfig.HwaResolution); hr = vsett.SetHWAccelResolutionFlags(VideoConfigurationUtils.GetHwaResolutions(_mbtConfig.Configuration.InternalPlayerConfiguration.VideoConfig)); DsError.ThrowExceptionForHR(hr); } hr = vsett.SetTrayIcon(_mbtConfig.Configuration.InternalPlayerConfiguration.VideoConfig.ShowTrayIcon); DsError.ThrowExceptionForHR(hr); } } } catch (Exception ex) { _logger.ErrorException("Error adding LAV Video filter", ex); } } try { _lavaudio = _urCom.GetObject(typeof(LAVAudio).GUID, true);// new LAVAudio(); var vlavaudio = _lavaudio as DirectShowLib.IBaseFilter; if (vlavaudio != null) { _logger.Debug("Add LAVAudio to the graph."); hr = m_graph.AddFilter(vlavaudio, "LAV Audio Decoder"); DsError.ThrowExceptionForHR(hr); ILAVAudioSettings asett = vlavaudio as ILAVAudioSettings; if (asett != null) { _logger.Debug("Enable LAVAudio Runtime Config"); //we only want to set it for MB hr = asett.SetRuntimeConfig(true); DsError.ThrowExceptionForHR(hr); foreach (string c in DirectShowPlayer.GetLAVAudioCodecs()) { LAVAudioCodec codec = (LAVAudioCodec)Enum.Parse(typeof(LAVAudioCodec), c); bool isEnabled = asett.GetFormatConfiguration(codec); if (_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.EnabledCodecs.Contains(c)) { if (!isEnabled) { _logger.Debug("Enable support for: {0}", c); hr = asett.SetFormatConfiguration(codec, true); DsError.ThrowExceptionForHR(hr); } } else if (isEnabled) { _logger.Debug("Disable support for: {0}", c); hr = asett.SetFormatConfiguration(codec, false); DsError.ThrowExceptionForHR(hr); } } //enable/disable bitstreaming if ((_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.AudioBitstreaming & BitstreamChoice.SPDIF) == BitstreamChoice.SPDIF) { _logger.Debug("Enable LAVAudio S/PDIF bitstreaming"); hr = asett.SetBitstreamConfig(LAVBitstreamCodec.AC3, true); DsError.ThrowExceptionForHR(hr); hr = asett.SetBitstreamConfig(LAVBitstreamCodec.DTS, true); DsError.ThrowExceptionForHR(hr); } if ((_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.AudioBitstreaming & BitstreamChoice.HDMI) == BitstreamChoice.HDMI) { _logger.Debug("Enable LAVAudio HDMI bitstreaming"); hr = asett.SetBitstreamConfig(LAVBitstreamCodec.EAC3, true); DsError.ThrowExceptionForHR(hr); hr = asett.SetBitstreamConfig(LAVBitstreamCodec.TRUEHD, true); DsError.ThrowExceptionForHR(hr); hr = asett.SetBitstreamConfig(LAVBitstreamCodec.DTSHD, true); DsError.ThrowExceptionForHR(hr); } if (_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.Delay > 0) { _logger.Debug("Set LAVAudio audio delay: {0}", _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.Delay); hr = asett.SetAudioDelay(true, _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.Delay); DsError.ThrowExceptionForHR(hr); } _logger.Debug("Set LAVAudio auto AV Sync: {0}", _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.EnableAutoSync); hr = asett.SetAutoAVSync(_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.EnableAutoSync); DsError.ThrowExceptionForHR(hr); _logger.Debug("Set LAVAudio Expand61: {0}", _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.Expand61); hr = asett.SetExpand61(_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.Expand61); DsError.ThrowExceptionForHR(hr); _logger.Debug("Set LAVAudio ExpandMono: {0}", _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.ExpandMono); hr = asett.SetExpandMono(_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.ExpandMono); DsError.ThrowExceptionForHR(hr); _logger.Debug("Set LAVAudio ConvertToStandardLayout: {0}", _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.ConvertToStandardLayout); hr = asett.SetOutputStandardLayout(_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.ConvertToStandardLayout); DsError.ThrowExceptionForHR(hr); _logger.Debug("Set LAVAudio audio EnableDRC: {0}", _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.EnableDRC); hr = asett.SetDRC(_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.EnableDRC, _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.DRCLevel); DsError.ThrowExceptionForHR(hr); _logger.Debug("Set LAVAudio audio ShowTrayIcon: {0}", _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.ShowTrayIcon); hr = asett.SetTrayIcon(_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.ShowTrayIcon); DsError.ThrowExceptionForHR(hr); bool mixingEnabled = asett.GetMixingEnabled(); if (mixingEnabled != _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.EnablePCMMixing) { _logger.Debug("Set LAVAudio EnablePCMMixing: {0}", _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.EnablePCMMixing); hr = asett.SetMixingEnabled(!mixingEnabled); DsError.ThrowExceptionForHR(hr); } if (_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.EnablePCMMixing) { _logger.Debug("Set LAVAudio MixingSetting: {0}", _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.MixingSetting); LAVAudioMixingFlag amf = (LAVAudioMixingFlag)_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.MixingSetting; hr = asett.SetMixingFlags(amf); DsError.ThrowExceptionForHR(hr); _logger.Debug("Set LAVAudio MixingEncoding: {0}", _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.MixingEncoding); LAVAudioMixingMode amm = (LAVAudioMixingMode)Enum.Parse(typeof(LAVAudioMixingMode), _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.MixingEncoding); hr = asett.SetMixingMode(amm); DsError.ThrowExceptionForHR(hr); _logger.Debug("Set LAVAudio MixingLayout: {0}", _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.MixingLayout); LAVAudioMixingLayout aml = (LAVAudioMixingLayout)Enum.Parse(typeof(LAVAudioMixingLayout), _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.MixingLayout); hr = asett.SetMixingLayout(aml); DsError.ThrowExceptionForHR(hr); _logger.Debug("Set LAVAudio LfeMixingLevel: {0} CenterMixingLevel: {1} SurroundMixingLevel: {2}", _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.LfeMixingLevel, _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.CenterMixingLevel, _mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.SurroundMixingLevel); int lfe, center, surround; //convert to the # that LAV Audio expects lfe = (int)(_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.LfeMixingLevel * 10000.01); center = (int)(_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.CenterMixingLevel * 10000.01); surround = (int)(_mbtConfig.Configuration.InternalPlayerConfiguration.AudioConfig.SurroundMixingLevel * 10000.01); hr = asett.SetMixingLevels(center, surround, lfe); DsError.ThrowExceptionForHR(hr); } for (int i = 0; i < (int)LAVBitstreamCodec.NB; i++) { LAVBitstreamCodec codec = (LAVBitstreamCodec)i; bool isEnabled = asett.GetBitstreamConfig(codec); _logger.Log(LogSeverity.Debug, "{0} bitstreaming: {1}", codec, isEnabled); } } } } catch (Exception ex) { _logger.ErrorException("Error adding LAV Audio filter", ex); } DirectShowLib.IEnumPins pEnum; hr = pSource.EnumPins(out pEnum); DsError.ThrowExceptionForHR(hr); DirectShowLib.IPin[] pins = { null }; /* Counter for how many pins successfully rendered */ var pinsRendered = 0; /* Loop over each pin of the source filter */ while (pEnum.Next(1, pins, IntPtr.Zero) == 0) { //explicitly build graph to avoid unwanted filters worming their way in List<Guid> mediaTypes = GetPinMediaTypes(pins[0]); bool needsRender = true; for (int m = 0; m < mediaTypes.Count; m++) { DirectShowLib.IPin decIn = null; DirectShowLib.IPin decOut = null; DirectShowLib.IPin rendIn = null; try { if (mediaTypes[m] == DirectShowLib.MediaType.Video && _lavvideo != null) { decIn = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_lavvideo, PinDirection.Input, 0); if (decIn != null) { hr = _filterGraph.ConnectDirect(pins[0], decIn, null); DsError.ThrowExceptionForHR(hr); decOut = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_lavvideo, PinDirection.Output, 0); if (_xyVsFilter != null) { //insert xyVsFilter b/w LAV Video and the renderer rendIn = DsFindPin.ByName((DirectShowLib.IBaseFilter)_xyVsFilter, "Video"); if (decOut != null && rendIn != null) { hr = _filterGraph.ConnectDirect(decOut, rendIn, null); DsError.ThrowExceptionForHR(hr); CleanUpInterface(decOut); CleanUpInterface(rendIn); //grab xyVsFilter's output pin so it can be connected to the renderer decOut = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_xyVsFilter, PinDirection.Output, 0); } } if (_madvr != null) { rendIn = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_madvr, PinDirection.Input, 0); } else { rendIn = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_mPEvr, PinDirection.Input, 0); } if (decOut != null && rendIn != null) { hr = _filterGraph.ConnectDirect(decOut, rendIn, null); DsError.ThrowExceptionForHR(hr); needsRender = false; break; } } } else if (mediaTypes[m] == DirectShowLib.MediaType.Audio && _lavaudio != null) { decIn = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_lavaudio, PinDirection.Input, 0); if (decIn != null) { hr = _filterGraph.ConnectDirect(pins[0], decIn, null); DsError.ThrowExceptionForHR(hr); decOut = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_lavaudio, PinDirection.Output, 0); if (_reclockAudioRenderer != null) { rendIn = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_reclockAudioRenderer, PinDirection.Input, 0); } else { rendIn = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_defaultAudioRenderer, PinDirection.Input, 0); } if (decOut != null && rendIn != null) { hr = _filterGraph.ConnectDirect(decOut, rendIn, null); DsError.ThrowExceptionForHR(hr); needsRender = false; break; } } } else if (mediaTypes[m] == new Guid("E487EB08-6B26-4be9-9DD3-993434D313FD") /*DirectShowLib.MediaType.Subtitle*/ && (_xySubFilter != null || _xyVsFilter != null)) { if (_xySubFilter != null) { rendIn = DsFindPin.ByDirection((DirectShowLib.IBaseFilter)_xySubFilter, PinDirection.Input, 0); } else { rendIn = DsFindPin.ByName((DirectShowLib.IBaseFilter)_xyVsFilter, "Input"); } if (rendIn != null) { hr = _filterGraph.ConnectDirect(pins[0], rendIn, null); DsError.ThrowExceptionForHR(hr); needsRender = false; break; } } } finally { CleanUpInterface(decIn); CleanUpInterface(decOut); CleanUpInterface(rendIn); } } if (needsRender) { if (_filterGraph.RenderEx(pins[0], AMRenderExFlags.RenderToExistingRenderers, IntPtr.Zero) >= 0) pinsRendered++; } else pinsRendered++; Marshal.ReleaseComObject(pins[0]); } Marshal.ReleaseComObject(pEnum); if (pinsRendered == 0) { throw new Exception("Could not render any streams from the source Uri"); } _logger.Debug("Completed RenderStreams with {0} pins.", pinsRendered); if (_item.IsVideo) { SetVideoWindow(enableMadvrExclusiveMode); if(_mPEvr != null) SetEvrVppMode(_mPEvr); } }
private void CloseInterfaces() { _hiddenWindow.SizeChanged -= _hiddenWindow_SizeChanged; int hr; if (_defaultAudioRenderer != null) { m_graph.RemoveFilter(_defaultAudioRenderer as DirectShowLib.IBaseFilter); Marshal.ReleaseComObject(_defaultAudioRenderer); _defaultAudioRenderer = null; } if (_reclockAudioRenderer != null) { m_graph.RemoveFilter(_reclockAudioRenderer as DirectShowLib.IBaseFilter); Marshal.ReleaseComObject(_reclockAudioRenderer); _reclockAudioRenderer = null; } if (_lavaudio != null) { m_graph.RemoveFilter(_lavaudio as DirectShowLib.IBaseFilter); Marshal.ReleaseComObject(_lavaudio); _lavaudio = null; } if (_xyVsFilter != null) { m_graph.RemoveFilter(_xyVsFilter as DirectShowLib.IBaseFilter); Marshal.ReleaseComObject(_xyVsFilter); _xyVsFilter = null; } if (_xySubFilter != null) { m_graph.RemoveFilter(_xySubFilter as DirectShowLib.IBaseFilter); Marshal.ReleaseComObject(_xySubFilter); _xySubFilter = null; } if (_lavvideo != null) { m_graph.RemoveFilter(_lavvideo as DirectShowLib.IBaseFilter); Marshal.ReleaseComObject(_lavvideo); _lavvideo = null; } if (_madvr != null) { m_graph.RemoveFilter(_madvr as DirectShowLib.IBaseFilter); Marshal.ReleaseComObject(_madvr); _madvr = null; } if (_videoWindow != null) { // Relinquish ownership (IMPORTANT!) after hiding video window hr = _videoWindow.put_Visible(OABool.False); hr = _videoWindow.put_Owner(IntPtr.Zero); } if (_mediaEventEx != null) { hr = _mediaEventEx.SetNotifyWindow(IntPtr.Zero, 0, IntPtr.Zero); Marshal.ReleaseComObject(_mediaEventEx); _mediaEventEx = null; } if (_dvdNav != null) { Marshal.ReleaseComObject(_dvdNav); _dvdNav = null; } if (_mDvdInfo != null) { Marshal.ReleaseComObject(_mDvdInfo); _mDvdInfo = null; } if (_mDvdControl != null) { Marshal.ReleaseComObject(_mDvdControl); _mDvdControl = null; } if (_mPDisplay != null) { Marshal.ReleaseComObject(_mPDisplay); _mPDisplay = null; } if (_filterGraph != null) { Marshal.ReleaseComObject(_filterGraph); _filterGraph = null; } if (_mPEvr != null) { Marshal.ReleaseComObject(_mPEvr); _mPEvr = null; } if (_mediaEventEx != null) { Marshal.ReleaseComObject(_mediaEventEx); _mediaEventEx = null; } if (_mediaSeeking != null) { Marshal.ReleaseComObject(_mediaSeeking); _mediaSeeking = null; } if (_mediaPosition != null) { Marshal.ReleaseComObject(_mediaPosition); _mediaPosition = null; } if (_mediaControl != null) { Marshal.ReleaseComObject(_mediaControl); _mediaControl = null; } if (_basicAudio != null) { Marshal.ReleaseComObject(_basicAudio); _basicAudio = null; } if (_basicVideo != null) { Marshal.ReleaseComObject(_basicVideo); _basicVideo = null; } if (_sourceFilter != null) { Marshal.ReleaseComObject(_sourceFilter); _sourceFilter = null; } if (m_graph != null) { Marshal.ReleaseComObject(m_graph); m_graph = null; } if (_videoWindow != null) { Marshal.ReleaseComObject(_videoWindow); _videoWindow = null; } _mSeekCaps = 0; _streams = null; GC.Collect(); }
private void RenderStreams(DirectShowLib.IBaseFilter pSource, bool enableReclock, bool enableMadvr, bool enableXySubFilter) { int hr; _filterGraph = m_graph as DirectShowLib.IFilterGraph2; if (_filterGraph == null) { throw new Exception("Could not QueryInterface for the IFilterGraph2"); } // Add video renderer if (_item.IsVideo) { _mPEvr = (DirectShowLib.IBaseFilter)new EnhancedVideoRenderer(); hr = m_graph.AddFilter(_mPEvr, "Enhanced Video Renderer"); DsError.ThrowExceptionForHR(hr); InitializeEvr(_mPEvr, 1); } // Add audio renderer var useDefaultRenderer = true; if (enableReclock) { try { _reclockAudioRenderer = new ReclockAudioRenderer(); var aRenderer = _reclockAudioRenderer as DirectShowLib.IBaseFilter; if (aRenderer != null) { hr = m_graph.AddFilter(aRenderer, "Reclock Audio Renderer"); DsError.ThrowExceptionForHR(hr); useDefaultRenderer = false; } } catch (Exception ex) { _logger.ErrorException("Error adding reclock filter", ex); } } if (useDefaultRenderer) { _defaultAudioRenderer = new DefaultAudioRenderer(); var aRenderer = _defaultAudioRenderer as DirectShowLib.IBaseFilter; if (aRenderer != null) { m_graph.AddFilter(aRenderer, "Default Audio Renderer"); } } if (_item.IsVideo) { try { _lavvideo = new LAVVideo(); var vlavvideo = _lavvideo as DirectShowLib.IBaseFilter; if (vlavvideo != null) { hr = m_graph.AddFilter(vlavvideo, "LAV Video Decoder"); DsError.ThrowExceptionForHR(hr); } } catch (Exception ex) { _logger.ErrorException("Error adding LAV Video filter", ex); } try { _lavaudio = new LAVAudio(); var vlavaudio = _lavaudio as DirectShowLib.IBaseFilter; if (vlavaudio != null) { hr = m_graph.AddFilter(vlavaudio, "LAV Audio Decoder"); DsError.ThrowExceptionForHR(hr); } } catch (Exception ex) { _logger.ErrorException("Error adding LAV Audio filter", ex); } if (_item.IsVideo) { var xySubFilterSucceeded = false; if (enableMadvr) { var madVrSucceded = false; try { _madvr = new MadVR(); var vmadvr = _madvr as DirectShowLib.IBaseFilter; if (vmadvr != null) { hr = m_graph.AddFilter(vmadvr, "MadVR Video Renderer"); DsError.ThrowExceptionForHR(hr); } madVrSucceded = true; } catch (Exception ex) { _logger.ErrorException("Error adding MadVR filter", ex); } // Load xySubFilter if configured and if madvr succeeded if (enableXySubFilter && madVrSucceded) { try { _xySubFilter = new XySubFilter(); var vxySubFilter = _xySubFilter as DirectShowLib.IBaseFilter; if (vxySubFilter != null) { hr = m_graph.AddFilter(vxySubFilter, "xy-SubFilter"); DsError.ThrowExceptionForHR(hr); } xySubFilterSucceeded = true; } catch (Exception ex) { _logger.ErrorException("Error adding xy-SubFilter filter", ex); } } } // Fallback to xyVsFilter if (!xySubFilterSucceeded) { try { _xyVsFilter = new XYVSFilter(); var vxyVsFilter = _xyVsFilter as DirectShowLib.IBaseFilter; if (vxyVsFilter != null) { hr = m_graph.AddFilter(vxyVsFilter, "xy-VSFilter"); DsError.ThrowExceptionForHR(hr); } } catch (Exception ex) { _logger.ErrorException("Error adding xy-VSFilter filter", ex); } } } } DirectShowLib.IEnumPins pEnum; hr = pSource.EnumPins(out pEnum); DsError.ThrowExceptionForHR(hr); DirectShowLib.IPin[] pins = { null }; /* Counter for how many pins successfully rendered */ var pinsRendered = 0; /* Loop over each pin of the source filter */ while (pEnum.Next(1, pins, IntPtr.Zero) == 0) { if (_filterGraph.RenderEx(pins[0], AMRenderExFlags.RenderToExistingRenderers, IntPtr.Zero) >= 0) pinsRendered++; Marshal.ReleaseComObject(pins[0]); } Marshal.ReleaseComObject(pEnum); if (pinsRendered == 0) { throw new Exception("Could not render any streams from the source Uri"); } _logger.Info("Completed RenderStreams with {0} pins.", pinsRendered); if (_item.IsVideo) { SetVideoWindow(); } }
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(); } }