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 }
/// <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 { } }
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); }
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(); }
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) { ; } } }
// 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; }
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; } }
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; }
/// <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); } }
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); }
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; }
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); }
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 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(); }
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 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); }
private static extern int SetWmvProfile(DirectShowLib.IBaseFilter filter, int bitrate, int fps, int screenX, int screenY);
// 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 }