public PlaneScene(VMR9Util util) { // Log.Info("PlaneScene: ctor()"); _textureAddress = 0; _vmr9Util = util; // Number of vertex buffers must be same as numer of segments in non-linear stretch _vertexBuffers = new VertexBuffer[nlsSourcePartitioning.Length]; for (int i = 0; i < _vertexBuffers.Length; i++) { _vertexBuffers[i] = new VertexBuffer(typeof(CustomVertex.TransformedColoredTextured), 4, GUIGraphicsContext.DX9Device, 0, CustomVertex.TransformedColoredTextured.Format, GUIGraphicsContext.GetTexturePoolType()); } _blackImage = new GUIImage(0); _blackImage.SetFileName("black.png"); _blackImage.AllocResources(); _cropSettings = new CropSettings(); }
/// <summary> /// removes the vmr9 filter from the graph and free up all unmanaged resources /// </summary> public void Dispose() { Log.Debug("VMR9: Dispose"); if (false == _isVmr9Initialized) { return; } if (_threadId != Thread.CurrentThread.ManagedThreadId) { Log.Error("VMR9: Dispose() from wrong thread"); //return; } if (_vmr9Filter == null) { Log.Error("VMR9: Dispose() no filter"); return; } if (_scene != null) { _scene.Stop(); _instanceCounter--; _scene.Deinit(); GUIGraphicsContext.Vmr9Active = false; GUIGraphicsContext.Vmr9FPS = 0f; GUIGraphicsContext.InVmr9Render = false; currentVmr9State = Vmr9PlayState.Playing; } _vmr9MixerBitmapInterface = null; _qualityInterface = null; if (GUIGraphicsContext.IsEvr) { EvrDeinit(); } else { Vmr9Deinit(); } DirectShowUtil.ReleaseComObject(_vmr9Filter); _vmr9Filter = null; _graphBuilderInterface = null; _scene = null; g_vmr9 = null; _isVmr9Initialized = false; }
protected override void ReInit() { //if (_vmr9 != null) //{ // int xx = 2; //} _vmr9 = new VMR9Util(); _vmr9.AddVMR9(_graphBuilder); _vmr9.Enable(false); _graphBuilder.Render(_pinVmr9ConnectedTo); //if (!_vmr9.IsVMR9Connected) //{ // int x = 1; //} }
public override void Stop() { if (SupportsReplay) { Log.Info("StreamBufferPlayer:stop"); if (_mediaCtrl == null) { return; } if (_vmr9 != null) { Log.Info("StreamBufferPlayer9: vmr9 disable"); _vmr9.Enable(false); } int counter = 0; while (GUIGraphicsContext.InVmr9Render) { counter++; Thread.Sleep(100); if (counter > 100) { break; } } _mediaCtrl.Stop(); if (_vmr9 != null) { Log.Info("StreamBufferPlayer9: vmr9 dispose"); _vmr9.SafeDispose(); _vmr9 = null; } } else { CloseInterfaces(); } //CloseInterfaces(); }
protected override void ReInit() { //if (VMR9Util.g_vmr9 != null) //{ // int xx = 2; //} _vmr9 = VMR9Util.g_vmr9 = new VMR9Util(); bool AddVMR9 = VMR9Util.g_vmr9.AddVMR9(_graphBuilder); if (!AddVMR9) { Log.Error("TSReaderPlayer:Failed to add VMR9 to graph"); return; } VMR9Util.g_vmr9.Enable(false); _graphBuilder.Render(_pinVmr9ConnectedTo); //if (!_vmr9.IsVMR9Connected) //{ // int x = 1; //} }
/// <summary> create the used COM components and get the interfaces. </summary> protected bool GetInterfaces() { VMR9Util.g_vmr9 = null; if (IsRadio == false) { Vmr9 = VMR9Util.g_vmr9 = new VMR9Util(); // switch back to directx fullscreen mode Log.Info("RTSPPlayer: Enabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 1, 0, null); GUIWindowManager.SendMessage(msg); } //Type comtype = null; //object comobj = null; DsRect rect = new DsRect(); rect.top = 0; rect.bottom = GUIGraphicsContext.form.Height; rect.left = 0; rect.right = GUIGraphicsContext.form.Width; try { graphBuilder = (IGraphBuilder)new FilterGraph(); Log.Info("RTSPPlayer: add source filter"); if (IsRadio == false) { bool AddVMR9 = VMR9Util.g_vmr9 != null && VMR9Util.g_vmr9.AddVMR9(graphBuilder); if (!AddVMR9) { Log.Error("RTSPPlayer:Failed to add VMR9 to graph"); return false; } VMR9Util.g_vmr9.Enable(false); } _mpegDemux = (IBaseFilter)new MPEG2Demultiplexer(); graphBuilder.AddFilter(_mpegDemux, "MPEG-2 Demultiplexer"); _rtspSource = (IBaseFilter)new RtpSourceFilter(); int hr = graphBuilder.AddFilter((IBaseFilter)_rtspSource, "RTSP Source Filter"); if (hr != 0) { Log.Error("RTSPPlayer:unable to add RTSP source filter:{0:X}", hr); return false; } // add preferred video & audio codecs Log.Info("RTSPPlayer: add video/audio codecs"); string strVideoCodec = ""; string strAudioCodec = ""; string strAudiorenderer = ""; int intFilters = 0; // FlipGer: count custom filters string strFilters = ""; // FlipGer: collect custom filters string postProcessingFilterSection = "mytv"; using (Settings xmlreader = new MPSettings()) { if (_mediaType == g_Player.MediaType.Video) { strVideoCodec = xmlreader.GetValueAsString("movieplayer", "mpeg2videocodec", ""); strAudioCodec = xmlreader.GetValueAsString("movieplayer", "mpeg2audiocodec", ""); strAudiorenderer = xmlreader.GetValueAsString("movieplayer", "audiorenderer", "Default DirectSound Device"); postProcessingFilterSection = "movieplayer"; } else { strVideoCodec = xmlreader.GetValueAsString("mytv", "videocodec", ""); strAudioCodec = xmlreader.GetValueAsString("mytv", "audiocodec", ""); strAudiorenderer = xmlreader.GetValueAsString("mytv", "audiorenderer", "Default DirectSound Device"); postProcessingFilterSection = "mytv"; } enableDvbSubtitles = xmlreader.GetValueAsBool("tvservice", "dvbsubtitles", false); // FlipGer: load infos for custom filters int intCount = 0; while (xmlreader.GetValueAsString(postProcessingFilterSection, "filter" + intCount.ToString(), "undefined") != "undefined") { if (xmlreader.GetValueAsBool(postProcessingFilterSection, "usefilter" + intCount.ToString(), false)) { strFilters += xmlreader.GetValueAsString(postProcessingFilterSection, "filter" + intCount.ToString(), "undefined") + ";"; intFilters++; } intCount++; } } string extension = Path.GetExtension(m_strCurrentFile).ToLowerInvariant(); if (IsRadio == false) { if (strVideoCodec.Length > 0) { DirectShowUtil.AddFilterToGraph(graphBuilder, strVideoCodec); } } if (strAudioCodec.Length > 0) { DirectShowUtil.AddFilterToGraph(graphBuilder, strAudioCodec); } if (enableDvbSubtitles == true) { try { _subtitleFilter = SubtitleRenderer.GetInstance().AddSubtitleFilter(graphBuilder); SubtitleRenderer.GetInstance().SetPlayer(this); dvbSubRenderer = SubtitleRenderer.GetInstance(); } catch (Exception e) { Log.Error(e); } } Log.Debug("Is subtitle fitler null? {0}", (_subtitleFilter == null)); // FlipGer: add custom filters to graph string[] arrFilters = strFilters.Split(';'); for (int i = 0; i < intFilters; i++) { DirectShowUtil.AddFilterToGraph(graphBuilder, arrFilters[i]); } if (strAudiorenderer.Length > 0) { audioRendererFilter = DirectShowUtil.AddAudioRendererToGraph(graphBuilder, strAudiorenderer, false); } Log.Info("RTSPPlayer: load:{0}", m_strCurrentFile); IFileSourceFilter interfaceFile = (IFileSourceFilter)_rtspSource; if (interfaceFile == null) { Log.Error("RTSPPlayer:Failed to get IFileSourceFilter"); return false; } //Log.Info("RTSPPlayer: open file:{0}",filename); hr = interfaceFile.Load(m_strCurrentFile, null); if (hr != 0) { Log.Error("RTSPPlayer:Failed to open file:{0} :0x{1:x}", m_strCurrentFile, hr); return false; } #region connect rtspsource->demux Log.Info("RTSPPlayer:connect rtspsource->mpeg2 demux"); IPin pinTsOut = DsFindPin.ByDirection((IBaseFilter)_rtspSource, PinDirection.Output, 0); if (pinTsOut == null) { Log.Info("RTSPPlayer:failed to find output pin of tsfilesource"); return false; } IPin pinDemuxIn = DsFindPin.ByDirection(_mpegDemux, PinDirection.Input, 0); if (pinDemuxIn == null) { Log.Info("RTSPPlayer:failed to find output pin of tsfilesource"); return false; } hr = graphBuilder.Connect(pinTsOut, pinDemuxIn); if (hr != 0) { Log.Info("RTSPPlayer:failed to connect rtspsource->mpeg2 demux:{0:X}", hr); return false; } DirectShowUtil.ReleaseComObject(pinTsOut); DirectShowUtil.ReleaseComObject(pinDemuxIn); #endregion #region render demux output pins if (IsRadio) { Log.Info("RTSPPlayer:render audio demux outputs"); IEnumPins enumPins; _mpegDemux.EnumPins(out enumPins); IPin[] pins = new IPin[2]; int fetched = 0; while (enumPins.Next(1, pins, out fetched) == 0) { if (fetched != 1) { break; } PinDirection direction; pins[0].QueryDirection(out direction); if (direction == PinDirection.Input) { continue; } IEnumMediaTypes enumMediaTypes; pins[0].EnumMediaTypes(out enumMediaTypes); AMMediaType[] mediaTypes = new AMMediaType[20]; int fetchedTypes; enumMediaTypes.Next(20, mediaTypes, out fetchedTypes); for (int i = 0; i < fetchedTypes; ++i) { if (mediaTypes[i].majorType == MediaType.Audio) { graphBuilder.Render(pins[0]); break; } } } } else { Log.Info("RTSPPlayer:render audio/video demux outputs"); IEnumPins enumPins; _mpegDemux.EnumPins(out enumPins); IPin[] pins = new IPin[2]; int fetched = 0; while (enumPins.Next(1, pins, out fetched) == 0) { if (fetched != 1) { break; } PinDirection direction; pins[0].QueryDirection(out direction); if (direction == PinDirection.Input) { continue; } graphBuilder.Render(pins[0]); } } #endregion // Connect DVB subtitle filter pins in the graph if (_mpegDemux != null && enableDvbSubtitles == true) { IMpeg2Demultiplexer demuxer = _mpegDemux as IMpeg2Demultiplexer; hr = demuxer.CreateOutputPin(GetTSMedia(), "Pcr", out _pinPcr); if (hr == 0) { Log.Info("RTSPPlayer:_pinPcr OK"); IPin pDemuxerPcr = DsFindPin.ByName(_mpegDemux, "Pcr"); IPin pSubtitlePcr = DsFindPin.ByName(_subtitleFilter, "Pcr"); hr = graphBuilder.Connect(pDemuxerPcr, pSubtitlePcr); } else { Log.Info("RTSPPlayer:Failed to create _pinPcr in demuxer:{0:X}", hr); } hr = demuxer.CreateOutputPin(GetTSMedia(), "Subtitle", out _pinSubtitle); if (hr == 0) { Log.Info("RTSPPlayer:_pinSubtitle OK"); IPin pDemuxerSubtitle = DsFindPin.ByName(_mpegDemux, "Subtitle"); IPin pSubtitle = DsFindPin.ByName(_subtitleFilter, "In"); hr = graphBuilder.Connect(pDemuxerSubtitle, pSubtitle); } else { Log.Info("RTSPPlayer:Failed to create _pinSubtitle in demuxer:{0:X}", hr); } hr = demuxer.CreateOutputPin(GetTSMedia(), "PMT", out _pinPMT); if (hr == 0) { Log.Info("RTSPPlayer:_pinPMT OK"); IPin pDemuxerSubtitle = DsFindPin.ByName(_mpegDemux, "PMT"); IPin pSubtitle = DsFindPin.ByName(_subtitleFilter, "PMT"); hr = graphBuilder.Connect(pDemuxerSubtitle, pSubtitle); } else { Log.Info("RTSPPlayer:Failed to create _pinPMT in demuxer:{0:X}", hr); } } if (IsRadio == false) { if (!VMR9Util.g_vmr9.IsVMR9Connected) { //VMR9 is not supported, switch to overlay Log.Info("RTSPPlayer: vmr9 not connected"); _mediaCtrl = null; Cleanup(); return false; } VMR9Util.g_vmr9.SetDeinterlaceMode(); } _mediaCtrl = (IMediaControl)graphBuilder; mediaEvt = (IMediaEventEx)graphBuilder; _mediaSeeking = (IMediaSeeking)graphBuilder; mediaPos = (IMediaPosition)graphBuilder; basicAudio = graphBuilder as IBasicAudio; //DirectShowUtil.SetARMode(graphBuilder,AspectRatioMode.Stretched); DirectShowUtil.EnableDeInterlace(graphBuilder); if (VMR9Util.g_vmr9 != null) { m_iVideoWidth = VMR9Util.g_vmr9.VideoWidth; m_iVideoHeight = VMR9Util.g_vmr9.VideoHeight; } if (audioRendererFilter != null) { Log.Info("RTSPPlayer9:set reference clock"); IMediaFilter mp = graphBuilder as IMediaFilter; IReferenceClock clock = audioRendererFilter as IReferenceClock; hr = mp.SetSyncSource(null); hr = mp.SetSyncSource(clock); Log.Info("RTSPPlayer9:set reference clock:{0:X}", hr); } Log.Info("RTSPPlayer: graph build successfull"); return true; } catch (Exception ex) { Error.SetError("Unable to play movie", "Unable build graph for VMR9"); Log.Error("RTSPPlayer:exception while creating DShow graph {0} {1}", ex.Message, ex.StackTrace); CloseInterfaces(); return false; } }
private void Cleanup() { if (_graphBuilder == null) { return; } int hr; using (Settings xmlreader = new MPSettings()) { int codecValue = 0; string codecType = ""; codecType = xmlreader.GetValueAsString("dvdplayer", "videocodec", ""); if (codecType == "InterVideo Video Decoder") { codecValue = xmlreader.GetValueAsInt("videocodec", "intervideo", 1); Log.Info("DVDPlayer9:Resetting InterVideo DXVA to {0}", codecValue); using ( RegistryKey subkey = Registry.CurrentUser.CreateSubKey(@"Software\InterVideo\Common\VideoDec\MediaPortal")) { subkey.SetValue("DXVA", codecValue); } } if (codecType.StartsWith("CyberLink Video/SP Decoder")) { codecValue = xmlreader.GetValueAsInt("videocodec", "cyberlink", 1); Log.Info("DVDPlayer9:Resetting CyberLink DXVA to {0}", codecValue); using (RegistryKey subkey = Registry.CurrentUser.CreateSubKey(@"Software\Cyberlink\Common\CLVSD\MediaPortal")) { subkey.SetValue("UIUseHVA", codecValue); } } if (codecType == "NVIDIA Video Decoder") { codecValue = xmlreader.GetValueAsInt("videocodec", "nvidia", 1); Log.Info("DVDPlayer9:Resetting NVIDIA DXVA to {0}", codecValue); using (RegistryKey subkey = Registry.LocalMachine.CreateSubKey(@"Software\NVIDIA Corporation\Filters\Video")) { subkey.SetValue("EnableDXVA", codecValue); } } } try { Log.Info("DVDPlayer9: cleanup DShow graph"); if (_mediaCtrl != null) { int counter = 0; FilterState state; hr = _mediaCtrl.Stop(); hr = _mediaCtrl.GetState(10, out state); while (state != FilterState.Stopped || GUIGraphicsContext.InVmr9Render) { System.Threading.Thread.Sleep(100); hr = _mediaCtrl.GetState(10, out state); counter++; if (counter >= 30) { if (state != FilterState.Stopped) { Log.Debug("DVDPlayer9: graph still running"); } if (GUIGraphicsContext.InVmr9Render) { Log.Debug("DVDPlayer9: in renderer"); } break; } } _mediaCtrl = null; } _state = PlayState.Stopped; VMR9Util.g_vmr9.EVRSetDVDMenuState(false); _visible = false; _mediaEvt = null; _dvdCtrl = null; _dvdInfo = null; _basicVideo = null; _basicAudio = null; _mediaPos = null; _videoWin = null; _pendingCmd = false; if (_cmdOption != null) { DirectShowUtil.ReleaseComObject(_cmdOption); _cmdOption = null; } if (_dvdbasefilter != null) { while ((hr = DirectShowUtil.ReleaseComObject(_dvdbasefilter)) > 0) { ; } _dvdbasefilter = null; } if (_dvdGraph != null) { while ((hr = DirectShowUtil.ReleaseComObject(_dvdGraph)) > 0) { ; } _dvdGraph = null; } if (_line21Decoder != null) { while ((hr = DirectShowUtil.ReleaseComObject(_line21Decoder)) > 0) { ; } _line21Decoder = null; } PostProcessingEngine.GetInstance().FreePostProcess(); if (_vmr9 != null) { _vmr9.Enable(false); _vmr9.SafeDispose(); _vmr9 = null; } if (_graphBuilder != null) { DirectShowUtil.RemoveFilters(_graphBuilder); // _rotEntry has a reference to _graphBuilder (see _rotEntry ctor) // so, release of _rotEntry must be before _graphBuilder is released if (_rotEntry != null) { _rotEntry.SafeDispose(); _rotEntry = null; } while ((hr = DirectShowUtil.ReleaseComObject(_graphBuilder)) > 0) { ; } _graphBuilder = null; } _state = PlayState.Init; GUIGraphicsContext.form.Invalidate(true); //GUIGraphicsContext.form.Activate(); } catch (Exception ex) { Log.Error("DVDPlayer9: Exception while cleanuping DShow graph - {0} {1}", ex.Message, ex.StackTrace); } Log.Info("DVDPlayer9: Disabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 0, 0, null); GUIWindowManager.SendMessage(msg); }
protected override bool GetInterfaces() { GetInterface = true; try { graphBuilder = (IGraphBuilder)new FilterGraph(); _rotEntry = new DsROTEntry((IFilterGraph)graphBuilder); int hr; filterConfig = GetFilterConfiguration(); filterCodec = GetFilterCodec(); if (filterConfig.bAutoDecoderSettings) { AutoRenderingCheck = true; return base.GetInterfaces(); } string extension = Path.GetExtension(m_strCurrentFile).ToLowerInvariant(); GUIMessage msg; if (extension == ".mpls" || extension == ".bdmv") { filterConfig.bForceSourceSplitter = false; filterConfig = GetFilterConfigurationBD(); } //Manually add codecs based on file extension if not in auto-settings // switch back to directx fullscreen mode Log.Info("MyAnime3Player: Enabling DX9 exclusive mode"); msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 1, 0, null); GUIWindowManager.SendMessage(msg); // add the VMR9 in the graph // after enabeling exclusive mode, if done first it causes MediPortal to minimize if for example the "Windows key" is pressed while playing a video if (extension != ".dts" && extension != ".mp3" && extension != ".mka" && extension != ".ac3") { if (g_Player._mediaInfo != null && !g_Player._mediaInfo.MediaInfoNotloaded && !g_Player._mediaInfo.hasVideo) { AudioOnly = true; } else { Vmr9 = new VMR9Util(); Vmr9.AddVMR9(graphBuilder); Vmr9.Enable(false); } } else { AudioOnly = true; } if (filterConfig.strsplitterfilter == LAV_SPLITTER_FILTER_SOURCE && filterConfig.bForceSourceSplitter) { LoadLAVSplitter(LAV_SPLITTER_FILTER_SOURCE); hr = graphBuilder.AddFilter(_interfaceSourceFilter, LAV_SPLITTER_FILTER_SOURCE); DsError.ThrowExceptionForHR(hr); Log.Debug("MyAnime3Player: Add LAVSplitter Source to graph"); IFileSourceFilter interfaceFile = (IFileSourceFilter) _interfaceSourceFilter; hr = interfaceFile.Load(m_strCurrentFile, null); if (hr != 0) { Error.SetError("Unable to play movie", "Unable build graph for VMR9"); Cleanup(); return false; } } else { _interfaceSourceFilter = filterConfig.bForceSourceSplitter ? DirectShowUtil.AddFilterToGraph(graphBuilder, filterConfig.strsplitterfilter) : null; if (_interfaceSourceFilter == null && !filterConfig.bForceSourceSplitter) { graphBuilder.AddSourceFilter(m_strCurrentFile, null, out _interfaceSourceFilter); } else { try { int result = ((IFileSourceFilter) _interfaceSourceFilter).Load(m_strCurrentFile, null); if (result != 0) { graphBuilder.RemoveFilter(_interfaceSourceFilter); DirectShowUtil.ReleaseComObject(_interfaceSourceFilter); _interfaceSourceFilter = null; graphBuilder.AddSourceFilter(m_strCurrentFile, null, out _interfaceSourceFilter); } } catch (Exception ex) { Log.Error( "MyAnime3Player: Exception loading Source Filter setup in setting in DShow graph , try to load by merit", ex); graphBuilder.RemoveFilter(_interfaceSourceFilter); DirectShowUtil.ReleaseComObject(_interfaceSourceFilter); _interfaceSourceFilter = null; graphBuilder.AddSourceFilter(m_strCurrentFile, null, out _interfaceSourceFilter); } } //Detection of File Source (Async.) as source filter, return true if found IBaseFilter fileSyncbaseFilter = null; DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.FilesyncSource, out fileSyncbaseFilter); if (fileSyncbaseFilter == null) graphBuilder.FindFilterByName("File Source (Async.)", out fileSyncbaseFilter); if (fileSyncbaseFilter != null && filterConfig.bForceSourceSplitter) { FileSync = true; DirectShowUtil.ReleaseComObject(fileSyncbaseFilter); fileSyncbaseFilter = null; if (filterConfig.strsplitterfilefilter == LAV_SPLITTER_FILTER) { LoadLAVSplitter(LAV_SPLITTER_FILTER); hr = graphBuilder.AddFilter(Splitter, LAV_SPLITTER_FILTER); DsError.ThrowExceptionForHR(hr); Log.Debug("MyAnime3Player: Add LAVSplitter to graph"); if (hr != 0) { Error.SetError("Unable to play movie", "Unable build graph for VMR9"); Cleanup(); return false; } } else { Splitter = DirectShowUtil.AddFilterToGraph(graphBuilder, filterConfig.strsplitterfilefilter); } } } // Add preferred video filters UpdateFilters("Video"); //Add Audio Renderer if (filterConfig.AudioRenderer.Length > 0 && filterCodec._audioRendererFilter == null) { filterCodec._audioRendererFilter = DirectShowUtil.AddAudioRendererToGraph(graphBuilder, filterConfig.AudioRenderer, false); } // Add preferred audio filters UpdateFilters("Audio"); #region Set High Audio //Set High Resolution Output > 2 channels IBaseFilter baseFilter = null; bool FFDShowLoaded = false; graphBuilder.FindFilterByName("WMAudio Decoder DMO", out baseFilter); if (baseFilter != null && filterConfig.wmvAudio != false) //Also check configuration option enabled { //Set the filter setting to enable more than 2 audio channels const string g_wszWMACHiResOutput = "_HIRESOUTPUT"; object val = true; IPropertyBag propBag = (IPropertyBag) baseFilter; hr = propBag.Write(g_wszWMACHiResOutput, ref val); if (hr != 0) { Log.Info("VideoPlayer9: Unable to turn WMAudio multichannel on. Reason: {0}", hr); } else { Log.Info("VideoPlayer9: WMAudio Decoder now set for > 2 audio channels"); } if (!FFDShowLoaded) { IBaseFilter FFDShowAudio = DirectShowUtil.GetFilterByName(graphBuilder, FFDSHOW_AUDIO_DECODER_FILTER); if (FFDShowAudio != null) { DirectShowUtil.ReleaseComObject(FFDShowAudio); FFDShowAudio = null; } else { _FFDShowAudio = DirectShowUtil.AddFilterToGraph(graphBuilder, FFDSHOW_AUDIO_DECODER_FILTER); } FFDShowLoaded = true; } DirectShowUtil.ReleaseComObject(baseFilter); baseFilter = null; } #endregion if (_interfaceSourceFilter != null) { DirectShowUtil.RenderGraphBuilderOutputPins(graphBuilder, _interfaceSourceFilter); } //Test and remove orphelin Audio Renderer //RemoveAudioR(); //remove InternalScriptRenderer as it takes subtitle pin disableISR(); //disable Closed Captions! disableCC(); DirectShowUtil.RemoveUnusedFiltersFromGraph(graphBuilder); //remove orphelin audio renderer RemoveAudioR(); //EnableClock(); if ((Vmr9 == null || !Vmr9.IsVMR9Connected) && !AudioOnly) { Log.Error("MyAnime3Player: Failed to render file -> vmr9"); mediaCtrl = null; Cleanup(); return false; } mediaCtrl = (IMediaControl) graphBuilder; mediaEvt = (IMediaEventEx) graphBuilder; mediaSeek = (IMediaSeeking) graphBuilder; mediaPos = (IMediaPosition) graphBuilder; basicAudio = (IBasicAudio) graphBuilder; videoWin = (IVideoWindow) graphBuilder; if (Vmr9 != null) { m_iVideoWidth = Vmr9.VideoWidth; m_iVideoHeight = Vmr9.VideoHeight; Vmr9.SetDeinterlaceMode(); } return true; } catch (Exception ex) { Error.SetError("Unable to play movie", "Unable build graph for VMR9"); Log.Error("MyAnime3Player: Exception while creating DShow graph {0} {1}", ex.Message, ex.StackTrace); Cleanup(); return false; } }
/// <summary> create the used COM components and get the interfaces. </summary> protected override bool GetInterfaces() { try { graphBuilder = (IGraphBuilder)new FilterGraph(); _rotEntry = new DsROTEntry((IFilterGraph)graphBuilder); // add preferred video & audio codecs int hr; int intFilters = 0; // FlipGer: count custom filters string strVideoCodec = ""; string strH264VideoCodec = ""; string strAudioCodec = ""; string strAACAudioCodec = ""; string strAudiorenderer = ""; string strFilters = ""; // FlipGer: collect custom filters bool wmvAudio; bool autoloadSubtitles; bool bAutoDecoderSettings = false; using (Settings xmlreader = new MPSettings()) { bAutoDecoderSettings = xmlreader.GetValueAsBool("movieplayer", "autodecodersettings", false); strVideoCodec = xmlreader.GetValueAsString("movieplayer", "mpeg2videocodec", ""); strH264VideoCodec = xmlreader.GetValueAsString("movieplayer", "h264videocodec", ""); strAudioCodec = xmlreader.GetValueAsString("movieplayer", "mpeg2audiocodec", ""); strAACAudioCodec = xmlreader.GetValueAsString("movieplayer", "aacaudiocodec", ""); strAudiorenderer = xmlreader.GetValueAsString("movieplayer", "audiorenderer", "Default DirectSound Device"); wmvAudio = xmlreader.GetValueAsBool("movieplayer", "wmvaudio", false); autoloadSubtitles = xmlreader.GetValueAsBool("subtitles", "enabled", false); // FlipGer: load infos for custom filters int intCount = 0; while (xmlreader.GetValueAsString("movieplayer", "filter" + intCount.ToString(), "undefined") != "undefined") { if (xmlreader.GetValueAsBool("movieplayer", "usefilter" + intCount.ToString(), false)) { strFilters += xmlreader.GetValueAsString("movieplayer", "filter" + intCount.ToString(), "undefined") + ";"; intFilters++; } intCount++; } } if (bAutoDecoderSettings) { return AutoRendering(wmvAudio); } //Manually add codecs based on file extension if not in auto-settings // switch back to directx fullscreen mode Log.Info("VideoPlayerVMR9: Enabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 1, 0, null); GUIWindowManager.SendMessage(msg); // add the VMR9 in the graph // after enabeling exclusive mode, if done first it causes MediPortal to minimize if for example the "Windows key" is pressed while playing a video Vmr9 = new VMR9Util(); Vmr9.AddVMR9(graphBuilder); Vmr9.Enable(false); IBaseFilter source = null; graphBuilder.AddSourceFilter(m_strCurrentFile, null, out source); string extension = Path.GetExtension(m_strCurrentFile).ToLower(); switch (extension) { case ".wmv": case ".asf": { //strVideoCodec = "WMVideo Decoder DMO"; //allow e.g. ffdshow usage strH264VideoCodec = ""; strAudioCodec = "WMAudio Decoder DMO"; // multichannel audio needs this filter strAACAudioCodec = ""; break; } case ".mkv": case ".m2ts": case ".mp4": { strVideoCodec = ""; break; } default: strH264VideoCodec = ""; strAACAudioCodec = ""; break; } if (!string.IsNullOrEmpty(strVideoCodec)) DirectShowUtil.AddFilterToGraph(graphBuilder, strVideoCodec); if (!string.IsNullOrEmpty(strH264VideoCodec) && strVideoCodec != strH264VideoCodec) DirectShowUtil.AddFilterToGraph(graphBuilder, strH264VideoCodec); if (!string.IsNullOrEmpty(strAudioCodec)) DirectShowUtil.AddFilterToGraph(graphBuilder, strAudioCodec); if (!string.IsNullOrEmpty(strAACAudioCodec) && strAudioCodec != strAACAudioCodec) DirectShowUtil.AddFilterToGraph(graphBuilder, strAACAudioCodec); if (strAudiorenderer.Length > 0) { DirectShowUtil.AddAudioRendererToGraph(graphBuilder, strAudiorenderer, false); } //We now add custom filters after the Audio Renderer as AC3Filter failed to connect otherwise. //FlipGer: add custom filters to graph string[] arrFilters = strFilters.Split(';'); for (int i = 0; i < intFilters; i++) { DirectShowUtil.AddFilterToGraph(graphBuilder, arrFilters[i]); } //Set High Resolution Output > 2 channels IBaseFilter baseFilter = null; bool FFDShowLoaded = false; graphBuilder.FindFilterByName("WMAudio Decoder DMO", out baseFilter); if (baseFilter != null && wmvAudio != false) //Also check configuration option enabled { //Set the filter setting to enable more than 2 audio channels const string g_wszWMACHiResOutput = "_HIRESOUTPUT"; object val = true; IPropertyBag propBag = (IPropertyBag)baseFilter; hr = propBag.Write(g_wszWMACHiResOutput, ref val); if (hr != 0) { Log.Info("VideoPlayerVMR9: Unable to turn WMAudio multichannel on. Reason: {0}", hr); } else { Log.Info("VideoPlayerVMR9: WMAudio Decoder now set for > 2 audio channels"); } if (!FFDShowLoaded) { IBaseFilter FFDShowAudio = DirectShowUtil.GetFilterByName(graphBuilder, FFDSHOW_AUDIO_DECODER_FILTER); if (FFDShowAudio != null) { DirectShowUtil.ReleaseComObject(FFDShowAudio); FFDShowAudio = null; } else { _FFDShowAudio = DirectShowUtil.AddFilterToGraph(graphBuilder, FFDSHOW_AUDIO_DECODER_FILTER); } FFDShowLoaded = true; } DirectShowUtil.ReleaseComObject(baseFilter); baseFilter = null; } #region load external audio streams // check if current "File" is a file... it could also be a URL // Directory.Getfiles, ... will other give us an exception if (File.Exists(m_strCurrentFile)) { //load audio file (ac3, dts, mka, mp3) only with if the name matches partially with video file. string[] audioFiles = Directory.GetFiles(Path.GetDirectoryName(m_strCurrentFile), Path.GetFileNameWithoutExtension(m_strCurrentFile) + "*.*"); bool audioSwitcherLoaded = false; foreach (string file in audioFiles) { switch (Path.GetExtension(file)) { case ".mp3": case ".dts": case ".mka": case ".ac3": if (!audioSwitcherLoaded) { IBaseFilter switcher = DirectShowUtil.GetFilterByName(graphBuilder, MEDIAPORTAL_AUDIOSWITCHER_FILTER); if (switcher != null) { DirectShowUtil.ReleaseComObject(switcher); switcher = null; } else { _audioSwitcher = DirectShowUtil.AddFilterToGraph(graphBuilder, MEDIAPORTAL_AUDIOSWITCHER_FILTER); } audioSwitcherLoaded = true; } _AudioSourceFilter = DirectShowUtil.AddFilterToGraph(graphBuilder, FILE_SYNC_FILTER); int result = ((IFileSourceFilter)_AudioSourceFilter).Load(file, null); //Force using LAVFilter _AudioExtSplitterFilter = DirectShowUtil.AddFilterToGraph(graphBuilder, LAV_SPLITTER_FILTER); if (result != 0 || _AudioExtSplitterFilter == null) { if (_AudioSourceFilter != null) { graphBuilder.RemoveFilter(_AudioSourceFilter); DirectShowUtil.ReleaseComObject(_AudioSourceFilter); _AudioSourceFilter = null; } if (_AudioExtSplitterFilter != null) { graphBuilder.RemoveFilter(_AudioExtSplitterFilter); DirectShowUtil.ReleaseComObject(_AudioExtSplitterFilter); _AudioExtSplitterFilter = null; } //Trying Add Audio decoder in graph AddFilterToGraphAndRelease(strAudioCodec); graphBuilder.RenderFile(file, string.Empty); Log.Debug("VideoPlayerVMR9 : External audio file loaded \"{0}\"", file); AudioExternal = true; break; } //Add Audio decoder in graph _AudioExtFilter = DirectShowUtil.AddFilterToGraph(graphBuilder, strAudioCodec); //Connect Filesource with the splitter IPin pinOutAudioExt1 = DsFindPin.ByDirection((IBaseFilter)_AudioSourceFilter, PinDirection.Output, 0); IPin pinInAudioExt2 = DsFindPin.ByDirection((IBaseFilter)_AudioExtSplitterFilter, PinDirection.Input, 0); hr = graphBuilder.Connect(pinOutAudioExt1, pinInAudioExt2); //Connect Splitter with the Audio Decoder IPin pinOutAudioExt3 = DsFindPin.ByDirection((IBaseFilter)_AudioExtSplitterFilter, PinDirection.Output, 0); IPin pinInAudioExt4 = DsFindPin.ByDirection((IBaseFilter)_AudioExtFilter, PinDirection.Input, 0); hr = graphBuilder.Connect(pinOutAudioExt3, pinInAudioExt4); //Render outpin from Audio Decoder DirectShowUtil.RenderUnconnectedOutputPins(graphBuilder, _AudioExtFilter); //Cleanup External Audio (Release) if (_AudioSourceFilter != null) { DirectShowUtil.ReleaseComObject(_AudioSourceFilter); _AudioSourceFilter = null; } if (_AudioExtSplitterFilter != null) { DirectShowUtil.ReleaseComObject(_AudioExtSplitterFilter); _AudioExtSplitterFilter = null; } if (_AudioExtFilter != null) { DirectShowUtil.ReleaseComObject(_AudioExtFilter); _AudioExtFilter = null; } if (pinOutAudioExt1 != null) { DirectShowUtil.ReleaseComObject(pinOutAudioExt1); pinOutAudioExt1 = null; } if (pinInAudioExt2 != null) { DirectShowUtil.ReleaseComObject(pinInAudioExt2); pinInAudioExt2 = null; } if (pinOutAudioExt3 != null) { DirectShowUtil.ReleaseComObject(pinOutAudioExt3); pinOutAudioExt3 = null; } if (pinInAudioExt4 != null) { DirectShowUtil.ReleaseComObject(pinInAudioExt4); pinInAudioExt4 = null; } Log.Debug("VideoPlayerVMR9 : External audio file loaded \"{0}\"", file); AudioExternal = true; break; } } } #endregion DirectShowUtil.RenderUnconnectedOutputPins(graphBuilder, source); if (source != null) { DirectShowUtil.ReleaseComObject(source); source = null; } DirectShowUtil.RemoveUnusedFiltersFromGraph(graphBuilder); if (Vmr9 == null || !Vmr9.IsVMR9Connected) { Log.Error("VideoPlayer9: Failed to render file -> vmr9"); mediaCtrl = null; Cleanup(); return false; } mediaCtrl = (IMediaControl)graphBuilder; mediaEvt = (IMediaEventEx)graphBuilder; mediaSeek = (IMediaSeeking)graphBuilder; mediaPos = (IMediaPosition)graphBuilder; basicAudio = (IBasicAudio)graphBuilder; videoWin = (IVideoWindow)graphBuilder; m_iVideoWidth = Vmr9.VideoWidth; m_iVideoHeight = Vmr9.VideoHeight; Vmr9.SetDeinterlaceMode(); return true; } catch (Exception ex) { Error.SetError("Unable to play movie", "Unable build graph for VMR9"); Log.Error("VideoPlayer9: Exception while creating DShow graph {0} {1}", ex.Message, ex.StackTrace); Cleanup(); return false; } }
private void Cleanup() { if (graphBuilder == null) { return; } int hr; Log.Info("RTSPPlayer:cleanup DShow graph"); try { if (_mediaCtrl != null) { int counter = 0; FilterState state; hr = _mediaCtrl.Stop(); hr = _mediaCtrl.GetState(10, out state); while (state != FilterState.Stopped || GUIGraphicsContext.InVmr9Render) { Thread.Sleep(100); hr = _mediaCtrl.GetState(10, out state); counter++; if (counter >= 30) { if (state != FilterState.Stopped) Log.Error("RTSPPlayer: graph still running"); if (GUIGraphicsContext.InVmr9Render) Log.Error("RTSPPlayer: in renderer"); break; } } _mediaCtrl = null; } if (Vmr9 != null) { Vmr9.Enable(false); } if (mediaEvt != null) { hr = mediaEvt.SetNotifyWindow(IntPtr.Zero, WM_GRAPHNOTIFY, IntPtr.Zero); mediaEvt = null; } videoWin = graphBuilder as IVideoWindow; if (videoWin != null) { hr = videoWin.put_Visible(OABool.False); hr = videoWin.put_Owner(IntPtr.Zero); videoWin = null; } _mediaSeeking = null; mediaPos = null; basicAudio = null; basicVideo = null; videoWin = null; SubEngine.GetInstance().FreeSubtitles(); if (graphBuilder != null) { DirectShowUtil.RemoveFilters(graphBuilder); if (_rotEntry != null) { _rotEntry.SafeDispose(); _rotEntry = null; } DirectShowUtil.ReleaseComObject(graphBuilder); graphBuilder = null; } if (Vmr9 != null) { Vmr9.SafeDispose(); Vmr9 = null; } GUIGraphicsContext.form.Invalidate(true); _state = PlayState.Init; if (_mpegDemux != null) { Log.Info("cleanup mpegdemux"); while ((hr = DirectShowUtil.ReleaseComObject(_mpegDemux)) > 0) { ; } _mpegDemux = null; } if (_rtspSource != null) { Log.Info("cleanup _rtspSource"); while ((hr = DirectShowUtil.ReleaseComObject(_rtspSource)) > 0) { ; } _rtspSource = null; } if (_subtitleFilter != null) { while ((hr = DirectShowUtil.ReleaseComObject(_subtitleFilter)) > 0) { ; } _subtitleFilter = null; if (this.dvbSubRenderer != null) { this.dvbSubRenderer.SetPlayer(null); } this.dvbSubRenderer = null; } if (vobSub != null) { Log.Info("cleanup vobSub"); while ((hr = DirectShowUtil.ReleaseComObject(vobSub)) > 0) { ; } vobSub = null; } } catch (Exception ex) { Log.Error("RTSPPlayer: Exception while cleanuping DShow graph - {0} {1}", ex.Message, ex.StackTrace); } //switch back to directx windowed mode Log.Info("RTSPPlayer: Disabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 0, 0, null); GUIWindowManager.SendMessage(msg); }
private void Cleanup() { lock (lockObj) { if (_graphBuilder == null) { return; } int hr; Log.Info("TSReaderPlayer: cleanup DShow graph {0}", GUIGraphicsContext.InVmr9Render); try { if (_mediaCtrl != null) { int counter = 0; FilterState state; hr = _mediaCtrl.Stop(); hr = _mediaCtrl.GetState(10, out state); while (state != FilterState.Stopped || GUIGraphicsContext.InVmr9Render) { Thread.Sleep(100); hr = _mediaCtrl.GetState(10, out state); counter++; if (counter >= 30) { if (state != FilterState.Stopped) Log.Error("TSReaderPlayer: graph still running"); if (GUIGraphicsContext.InVmr9Render) Log.Error("TSReaderPlayer: in renderer"); break; } } _mediaCtrl = null; } if (_mediaEvt != null) { hr = _mediaEvt.SetNotifyWindow(IntPtr.Zero, WM_GRAPHNOTIFY, IntPtr.Zero); _mediaEvt = null; } _videoWin = _graphBuilder as IVideoWindow; if (_videoWin != null) { hr = _videoWin.put_Visible(OABool.False); hr = _videoWin.put_Owner(IntPtr.Zero); _videoWin = null; } _mediaSeeking = null; _basicAudio = null; _basicVideo = null; _ireader = null; if (_audioRendererFilter != null) { while (DirectShowUtil.ReleaseComObject(_audioRendererFilter) > 0) ; _audioRendererFilter = null; } if (_fileSource != null) { DirectShowUtil.ReleaseComObject(_fileSource, 5000); _fileSource = null; } PostProcessingEngine.GetInstance().FreePostProcess(); if (_vmr9 != null) { _vmr9.Enable(false); _vmr9.SafeDispose(); _vmr9 = null; } if (_line21Decoder != null) { while ((hr = DirectShowUtil.ReleaseComObject(_line21Decoder)) > 0) ; _line21Decoder = null; } if (_graphBuilder != null) { DirectShowUtil.RemoveFilters(_graphBuilder); if (_rotEntry != null) { _rotEntry.SafeDispose(); _rotEntry = null; } while ((hr = DirectShowUtil.ReleaseComObject(_graphBuilder)) > 0) ; _graphBuilder = null; } if (_dvbSubRenderer != null) { _dvbSubRenderer.SetPlayer(null); _dvbSubRenderer = null; } GUIGraphicsContext.form.Invalidate(true); _state = PlayState.Init; } catch (Exception ex) { Log.Error("TSReaderPlayer: Exception while cleaning DShow graph - {0} {1}", ex.Message, ex.StackTrace); } try { using (MPSettings xmlreader = new MPSettings()) xmlreader.SetValue("tvservice", "dvbdefttxtsubtitles", "999;999"); } catch { } //switch back to directx windowed mode Log.Info("TSReaderPlayer: Disabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 0, 0, null); GUIWindowManager.SendMessage(msg); } }
protected void Cleanup() { if (graphBuilder == null) { return; } int hr = 0; Log.Info("VideoPlayer9: Cleanup DShow graph"); try { if (mediaCtrl != null) { int counter = 0; FilterState state; hr = mediaCtrl.Stop(); hr = mediaCtrl.GetState(10, out state); while (state != FilterState.Stopped || GUIGraphicsContext.InVmr9Render) { Log.Debug("VideoPlayer9: graph still running"); Thread.Sleep(100); hr = mediaCtrl.GetState(10, out state); counter++; if (counter >= 30) { if (state != FilterState.Stopped) { Log.Debug("VideoPlayer9: graph still running"); } if (GUIGraphicsContext.InVmr9Render) { Log.Debug("VideoPlayer9: in renderer"); } break; } } mediaCtrl = null; } if (mediaEvt != null) { hr = mediaEvt.SetNotifyWindow(IntPtr.Zero, WM_GRAPHNOTIFY, IntPtr.Zero); mediaEvt = null; } if (videoWin != null) { hr = videoWin.put_Visible(OABool.False); hr = videoWin.put_Owner(IntPtr.Zero); videoWin = null; } mediaSeek = null; mediaPos = null; basicAudio = null; basicVideo = null; SubEngine.GetInstance().FreeSubtitles(); PostProcessingEngine.GetInstance().FreePostProcess(); if (_FFDShowAudio != null) { DirectShowUtil.ReleaseComObject(_FFDShowAudio); _FFDShowAudio = null; } if (_audioSwitcher != null) { DirectShowUtil.ReleaseComObject(_audioSwitcher); _audioSwitcher = null; } if (Vmr9 != null) { Vmr9.Enable(false); Vmr9.SafeDispose(); Vmr9 = null; } if (graphBuilder != null) { DirectShowUtil.RemoveFilters(graphBuilder); if (_rotEntry != null) { _rotEntry.SafeDispose(); _rotEntry = null; } DirectShowUtil.ReleaseComObject(graphBuilder); graphBuilder = null; } GUIGraphicsContext.form.Invalidate(true); m_state = PlayState.Init; } catch (Exception ex) { Log.Error("VideoPlayerVMR9: Exception while cleanuping DShow graph - {0} {1}", ex.Message, ex.StackTrace); } //switch back to directx windowed mode Log.Info("VideoPlayerVMR9: Disabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 0, 0, null); GUIWindowManager.SendMessage(msg); }
/// <summary> create the used COM components and get the interfaces. </summary> protected override bool GetInterfaces(string path) { int hr; object comobj = null; _freeNavigator = true; _dvdInfo = null; _dvdCtrl = null; _videoWin = null; string dvdDNavigator = "DVD Navigator"; string aspectRatio = ""; string displayMode = ""; bool turnoffDXVA = false; bool showClosedCaptions = false; int codecValue = 0; string codecType = ""; using (Settings xmlreader = new MPSettings()) { showClosedCaptions = xmlreader.GetValueAsBool("dvdplayer", "showclosedcaptions", false); dvdDNavigator = xmlreader.GetValueAsString("dvdplayer", "navigator", "DVD Navigator"); if (dvdDNavigator.ToLowerInvariant().Contains("cyberlink dvd navigator")) { _cyberlinkDVDNavigator = true; } aspectRatio = xmlreader.GetValueAsString("dvdplayer", "armode", "").ToLowerInvariant(); if (aspectRatio == "crop") { arMode = AspectRatioMode.Crop; } else if (aspectRatio == "letterbox") { arMode = AspectRatioMode.LetterBox; } else if (aspectRatio == "stretch") { arMode = AspectRatioMode.Stretched; } else if (aspectRatio == "follow stream") { arMode = AspectRatioMode.StretchedAsPrimary; } displayMode = xmlreader.GetValueAsString("dvdplayer", "displaymode", "").ToLowerInvariant(); if (displayMode == "default") { _videoPref = DvdPreferredDisplayMode.DisplayContentDefault; } else if (displayMode == "16:9") { _videoPref = DvdPreferredDisplayMode.Display16x9; } else if (displayMode == "4:3 pan scan") { _videoPref = DvdPreferredDisplayMode.Display4x3PanScanPreferred; } else if (displayMode == "4:3 letterbox") { _videoPref = DvdPreferredDisplayMode.Display4x3LetterBoxPreferred; } turnoffDXVA = xmlreader.GetValueAsBool("dvdplayer", "turnoffdxva", true); Log.Info("DVDPlayer9:Turn off DXVA value = {0}", turnoffDXVA); if (turnoffDXVA == true) { codecType = xmlreader.GetValueAsString("dvdplayer", "videocodec", ""); Log.Info("DVDPlayer9:Video Decoder = {0}", codecType); if (codecType == "InterVideo Video Decoder") { codecValue = xmlreader.GetValueAsInt("videocodec", "intervideo", 1); if (codecValue == 1) { Log.Info("DVDPlayer9:Turning InterVideo DXVA off"); using ( RegistryKey subkey = Registry.CurrentUser.CreateSubKey(@"Software\InterVideo\Common\VideoDec\MediaPortal")) { subkey.SetValue("DXVA", 0); } } if (codecValue == 0) { Log.Info("DVDPlayer9:InterVideo DXVA already off"); } } if (codecType.StartsWith("CyberLink Video/SP Decoder")) { codecValue = xmlreader.GetValueAsInt("videocodec", "cyberlink", 1); if (codecValue == 1) { Log.Info("DVDPlayer9:Turning CyberLink DXVA off"); using ( RegistryKey subkey = Registry.CurrentUser.CreateSubKey(@"Software\Cyberlink\Common\CLVSD\MediaPortal")) { subkey.SetValue("UIUseHVA", 0); } } if (codecValue == 0) { Log.Info("DVDPlayer9:CyberLink DXVA already off"); } } if (codecType == "NVIDIA Video Decoder") { codecValue = xmlreader.GetValueAsInt("videocodec", "nvidia", 1); if (codecValue == 1) { Log.Info("DVDPlayer9:Turning NVIDIA DXVA off"); using ( RegistryKey subkey = Registry.LocalMachine.CreateSubKey(@"Software\NVIDIA Corporation\Filters\Video")) { subkey.SetValue("EnableDXVA", 0); } } if (codecValue == 0) { Log.Info("DVDPlayer9:NVIDIA DXVA already off"); } } } } Log.Info("DVDPlayer9:Enabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 1, 0, null); GUIWindowManager.SendMessage(msg); try { _dvdGraph = (IDvdGraphBuilder)new DvdGraphBuilder(); hr = _dvdGraph.GetFiltergraph(out _graphBuilder); DsError.ThrowExceptionForHR(hr); _basicVideo = _graphBuilder as IBasicVideo2; _videoWin = _graphBuilder as IVideoWindow; _rotEntry = new DsROTEntry((IFilterGraph)_graphBuilder); _vmr9 = VMR9Util.g_vmr9 = new VMR9Util(); bool AddVMR9 = VMR9Util.g_vmr9.AddVMR9(_graphBuilder); if (!AddVMR9) { Log.Error("DVDPlayer9:Failed to add VMR9 to graph"); return false; } VMR9Util.g_vmr9.Enable(false); try { Log.Info("DVDPlayer9:Add {0}", dvdDNavigator); _dvdbasefilter = DirectShowUtil.AddFilterToGraph(_graphBuilder, dvdDNavigator); if (_dvdbasefilter != null) { AddPreferedCodecs(_graphBuilder); _dvdCtrl = (IDvdControl2)_dvdbasefilter; if (_dvdCtrl != null) { _dvdInfo = (IDvdInfo2)_dvdbasefilter; if (!String.IsNullOrEmpty(path)) { hr = _dvdCtrl.SetDVDDirectory(path); DsError.ThrowExceptionForHR(hr); } _dvdCtrl.SetOption(DvdOptionFlag.HMSFTimeCodeEvents, true); // use new HMSF timecode format _dvdCtrl.SetOption(DvdOptionFlag.ResetOnStop, false); DirectShowUtil.RenderGraphBuilderOutputPins(_graphBuilder, _dvdbasefilter); _freeNavigator = false; } } } catch (Exception ex) { Log.Error("DVDPlayer9:Add {0} as navigator failed: {1}", dvdDNavigator, ex.Message); } if (_dvdInfo == null) { Log.Info("Dvdplayer9:Volume rendered, get interfaces"); hr = _dvdGraph.GetDvdInterface(typeof (IDvdInfo2).GUID, out comobj); DsError.ThrowExceptionForHR(hr); _dvdInfo = (IDvdInfo2)comobj; comobj = null; } if (_dvdCtrl == null) { Log.Info("Dvdplayer9:Get IDvdControl2"); hr = _dvdGraph.GetDvdInterface(typeof (IDvdControl2).GUID, out comobj); DsError.ThrowExceptionForHR(hr); _dvdCtrl = (IDvdControl2)comobj; comobj = null; if (_dvdCtrl != null) { Log.Info("Dvdplayer9:Get IDvdControl2"); } else { Log.Error("Dvdplayer9:Failed to get IDvdControl2"); } } // disable Closed Captions! IBaseFilter basefilter; _graphBuilder.FindFilterByName("Line 21 Decoder", out basefilter); if (basefilter == null) { _graphBuilder.FindFilterByName("Line21 Decoder", out basefilter); } if (basefilter == null) { _graphBuilder.FindFilterByName("Line 21 Decoder 2", out basefilter); } if (basefilter != null) { Log.Info("Dvdplayer9: Line21 Decoder (Closed Captions), in use: {0}", showClosedCaptions); _line21Decoder = (IAMLine21Decoder)basefilter; if (_line21Decoder != null) { AMLine21CCState state = showClosedCaptions ? AMLine21CCState.On : AMLine21CCState.Off; hr = _line21Decoder.SetServiceState(state); if (hr == 0) { Log.Info("DVDPlayer9: Closed Captions state change successful"); } else { Log.Info("DVDPlayer9: Failed to change Closed Captions state"); } } } if (!VMR9Util.g_vmr9.IsVMR9Connected) { Log.Info("DVDPlayer9:Failed vmr9 not connected"); _mediaCtrl = null; Cleanup(); return false; } #region PostProcessingEngine Detection IPostProcessingEngine postengine = PostProcessingEngine.GetInstance(true); if (!postengine.LoadPostProcessing(_graphBuilder)) { PostProcessingEngine.engine = new PostProcessingEngine.DummyEngine(); } #endregion _mediaCtrl = (IMediaControl)_graphBuilder; _mediaEvt = (IMediaEventEx)_graphBuilder; _basicAudio = (IBasicAudio)_graphBuilder; _mediaPos = (IMediaPosition)_graphBuilder; _basicVideo = (IBasicVideo2)_graphBuilder; _videoWidth = VMR9Util.g_vmr9.VideoWidth; _videoHeight = VMR9Util.g_vmr9.VideoHeight; DirectShowUtil.SetARMode(_graphBuilder, arMode); VMR9Util.g_vmr9.SetDeinterlaceMode(); VMR9Util.g_vmr9.Enable(true); Log.Info("Dvdplayer9:Graph created"); _started = true; return true; } catch (Exception ex) { Log.Error("DvdPlayer9:Exception while creating DShow graph {0} {1}", ex.Message, ex.StackTrace); CloseInterfaces(); return false; } }
/// <summary> create the used COM components and get the interfaces. </summary> protected override bool GetInterfaces(string filename) { Log.Info("TSReaderPlayer: GetInterfaces()"); try { string strAudioRenderer = ""; int intFilters = 0; // FlipGer: count custom filters string strFilters = ""; // FlipGer: collect custom filters LoadMyTvFilterSettings(ref intFilters, ref strFilters, ref strVideoCodec, ref strAudioCodec, ref strAACAudioCodec, ref strDDPLUSAudioCodec, ref strH264VideoCodec, ref strAudioRenderer, ref enableDVBBitmapSubtitles, ref enableDVBTtxtSubtitles, ref relaxTsReader); _graphBuilder = (IGraphBuilder) new FilterGraph(); _rotEntry = new DsROTEntry((IFilterGraph)_graphBuilder); if (strAudioRenderer.Length > 0) //audio renderer must be in graph before audio switcher { _audioRendererFilter = DirectShowUtil.AddAudioRendererToGraph(_graphBuilder, strAudioRenderer, true); } #region add AudioSwitcher if (enableMPAudioSwitcher) //audio switcher must be in graph before tsreader audiochangecallback { _audioSwitcherFilter = DirectShowUtil.AddFilterToGraph(_graphBuilder, "MediaPortal AudioSwitcher"); if (_audioSwitcherFilter == null) { Log.Error("TSReaderPlayer: Failed to add AudioSwitcher to graph"); } } #endregion #region add TsReader TsReader reader = new TsReader(); _fileSource = (IBaseFilter)reader; _ireader = (ITSReader)reader; _interfaceTSReader = _fileSource; _ireader.SetRelaxedMode(relaxTsReader); // enable/disable continousity filtering _ireader.SetTsReaderCallback(this); _ireader.SetRequestAudioChangeCallback(this); Log.Info("TSReaderPlayer: Add TsReader to graph"); int hr = _graphBuilder.AddFilter((IBaseFilter)_fileSource, "TsReader"); DsError.ThrowExceptionForHR(hr); #endregion #region load file in TsReader IFileSourceFilter interfaceFile = (IFileSourceFilter)_fileSource; if (interfaceFile == null) { Log.Error("TSReaderPlayer: Failed to get IFileSourceFilter"); Cleanup(); return(false); } Log.Info("TSReaderPlayer: Open file: {0}", filename); hr = interfaceFile.Load(filename, null); if (hr != 0) { Log.Error("TSReaderPlayer: Failed to open file:{0} :0x{1:x}", filename, hr); Cleanup(); return(false); } #endregion #region add codecs Log.Info("TSReaderPlayer: Add codecs"); // add preferred video & audio codecs MatchFilters("Video"); MatchFilters("Audio"); // does .ts file contain video? // default is _isRadio=false which prevents recorded radio file playing if (!_videoFormat.IsValid) { _isRadio = true; } if (!_isRadio) { _vmr9 = new VMR9Util(); _vmr9.AddVMR9(_graphBuilder); _vmr9.Enable(false); DirectShowUtil.AddFilterToGraph(_graphBuilder, videoFilter); if (enableDVBBitmapSubtitles) { try { SubtitleRenderer.GetInstance().AddSubtitleFilter(_graphBuilder); } catch (Exception e) { Log.Error(e); } } } DirectShowUtil.AddFilterToGraph(_graphBuilder, audioFilter); // FlipGer: add custom filters to graph string[] arrFilters = strFilters.Split(';'); for (int i = 0; i < intFilters; i++) { DirectShowUtil.AddFilterToGraph(_graphBuilder, arrFilters[i]); } #endregion #region PostProcessingEngine Detection IPostProcessingEngine postengine = PostProcessingEngine.GetInstance(true); if (!postengine.LoadPostProcessing(_graphBuilder)) { PostProcessingEngine.engine = new PostProcessingEngine.DummyEngine(); } #endregion #region render TsReader output pins Log.Info("TSReaderPlayer: Render TsReader outputs"); if (_isRadio) { IEnumPins enumPins; hr = _fileSource.EnumPins(out enumPins); DsError.ThrowExceptionForHR(hr); IPin[] pins = new IPin[1]; int fetched = 0; while (enumPins.Next(1, pins, out fetched) == 0) { if (fetched != 1) { break; } PinDirection direction; pins[0].QueryDirection(out direction); if (direction == PinDirection.Output) { IEnumMediaTypes enumMediaTypes; pins[0].EnumMediaTypes(out enumMediaTypes); AMMediaType[] mediaTypes = new AMMediaType[20]; int fetchedTypes; enumMediaTypes.Next(20, mediaTypes, out fetchedTypes); for (int i = 0; i < fetchedTypes; ++i) { if (mediaTypes[i].majorType == MediaType.Audio) { hr = _graphBuilder.Render(pins[0]); DsError.ThrowExceptionForHR(hr); break; } } } DirectShowUtil.ReleaseComObject(pins[0]); } DirectShowUtil.ReleaseComObject(enumPins); } else { DirectShowUtil.RenderGraphBuilderOutputPins(_graphBuilder, _fileSource); } DirectShowUtil.RemoveUnusedFiltersFromGraph(_graphBuilder); #endregion _mediaCtrl = (IMediaControl)_graphBuilder; _mediaEvt = (IMediaEventEx)_graphBuilder; _mediaSeeking = (IMediaSeeking)_graphBuilder; if (_mediaSeeking == null) { Log.Error("TSReaderPlayer: Unable to get IMediaSeeking interface"); } _audioStream = (IAudioStream)_fileSource; if (_audioStream == null) { Log.Error("TSReaderPlayer: Unable to get IAudioStream interface"); } _audioSelector = new AudioSelector(_audioStream); if (!_isRadio) { if (enableDVBTtxtSubtitles || enableDVBBitmapSubtitles) { try { SubtitleRenderer.GetInstance().SetPlayer(this); _dvbSubRenderer = SubtitleRenderer.GetInstance(); } catch (Exception e) { Log.Error(e); } } if (enableDVBBitmapSubtitles) { _subtitleStream = (ISubtitleStream)_fileSource; if (_subtitleStream == null) { Log.Error("TSReaderPlayer: Unable to get ISubtitleStream interface"); } } if (enableDVBTtxtSubtitles) { //Log.Debug("TSReaderPlayer: Obtaining TeletextSource"); _teletextSource = (ITeletextSource)_fileSource; if (_teletextSource == null) { Log.Error("TSReaderPlayer: Unable to get ITeletextSource interface"); } Log.Debug("TSReaderPlayer: Creating Teletext Receiver"); TeletextSubtitleDecoder ttxtDecoder = new TeletextSubtitleDecoder(_dvbSubRenderer); _ttxtReceiver = new TeletextReceiver(_teletextSource, ttxtDecoder); // regardless of whether dvb subs are enabled, the following call is okay // if _subtitleStream is null the subtitle will just not setup for bitmap subs _subSelector = new SubtitleSelector(_subtitleStream, _dvbSubRenderer, ttxtDecoder); } else if (enableDVBBitmapSubtitles) { // if only dvb subs are enabled, pass null for ttxtDecoder _subSelector = new SubtitleSelector(_subtitleStream, _dvbSubRenderer, null); } } if (_audioRendererFilter != null) { //Log.Info("TSReaderPlayer:set reference clock"); IMediaFilter mp = (IMediaFilter)_graphBuilder; IReferenceClock clock = (IReferenceClock)_audioRendererFilter; hr = mp.SetSyncSource(null); hr = mp.SetSyncSource(clock); //Log.Info("TSReaderPlayer:set reference clock:{0:X}", hr); _basicAudio = (IBasicAudio)_graphBuilder; } if (!_isRadio) { IBaseFilter basefilter; _graphBuilder.FindFilterByName("Line 21 Decoder", out basefilter); if (basefilter == null) { _graphBuilder.FindFilterByName("Line21 Decoder", out basefilter); } if (basefilter == null) { _graphBuilder.FindFilterByName("Line 21 Decoder 2", out basefilter); } if (basefilter != null) { Log.Info("TSreaderPlayer: Line21 Decoder (Closed Captions), in use"); //: {0}", showClosedCaptions); _line21Decoder = (IAMLine21Decoder)basefilter; if (_line21Decoder != null) { AMLine21CCState state = AMLine21CCState.Off; hr = _line21Decoder.SetServiceState(state); if (hr == 0) { Log.Info("TSReaderPlayer: Closed Captions state change successful"); } else { Log.Info("TSReaderPlayer: Failed to change Closed Captions state"); } } } if (!_vmr9.IsVMR9Connected) { Log.Error("TSReaderPlayer: Failed vmr9 not connected"); Cleanup(); return(false); } DirectShowUtil.EnableDeInterlace(_graphBuilder); _vmr9.SetDeinterlaceMode(); } using (MPSettings xmlreader = new MPSettings()) { int lastSubIndex = xmlreader.GetValueAsInt("tvservice", "lastsubtitleindex", 0); Log.Debug("TSReaderPlayer: Last subtitle index: {0}", lastSubIndex); CurrentSubtitleStream = lastSubIndex; } return(true); } catch (Exception ex) { Log.Error("TSReaderPlayer: Exception while creating DShow graph {0}", ex.Message); Cleanup(); return(false); } }
/// <summary> create the used COM components and get the interfaces. </summary> protected override bool GetInterfaces(string filename) { Log.Info("TSReaderPlayer: GetInterfaces()"); try { _graphBuilder = (IGraphBuilder)new FilterGraphNoThread(); _rotEntry = new DsROTEntry((IFilterGraph)_graphBuilder); //Get filterCodecName and filterConfig filterConfig = GetFilterConfiguration(); filterCodec = GetFilterCodec(); #region add AudioRenderer //Add Audio Renderer AudioRendererAdd(); #endregion #region add AudioSwitcher MPAudioSwitcherAdd(); #endregion #region add TsReader TsReader reader = new TsReader(); _fileSource = (IBaseFilter)reader; _ireader = (ITSReader)reader; _interfaceTSReader = _fileSource; if (filterConfig != null) _ireader.SetRelaxedMode(filterConfig.relaxTsReader); // enable/disable continousity filtering _ireader.SetTsReaderCallback(this); _ireader.SetRequestAudioChangeCallback(this); Log.Info("TSReaderPlayer: Add TsReader to graph"); int hr = _graphBuilder.AddFilter((IBaseFilter)_fileSource, "TsReader"); DsError.ThrowExceptionForHR(hr); #endregion #region load file in TsReader IFileSourceFilter interfaceFile = (IFileSourceFilter)_fileSource; if (interfaceFile == null) { Log.Error("TSReaderPlayer: Failed to get IFileSourceFilter"); Cleanup(); return false; } Log.Info("TSReaderPlayer: Open file: {0}", filename); hr = interfaceFile.Load(filename, null); if (hr != 0) { Log.Error("TSReaderPlayer: Failed to open file:{0} :0x{1:x}", filename, hr); Cleanup(); return false; } #endregion #region add codecs Log.Info("TSReaderPlayer: Add codecs"); // does .ts file contain video? // default is _isRadio=false which prevents recorded radio file playing if (!_videoFormat.IsValid && g_Player.AudioStreams == 1) { Log.Debug("TSReaderPlayer: Stream is Radio"); _isRadio = true; } if (!_isRadio) { if (_videoFormat.IsValid) { _vmr9 = VMR9Util.g_vmr9 = new VMR9Util(); bool AddVMR9 = VMR9Util.g_vmr9.AddVMR9(_graphBuilder); if (!AddVMR9) { Log.Error("TSReaderPlayer:Failed to add VMR9 to graph"); return false; } VMR9Util.g_vmr9.Enable(false); } // Add preferred video filters UpdateFilters("Video"); Log.Debug("TSReaderPlayer: UpdateFilters Video done"); if (filterConfig != null && filterConfig.enableDVBBitmapSubtitles) { try { SubtitleRenderer.GetInstance().AddSubtitleFilter(_graphBuilder); Log.Debug("TSReaderPlayer: SubtitleRenderer AddSubtitleFilter"); } catch (Exception e) { Log.Error(e); } } } // Add preferred audio filters UpdateFilters("Audio"); Log.Debug("TSReaderPlayer: UpdateFilters Audio done"); #endregion #region PostProcessingEngine Detection IPostProcessingEngine postengine = PostProcessingEngine.GetInstance(true); if (!postengine.LoadPostProcessing(_graphBuilder)) { PostProcessingEngine.engine = new PostProcessingEngine.DummyEngine(); Log.Debug("TSReaderPlayer: PostProcessingEngine to DummyEngine"); } #endregion #region render TsReader output pins Log.Info("TSReaderPlayer: Render TsReader outputs"); if (_isRadio && g_Player.AudioStreams == 1) { IEnumPins enumPins; hr = _fileSource.EnumPins(out enumPins); DsError.ThrowExceptionForHR(hr); IPin[] pins = new IPin[1]; int fetched = 0; while (enumPins.Next(1, pins, out fetched) == 0) { if (fetched != 1) { break; } PinDirection direction; pins[0].QueryDirection(out direction); if (direction == PinDirection.Output) { IEnumMediaTypes enumMediaTypes; pins[0].EnumMediaTypes(out enumMediaTypes); AMMediaType[] mediaTypes = new AMMediaType[20]; int fetchedTypes; enumMediaTypes.Next(20, mediaTypes, out fetchedTypes); for (int i = 0; i < fetchedTypes; ++i) { if (mediaTypes[i].majorType == MediaType.Audio) { hr = _graphBuilder.Render(pins[0]); DsError.ThrowExceptionForHR(hr); break; } } } DirectShowUtil.ReleaseComObject(pins[0]); } DirectShowUtil.ReleaseComObject(enumPins); } else { DirectShowUtil.RenderGraphBuilderOutputPins(_graphBuilder, _fileSource); if (filterConfig != null && !filterConfig.enableCCSubtitles) { CleanupCC(); Log.Debug("TSReaderPlayer: CleanupCC filter (Tv/Recorded Stream Detected)"); } } DirectShowUtil.RemoveUnusedFiltersFromGraph(_graphBuilder); #endregion _mediaCtrl = (IMediaControl)_graphBuilder; _mediaEvt = (IMediaEventEx)_graphBuilder; _mediaSeeking = (IMediaSeeking)_graphBuilder; if (_mediaSeeking == null) { Log.Error("TSReaderPlayer: Unable to get IMediaSeeking interface"); } _audioStream = (IAudioStream)_fileSource; if (_audioStream == null) { Log.Error("TSReaderPlayer: Unable to get IAudioStream interface"); } _audioSelector = new AudioSelector(_audioStream); if (!_isRadio) { if (filterConfig != null && (filterConfig != null && filterConfig.enableDVBTtxtSubtitles || filterConfig.enableDVBBitmapSubtitles)) { try { SubtitleRenderer.GetInstance().SetPlayer(this); _dvbSubRenderer = SubtitleRenderer.GetInstance(); } catch (Exception e) { Log.Error(e); } } if (filterConfig != null && filterConfig.enableDVBBitmapSubtitles) { _subtitleStream = (ISubtitleStream)_fileSource; if (_subtitleStream == null) { Log.Error("TSReaderPlayer: Unable to get ISubtitleStream interface"); } } if (filterConfig != null && filterConfig.enableDVBTtxtSubtitles) { //Log.Debug("TSReaderPlayer: Obtaining TeletextSource"); _teletextSource = (ITeletextSource)_fileSource; if (_teletextSource == null) { Log.Error("TSReaderPlayer: Unable to get ITeletextSource interface"); } Log.Debug("TSReaderPlayer: Creating Teletext Receiver"); try { using (MPSettings xmlreader = new MPSettings()) xmlreader.SetValue("tvservice", "dvbdefttxtsubtitles", "999;999"); } catch { } TeletextSubtitleDecoder ttxtDecoder = new TeletextSubtitleDecoder(_dvbSubRenderer); _ttxtReceiver = new TeletextReceiver(_teletextSource, ttxtDecoder); // regardless of whether dvb subs are enabled, the following call is okay // if _subtitleStream is null the subtitle will just not setup for bitmap subs _subSelector = new SubtitleSelector(_subtitleStream, _dvbSubRenderer, ttxtDecoder); } else if (filterConfig != null && filterConfig.enableDVBBitmapSubtitles) { // if only dvb subs are enabled, pass null for ttxtDecoder _subSelector = new SubtitleSelector(_subtitleStream, _dvbSubRenderer, null); } } if (filterCodec._audioRendererFilter != null) { //Log.Info("TSReaderPlayer:set reference clock"); /*IMediaFilter mp = (IMediaFilter)_graphBuilder; IReferenceClock clock = (IReferenceClock)filterCodec._audioRendererFilter; hr = mp.SetSyncSource(null); hr = mp.SetSyncSource(clock);*/ //Log.Info("TSReaderPlayer:set reference clock:{0:X}", hr); SyncAudioRenderer(); _basicAudio = (IBasicAudio)_graphBuilder; } if (!_isRadio) { if (VMR9Util.g_vmr9 != null && filterConfig != null && filterConfig.enableCCSubtitles) { CleanupCC(); ReleaseCC(); ReleaseCC2(); CoreCCParserCheck(); DirectShowUtil.RenderUnconnectedOutputPins(_graphBuilder, filterCodec.VideoCodec); Log.Debug("TSReaderPlayer: Render VideoCodec filter (Tv/Recorded Stream Detected)"); EnableCC(); Log.Debug("TSReaderPlayer: EnableCC"); if (CoreCCPresent) { DirectShowUtil.RenderUnconnectedOutputPins(_graphBuilder, filterCodec.CoreCCParser); Log.Debug("TSReaderPlayer: Render CoreCCParser filter (Tv/Recorded Stream Detected)"); EnableCC2(); Log.Debug("TSReaderPlayer: EnableCC2"); } } if (VMR9Util.g_vmr9 != null && !VMR9Util.g_vmr9.IsVMR9Connected) { Log.Error("TSReaderPlayer: Failed vmr9 not connected"); Cleanup(); return false; } DirectShowUtil.EnableDeInterlace(_graphBuilder); if (VMR9Util.g_vmr9 != null) { VMR9Util.g_vmr9.SetDeinterlaceMode(); } } using (MPSettings xmlreader = new MPSettings()) { if (filterConfig.autoShowSubWhenTvStarts && SupportsCC && CurrentSubtitleStream == 0) { CurrentSubtitleStream = -1; } else { int lastSubIndex = xmlreader.GetValueAsInt("tvservice", "lastsubtitleindex", 0); Log.Debug("TSReaderPlayer: Last subtitle index: {0}", lastSubIndex); CurrentSubtitleStream = lastSubIndex; } } if (filterConfig != null && !filterConfig.autoShowSubWhenTvStarts) { Log.Debug("TSReaderPlayer: Automatically show subtitles when TV starts is set to {0}", filterConfig.autoShowSubWhenTvStarts); EnableSubtitle = filterConfig.autoShowSubWhenTvStarts; } return true; } catch (Exception ex) { Log.Error("TSReaderPlayer: Exception while creating DShow graph {0}", ex.Message); Cleanup(); return false; } }
private void Cleanup() { if (_graphBuilder == null) { return; } int hr; using (Settings xmlreader = new MPSettings()) { int codecValue = 0; string codecType = ""; codecType = xmlreader.GetValueAsString("dvdplayer", "videocodec", ""); if (codecType == "InterVideo Video Decoder") { codecValue = xmlreader.GetValueAsInt("videocodec", "intervideo", 1); Log.Info("DVDPlayer9:Resetting InterVideo DXVA to {0}", codecValue); using ( RegistryKey subkey = Registry.CurrentUser.CreateSubKey(@"Software\InterVideo\Common\VideoDec\MediaPortal")) { subkey.SetValue("DXVA", codecValue); } } if (codecType.StartsWith("CyberLink Video/SP Decoder")) { codecValue = xmlreader.GetValueAsInt("videocodec", "cyberlink", 1); Log.Info("DVDPlayer9:Resetting CyberLink DXVA to {0}", codecValue); using (RegistryKey subkey = Registry.CurrentUser.CreateSubKey(@"Software\Cyberlink\Common\CLVSD\MediaPortal")) { subkey.SetValue("UIUseHVA", codecValue); } } if (codecType == "NVIDIA Video Decoder") { codecValue = xmlreader.GetValueAsInt("videocodec", "nvidia", 1); Log.Info("DVDPlayer9:Resetting NVIDIA DXVA to {0}", codecValue); using (RegistryKey subkey = Registry.LocalMachine.CreateSubKey(@"Software\NVIDIA Corporation\Filters\Video")) { subkey.SetValue("EnableDXVA", codecValue); } } } try { Log.Info("DVDPlayer9: cleanup DShow graph"); if (_mediaCtrl != null) { int counter = 0; FilterState state; hr = _mediaCtrl.Stop(); hr = _mediaCtrl.GetState(10, out state); while (state != FilterState.Stopped || GUIGraphicsContext.InVmr9Render) { System.Threading.Thread.Sleep(100); hr = _mediaCtrl.GetState(10, out state); counter++; if (counter >= 30) { if (state != FilterState.Stopped) Log.Debug("DVDPlayer9: graph still running"); if (GUIGraphicsContext.InVmr9Render) Log.Debug("DVDPlayer9: in renderer"); break; } } _mediaCtrl = null; } _state = PlayState.Stopped; VMR9Util.g_vmr9.EVRSetDVDMenuState(false); if (_vmr9 != null) { _vmr9.Enable(false); } _visible = false; _mediaEvt = null; _dvdCtrl = null; _dvdInfo = null; _basicVideo = null; _basicAudio = null; _mediaPos = null; _videoWin = null; _pendingCmd = false; if (_cmdOption != null) { DirectShowUtil.ReleaseComObject(_cmdOption); _cmdOption = null; } if (_dvdbasefilter != null) { while ((hr = DirectShowUtil.ReleaseComObject(_dvdbasefilter)) > 0) ; _dvdbasefilter = null; } if (_dvdGraph != null) { while ((hr = DirectShowUtil.ReleaseComObject(_dvdGraph)) > 0) ; _dvdGraph = null; } if (_line21Decoder != null) { while ((hr = DirectShowUtil.ReleaseComObject(_line21Decoder)) > 0) ; _line21Decoder = null; } if (_graphBuilder != null) { DirectShowUtil.RemoveFilters(_graphBuilder); // _rotEntry has a reference to _graphBuilder (see _rotEntry ctor) // so, release of _rotEntry must be before _graphBuilder is released if (_rotEntry != null) { _rotEntry.SafeDispose(); _rotEntry = null; } while ((hr = DirectShowUtil.ReleaseComObject(_graphBuilder)) > 0) ; _graphBuilder = null; } if (_vmr9 != null) { _vmr9.SafeDispose(); _vmr9 = null; } _state = PlayState.Init; GUIGraphicsContext.form.Invalidate(true); //GUIGraphicsContext.form.Activate(); } catch (Exception ex) { Log.Error("DVDPlayer9: Exception while cleanuping DShow graph - {0} {1}", ex.Message, ex.StackTrace); } Log.Info("DVDPlayer9: Disabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 0, 0, null); GUIWindowManager.SendMessage(msg); }
/// <summary> /// If the url to be played can be buffered before starting playback, this function /// starts building a graph by adding the preferred video and audio render to it. /// This needs to be called on the MpMain Thread. /// </summary> /// <returns>true, if the url can be buffered (a graph was started), false if it can't be and null if an error occured building the graph</returns> public bool? PrepareGraph() { Uri uri = new Uri(CurrentFile); string sourceFilterName = uri.Scheme == "http" ? httpSourceFilterName : (uri.Scheme == "mms" || CurrentFile.ToLower().Contains(".asf")) ? "WM ASF Reader" : string.Empty; if (!string.IsNullOrEmpty(sourceFilterName)) { graphBuilder = (IGraphBuilder)new FilterGraph(); _rotEntry = new DsROTEntry((IFilterGraph)graphBuilder); Vmr9 = new VMR9Util(); Vmr9.AddVMR9(graphBuilder); Vmr9.Enable(false); // set VMR9 back to NOT Active -> otherwise GUI is not refreshed while graph is building GUIGraphicsContext.Vmr9Active = false; // add the audio renderer using (Settings settings = new MPSettings()) { string audiorenderer = settings.GetValueAsString("movieplayer", "audiorenderer", "Default DirectSound Device"); DirectShowUtil.AddAudioRendererToGraph(graphBuilder, audiorenderer, false); } // set fields for playback mediaCtrl = (IMediaControl)graphBuilder; mediaEvt = (IMediaEventEx)graphBuilder; mediaSeek = (IMediaSeeking)graphBuilder; mediaPos = (IMediaPosition)graphBuilder; basicAudio = (IBasicAudio)graphBuilder; videoWin = (IVideoWindow)graphBuilder; // add the source filter IBaseFilter sourceFilter = null; try { sourceFilter = DirectShowUtil.AddFilterToGraph(graphBuilder, sourceFilterName); } catch (Exception ex) { Log.Warn("Error adding '{0}' filter to graph: {1}", sourceFilterName, ex.Message); return null; } finally { if (sourceFilter != null) DirectShowUtil.ReleaseComObject(sourceFilter, 2000); } return true; } else { return false; } }
/// <summary> do cleanup and release DirectShow. </summary> protected void CloseInterfaces() { if (_graphBuilder == null) { return; } int hr; Log.Debug("BDPlayer: Cleanup DShow graph {0}", GUIGraphicsContext.InVmr9Render); try { BDOSDRenderer.Release(); if (_mediaCtrl != null) { int counter = 0; FilterState state; hr = _mediaCtrl.Stop(); hr = _mediaCtrl.GetState(10, out state); while (state != FilterState.Stopped || GUIGraphicsContext.InVmr9Render) { Thread.Sleep(100); hr = _mediaCtrl.GetState(10, out state); counter++; if (counter >= 30) { if (state != FilterState.Stopped) Log.Error("BDPlayer: graph still running"); if (GUIGraphicsContext.InVmr9Render) Log.Error("BDPlayer: in renderer"); break; } } _mediaCtrl = null; } if (_vmr9 != null) { _vmr9.Enable(false); } if (_mediaEvt != null) { hr = _mediaEvt.SetNotifyWindow(IntPtr.Zero, WM_GRAPHNOTIFY, IntPtr.Zero); _mediaEvt = null; } _videoWin = _graphBuilder as IVideoWindow; if (_videoWin != null) { hr = _videoWin.put_Visible(OABool.False); hr = _videoWin.put_Owner(IntPtr.Zero); _videoWin = null; } _mediaSeeking = null; _basicAudio = null; _basicVideo = null; _ireader = null; #region Cleanup Sebastiii if (VideoCodec != null) { DirectShowUtil.ReleaseComObject(VideoCodec, 5000); VideoCodec = null; Log.Info("BDPlayer: Cleanup VideoCodec"); } if (AudioCodec != null) { DirectShowUtil.ReleaseComObject(AudioCodec, 5000); AudioCodec = null; Log.Info("BDPlayer: Cleanup AudioCodec"); } if (_audioRendererFilter != null) { while (DirectShowUtil.ReleaseComObject(_audioRendererFilter) > 0) ; _audioRendererFilter = null; Log.Info("BDPlayer: Cleanup AudioRenderer"); } //Test to ReleaseComObject from PostProcessFilter list objects. if (PostProcessFilterVideo.Count > 0) { foreach (var ppFilter in PostProcessFilterVideo) { if (ppFilter.Value != null) DirectShowUtil.ReleaseComObject(ppFilter.Value, 5000); } PostProcessFilterVideo.Clear(); Log.Info("BDPlayer: Cleanup PostProcessVideo"); } //Test to ReleaseComObject from PostProcessFilter list objects. if (PostProcessFilterAudio.Count > 0) { foreach (var ppFilter in PostProcessFilterAudio) { if (ppFilter.Value != null) DirectShowUtil.ReleaseComObject(ppFilter.Value, 5000); } PostProcessFilterAudio.Clear(); Log.Info("BDPlayer: Cleanup PostProcessAudio"); } #endregion if (_interfaceBDReader != null) { DirectShowUtil.ReleaseComObject(_interfaceBDReader, 5000); _interfaceBDReader = null; } if (_graphBuilder != null) { DirectShowUtil.RemoveFilters(_graphBuilder); if (_rotEntry != null) { _rotEntry.SafeDispose(); _rotEntry = null; } while ((hr = DirectShowUtil.ReleaseComObject(_graphBuilder)) > 0) ; _graphBuilder = null; } if (_dvbSubRenderer != null) { _dvbSubRenderer.SetPlayer(null); _dvbSubRenderer = null; } if (_vmr9 != null) { _vmr9.SafeDispose(); _vmr9 = null; } GUIGraphicsContext.form.Invalidate(true); _state = PlayState.Init; } catch (Exception ex) { Log.Error("BDPlayer: Exception while cleaning DShow graph - {0} {1}", ex.Message, ex.StackTrace); } //switch back to directx windowed mode ExclusiveMode(false); }
private void Cleanup() { if (_graphBuilder == null) { Log.Info("StreamBufferPlayer9:grapbuilder=null"); return; } int hr; Log.Info("StreamBufferPlayer9:cleanup DShow graph {0}", GUIGraphicsContext.InVmr9Render); try { if (_mediaCtrl != null) { int counter = 0; FilterState state; hr = _mediaCtrl.Stop(); hr = _mediaCtrl.GetState(10, out state); while (state != FilterState.Stopped || GUIGraphicsContext.InVmr9Render) { System.Threading.Thread.Sleep(100); hr = _mediaCtrl.GetState(10, out state); counter++; if (counter >= 30) { if (state != FilterState.Stopped) { Log.Debug("StreamBufferPlayer9: graph still running"); } if (GUIGraphicsContext.InVmr9Render) { Log.Debug("StreamBufferPlayer9: in renderer"); } break; } } _mediaCtrl = null; } if (_vmr9 != null) { Log.Info("StreamBufferPlayer9: vmr9 disable"); _vmr9.Enable(false); } _mediaEvt = null; _mediaSeeking = null; _mediaSeeking2 = null; _videoWin = null; _basicAudio = null; _basicVideo = null; _bufferSource = null; _pinVmr9ConnectedTo = null; if (_pinVmr9ConnectedTo != null) { DirectShowUtil.ReleaseComObject(_pinVmr9ConnectedTo); _pinVmr9ConnectedTo = null; } if (streamConfig2 != null) { while ((hr = DirectShowUtil.ReleaseComObject(streamConfig2)) > 0) { ; } streamConfig2 = null; } m_StreamBufferConfig = null; if (_vmr9 != null) { Log.Info("StreamBufferPlayer9: vmr9 dispose"); _vmr9.SafeDispose(); _vmr9 = null; } if (_graphBuilder != null) { DirectShowUtil.RemoveFilters(_graphBuilder); if (_rotEntry != null) { _rotEntry.SafeDispose(); _rotEntry = null; } while ((hr = DirectShowUtil.ReleaseComObject(_graphBuilder)) > 0) { ; } _graphBuilder = null; } GUIGraphicsContext.form.Invalidate(true); _state = PlayState.Init; } catch (Exception ex) { Log.Error("StreamBufferPlayer9: Exception while cleaning DShow graph - {0} {1}", ex.Message, ex.StackTrace); } //switch back to directx windowed mode Log.Info("StreamBufferPlayer9: Disabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 0, 0, null); GUIWindowManager.SendMessage(msg); Log.Info("StreamBufferPlayer9: Cleanup done"); }
/// <summary> create the used COM components and get the interfaces. </summary> protected bool GetInterfaces() { VMR9Util.g_vmr9 = null; if (IsRadio == false) { Vmr9 = VMR9Util.g_vmr9 = new VMR9Util(); // switch back to directx fullscreen mode Log.Info("RTSPPlayer: Enabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 1, 0, null); GUIWindowManager.SendMessage(msg); } //Type comtype = null; //object comobj = null; DsRect rect = new DsRect(); rect.top = 0; rect.bottom = GUIGraphicsContext.form.Height; rect.left = 0; rect.right = GUIGraphicsContext.form.Width; try { graphBuilder = (IGraphBuilder) new FilterGraph(); Log.Info("RTSPPlayer: add source filter"); if (IsRadio == false) { bool AddVMR9 = VMR9Util.g_vmr9 != null && VMR9Util.g_vmr9.AddVMR9(graphBuilder); if (!AddVMR9) { Log.Error("RTSPPlayer:Failed to add VMR9 to graph"); return(false); } VMR9Util.g_vmr9.Enable(false); } _mpegDemux = (IBaseFilter) new MPEG2Demultiplexer(); graphBuilder.AddFilter(_mpegDemux, "MPEG-2 Demultiplexer"); _rtspSource = (IBaseFilter) new RtpSourceFilter(); int hr = graphBuilder.AddFilter((IBaseFilter)_rtspSource, "RTSP Source Filter"); if (hr != 0) { Log.Error("RTSPPlayer:unable to add RTSP source filter:{0:X}", hr); return(false); } // add preferred video & audio codecs Log.Info("RTSPPlayer: add video/audio codecs"); string strVideoCodec = ""; string strAudioCodec = ""; string strAudiorenderer = ""; int intFilters = 0; // FlipGer: count custom filters string strFilters = ""; // FlipGer: collect custom filters string postProcessingFilterSection = "mytv"; using (Settings xmlreader = new MPSettings()) { if (_mediaType == g_Player.MediaType.Video) { strVideoCodec = xmlreader.GetValueAsString("movieplayer", "mpeg2videocodec", ""); strAudioCodec = xmlreader.GetValueAsString("movieplayer", "mpeg2audiocodec", ""); strAudiorenderer = xmlreader.GetValueAsString("movieplayer", "audiorenderer", "Default DirectSound Device"); postProcessingFilterSection = "movieplayer"; } else { strVideoCodec = xmlreader.GetValueAsString("mytv", "videocodec", ""); strAudioCodec = xmlreader.GetValueAsString("mytv", "audiocodec", ""); strAudiorenderer = xmlreader.GetValueAsString("mytv", "audiorenderer", "Default DirectSound Device"); postProcessingFilterSection = "mytv"; } enableDvbSubtitles = xmlreader.GetValueAsBool("tvservice", "dvbsubtitles", false); // FlipGer: load infos for custom filters int intCount = 0; while (xmlreader.GetValueAsString(postProcessingFilterSection, "filter" + intCount.ToString(), "undefined") != "undefined") { if (xmlreader.GetValueAsBool(postProcessingFilterSection, "usefilter" + intCount.ToString(), false)) { strFilters += xmlreader.GetValueAsString(postProcessingFilterSection, "filter" + intCount.ToString(), "undefined") + ";"; intFilters++; } intCount++; } } string extension = Path.GetExtension(m_strCurrentFile).ToLowerInvariant(); if (IsRadio == false) { if (strVideoCodec.Length > 0) { DirectShowUtil.AddFilterToGraph(graphBuilder, strVideoCodec); } } if (strAudioCodec.Length > 0) { DirectShowUtil.AddFilterToGraph(graphBuilder, strAudioCodec); } if (enableDvbSubtitles == true) { try { _subtitleFilter = SubtitleRenderer.GetInstance().AddSubtitleFilter(graphBuilder); SubtitleRenderer.GetInstance().SetPlayer(this); dvbSubRenderer = SubtitleRenderer.GetInstance(); } catch (Exception e) { Log.Error(e); } } Log.Debug("Is subtitle fitler null? {0}", (_subtitleFilter == null)); // FlipGer: add custom filters to graph string[] arrFilters = strFilters.Split(';'); for (int i = 0; i < intFilters; i++) { DirectShowUtil.AddFilterToGraph(graphBuilder, arrFilters[i]); } if (strAudiorenderer.Length > 0) { audioRendererFilter = DirectShowUtil.AddAudioRendererToGraph(graphBuilder, strAudiorenderer, false); } Log.Info("RTSPPlayer: load:{0}", m_strCurrentFile); IFileSourceFilter interfaceFile = (IFileSourceFilter)_rtspSource; if (interfaceFile == null) { Log.Error("RTSPPlayer:Failed to get IFileSourceFilter"); return(false); } //Log.Info("RTSPPlayer: open file:{0}",filename); hr = interfaceFile.Load(m_strCurrentFile, null); if (hr != 0) { Log.Error("RTSPPlayer:Failed to open file:{0} :0x{1:x}", m_strCurrentFile, hr); return(false); } #region connect rtspsource->demux Log.Info("RTSPPlayer:connect rtspsource->mpeg2 demux"); IPin pinTsOut = DsFindPin.ByDirection((IBaseFilter)_rtspSource, PinDirection.Output, 0); if (pinTsOut == null) { Log.Info("RTSPPlayer:failed to find output pin of tsfilesource"); return(false); } IPin pinDemuxIn = DsFindPin.ByDirection(_mpegDemux, PinDirection.Input, 0); if (pinDemuxIn == null) { Log.Info("RTSPPlayer:failed to find output pin of tsfilesource"); return(false); } hr = graphBuilder.Connect(pinTsOut, pinDemuxIn); if (hr != 0) { Log.Info("RTSPPlayer:failed to connect rtspsource->mpeg2 demux:{0:X}", hr); return(false); } DirectShowUtil.ReleaseComObject(pinTsOut); DirectShowUtil.ReleaseComObject(pinDemuxIn); #endregion #region render demux output pins if (IsRadio) { Log.Info("RTSPPlayer:render audio demux outputs"); IEnumPins enumPins; _mpegDemux.EnumPins(out enumPins); IPin[] pins = new IPin[2]; int fetched = 0; while (enumPins.Next(1, pins, out fetched) == 0) { if (fetched != 1) { break; } PinDirection direction; pins[0].QueryDirection(out direction); if (direction == PinDirection.Input) { continue; } IEnumMediaTypes enumMediaTypes; pins[0].EnumMediaTypes(out enumMediaTypes); AMMediaType[] mediaTypes = new AMMediaType[20]; int fetchedTypes; enumMediaTypes.Next(20, mediaTypes, out fetchedTypes); for (int i = 0; i < fetchedTypes; ++i) { if (mediaTypes[i].majorType == MediaType.Audio) { graphBuilder.Render(pins[0]); break; } } } } else { Log.Info("RTSPPlayer:render audio/video demux outputs"); IEnumPins enumPins; _mpegDemux.EnumPins(out enumPins); IPin[] pins = new IPin[2]; int fetched = 0; while (enumPins.Next(1, pins, out fetched) == 0) { if (fetched != 1) { break; } PinDirection direction; pins[0].QueryDirection(out direction); if (direction == PinDirection.Input) { continue; } graphBuilder.Render(pins[0]); } } #endregion // Connect DVB subtitle filter pins in the graph if (_mpegDemux != null && enableDvbSubtitles == true) { IMpeg2Demultiplexer demuxer = _mpegDemux as IMpeg2Demultiplexer; hr = demuxer.CreateOutputPin(GetTSMedia(), "Pcr", out _pinPcr); if (hr == 0) { Log.Info("RTSPPlayer:_pinPcr OK"); IPin pDemuxerPcr = DsFindPin.ByName(_mpegDemux, "Pcr"); IPin pSubtitlePcr = DsFindPin.ByName(_subtitleFilter, "Pcr"); hr = graphBuilder.Connect(pDemuxerPcr, pSubtitlePcr); } else { Log.Info("RTSPPlayer:Failed to create _pinPcr in demuxer:{0:X}", hr); } hr = demuxer.CreateOutputPin(GetTSMedia(), "Subtitle", out _pinSubtitle); if (hr == 0) { Log.Info("RTSPPlayer:_pinSubtitle OK"); IPin pDemuxerSubtitle = DsFindPin.ByName(_mpegDemux, "Subtitle"); IPin pSubtitle = DsFindPin.ByName(_subtitleFilter, "In"); hr = graphBuilder.Connect(pDemuxerSubtitle, pSubtitle); } else { Log.Info("RTSPPlayer:Failed to create _pinSubtitle in demuxer:{0:X}", hr); } hr = demuxer.CreateOutputPin(GetTSMedia(), "PMT", out _pinPMT); if (hr == 0) { Log.Info("RTSPPlayer:_pinPMT OK"); IPin pDemuxerSubtitle = DsFindPin.ByName(_mpegDemux, "PMT"); IPin pSubtitle = DsFindPin.ByName(_subtitleFilter, "PMT"); hr = graphBuilder.Connect(pDemuxerSubtitle, pSubtitle); } else { Log.Info("RTSPPlayer:Failed to create _pinPMT in demuxer:{0:X}", hr); } } if (IsRadio == false) { if (!VMR9Util.g_vmr9.IsVMR9Connected) { //VMR9 is not supported, switch to overlay Log.Info("RTSPPlayer: vmr9 not connected"); _mediaCtrl = null; Cleanup(); return(false); } VMR9Util.g_vmr9.SetDeinterlaceMode(); } _mediaCtrl = (IMediaControl)graphBuilder; mediaEvt = (IMediaEventEx)graphBuilder; _mediaSeeking = (IMediaSeeking)graphBuilder; mediaPos = (IMediaPosition)graphBuilder; basicAudio = graphBuilder as IBasicAudio; //DirectShowUtil.SetARMode(graphBuilder,AspectRatioMode.Stretched); DirectShowUtil.EnableDeInterlace(graphBuilder); if (VMR9Util.g_vmr9 != null) { m_iVideoWidth = VMR9Util.g_vmr9.VideoWidth; m_iVideoHeight = VMR9Util.g_vmr9.VideoHeight; } if (audioRendererFilter != null) { Log.Info("RTSPPlayer9:set reference clock"); IMediaFilter mp = graphBuilder as IMediaFilter; IReferenceClock clock = audioRendererFilter as IReferenceClock; hr = mp.SetSyncSource(null); hr = mp.SetSyncSource(clock); Log.Info("RTSPPlayer9:set reference clock:{0:X}", hr); } Log.Info("RTSPPlayer: graph build successfull"); return(true); } catch (Exception ex) { Error.SetError("Unable to play movie", "Unable build graph for VMR9"); Log.Error("RTSPPlayer:exception while creating DShow graph {0} {1}", ex.Message, ex.StackTrace); CloseInterfaces(); return(false); } }
/// <summary> create the used COM components and get the interfaces. </summary> protected override bool GetInterfaces() { try { graphBuilder = (IGraphBuilder) new FilterGraph(); _rotEntry = new DsROTEntry((IFilterGraph)graphBuilder); // add preferred video & audio codecs int hr; int intFilters = 0; // FlipGer: count custom filters string strVideoCodec = ""; string strH264VideoCodec = ""; string strAudioCodec = ""; string strAACAudioCodec = ""; string strAudiorenderer = ""; string strFilters = ""; // FlipGer: collect custom filters bool wmvAudio; bool autoloadSubtitles; bool bAutoDecoderSettings = false; using (Settings xmlreader = new MPSettings()) { bAutoDecoderSettings = xmlreader.GetValueAsBool("movieplayer", "autodecodersettings", false); strVideoCodec = xmlreader.GetValueAsString("movieplayer", "mpeg2videocodec", ""); strH264VideoCodec = xmlreader.GetValueAsString("movieplayer", "h264videocodec", ""); strAudioCodec = xmlreader.GetValueAsString("movieplayer", "mpeg2audiocodec", ""); strAACAudioCodec = xmlreader.GetValueAsString("movieplayer", "aacaudiocodec", ""); strAudiorenderer = xmlreader.GetValueAsString("movieplayer", "audiorenderer", "Default DirectSound Device"); wmvAudio = xmlreader.GetValueAsBool("movieplayer", "wmvaudio", false); autoloadSubtitles = xmlreader.GetValueAsBool("subtitles", "enabled", false); // FlipGer: load infos for custom filters int intCount = 0; while (xmlreader.GetValueAsString("movieplayer", "filter" + intCount.ToString(), "undefined") != "undefined") { if (xmlreader.GetValueAsBool("movieplayer", "usefilter" + intCount.ToString(), false)) { strFilters += xmlreader.GetValueAsString("movieplayer", "filter" + intCount.ToString(), "undefined") + ";"; intFilters++; } intCount++; } } if (bAutoDecoderSettings) { return(AutoRendering(wmvAudio)); } //Manually add codecs based on file extension if not in auto-settings // switch back to directx fullscreen mode Log.Info("VideoPlayerVMR9: Enabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 1, 0, null); GUIWindowManager.SendMessage(msg); // add the VMR9 in the graph // after enabeling exclusive mode, if done first it causes MediPortal to minimize if for example the "Windows key" is pressed while playing a video Vmr9 = new VMR9Util(); Vmr9.AddVMR9(graphBuilder); Vmr9.Enable(false); IBaseFilter source = null; graphBuilder.AddSourceFilter(m_strCurrentFile, null, out source); string extension = Path.GetExtension(m_strCurrentFile).ToLower(); switch (extension) { case ".wmv": case ".asf": { //strVideoCodec = "WMVideo Decoder DMO"; //allow e.g. ffdshow usage strH264VideoCodec = ""; strAudioCodec = "WMAudio Decoder DMO"; // multichannel audio needs this filter strAACAudioCodec = ""; break; } case ".mkv": case ".m2ts": case ".mp4": { strVideoCodec = ""; break; } default: strH264VideoCodec = ""; strAACAudioCodec = ""; break; } if (!string.IsNullOrEmpty(strVideoCodec)) { DirectShowUtil.AddFilterToGraph(graphBuilder, strVideoCodec); } if (!string.IsNullOrEmpty(strH264VideoCodec) && strVideoCodec != strH264VideoCodec) { DirectShowUtil.AddFilterToGraph(graphBuilder, strH264VideoCodec); } if (!string.IsNullOrEmpty(strAudioCodec)) { DirectShowUtil.AddFilterToGraph(graphBuilder, strAudioCodec); } if (!string.IsNullOrEmpty(strAACAudioCodec) && strAudioCodec != strAACAudioCodec) { DirectShowUtil.AddFilterToGraph(graphBuilder, strAACAudioCodec); } if (strAudiorenderer.Length > 0) { DirectShowUtil.AddAudioRendererToGraph(graphBuilder, strAudiorenderer, false); } //We now add custom filters after the Audio Renderer as AC3Filter failed to connect otherwise. //FlipGer: add custom filters to graph string[] arrFilters = strFilters.Split(';'); for (int i = 0; i < intFilters; i++) { DirectShowUtil.AddFilterToGraph(graphBuilder, arrFilters[i]); } //Set High Resolution Output > 2 channels IBaseFilter baseFilter = null; bool FFDShowLoaded = false; graphBuilder.FindFilterByName("WMAudio Decoder DMO", out baseFilter); if (baseFilter != null && wmvAudio != false) //Also check configuration option enabled { //Set the filter setting to enable more than 2 audio channels const string g_wszWMACHiResOutput = "_HIRESOUTPUT"; object val = true; IPropertyBag propBag = (IPropertyBag)baseFilter; hr = propBag.Write(g_wszWMACHiResOutput, ref val); if (hr != 0) { Log.Info("VideoPlayerVMR9: Unable to turn WMAudio multichannel on. Reason: {0}", hr); } else { Log.Info("VideoPlayerVMR9: WMAudio Decoder now set for > 2 audio channels"); } if (!FFDShowLoaded) { IBaseFilter FFDShowAudio = DirectShowUtil.GetFilterByName(graphBuilder, FFDSHOW_AUDIO_DECODER_FILTER); if (FFDShowAudio != null) { DirectShowUtil.ReleaseComObject(FFDShowAudio); FFDShowAudio = null; } else { _FFDShowAudio = DirectShowUtil.AddFilterToGraph(graphBuilder, FFDSHOW_AUDIO_DECODER_FILTER); } FFDShowLoaded = true; } DirectShowUtil.ReleaseComObject(baseFilter); baseFilter = null; } #region load external audio streams // check if current "File" is a file... it could also be a URL // Directory.Getfiles, ... will other give us an exception if (File.Exists(m_strCurrentFile)) { //load audio file (ac3, dts, mka, mp3) only with if the name matches partially with video file. string[] audioFiles = Directory.GetFiles(Path.GetDirectoryName(m_strCurrentFile), Path.GetFileNameWithoutExtension(m_strCurrentFile) + "*.*"); bool audioSwitcherLoaded = false; foreach (string file in audioFiles) { switch (Path.GetExtension(file)) { case ".mp3": case ".dts": case ".mka": case ".ac3": if (!audioSwitcherLoaded) { IBaseFilter switcher = DirectShowUtil.GetFilterByName(graphBuilder, MEDIAPORTAL_AUDIOSWITCHER_FILTER); if (switcher != null) { DirectShowUtil.ReleaseComObject(switcher); switcher = null; } else { _audioSwitcher = DirectShowUtil.AddFilterToGraph(graphBuilder, MEDIAPORTAL_AUDIOSWITCHER_FILTER); } audioSwitcherLoaded = true; } _AudioSourceFilter = DirectShowUtil.AddFilterToGraph(graphBuilder, FILE_SYNC_FILTER); int result = ((IFileSourceFilter)_AudioSourceFilter).Load(file, null); //Force using LAVFilter _AudioExtSplitterFilter = DirectShowUtil.AddFilterToGraph(graphBuilder, LAV_SPLITTER_FILTER); if (result != 0 || _AudioExtSplitterFilter == null) { if (_AudioSourceFilter != null) { graphBuilder.RemoveFilter(_AudioSourceFilter); DirectShowUtil.ReleaseComObject(_AudioSourceFilter); _AudioSourceFilter = null; } if (_AudioExtSplitterFilter != null) { graphBuilder.RemoveFilter(_AudioExtSplitterFilter); DirectShowUtil.ReleaseComObject(_AudioExtSplitterFilter); _AudioExtSplitterFilter = null; } //Trying Add Audio decoder in graph AddFilterToGraphAndRelease(strAudioCodec); graphBuilder.RenderFile(file, string.Empty); Log.Debug("VideoPlayerVMR9 : External audio file loaded \"{0}\"", file); AudioExternal = true; break; } //Add Audio decoder in graph _AudioExtFilter = DirectShowUtil.AddFilterToGraph(graphBuilder, strAudioCodec); //Connect Filesource with the splitter IPin pinOutAudioExt1 = DsFindPin.ByDirection((IBaseFilter)_AudioSourceFilter, PinDirection.Output, 0); IPin pinInAudioExt2 = DsFindPin.ByDirection((IBaseFilter)_AudioExtSplitterFilter, PinDirection.Input, 0); hr = graphBuilder.Connect(pinOutAudioExt1, pinInAudioExt2); //Connect Splitter with the Audio Decoder IPin pinOutAudioExt3 = DsFindPin.ByDirection((IBaseFilter)_AudioExtSplitterFilter, PinDirection.Output, 0); IPin pinInAudioExt4 = DsFindPin.ByDirection((IBaseFilter)_AudioExtFilter, PinDirection.Input, 0); hr = graphBuilder.Connect(pinOutAudioExt3, pinInAudioExt4); //Render outpin from Audio Decoder DirectShowUtil.RenderUnconnectedOutputPins(graphBuilder, _AudioExtFilter); //Cleanup External Audio (Release) if (_AudioSourceFilter != null) { DirectShowUtil.ReleaseComObject(_AudioSourceFilter); _AudioSourceFilter = null; } if (_AudioExtSplitterFilter != null) { DirectShowUtil.ReleaseComObject(_AudioExtSplitterFilter); _AudioExtSplitterFilter = null; } if (_AudioExtFilter != null) { DirectShowUtil.ReleaseComObject(_AudioExtFilter); _AudioExtFilter = null; } if (pinOutAudioExt1 != null) { DirectShowUtil.ReleaseComObject(pinOutAudioExt1); pinOutAudioExt1 = null; } if (pinInAudioExt2 != null) { DirectShowUtil.ReleaseComObject(pinInAudioExt2); pinInAudioExt2 = null; } if (pinOutAudioExt3 != null) { DirectShowUtil.ReleaseComObject(pinOutAudioExt3); pinOutAudioExt3 = null; } if (pinInAudioExt4 != null) { DirectShowUtil.ReleaseComObject(pinInAudioExt4); pinInAudioExt4 = null; } Log.Debug("VideoPlayerVMR9 : External audio file loaded \"{0}\"", file); AudioExternal = true; break; } } } #endregion DirectShowUtil.RenderUnconnectedOutputPins(graphBuilder, source); if (source != null) { DirectShowUtil.ReleaseComObject(source); source = null; } DirectShowUtil.RemoveUnusedFiltersFromGraph(graphBuilder); if (Vmr9 == null || !Vmr9.IsVMR9Connected) { Log.Error("VideoPlayer9: Failed to render file -> vmr9"); mediaCtrl = null; Cleanup(); return(false); } mediaCtrl = (IMediaControl)graphBuilder; mediaEvt = (IMediaEventEx)graphBuilder; mediaSeek = (IMediaSeeking)graphBuilder; mediaPos = (IMediaPosition)graphBuilder; basicAudio = (IBasicAudio)graphBuilder; videoWin = (IVideoWindow)graphBuilder; m_iVideoWidth = Vmr9.VideoWidth; m_iVideoHeight = Vmr9.VideoHeight; Vmr9.SetDeinterlaceMode(); return(true); } catch (Exception ex) { Error.SetError("Unable to play movie", "Unable build graph for VMR9"); Log.Error("VideoPlayer9: Exception while creating DShow graph {0} {1}", ex.Message, ex.StackTrace); Cleanup(); return(false); } }
/// <summary> create the used COM components and get the interfaces. </summary> protected override bool GetInterfaces(string filename) { Log.Info("TSReaderPlayer: GetInterfaces()"); try { string strAudioRenderer = ""; int intFilters = 0; // FlipGer: count custom filters string strFilters = ""; // FlipGer: collect custom filters LoadMyTvFilterSettings(ref intFilters, ref strFilters, ref strVideoCodec, ref strAudioCodec, ref strAACAudioCodec, ref strDDPLUSAudioCodec, ref strH264VideoCodec, ref strAudioRenderer, ref enableDVBBitmapSubtitles, ref enableDVBTtxtSubtitles, ref relaxTsReader); _graphBuilder = (IGraphBuilder)new FilterGraph(); _rotEntry = new DsROTEntry((IFilterGraph)_graphBuilder); if (strAudioRenderer.Length > 0) //audio renderer must be in graph before audio switcher { _audioRendererFilter = DirectShowUtil.AddAudioRendererToGraph(_graphBuilder, strAudioRenderer, true); } #region add AudioSwitcher if (enableMPAudioSwitcher) //audio switcher must be in graph before tsreader audiochangecallback { _audioSwitcherFilter = DirectShowUtil.AddFilterToGraph(_graphBuilder, "MediaPortal AudioSwitcher"); if (_audioSwitcherFilter == null) { Log.Error("TSReaderPlayer: Failed to add AudioSwitcher to graph"); } } #endregion #region add TsReader TsReader reader = new TsReader(); _fileSource = (IBaseFilter)reader; _ireader = (ITSReader)reader; _interfaceTSReader = _fileSource; _ireader.SetRelaxedMode(relaxTsReader); // enable/disable continousity filtering _ireader.SetTsReaderCallback(this); _ireader.SetRequestAudioChangeCallback(this); Log.Info("TSReaderPlayer: Add TsReader to graph"); int hr = _graphBuilder.AddFilter((IBaseFilter)_fileSource, "TsReader"); DsError.ThrowExceptionForHR(hr); #endregion #region load file in TsReader IFileSourceFilter interfaceFile = (IFileSourceFilter)_fileSource; if (interfaceFile == null) { Log.Error("TSReaderPlayer: Failed to get IFileSourceFilter"); Cleanup(); return false; } Log.Info("TSReaderPlayer: Open file: {0}", filename); hr = interfaceFile.Load(filename, null); if (hr != 0) { Log.Error("TSReaderPlayer: Failed to open file:{0} :0x{1:x}", filename, hr); Cleanup(); return false; } #endregion #region add codecs Log.Info("TSReaderPlayer: Add codecs"); // add preferred video & audio codecs MatchFilters("Video"); MatchFilters("Audio"); // does .ts file contain video? // default is _isRadio=false which prevents recorded radio file playing if (!_videoFormat.IsValid) _isRadio = true; if (!_isRadio) { _vmr9 = new VMR9Util(); _vmr9.AddVMR9(_graphBuilder); _vmr9.Enable(false); DirectShowUtil.AddFilterToGraph(_graphBuilder, videoFilter); if (enableDVBBitmapSubtitles) { try { SubtitleRenderer.GetInstance().AddSubtitleFilter(_graphBuilder); } catch (Exception e) { Log.Error(e); } } } DirectShowUtil.AddFilterToGraph(_graphBuilder, audioFilter); // FlipGer: add custom filters to graph string[] arrFilters = strFilters.Split(';'); for (int i = 0; i < intFilters; i++) { DirectShowUtil.AddFilterToGraph(_graphBuilder, arrFilters[i]); } #endregion #region PostProcessingEngine Detection IPostProcessingEngine postengine = PostProcessingEngine.GetInstance(true); if (!postengine.LoadPostProcessing(_graphBuilder)) { PostProcessingEngine.engine = new PostProcessingEngine.DummyEngine(); } #endregion #region render TsReader output pins Log.Info("TSReaderPlayer: Render TsReader outputs"); if (_isRadio) { IEnumPins enumPins; hr = _fileSource.EnumPins(out enumPins); DsError.ThrowExceptionForHR(hr); IPin[] pins = new IPin[1]; int fetched = 0; while (enumPins.Next(1, pins, out fetched) == 0) { if (fetched != 1) { break; } PinDirection direction; pins[0].QueryDirection(out direction); if (direction == PinDirection.Output) { IEnumMediaTypes enumMediaTypes; pins[0].EnumMediaTypes(out enumMediaTypes); AMMediaType[] mediaTypes = new AMMediaType[20]; int fetchedTypes; enumMediaTypes.Next(20, mediaTypes, out fetchedTypes); for (int i = 0; i < fetchedTypes; ++i) { if (mediaTypes[i].majorType == MediaType.Audio) { hr = _graphBuilder.Render(pins[0]); DsError.ThrowExceptionForHR(hr); break; } } } DirectShowUtil.ReleaseComObject(pins[0]); } DirectShowUtil.ReleaseComObject(enumPins); } else { DirectShowUtil.RenderGraphBuilderOutputPins(_graphBuilder, _fileSource); } DirectShowUtil.RemoveUnusedFiltersFromGraph(_graphBuilder); #endregion _mediaCtrl = (IMediaControl)_graphBuilder; _mediaEvt = (IMediaEventEx)_graphBuilder; _mediaSeeking = (IMediaSeeking)_graphBuilder; if (_mediaSeeking == null) { Log.Error("TSReaderPlayer: Unable to get IMediaSeeking interface"); } _audioStream = (IAudioStream)_fileSource; if (_audioStream == null) { Log.Error("TSReaderPlayer: Unable to get IAudioStream interface"); } _audioSelector = new AudioSelector(_audioStream); if (!_isRadio) { if (enableDVBTtxtSubtitles || enableDVBBitmapSubtitles) { try { SubtitleRenderer.GetInstance().SetPlayer(this); _dvbSubRenderer = SubtitleRenderer.GetInstance(); } catch (Exception e) { Log.Error(e); } } if (enableDVBBitmapSubtitles) { _subtitleStream = (ISubtitleStream)_fileSource; if (_subtitleStream == null) { Log.Error("TSReaderPlayer: Unable to get ISubtitleStream interface"); } } if (enableDVBTtxtSubtitles) { //Log.Debug("TSReaderPlayer: Obtaining TeletextSource"); _teletextSource = (ITeletextSource)_fileSource; if (_teletextSource == null) { Log.Error("TSReaderPlayer: Unable to get ITeletextSource interface"); } Log.Debug("TSReaderPlayer: Creating Teletext Receiver"); try { using (MPSettings xmlreader = new MPSettings()) xmlreader.SetValue("tvservice", "dvbdefttxtsubtitles", "999;999"); } catch { } TeletextSubtitleDecoder ttxtDecoder = new TeletextSubtitleDecoder(_dvbSubRenderer); _ttxtReceiver = new TeletextReceiver(_teletextSource, ttxtDecoder); // regardless of whether dvb subs are enabled, the following call is okay // if _subtitleStream is null the subtitle will just not setup for bitmap subs _subSelector = new SubtitleSelector(_subtitleStream, _dvbSubRenderer, ttxtDecoder); } else if (enableDVBBitmapSubtitles) { // if only dvb subs are enabled, pass null for ttxtDecoder _subSelector = new SubtitleSelector(_subtitleStream, _dvbSubRenderer, null); } } if (_audioRendererFilter != null) { //Log.Info("TSReaderPlayer:set reference clock"); IMediaFilter mp = (IMediaFilter)_graphBuilder; IReferenceClock clock = (IReferenceClock)_audioRendererFilter; hr = mp.SetSyncSource(null); hr = mp.SetSyncSource(clock); //Log.Info("TSReaderPlayer:set reference clock:{0:X}", hr); _basicAudio = (IBasicAudio)_graphBuilder; } if (!_isRadio) { IBaseFilter basefilter; _graphBuilder.FindFilterByName("Line 21 Decoder", out basefilter); if (basefilter == null) { _graphBuilder.FindFilterByName("Line21 Decoder", out basefilter); } if (basefilter == null) { _graphBuilder.FindFilterByName("Line 21 Decoder 2", out basefilter); } if (basefilter != null) { Log.Info("TSreaderPlayer: Line21 Decoder (Closed Captions), in use"); //: {0}", showClosedCaptions); _line21Decoder = (IAMLine21Decoder)basefilter; if (_line21Decoder != null) { AMLine21CCState state = AMLine21CCState.Off; hr = _line21Decoder.SetServiceState(state); if (hr == 0) { Log.Info("TSReaderPlayer: Closed Captions state change successful"); } else { Log.Info("TSReaderPlayer: Failed to change Closed Captions state"); } } } if (!_vmr9.IsVMR9Connected) { Log.Error("TSReaderPlayer: Failed vmr9 not connected"); Cleanup(); return false; } DirectShowUtil.EnableDeInterlace(_graphBuilder); _vmr9.SetDeinterlaceMode(); } using (MPSettings xmlreader = new MPSettings()) { int lastSubIndex = xmlreader.GetValueAsInt("tvservice", "lastsubtitleindex", 0); Log.Debug("TSReaderPlayer: Last subtitle index: {0}", lastSubIndex); CurrentSubtitleStream = lastSubIndex; } return true; } catch (Exception ex) { Log.Error("TSReaderPlayer: Exception while creating DShow graph {0}", ex.Message); Cleanup(); return false; } }
protected void Cleanup() { if (graphBuilder == null) { return; } int hr = 0; Log.Info("VideoPlayer9: Cleanup DShow graph"); try { if (mediaCtrl != null) { int counter = 0; FilterState state; hr = mediaCtrl.Stop(); hr = mediaCtrl.GetState(10, out state); while (state != FilterState.Stopped || GUIGraphicsContext.InVmr9Render) { Log.Debug("VideoPlayer9: graph still running"); Thread.Sleep(100); hr = mediaCtrl.GetState(10, out state); counter++; if (counter >= 30) { if (state != FilterState.Stopped) Log.Debug("VideoPlayer9: graph still running"); if (GUIGraphicsContext.InVmr9Render) Log.Debug("VideoPlayer9: in renderer"); break; } } mediaCtrl = null; } if (Vmr9 != null) { Vmr9.Enable(false); } if (mediaEvt != null) { hr = mediaEvt.SetNotifyWindow(IntPtr.Zero, WM_GRAPHNOTIFY, IntPtr.Zero); mediaEvt = null; } if (videoWin != null) { hr = videoWin.put_Visible(OABool.False); hr = videoWin.put_Owner(IntPtr.Zero); videoWin = null; } mediaSeek = null; mediaPos = null; basicAudio = null; basicVideo = null; SubEngine.GetInstance().FreeSubtitles(); PostProcessingEngine.GetInstance().FreePostProcess(); Log.Info("VideoPlayer9: Cleanup Sub/PostProcess"); #region Cleanup Sebastiii if (Splitter != null) { DirectShowUtil.ReleaseComObject(Splitter);//, 5000); Splitter = null; Log.Info("VideoPlayer9: Cleanup Splitter"); } if (filterCodec != null && filterCodec.VideoCodec != null) { DirectShowUtil.ReleaseComObject(filterCodec.VideoCodec);//, 5000); filterCodec.VideoCodec = null; Log.Info("VideoPlayer9: Cleanup VideoCodec"); } if (filterCodec != null && filterCodec.AudioCodec != null) { DirectShowUtil.ReleaseComObject(filterCodec.AudioCodec);//, 5000); filterCodec.AudioCodec = null; Log.Info("VideoPlayer9: Cleanup AudioCodec"); } if (filterCodec != null && filterCodec._audioRendererFilter != null) { //DirectShowUtil.DisconnectAllPins(graphBuilder, filterCodec._audioRendererFilter); //graphBuilder.RemoveFilter(filterCodec._audioRendererFilter); //while (DirectShowUtil.ReleaseComObject(filterCodec._audioRendererFilter) > 0) ; DirectShowUtil.ReleaseComObject(filterCodec._audioRendererFilter); filterCodec._audioRendererFilter = null; Log.Info("VideoPlayer9: Cleanup AudioRenderer"); } if (_interfaceSourceFilter != null) { DirectShowUtil.ReleaseComObject(_interfaceSourceFilter);//, 5000); _interfaceSourceFilter = null; Log.Info("VideoPlayer9: Cleanup InterfaceSourceFilter"); } //Test to ReleaseComObject from PostProcessFilter list objects. foreach (var ppFilter in PostProcessFilterVideo) { if (ppFilter.Value != null) DirectShowUtil.ReleaseComObject(ppFilter.Value);//, 5000); } PostProcessFilterVideo.Clear(); foreach (var ppFilter in PostProcessFilterAudio) { if (ppFilter.Value != null) DirectShowUtil.ReleaseComObject(ppFilter.Value);//, 5000); } PostProcessFilterAudio.Clear(); Log.Info("VideoPlayer9: Cleanup PostProcess"); foreach (var ppFilter in PostProcessFilterMPAudio) { if (ppFilter.Value != null) DirectShowUtil.ReleaseComObject(ppFilter.Value);//, 5000); } PostProcessFilterMPAudio.Clear(); Log.Info("VideoPlayer9: Cleanup PostProcess MediaPortal AudioSwitcher"); if (_FFDShowAudio != null) { DirectShowUtil.ReleaseComObject(_FFDShowAudio); _FFDShowAudio = null; Log.Info("VideoPlayer9: Cleanup _FFDShowAudio"); } if (_audioSwitcher != null) { DirectShowUtil.ReleaseComObject(_audioSwitcher); _audioSwitcher = null; Log.Info("VideoPlayer9: Cleanup MediaPortal AudioSwitcher (for external audio files)"); } #endregion if (graphBuilder != null) { DirectShowUtil.RemoveFilters(graphBuilder); if (_rotEntry != null) { _rotEntry.SafeDispose(); _rotEntry = null; } DirectShowUtil.ReleaseComObject(graphBuilder); graphBuilder = null; Log.Info("VideoPlayer9: Cleanup Graphbuilder"); } if (Vmr9 != null) { Vmr9.SafeDispose(); Vmr9 = null; } GC.Collect(); GC.Collect(); GC.Collect(); GUIGraphicsContext.form.Invalidate(true); m_state = PlayState.Init; } catch (Exception ex) { Log.Error("VideoPlayer9: Exception while cleanuping DShow graph - {0} {1}", ex.Message, ex.StackTrace); } //switch back to directx windowed mode Log.Info("VideoPlayer9: Disabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 0, 0, null); GUIWindowManager.SendMessage(msg); }
private void Cleanup() { if (graphBuilder == null) { return; } int hr; Log.Info("RTSPPlayer:cleanup DShow graph"); try { if (_mediaCtrl != null) { int counter = 0; FilterState state; hr = _mediaCtrl.Stop(); hr = _mediaCtrl.GetState(10, out state); while (state != FilterState.Stopped || GUIGraphicsContext.InVmr9Render) { Thread.Sleep(100); hr = _mediaCtrl.GetState(10, out state); counter++; if (counter >= 30) { if (state != FilterState.Stopped) { Log.Error("RTSPPlayer: graph still running"); } if (GUIGraphicsContext.InVmr9Render) { Log.Error("RTSPPlayer: in renderer"); } break; } } _mediaCtrl = null; } if (Vmr9 != null) { Vmr9.Enable(false); } if (mediaEvt != null) { hr = mediaEvt.SetNotifyWindow(IntPtr.Zero, WM_GRAPHNOTIFY, IntPtr.Zero); mediaEvt = null; } videoWin = graphBuilder as IVideoWindow; if (videoWin != null) { hr = videoWin.put_Visible(OABool.False); hr = videoWin.put_Owner(IntPtr.Zero); videoWin = null; } _mediaSeeking = null; mediaPos = null; basicAudio = null; basicVideo = null; videoWin = null; SubEngine.GetInstance().FreeSubtitles(); if (graphBuilder != null) { DirectShowUtil.RemoveFilters(graphBuilder); if (_rotEntry != null) { _rotEntry.SafeDispose(); _rotEntry = null; } DirectShowUtil.ReleaseComObject(graphBuilder); graphBuilder = null; } if (Vmr9 != null) { Vmr9.SafeDispose(); Vmr9 = null; } GUIGraphicsContext.form.Invalidate(true); _state = PlayState.Init; if (_mpegDemux != null) { Log.Info("cleanup mpegdemux"); while ((hr = DirectShowUtil.ReleaseComObject(_mpegDemux)) > 0) { ; } _mpegDemux = null; } if (_rtspSource != null) { Log.Info("cleanup _rtspSource"); while ((hr = DirectShowUtil.ReleaseComObject(_rtspSource)) > 0) { ; } _rtspSource = null; } if (_subtitleFilter != null) { while ((hr = DirectShowUtil.ReleaseComObject(_subtitleFilter)) > 0) { ; } _subtitleFilter = null; if (this.dvbSubRenderer != null) { this.dvbSubRenderer.SetPlayer(null); } this.dvbSubRenderer = null; } if (vobSub != null) { Log.Info("cleanup vobSub"); while ((hr = DirectShowUtil.ReleaseComObject(vobSub)) > 0) { ; } vobSub = null; } } catch (Exception ex) { Log.Error("RTSPPlayer: Exception while cleanuping DShow graph - {0} {1}", ex.Message, ex.StackTrace); } //switch back to directx windowed mode Log.Info("RTSPPlayer: Disabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 0, 0, null); GUIWindowManager.SendMessage(msg); }
private void Cleanup() { if (_graphBuilder == null) { Log.Info("StreamBufferPlayer9:grapbuilder=null"); return; } int hr; Log.Info("StreamBufferPlayer9:cleanup DShow graph {0}", GUIGraphicsContext.InVmr9Render); try { if (_mediaCtrl != null) { int counter = 0; FilterState state; hr = _mediaCtrl.Stop(); hr = _mediaCtrl.GetState(10, out state); while (state != FilterState.Stopped || GUIGraphicsContext.InVmr9Render) { System.Threading.Thread.Sleep(100); hr = _mediaCtrl.GetState(10, out state); counter++; if (counter >= 30) { if (state != FilterState.Stopped) Log.Debug("StreamBufferPlayer9: graph still running"); if (GUIGraphicsContext.InVmr9Render) Log.Debug("StreamBufferPlayer9: in renderer"); break; } } _mediaCtrl = null; } if (_vmr9 != null) { Log.Info("StreamBufferPlayer9: vmr9 disable"); _vmr9.Enable(false); } _mediaEvt = null; _mediaSeeking = null; _mediaSeeking2 = null; _videoWin = null; _basicAudio = null; _basicVideo = null; _bufferSource = null; _pinVmr9ConnectedTo = null; if (_pinVmr9ConnectedTo != null) { DirectShowUtil.ReleaseComObject(_pinVmr9ConnectedTo); _pinVmr9ConnectedTo = null; } if (streamConfig2 != null) { while ((hr = DirectShowUtil.ReleaseComObject(streamConfig2)) > 0) { ; } streamConfig2 = null; } m_StreamBufferConfig = null; if (_graphBuilder != null) { DirectShowUtil.RemoveFilters(_graphBuilder); if (_rotEntry != null) { _rotEntry.SafeDispose(); _rotEntry = null; } while ((hr = DirectShowUtil.ReleaseComObject(_graphBuilder)) > 0) ; _graphBuilder = null; } if (_vmr9 != null) { Log.Info("StreamBufferPlayer9: vmr9 dispose"); _vmr9.SafeDispose(); _vmr9 = null; } GUIGraphicsContext.form.Invalidate(true); _state = PlayState.Init; } catch (Exception ex) { Log.Error("StreamBufferPlayer9: Exception while cleaning DShow graph - {0} {1}", ex.Message, ex.StackTrace); } //switch back to directx windowed mode Log.Info("StreamBufferPlayer9: Disabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 0, 0, null); GUIWindowManager.SendMessage(msg); Log.Info("StreamBufferPlayer9: Cleanup done"); }
protected void Cleanup() { if (graphBuilder == null) { return; } int hr = 0; Log.Info("VideoPlayer9: Cleanup DShow graph"); try { if (mediaCtrl != null) { int counter = 0; FilterState state; hr = mediaCtrl.Stop(); hr = mediaCtrl.GetState(10, out state); while (state != FilterState.Stopped || GUIGraphicsContext.InVmr9Render) { Log.Debug("VideoPlayer9: graph still running"); Thread.Sleep(100); hr = mediaCtrl.GetState(10, out state); counter++; if (counter >= 30) { if (state != FilterState.Stopped) Log.Debug("VideoPlayer9: graph still running"); if (GUIGraphicsContext.InVmr9Render) Log.Debug("VideoPlayer9: in renderer"); break; } } mediaCtrl = null; } if (mediaEvt != null) { hr = mediaEvt.SetNotifyWindow(IntPtr.Zero, WM_GRAPHNOTIFY, IntPtr.Zero); mediaEvt = null; } if (videoWin != null) { hr = videoWin.put_Visible(OABool.False); hr = videoWin.put_Owner(IntPtr.Zero); videoWin = null; } mediaSeek = null; mediaPos = null; basicAudio = null; basicVideo = null; SubEngine.GetInstance().FreeSubtitles(); PostProcessingEngine.GetInstance().FreePostProcess(); if (_FFDShowAudio != null) { DirectShowUtil.ReleaseComObject(_FFDShowAudio); _FFDShowAudio = null; } if (_audioSwitcher != null) { DirectShowUtil.ReleaseComObject(_audioSwitcher); _audioSwitcher = null; } if (Vmr9 != null) { Vmr9.Enable(false); Vmr9.SafeDispose(); Vmr9 = null; } if (graphBuilder != null) { DirectShowUtil.RemoveFilters(graphBuilder); if (_rotEntry != null) { _rotEntry.SafeDispose(); _rotEntry = null; } DirectShowUtil.ReleaseComObject(graphBuilder); graphBuilder = null; } GUIGraphicsContext.form.Invalidate(true); m_state = PlayState.Init; } catch (Exception ex) { Log.Error("VideoPlayerVMR9: Exception while cleanuping DShow graph - {0} {1}", ex.Message, ex.StackTrace); } //switch back to directx windowed mode Log.Info("VideoPlayerVMR9: Disabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 0, 0, null); GUIWindowManager.SendMessage(msg); }
private bool AutoRendering(bool wmvAudio) { try { if (!OSInfo.OSInfo.VistaOrLater()) { // step 1: figure out the renderer of the graph to be removed int hr = graphBuilder.RenderFile(m_strCurrentFile, string.Empty); IEnumFilters enumFilters; hr = graphBuilder.EnumFilters(out enumFilters); do { int ffetched; IBaseFilter[] filters = new IBaseFilter[1]; hr = enumFilters.Next(1, filters, out ffetched); if (hr == 0 && ffetched > 0) { IBasicVideo2 localBasicVideo = filters[0] as IBasicVideo2; if (localBasicVideo != null) { graphBuilder.RemoveFilter(filters[0]); } DirectShowUtil.ReleaseComObject(filters[0]); } } while (hr == 0); DirectShowUtil.ReleaseComObject(enumFilters); } // switch back to directx fullscreen mode Log.Info("VideoPlayer9: Enabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 1, 0, null); GUIWindowManager.SendMessage(msg); // step 2: add the VMR9 in the graph // after enabeling exclusive mode, if done first it causes MediPortal to minimize if for example the "Windows key" is pressed while playing a video Vmr9 = new VMR9Util(); Vmr9.AddVMR9(graphBuilder); Vmr9.Enable(false); // Render file in graph if (OSInfo.OSInfo.VistaOrLater()) { int hr = graphBuilder.RenderFile(m_strCurrentFile, string.Empty); } // render DirectShowUtil.RenderGraphBuilderOutputPins(graphBuilder, null); if (Vmr9 == null || !Vmr9.IsVMR9Connected) { Log.Error("VideoPlayer9: Failed to render file -> vmr9"); mediaCtrl = null; Cleanup(); return false; } mediaCtrl = (IMediaControl)graphBuilder; mediaEvt = (IMediaEventEx)graphBuilder; mediaSeek = (IMediaSeeking)graphBuilder; mediaPos = (IMediaPosition)graphBuilder; basicAudio = (IBasicAudio)graphBuilder; videoWin = (IVideoWindow)graphBuilder; m_iVideoWidth = Vmr9.VideoWidth; m_iVideoHeight = Vmr9.VideoHeight; Vmr9.SetDeinterlaceMode(); return true; } catch (Exception ex) { Error.SetError("Unable to play movie", "Unable build graph for VMR9"); Log.Error("VideoPlayer9: Exception while creating DShow graph {0} {1}", ex.Message, ex.StackTrace); Cleanup(); return false; } }
private void Cleanup() { lock (lockObj) { if (_graphBuilder == null) { return; } int hr; Log.Info("TSReaderPlayer: cleanup DShow graph {0}", GUIGraphicsContext.InVmr9Render); try { if (_mediaCtrl != null) { int counter = 0; FilterState state; hr = _mediaCtrl.Stop(); hr = _mediaCtrl.GetState(10, out state); while (state != FilterState.Stopped || GUIGraphicsContext.InVmr9Render) { Thread.Sleep(100); hr = _mediaCtrl.GetState(10, out state); counter++; if (counter >= 30) { if (state != FilterState.Stopped) { Log.Error("TSReaderPlayer: graph still running"); } if (GUIGraphicsContext.InVmr9Render) { Log.Error("TSReaderPlayer: in renderer"); } break; } } _mediaCtrl = null; } if (_mediaEvt != null) { hr = _mediaEvt.SetNotifyWindow(IntPtr.Zero, WM_GRAPHNOTIFY, IntPtr.Zero); _mediaEvt = null; } _videoWin = _graphBuilder as IVideoWindow; if (_videoWin != null) { hr = _videoWin.put_Visible(OABool.False); hr = _videoWin.put_Owner(IntPtr.Zero); _videoWin = null; } _mediaSeeking = null; _basicAudio = null; _basicVideo = null; _ireader = null; if (_audioRendererFilter != null) { while (DirectShowUtil.ReleaseComObject(_audioRendererFilter) > 0) { ; } _audioRendererFilter = null; } if (_fileSource != null) { DirectShowUtil.ReleaseComObject(_fileSource, 5000); _fileSource = null; } PostProcessingEngine.GetInstance().FreePostProcess(); if (_vmr9 != null) { _vmr9.Enable(false); _vmr9.SafeDispose(); _vmr9 = null; } if (_line21Decoder != null) { while ((hr = DirectShowUtil.ReleaseComObject(_line21Decoder)) > 0) { ; } _line21Decoder = null; } if (_graphBuilder != null) { DirectShowUtil.RemoveFilters(_graphBuilder); if (_rotEntry != null) { _rotEntry.SafeDispose(); _rotEntry = null; } while ((hr = DirectShowUtil.ReleaseComObject(_graphBuilder)) > 0) { ; } _graphBuilder = null; } if (_dvbSubRenderer != null) { _dvbSubRenderer.SetPlayer(null); _dvbSubRenderer = null; } GUIGraphicsContext.form.Invalidate(true); _state = PlayState.Init; } catch (Exception ex) { Log.Error("TSReaderPlayer: Exception while cleaning DShow graph - {0} {1}", ex.Message, ex.StackTrace); } //switch back to directx windowed mode Log.Info("TSReaderPlayer: Disabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 0, 0, null); GUIWindowManager.SendMessage(msg); } }
/// <summary> create the used COM components and get the interfaces. </summary> protected override bool GetInterfaces() { GetInterface = true; try { graphBuilder = (IGraphBuilder) new FilterGraph(); _rotEntry = new DsROTEntry((IFilterGraph) graphBuilder); // add preferred video & audio codecs int hr; filterConfig = GetFilterConfiguration(); //Get filterCodecName filterCodec = GetFilterCodec(); if (filterConfig.bAutoDecoderSettings) { AutoRenderingCheck = true; return AutoRendering(this.filterConfig.wmvAudio); } string extension = Path.GetExtension(m_strCurrentFile).ToLowerInvariant(); //Get video/audio Info _mediaInfo = new MediaInfoWrapper(m_strCurrentFile); //Manually add codecs based on file extension if not in auto-settings // switch back to directx fullscreen mode Log.Info("VideoPlayer9: Enabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 1, 0, null); GUIWindowManager.SendMessage(msg); // add the VMR9 in the graph // after enabeling exclusive mode, if done first it causes MediPortal to minimize if for example the "Windows key" is pressed while playing a video Vmr9 = new VMR9Util(); if (File.Exists(m_strCurrentFile) && extension != ".dts" && extension != ".mp3" && extension != ".mka" && extension != ".ac3") { Vmr9.AddVMR9(graphBuilder); Vmr9.Enable(false); } else { AudioOnly = true; } if (extension == ".mpls" || extension == ".bdmv") filterConfig.bForceSourceSplitter = false; if (filterConfig.strsplitterfilter == LAV_SPLITTER_FILTER_SOURCE && filterConfig.bForceSourceSplitter) { LoadLAVSplitter(LAV_SPLITTER_FILTER_SOURCE); hr = graphBuilder.AddFilter(_interfaceSourceFilter, LAV_SPLITTER_FILTER_SOURCE); DsError.ThrowExceptionForHR(hr); Log.Debug("VideoPlayer9: Add LAVSplitter Source to graph"); IFileSourceFilter interfaceFile = (IFileSourceFilter)_interfaceSourceFilter; hr = interfaceFile.Load(m_strCurrentFile, null); if (hr != 0) { Error.SetError("Unable to play movie", "Unable build graph for VMR9"); Cleanup(); return false; } } else { _interfaceSourceFilter = filterConfig.bForceSourceSplitter ? DirectShowUtil.AddFilterToGraph(graphBuilder, filterConfig.strsplitterfilter) : null; if (_interfaceSourceFilter == null && !filterConfig.bForceSourceSplitter) { graphBuilder.AddSourceFilter(m_strCurrentFile, null, out _interfaceSourceFilter); } else { try { int result = ((IFileSourceFilter) _interfaceSourceFilter).Load(m_strCurrentFile, null); if (result != 0) { graphBuilder.RemoveFilter(_interfaceSourceFilter); DirectShowUtil.ReleaseComObject(_interfaceSourceFilter); _interfaceSourceFilter = null; graphBuilder.AddSourceFilter(m_strCurrentFile, null, out _interfaceSourceFilter); } } catch (Exception ex) { Log.Error( "VideoPlayer9: Exception loading Source Filter setup in setting in DShow graph , try to load by merit", ex); graphBuilder.RemoveFilter(_interfaceSourceFilter); DirectShowUtil.ReleaseComObject(_interfaceSourceFilter); _interfaceSourceFilter = null; graphBuilder.AddSourceFilter(m_strCurrentFile, null, out _interfaceSourceFilter); } } //Detection of File Source (Async.) as source filter, return true if found IBaseFilter fileSyncbaseFilter = null; DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.FilesyncSource, out fileSyncbaseFilter); if (fileSyncbaseFilter == null) graphBuilder.FindFilterByName("File Source (Async.)", out fileSyncbaseFilter); if (fileSyncbaseFilter != null && filterConfig.bForceSourceSplitter) { FileSync = true; DirectShowUtil.ReleaseComObject(fileSyncbaseFilter); fileSyncbaseFilter = null; if (filterConfig.strsplitterfilefilter == LAV_SPLITTER_FILTER) { LoadLAVSplitter(LAV_SPLITTER_FILTER); hr = graphBuilder.AddFilter(Splitter, LAV_SPLITTER_FILTER); DsError.ThrowExceptionForHR(hr); Log.Debug("VideoPlayer9: Add LAVSplitter to graph"); if (hr != 0) { Error.SetError("Unable to play movie", "Unable build graph for VMR9"); Cleanup(); return false; } } else { Splitter = DirectShowUtil.AddFilterToGraph(graphBuilder, filterConfig.strsplitterfilefilter); } } } // Add preferred video filters UpdateFilters("Video"); //Add Audio Renderer if (filterConfig.AudioRenderer.Length > 0 && filterCodec._audioRendererFilter == null) { filterCodec._audioRendererFilter = DirectShowUtil.AddAudioRendererToGraph(graphBuilder, filterConfig.AudioRenderer, false); } #region load external audio streams // check if current "File" is a file... it could also be a URL // Directory.Getfiles, ... will other give us an exception if (File.Exists(m_strCurrentFile) && !AudioOnly) { //load audio file (ac3, dts, mka, mp3) only with if the name matches partially with video file. string[] audioFiles = Directory.GetFiles(Path.GetDirectoryName(m_strCurrentFile), Path.GetFileNameWithoutExtension(m_strCurrentFile) + "*.*"); bool audioSwitcherLoaded = false; foreach (string file in audioFiles) { switch (Path.GetExtension(file)) { case ".mp3": case ".dts": case ".mka": case ".ac3": if (!audioSwitcherLoaded) { IBaseFilter switcher = DirectShowUtil.GetFilterByName(graphBuilder, MEDIAPORTAL_AUDIOSWITCHER_FILTER); if (switcher != null) { DirectShowUtil.ReleaseComObject(switcher); switcher = null; } else { _audioSwitcher = DirectShowUtil.AddFilterToGraph(graphBuilder, MEDIAPORTAL_AUDIOSWITCHER_FILTER); } audioSwitcherLoaded = true; } _AudioSourceFilter = DirectShowUtil.AddFilterToGraph(graphBuilder, FILE_SYNC_FILTER); int result = ((IFileSourceFilter) _AudioSourceFilter).Load(file, null); //Force using LAVFilter _AudioExtSplitterFilter = DirectShowUtil.AddFilterToGraph(graphBuilder, LAV_SPLITTER_FILTER); if (result != 0 || _AudioExtSplitterFilter == null) { if (_AudioSourceFilter != null) { graphBuilder.RemoveFilter(_AudioSourceFilter); DirectShowUtil.ReleaseComObject(_AudioSourceFilter); _AudioSourceFilter = null; } if (_AudioExtSplitterFilter != null) { graphBuilder.RemoveFilter(_AudioExtSplitterFilter); DirectShowUtil.ReleaseComObject(_AudioExtSplitterFilter); _AudioExtSplitterFilter = null; } //Trying Add Audio decoder in graph AddFilterToGraphAndRelease(filterConfig.Audio); graphBuilder.RenderFile(file, string.Empty); Log.Debug("VideoPlayerVMR9 : External audio file loaded \"{0}\"", file); AudioExternal = true; break; } //Add Audio decoder in graph _AudioExtFilter = DirectShowUtil.AddFilterToGraph(graphBuilder, filterConfig.Audio); //Connect Filesource with the splitter IPin pinOutAudioExt1 = DsFindPin.ByDirection((IBaseFilter) _AudioSourceFilter, PinDirection.Output, 0); IPin pinInAudioExt2 = DsFindPin.ByDirection((IBaseFilter) _AudioExtSplitterFilter, PinDirection.Input, 0); hr = graphBuilder.Connect(pinOutAudioExt1, pinInAudioExt2); //Connect Splitter with the Audio Decoder IPin pinOutAudioExt3 = DsFindPin.ByDirection((IBaseFilter) _AudioExtSplitterFilter, PinDirection.Output, 0); IPin pinInAudioExt4 = DsFindPin.ByDirection((IBaseFilter) _AudioExtFilter, PinDirection.Input, 0); hr = graphBuilder.Connect(pinOutAudioExt3, pinInAudioExt4); //Render outpin from Audio Decoder DirectShowUtil.RenderUnconnectedOutputPins(graphBuilder, _AudioExtFilter); //Cleanup External Audio (Release) if (_AudioSourceFilter != null) { DirectShowUtil.ReleaseComObject(_AudioSourceFilter); _AudioSourceFilter = null; } if (_AudioExtSplitterFilter != null) { DirectShowUtil.ReleaseComObject(_AudioExtSplitterFilter); _AudioExtSplitterFilter = null; } if (_AudioExtFilter != null) { DirectShowUtil.ReleaseComObject(_AudioExtFilter); _AudioExtFilter = null; } if (pinOutAudioExt1 != null) { DirectShowUtil.ReleaseComObject(pinOutAudioExt1); pinOutAudioExt1 = null; } if (pinInAudioExt2 != null) { DirectShowUtil.ReleaseComObject(pinInAudioExt2); pinInAudioExt2 = null; } if (pinOutAudioExt3 != null) { DirectShowUtil.ReleaseComObject(pinOutAudioExt3); pinOutAudioExt3 = null; } if (pinInAudioExt4 != null) { DirectShowUtil.ReleaseComObject(pinInAudioExt4); pinInAudioExt4 = null; } Log.Debug("VideoPlayerVMR9 : External audio file loaded \"{0}\"", file); AudioExternal = true; break; } } } #endregion // Add preferred audio filters UpdateFilters("Audio"); #region Set High Audio //Set High Resolution Output > 2 channels IBaseFilter baseFilter = null; bool FFDShowLoaded = false; graphBuilder.FindFilterByName("WMAudio Decoder DMO", out baseFilter); if (baseFilter != null && filterConfig.wmvAudio != false) //Also check configuration option enabled { //Set the filter setting to enable more than 2 audio channels const string g_wszWMACHiResOutput = "_HIRESOUTPUT"; object val = true; IPropertyBag propBag = (IPropertyBag) baseFilter; hr = propBag.Write(g_wszWMACHiResOutput, ref val); if (hr != 0) { Log.Info("VideoPlayer9: Unable to turn WMAudio multichannel on. Reason: {0}", hr); } else { Log.Info("VideoPlayer9: WMAudio Decoder now set for > 2 audio channels"); } if (!FFDShowLoaded) { IBaseFilter FFDShowAudio = DirectShowUtil.GetFilterByName(graphBuilder, FFDSHOW_AUDIO_DECODER_FILTER); if (FFDShowAudio != null) { DirectShowUtil.ReleaseComObject(FFDShowAudio); FFDShowAudio = null; } else { _FFDShowAudio = DirectShowUtil.AddFilterToGraph(graphBuilder, FFDSHOW_AUDIO_DECODER_FILTER); } FFDShowLoaded = true; } DirectShowUtil.ReleaseComObject(baseFilter); baseFilter = null; } #endregion if (_interfaceSourceFilter != null) { DirectShowUtil.RenderGraphBuilderOutputPins(graphBuilder, _interfaceSourceFilter); } //Test and remove orphelin Audio Renderer //RemoveAudioR(); //remove InternalScriptRenderer as it takes subtitle pin disableISR(); //disable Closed Captions! disableCC(); DirectShowUtil.RemoveUnusedFiltersFromGraph(graphBuilder); //remove orphelin audio renderer RemoveAudioR(); //EnableClock(); if (Vmr9 == null || !Vmr9.IsVMR9Connected && !AudioOnly) { Log.Error("VideoPlayer9: Failed to render file -> vmr9"); mediaCtrl = null; Cleanup(); return false; } mediaCtrl = (IMediaControl) graphBuilder; mediaEvt = (IMediaEventEx) graphBuilder; mediaSeek = (IMediaSeeking) graphBuilder; mediaPos = (IMediaPosition) graphBuilder; basicAudio = (IBasicAudio) graphBuilder; videoWin = (IVideoWindow) graphBuilder; m_iVideoWidth = Vmr9.VideoWidth; m_iVideoHeight = Vmr9.VideoHeight; Vmr9.SetDeinterlaceMode(); return true; } catch (Exception ex) { Error.SetError("Unable to play movie", "Unable build graph for VMR9"); Log.Error("VideoPlayer9: Exception while creating DShow graph {0} {1}", ex.Message, ex.StackTrace); Cleanup(); return false; } }
/// <summary> create the used COM components and get the interfaces. </summary> protected override bool GetInterfaces(string filename) { Speed = 1; Log.Info("StreamBufferPlayer9: GetInterfaces()"); //switch back to directx fullscreen mode // Log.Info("StreamBufferPlayer9: switch to fullscreen mode"); Log.Info("StreamBufferPlayer9: Enabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 1, 0, null); GUIWindowManager.SendMessage(msg); //Log.Info("StreamBufferPlayer9: build graph"); try { _graphBuilder = (IGraphBuilder) new FilterGraph(); //Log.Info("StreamBufferPlayer9: add _vmr9"); _vmr9 = new VMR9Util(); _vmr9.AddVMR9(_graphBuilder); _vmr9.Enable(false); int hr; m_StreamBufferConfig = new StreamBufferConfig(); streamConfig2 = m_StreamBufferConfig as IStreamBufferConfigure2; if (streamConfig2 != null) { // setting the StreamBufferEngine registry key IntPtr HKEY = (IntPtr) unchecked ((int)0x80000002L); IStreamBufferInitialize pTemp = (IStreamBufferInitialize)streamConfig2; IntPtr subKey = IntPtr.Zero; RegOpenKeyEx(HKEY, "SOFTWARE\\MediaPortal", 0, 0x3f, out subKey); hr = pTemp.SetHKEY(subKey); hr = streamConfig2.SetFFTransitionRates(8, 32); //Log.Info("set FFTransitionRates:{0:X}",hr); int max, maxnon; hr = streamConfig2.GetFFTransitionRates(out max, out maxnon); streamConfig2.GetBackingFileCount(out _minBackingFiles, out _maxBackingFiles); streamConfig2.GetBackingFileDuration(out _backingFileDuration); } //Log.Info("StreamBufferPlayer9: add sbe"); // create SBE source _bufferSource = (IStreamBufferSource) new StreamBufferSource(); if (_bufferSource == null) { Log.Error("StreamBufferPlayer9:Failed to create instance of SBE (do you have WinXp SP1?)"); return(false); } IBaseFilter filter = (IBaseFilter)_bufferSource; hr = _graphBuilder.AddFilter(filter, "SBE SOURCE"); if (hr != 0) { Log.Error("StreamBufferPlayer9:Failed to add SBE to graph"); return(false); } IFileSourceFilter fileSource = (IFileSourceFilter)_bufferSource; if (fileSource == null) { Log.Error("StreamBufferPlayer9:Failed to get IFileSourceFilter"); return(false); } //Log.Info("StreamBufferPlayer9: open file:{0}",filename); hr = fileSource.Load(filename, null); if (hr != 0) { Log.Error("StreamBufferPlayer9:Failed to open file:{0} :0x{1:x}", filename, hr); return(false); } //Log.Info("StreamBufferPlayer9: add codecs"); // add preferred video & audio codecs string strVideoCodec = ""; string strAudioCodec = ""; string strAudioRenderer = ""; int intFilters = 0; // FlipGer: count custom filters string strFilters = ""; // FlipGer: collect custom filters using (Settings xmlreader = new MPSettings()) { // FlipGer: load infos for custom filters int intCount = 0; while (xmlreader.GetValueAsString("mytv", "filter" + intCount.ToString(), "undefined") != "undefined") { if (xmlreader.GetValueAsBool("mytv", "usefilter" + intCount.ToString(), false)) { strFilters += xmlreader.GetValueAsString("mytv", "filter" + intCount.ToString(), "undefined") + ";"; intFilters++; } intCount++; } strVideoCodec = xmlreader.GetValueAsString("mytv", "videocodec", ""); strAudioCodec = xmlreader.GetValueAsString("mytv", "audiocodec", ""); strAudioRenderer = xmlreader.GetValueAsString("mytv", "audiorenderer", "Default DirectSound Device"); string strValue = xmlreader.GetValueAsString("mytv", "defaultar", "Normal"); GUIGraphicsContext.ARType = Util.Utils.GetAspectRatio(strValue); } if (strVideoCodec.Length > 0) { _videoCodecFilter = DirectShowUtil.AddFilterToGraph(_graphBuilder, strVideoCodec); } if (strAudioCodec.Length > 0) { _audioCodecFilter = DirectShowUtil.AddFilterToGraph(_graphBuilder, strAudioCodec); } if (strAudioRenderer.Length > 0) { _audioRendererFilter = DirectShowUtil.AddAudioRendererToGraph(_graphBuilder, strAudioRenderer, true); } // FlipGer: add custom filters to graph customFilters = new IBaseFilter[intFilters]; string[] arrFilters = strFilters.Split(';'); for (int i = 0; i < intFilters; i++) { customFilters[i] = DirectShowUtil.AddFilterToGraph(_graphBuilder, arrFilters[i]); } // render output pins of SBE DirectShowUtil.RenderOutputPins(_graphBuilder, (IBaseFilter)fileSource); _mediaCtrl = (IMediaControl)_graphBuilder; _mediaEvt = (IMediaEventEx)_graphBuilder; _mediaSeeking = _bufferSource as IStreamBufferMediaSeeking; _mediaSeeking2 = _bufferSource as IStreamBufferMediaSeeking2; if (_mediaSeeking == null) { Log.Error("Unable to get IMediaSeeking interface#1"); } if (_mediaSeeking2 == null) { Log.Error("Unable to get IMediaSeeking interface#2"); } if (_audioRendererFilter != null) { IMediaFilter mp = _graphBuilder as IMediaFilter; IReferenceClock clock = _audioRendererFilter as IReferenceClock; hr = mp.SetSyncSource(clock); } // Set the IBasicAudioInterface _basicAudio = (IBasicAudio)_graphBuilder; // Log.Info("StreamBufferPlayer9:SetARMode"); // DirectShowUtil.SetARMode(_graphBuilder,AspectRatioMode.Stretched); //Log.Info("StreamBufferPlayer9: set Deinterlace"); if (!_vmr9.IsVMR9Connected) { //_vmr9 is not supported, switch to overlay Log.Info("StreamBufferPlayer9: switch to overlay"); _mediaCtrl = null; Cleanup(); return(base.GetInterfaces(filename)); } _pinVmr9ConnectedTo = _vmr9.PinConnectedTo; _vmr9.SetDeinterlaceMode(); return(true); } catch (Exception ex) { Log.Error("StreamBufferPlayer9:exception while creating DShow graph {0} {1}", ex.Message, ex.StackTrace); return(false); } }
/// <summary> /// removes the vmr9 filter from the graph and free up all unmanaged resources /// </summary> public void Dispose() { try { Log.Debug("VMR9: Dispose"); if (false == _isVmr9Initialized) { Log.Debug("VMR9: Dispose 0"); return; } if (_threadId != Thread.CurrentThread.ManagedThreadId) { Log.Error("VMR9: Dispose() from wrong thread"); //return; } if (_vmr9Filter == null) { Log.Error("VMR9: Dispose() no filter"); return; } if (_scene != null) { _scene.Stop(); _instanceCounter--; _scene.Deinit(); GUIGraphicsContext.Vmr9Active = false; GUIGraphicsContext.Vmr9FPS = 0f; GUIGraphicsContext.InVmr9Render = false; currentVmr9State = Vmr9PlayState.Playing; Log.Debug("VMR9: Dispose 1"); } _vmr9MixerBitmapInterface = null; _qualityInterface = null; if (GUIGraphicsContext.VideoRenderer == GUIGraphicsContext.VideoRendererType.EVR) { EvrDeinit(); } else if (GUIGraphicsContext.VideoRenderer == GUIGraphicsContext.VideoRendererType.madVR) { Log.Debug("VMR9: Dispose MadDeinit - thread : {0}", Thread.CurrentThread.Name); GC.Collect(); MadDeinit(); GC.Collect(); MadvrInterface.restoreDisplayModeNow(_vmr9Filter); DirectShowUtil.FinalReleaseComObject(_vmr9Filter); Log.Debug("VMR9: Dispose 2"); } else { Vmr9Deinit(); } if (_vmr9Filter != null) { DirectShowUtil.RemoveFilter(_graphBuilder, _vmr9Filter); DirectShowUtil.ReleaseComObject(_vmr9Filter); Log.Debug("VMR9: Dispose 3"); } g_vmr9.Enable(false); _scene = null; g_vmr9 = null; _isVmr9Initialized = false; GUIGraphicsContext.DX9DeviceMadVr = null; Log.Debug("VMR9: Dispose 4"); } catch (Exception) { _vmr9Filter = null; _scene = null; g_vmr9 = null; _isVmr9Initialized = false; GUIGraphicsContext.DX9DeviceMadVr = null; } finally { RestoreGuiForMadVr(); DirectShowUtil.TryRelease(ref _vmr9Filter); GUIWindowManager.MadVrProcess(); _vmr9Filter = null; Log.Debug("VMR9: Dispose done"); } }
/// <summary> create the used COM components and get the interfaces. </summary> protected override bool GetInterfaces(string filename) { Speed = 1; Log.Info("StreamBufferPlayer9: GetInterfaces()"); //switch back to directx fullscreen mode // Log.Info("StreamBufferPlayer9: switch to fullscreen mode"); Log.Info("StreamBufferPlayer9: Enabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 1, 0, null); GUIWindowManager.SendMessage(msg); //Log.Info("StreamBufferPlayer9: build graph"); try { _graphBuilder = (IGraphBuilder)new FilterGraph(); //Log.Info("StreamBufferPlayer9: add _vmr9"); _vmr9 = new VMR9Util(); _vmr9.AddVMR9(_graphBuilder); _vmr9.Enable(false); int hr; m_StreamBufferConfig = new StreamBufferConfig(); streamConfig2 = m_StreamBufferConfig as IStreamBufferConfigure2; if (streamConfig2 != null) { // setting the StreamBufferEngine registry key IntPtr HKEY = (IntPtr)unchecked((int)0x80000002L); IStreamBufferInitialize pTemp = (IStreamBufferInitialize)streamConfig2; IntPtr subKey = IntPtr.Zero; RegOpenKeyEx(HKEY, "SOFTWARE\\MediaPortal", 0, 0x3f, out subKey); hr = pTemp.SetHKEY(subKey); hr = streamConfig2.SetFFTransitionRates(8, 32); //Log.Info("set FFTransitionRates:{0:X}",hr); int max, maxnon; hr = streamConfig2.GetFFTransitionRates(out max, out maxnon); streamConfig2.GetBackingFileCount(out _minBackingFiles, out _maxBackingFiles); streamConfig2.GetBackingFileDuration(out _backingFileDuration); } //Log.Info("StreamBufferPlayer9: add sbe"); // create SBE source _bufferSource = (IStreamBufferSource)new StreamBufferSource(); if (_bufferSource == null) { Log.Error("StreamBufferPlayer9:Failed to create instance of SBE (do you have WinXp SP1?)"); return false; } IBaseFilter filter = (IBaseFilter)_bufferSource; hr = _graphBuilder.AddFilter(filter, "SBE SOURCE"); if (hr != 0) { Log.Error("StreamBufferPlayer9:Failed to add SBE to graph"); return false; } IFileSourceFilter fileSource = (IFileSourceFilter)_bufferSource; if (fileSource == null) { Log.Error("StreamBufferPlayer9:Failed to get IFileSourceFilter"); return false; } //Log.Info("StreamBufferPlayer9: open file:{0}",filename); hr = fileSource.Load(filename, null); if (hr != 0) { Log.Error("StreamBufferPlayer9:Failed to open file:{0} :0x{1:x}", filename, hr); return false; } //Log.Info("StreamBufferPlayer9: add codecs"); // add preferred video & audio codecs string strVideoCodec = ""; string strAudioCodec = ""; string strAudioRenderer = ""; int intFilters = 0; // FlipGer: count custom filters string strFilters = ""; // FlipGer: collect custom filters using (Settings xmlreader = new MPSettings()) { // FlipGer: load infos for custom filters int intCount = 0; while (xmlreader.GetValueAsString("mytv", "filter" + intCount.ToString(), "undefined") != "undefined") { if (xmlreader.GetValueAsBool("mytv", "usefilter" + intCount.ToString(), false)) { strFilters += xmlreader.GetValueAsString("mytv", "filter" + intCount.ToString(), "undefined") + ";"; intFilters++; } intCount++; } strVideoCodec = xmlreader.GetValueAsString("mytv", "videocodec", ""); strAudioCodec = xmlreader.GetValueAsString("mytv", "audiocodec", ""); strAudioRenderer = xmlreader.GetValueAsString("mytv", "audiorenderer", "Default DirectSound Device"); string strValue = xmlreader.GetValueAsString("mytv", "defaultar", "Normal"); GUIGraphicsContext.ARType = Util.Utils.GetAspectRatio(strValue); } if (strVideoCodec.Length > 0) { _videoCodecFilter = DirectShowUtil.AddFilterToGraph(_graphBuilder, strVideoCodec); } if (strAudioCodec.Length > 0) { _audioCodecFilter = DirectShowUtil.AddFilterToGraph(_graphBuilder, strAudioCodec); } if (strAudioRenderer.Length > 0) { _audioRendererFilter = DirectShowUtil.AddAudioRendererToGraph(_graphBuilder, strAudioRenderer, true); } // FlipGer: add custom filters to graph customFilters = new IBaseFilter[intFilters]; string[] arrFilters = strFilters.Split(';'); for (int i = 0; i < intFilters; i++) { customFilters[i] = DirectShowUtil.AddFilterToGraph(_graphBuilder, arrFilters[i]); } // render output pins of SBE DirectShowUtil.RenderOutputPins(_graphBuilder, (IBaseFilter)fileSource); _mediaCtrl = (IMediaControl)_graphBuilder; _mediaEvt = (IMediaEventEx)_graphBuilder; _mediaSeeking = _bufferSource as IStreamBufferMediaSeeking; _mediaSeeking2 = _bufferSource as IStreamBufferMediaSeeking2; if (_mediaSeeking == null) { Log.Error("Unable to get IMediaSeeking interface#1"); } if (_mediaSeeking2 == null) { Log.Error("Unable to get IMediaSeeking interface#2"); } if (_audioRendererFilter != null) { IMediaFilter mp = _graphBuilder as IMediaFilter; IReferenceClock clock = _audioRendererFilter as IReferenceClock; hr = mp.SetSyncSource(clock); } // Set the IBasicAudioInterface _basicAudio = (IBasicAudio)_graphBuilder; // Log.Info("StreamBufferPlayer9:SetARMode"); // DirectShowUtil.SetARMode(_graphBuilder,AspectRatioMode.Stretched); //Log.Info("StreamBufferPlayer9: set Deinterlace"); if (!_vmr9.IsVMR9Connected) { //_vmr9 is not supported, switch to overlay Log.Info("StreamBufferPlayer9: switch to overlay"); _mediaCtrl = null; Cleanup(); return base.GetInterfaces(filename); } _pinVmr9ConnectedTo = _vmr9.PinConnectedTo; _vmr9.SetDeinterlaceMode(); return true; } catch (Exception ex) { Log.Error("StreamBufferPlayer9:exception while creating DShow graph {0} {1}", ex.Message, ex.StackTrace); return false; } }
/// <summary> /// Add VMR9 filter to graph and configure it /// </summary> /// <param name="graphBuilder"></param> public bool AddVMR9(IGraphBuilder graphBuilder) { try { // Read settings using (Settings xmlreader = new MPSettings()) { UseMadVideoRenderer = xmlreader.GetValueAsBool("general", "useMadVideoRenderer", false); UseEVRMadVRForTV = xmlreader.GetValueAsBool("general", "useEVRMadVRForTV", false); UseMadVideoRenderer3D = xmlreader.GetValueAsBool("general", "useMadVideoRenderer3D", false); } Log.Debug("VMR9: addvmr9 - thread : {0}", Thread.CurrentThread.Name); if (!_useVmr9) { Log.Debug("VMR9: addvmr9 - vmr9 is deactivated"); return false; } if (_isVmr9Initialized) { Log.Debug("VMR9: addvmr9: vmr9 has already been initialized"); return false; } if (_instanceCounter != 0) { Log.Error("VMR9: Multiple instances of VMR9 running!!!"); throw new Exception("VMR9Helper: Multiple instances of VMR9 running!!!"); } HResult hr; IntPtr hMonitor = Manager.GetAdapterMonitor(GUIGraphicsContext.DX9Device.DeviceCaps.AdapterOrdinal); IntPtr upDevice = DirectShowUtil.GetUnmanagedDevice(GUIGraphicsContext.DX9Device); _scene = new PlaneScene(this); // Check if need to set EVR for LiveTV when using madVR if (UseMadVideoRenderer) { if (UseEVRMadVRForTV && g_Player.IsTimeShifting) { GUIGraphicsContext.VideoRenderer = GUIGraphicsContext.VideoRendererType.EVR; } else { GUIGraphicsContext.VideoRenderer = GUIGraphicsContext.VideoRendererType.madVR; } } if (GUIGraphicsContext.VideoRenderer == GUIGraphicsContext.VideoRendererType.madVR) { // Process frames to clear D3D dialog window GUIWindowManager.MadVrProcess(); //_scene.MadVrRenderTarget = GUIGraphicsContext.DX9Device.GetRenderTarget(0); //MadVrRenderTargetVMR9 = GUIGraphicsContext.DX9Device.GetRenderTarget(0); } _scene.Init(); if (GUIGraphicsContext.VideoRenderer == GUIGraphicsContext.VideoRendererType.EVR) { // Fix RDP Screen out of bound (force to use AdapterOrdinal to 0 if adapter number are out of bounds) int AdapterOrdinal = GUIGraphicsContext.DX9Device.DeviceCaps.AdapterOrdinal; if (AdapterOrdinal >= Screen.AllScreens.Length) { AdapterOrdinal = Screen.AllScreens.Length - 1; Log.Info("VMR9: adapter number out of bounds"); } if (GUIGraphicsContext.currentMonitorIdx != -1) { if ((OSInfo.OSInfo.Win7OrLater() && Screen.AllScreens[AdapterOrdinal].Primary) || OSInfo.OSInfo.Win8OrLater()) { EvrInit(_scene, (uint) upDevice.ToInt32(), ref _vmr9Filter, (uint) hMonitor.ToInt32(), GUIGraphicsContext.currentMonitorIdx, false, false); } else { EvrInit(_scene, (uint) upDevice.ToInt32(), ref _vmr9Filter, (uint) hMonitor.ToInt32(), GUIGraphicsContext.currentMonitorIdx, true, true); Log.Debug("VMR9: force disable vsync and bias correction for Win7 or lower - current primary is : {0}", Screen.AllScreens[AdapterOrdinal].Primary); } } else { if ((OSInfo.OSInfo.Win7OrLater() && Screen.AllScreens[AdapterOrdinal].Primary) || OSInfo.OSInfo.Win8OrLater()) { EvrInit(_scene, (uint) upDevice.ToInt32(), ref _vmr9Filter, (uint) hMonitor.ToInt32(), AdapterOrdinal, false, false); } else { EvrInit(_scene, (uint) upDevice.ToInt32(), ref _vmr9Filter, (uint) hMonitor.ToInt32(), AdapterOrdinal, true, true); Log.Debug("VMR9: force disable vsync and bias correction for Win7 or lower - current primary is : {0}", Screen.AllScreens[AdapterOrdinal].Primary); } } hr = new HResult(graphBuilder.AddFilter(_vmr9Filter, "Enhanced Video Renderer")); // Adding put_Owner here. IVideoWindow videoWin = (IVideoWindow)graphBuilder; videoWin.put_Owner(GUIGraphicsContext.ActiveForm); Log.Info("VMR9: added EVR Renderer to graph"); } else if (GUIGraphicsContext.VideoRenderer == GUIGraphicsContext.VideoRendererType.madVR) { GUIGraphicsContext.MadVrOsd = false; GUIGraphicsContext.MadVrStop = false; IMediaControl mPMediaControl = (IMediaControl) graphBuilder; var backbuffer = GUIGraphicsContext.DX9Device.PresentationParameters; MadInit(_scene, backbuffer.BackBufferWidth, backbuffer.BackBufferHeight, (uint) upDevice.ToInt32(), (uint) GUIGraphicsContext.ActiveForm.ToInt32(), ref _vmr9Filter, mPMediaControl); hr = new HResult(graphBuilder.AddFilter(_vmr9Filter, "madVR")); Log.Info("VMR9: added madVR Renderer to graph"); backbuffer.SafeDispose(); //IVideoWindow videoWin = (IVideoWindow)graphBuilder; //videoWin.put_Owner(GUIGraphicsContext.ActiveForm); //videoWin.put_WindowStyle((WindowStyle)((int)WindowStyle.Child + (int)WindowStyle.ClipChildren + (int)WindowStyle.ClipSiblings)); //videoWin.put_MessageDrain(GUIGraphicsContext.ActiveForm); } else { _vmr9Filter = (IBaseFilter) new VideoMixingRenderer9(); Log.Info("VMR9: added Video Mixing Renderer 9 to graph"); Vmr9Init(_scene, (uint) upDevice.ToInt32(), _vmr9Filter, (uint) hMonitor.ToInt32()); hr = new HResult(graphBuilder.AddFilter(_vmr9Filter, "Video Mixing Renderer 9")); } if (_vmr9Filter == null) { Error.SetError("Unable to play movie", "Renderer could not be added"); Log.Error("VMR9: Renderer not installed / cannot be used!"); _scene.Stop(); _scene.Deinit(); _scene = null; return false; } if (hr != 0) { if (GUIGraphicsContext.VideoRenderer == GUIGraphicsContext.VideoRendererType.EVR) { EvrDeinit(); } else if (GUIGraphicsContext.VideoRenderer == GUIGraphicsContext.VideoRendererType.madVR) { Log.Error("VMR9: MadDeinit - thread : {0}", Thread.CurrentThread.Name); GC.Collect(); MadDeinit(); GC.Collect(); DirectShowUtil.FinalReleaseComObject(_vmr9Filter); Thread.Sleep(200); RestoreGuiForMadVr(); } else { Vmr9Deinit(); } _scene.Stop(); _scene.Deinit(); _scene = null; DirectShowUtil.FinalReleaseComObject(_vmr9Filter); _vmr9Filter = null; Error.SetError("Unable to play movie", "Unable to initialize Renderer"); Log.Error("VMR9: Failed to add Renderer to filter graph"); return false; } _graphBuilder = graphBuilder; _instanceCounter++; _isVmr9Initialized = true; if (GUIGraphicsContext.VideoRenderer == GUIGraphicsContext.VideoRendererType.VMR9) { _qualityInterface = _vmr9Filter as IQualProp; _vmr9MixerBitmapInterface = _vmr9Filter as IVMRMixerBitmap9; Log.Debug("VMR9: SetDeinterlacePrefs() for VMR9 mode"); SetDeinterlacePrefs(); IVMRMixerControl9 mixer = _vmr9Filter as IVMRMixerControl9; if (mixer != null) { VMR9MixerPrefs dwPrefs; mixer.GetMixingPrefs(out dwPrefs); dwPrefs &= ~VMR9MixerPrefs.RenderTargetMask; dwPrefs |= VMR9MixerPrefs.RenderTargetYUV; // YUV saves graphics bandwith http://msdn2.microsoft.com/en-us/library/ms788177(VS.85).aspx hr.Set(mixer.SetMixingPrefs(dwPrefs)); Log.Debug("VMR9: Enabled YUV mixing - " + hr.ToDXString()); using (Settings xmlreader = new MPSettings()) { //Enable nonsquaremixing if (xmlreader.GetValueAsBool("general", "nonsquare", true)) { mixer.GetMixingPrefs(out dwPrefs); dwPrefs |= VMR9MixerPrefs.NonSquareMixing; hr.Set(mixer.SetMixingPrefs(dwPrefs)); Log.Debug("VRM9: Turning on nonsquare mixing - " + hr.ToDXString()); hr.Set(mixer.SetMixingPrefs(dwPrefs)); } // Enable DecimateMask - this will effectively use only half of the input width & length if (xmlreader.GetValueAsBool("general", "dx9decimatemask", false)) { mixer.GetMixingPrefs(out dwPrefs); dwPrefs &= ~VMR9MixerPrefs.DecimateMask; dwPrefs |= VMR9MixerPrefs.DecimateOutput; hr.Set(mixer.SetMixingPrefs(dwPrefs)); Log.Debug("VRM9: Enable decimatemask - " + hr.ToDXString()); hr.Set(mixer.SetMixingPrefs(dwPrefs)); } // see D3DTEXTUREFILTERTYPE Enumerated Type documents for further information // MixerPref9_PointFiltering // MixerPref9_BiLinearFiltering // MixerPref9_AnisotropicFiltering // MixerPref9_PyramidalQuadFiltering // MixerPref9_GaussianQuadFiltering mixer.SetMixingPrefs(dwPrefs); mixer.GetMixingPrefs(out dwPrefs); dwPrefs &= ~VMR9MixerPrefs.FilteringMask; string filtermode9 = xmlreader.GetValueAsString("general", "dx9filteringmode", "Gaussian Quad Filtering"); if (filtermode9 == "Point Filtering") { dwPrefs |= VMR9MixerPrefs.PointFiltering; } else if (filtermode9 == "Bilinear Filtering") { dwPrefs |= VMR9MixerPrefs.BiLinearFiltering; } else if (filtermode9 == "Anisotropic Filtering") { dwPrefs |= VMR9MixerPrefs.AnisotropicFiltering; } else if (filtermode9 == "Pyrimidal Quad Filtering") { dwPrefs |= VMR9MixerPrefs.PyramidalQuadFiltering; } else { dwPrefs |= VMR9MixerPrefs.GaussianQuadFiltering; } hr.Set(mixer.SetMixingPrefs(dwPrefs)); Log.Debug("VRM9: Set filter mode - " + filtermode9 + " " + hr.ToDXString()); } } } _threadId = Thread.CurrentThread.ManagedThreadId; GUIGraphicsContext.Vmr9Active = true; g_vmr9 = this; Log.Debug("VMR9: Renderer successfully added"); } catch (Exception) { _scene.Stop(); _scene.Deinit(); _scene = null; return false; } return true; }
/// <summary> create the used COM components and get the interfaces. </summary> protected override bool GetInterfaces(string path) { int hr; object comobj = null; _freeNavigator = true; _dvdInfo = null; _dvdCtrl = null; _videoWin = null; string dvdDNavigator = "DVD Navigator"; string aspectRatio = ""; string displayMode = ""; bool turnoffDXVA = false; bool showClosedCaptions = false; int codecValue = 0; string codecType = ""; using (Settings xmlreader = new MPSettings()) { showClosedCaptions = xmlreader.GetValueAsBool("dvdplayer", "showclosedcaptions", false); dvdDNavigator = xmlreader.GetValueAsString("dvdplayer", "navigator", "DVD Navigator"); if (dvdDNavigator.ToLower().Contains("cyberlink dvd navigator")) { _cyberlinkDVDNavigator = true; } aspectRatio = xmlreader.GetValueAsString("dvdplayer", "armode", "").ToLower(); if (aspectRatio == "crop") { arMode = AspectRatioMode.Crop; } else if (aspectRatio == "letterbox") { arMode = AspectRatioMode.LetterBox; } else if (aspectRatio == "stretch") { arMode = AspectRatioMode.Stretched; } else if (aspectRatio == "follow stream") { arMode = AspectRatioMode.StretchedAsPrimary; } displayMode = xmlreader.GetValueAsString("dvdplayer", "displaymode", "").ToLower(); if (displayMode == "default") { _videoPref = DvdPreferredDisplayMode.DisplayContentDefault; } else if (displayMode == "16:9") { _videoPref = DvdPreferredDisplayMode.Display16x9; } else if (displayMode == "4:3 pan scan") { _videoPref = DvdPreferredDisplayMode.Display4x3PanScanPreferred; } else if (displayMode == "4:3 letterbox") { _videoPref = DvdPreferredDisplayMode.Display4x3LetterBoxPreferred; } turnoffDXVA = xmlreader.GetValueAsBool("dvdplayer", "turnoffdxva", true); Log.Info("DVDPlayer9:Turn off DXVA value = {0}", turnoffDXVA); if (turnoffDXVA == true) { codecType = xmlreader.GetValueAsString("dvdplayer", "videocodec", ""); Log.Info("DVDPlayer9:Video Decoder = {0}", codecType); if (codecType == "InterVideo Video Decoder") { codecValue = xmlreader.GetValueAsInt("videocodec", "intervideo", 1); if (codecValue == 1) { Log.Info("DVDPlayer9:Turning InterVideo DXVA off"); using ( RegistryKey subkey = Registry.CurrentUser.CreateSubKey(@"Software\InterVideo\Common\VideoDec\MediaPortal")) { subkey.SetValue("DXVA", 0); } } if (codecValue == 0) { Log.Info("DVDPlayer9:InterVideo DXVA already off"); } } if (codecType.StartsWith("CyberLink Video/SP Decoder")) { codecValue = xmlreader.GetValueAsInt("videocodec", "cyberlink", 1); if (codecValue == 1) { Log.Info("DVDPlayer9:Turning CyberLink DXVA off"); using ( RegistryKey subkey = Registry.CurrentUser.CreateSubKey(@"Software\Cyberlink\Common\CLVSD\MediaPortal")) { subkey.SetValue("UIUseHVA", 0); } } if (codecValue == 0) { Log.Info("DVDPlayer9:CyberLink DXVA already off"); } } if (codecType == "NVIDIA Video Decoder") { codecValue = xmlreader.GetValueAsInt("videocodec", "nvidia", 1); if (codecValue == 1) { Log.Info("DVDPlayer9:Turning NVIDIA DXVA off"); using ( RegistryKey subkey = Registry.LocalMachine.CreateSubKey(@"Software\NVIDIA Corporation\Filters\Video")) { subkey.SetValue("EnableDXVA", 0); } } if (codecValue == 0) { Log.Info("DVDPlayer9:NVIDIA DXVA already off"); } } } } Log.Info("DVDPlayer9:Enabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 1, 0, null); GUIWindowManager.SendMessage(msg); try { _dvdGraph = (IDvdGraphBuilder) new DvdGraphBuilder(); hr = _dvdGraph.GetFiltergraph(out _graphBuilder); DsError.ThrowExceptionForHR(hr); _rotEntry = new DsROTEntry((IFilterGraph)_graphBuilder); _vmr9 = new VMR9Util(); _vmr9.AddVMR9(_graphBuilder); _vmr9.Enable(false); try { Log.Info("DVDPlayer9:Add {0}", dvdDNavigator); _dvdbasefilter = DirectShowUtil.AddFilterToGraph(_graphBuilder, dvdDNavigator); if (_dvdbasefilter != null) { AddPreferedCodecs(_graphBuilder); _dvdCtrl = (IDvdControl2)_dvdbasefilter; if (_dvdCtrl != null) { _dvdInfo = (IDvdInfo2)_dvdbasefilter; if (!String.IsNullOrEmpty(path)) { hr = _dvdCtrl.SetDVDDirectory(path); DsError.ThrowExceptionForHR(hr); } _dvdCtrl.SetOption(DvdOptionFlag.HMSFTimeCodeEvents, true); // use new HMSF timecode format _dvdCtrl.SetOption(DvdOptionFlag.ResetOnStop, false); DirectShowUtil.RenderGraphBuilderOutputPins(_graphBuilder, _dvdbasefilter); _freeNavigator = false; } } } catch (Exception ex) { Log.Error("DVDPlayer9:Add {0} as navigator failed: {1}", dvdDNavigator, ex.Message); } if (_dvdInfo == null) { Log.Info("Dvdplayer9:Volume rendered, get interfaces"); hr = _dvdGraph.GetDvdInterface(typeof(IDvdInfo2).GUID, out comobj); DsError.ThrowExceptionForHR(hr); _dvdInfo = (IDvdInfo2)comobj; comobj = null; } if (_dvdCtrl == null) { Log.Info("Dvdplayer9:Get IDvdControl2"); hr = _dvdGraph.GetDvdInterface(typeof(IDvdControl2).GUID, out comobj); DsError.ThrowExceptionForHR(hr); _dvdCtrl = (IDvdControl2)comobj; comobj = null; if (_dvdCtrl != null) { Log.Info("Dvdplayer9:Get IDvdControl2"); } else { Log.Error("Dvdplayer9:Failed to get IDvdControl2"); } } // disable Closed Captions! IBaseFilter basefilter; _graphBuilder.FindFilterByName("Line 21 Decoder", out basefilter); if (basefilter == null) { _graphBuilder.FindFilterByName("Line21 Decoder", out basefilter); } if (basefilter == null) { _graphBuilder.FindFilterByName("Line 21 Decoder 2", out basefilter); } if (basefilter != null) { Log.Info("Dvdplayer9: Line21 Decoder (Closed Captions), in use: {0}", showClosedCaptions); _line21Decoder = (IAMLine21Decoder)basefilter; if (_line21Decoder != null) { AMLine21CCState state = showClosedCaptions ? AMLine21CCState.On : AMLine21CCState.Off; hr = _line21Decoder.SetServiceState(state); if (hr == 0) { Log.Info("DVDPlayer9: Closed Captions state change successful"); } else { Log.Info("DVDPlayer9: Failed to change Closed Captions state"); } } } if (!_vmr9.IsVMR9Connected) { Log.Info("DVDPlayer9:Failed vmr9 not connected"); _mediaCtrl = null; Cleanup(); return(false); } #region PostProcessingEngine Detection IPostProcessingEngine postengine = PostProcessingEngine.GetInstance(true); if (!postengine.LoadPostProcessing(_graphBuilder)) { PostProcessingEngine.engine = new PostProcessingEngine.DummyEngine(); } #endregion _mediaCtrl = (IMediaControl)_graphBuilder; _mediaEvt = (IMediaEventEx)_graphBuilder; _basicAudio = (IBasicAudio)_graphBuilder; _mediaPos = (IMediaPosition)_graphBuilder; _basicVideo = (IBasicVideo2)_graphBuilder; _videoWidth = _vmr9.VideoWidth; _videoHeight = _vmr9.VideoHeight; DirectShowUtil.SetARMode(_graphBuilder, arMode); _vmr9.SetDeinterlaceMode(); _vmr9.Enable(true); Log.Info("Dvdplayer9:Graph created"); _started = true; return(true); } catch (Exception ex) { Log.Error("DvdPlayer9:Exception while creating DShow graph {0} {1}", ex.Message, ex.StackTrace); CloseInterfaces(); return(false); } }
//public bool IsVMR9Connected #endregion #region public members /// <summary> /// Add VMR9 filter to graph and configure it /// </summary> /// <param name="graphBuilder"></param> public bool AddVMR9(IGraphBuilder graphBuilder) { if (!_useVmr9) { Log.Debug("VMR9: addvmr9 - vmr9 is deactivated"); return(false); } if (_isVmr9Initialized) { Log.Debug("VMR9: addvmr9: vmr9 has already been initialized"); return(false); } bool _useEvr = GUIGraphicsContext.IsEvr; if (_instanceCounter != 0) { Log.Error("VMR9: Multiple instances of VMR9 running!!!"); throw new Exception("VMR9Helper: Multiple instances of VMR9 running!!!"); } HResult hr; IntPtr hMonitor = Manager.GetAdapterMonitor(GUIGraphicsContext.DX9Device.DeviceCaps.AdapterOrdinal); IntPtr upDevice = DirectShowUtil.GetUnmanagedDevice(GUIGraphicsContext.DX9Device); _scene = new PlaneScene(this); _scene.Init(); if (_useEvr) { EvrInit(_scene, (uint)upDevice.ToInt32(), ref _vmr9Filter, (uint)hMonitor.ToInt32()); hr = new HResult(graphBuilder.AddFilter(_vmr9Filter, "Enhanced Video Renderer")); Log.Info("VMR9: added EVR Renderer to graph"); } else { _vmr9Filter = (IBaseFilter) new VideoMixingRenderer9(); Log.Info("VMR9: added Video Mixing Renderer 9 to graph"); Vmr9Init(_scene, (uint)upDevice.ToInt32(), _vmr9Filter, (uint)hMonitor.ToInt32()); hr = new HResult(graphBuilder.AddFilter(_vmr9Filter, "Video Mixing Renderer 9")); } if (_vmr9Filter == null) { Error.SetError("Unable to play movie", "Renderer could not be added"); Log.Error("VMR9: Renderer not installed / cannot be used!"); return(false); } if (hr != 0) { if (_useEvr) { EvrDeinit(); } else { Vmr9Deinit(); } _scene.Stop(); _scene.Deinit(); _scene = null; DirectShowUtil.ReleaseComObject(_vmr9Filter); _vmr9Filter = null; Error.SetError("Unable to play movie", "Unable to initialize Renderer"); Log.Error("VMR9: Failed to add Renderer to filter graph"); return(false); } _qualityInterface = _vmr9Filter as IQualProp; _vmr9MixerBitmapInterface = _vmr9Filter as IVMRMixerBitmap9; _graphBuilderInterface = graphBuilder; _instanceCounter++; _isVmr9Initialized = true; if (!_useEvr) { SetDeinterlacePrefs(); IVMRMixerControl9 mixer = _vmr9Filter as IVMRMixerControl9; if (mixer != null) { VMR9MixerPrefs dwPrefs; mixer.GetMixingPrefs(out dwPrefs); dwPrefs &= ~VMR9MixerPrefs.RenderTargetMask; dwPrefs |= VMR9MixerPrefs.RenderTargetYUV; // YUV saves graphics bandwith http://msdn2.microsoft.com/en-us/library/ms788177(VS.85).aspx hr.Set(mixer.SetMixingPrefs(dwPrefs)); Log.Debug("VMR9: Enabled YUV mixing - " + hr.ToDXString()); using (Settings xmlreader = new MPSettings()) { //Enable nonsquaremixing if (xmlreader.GetValueAsBool("general", "nonsquare", true)) { mixer.GetMixingPrefs(out dwPrefs); dwPrefs |= VMR9MixerPrefs.NonSquareMixing; hr.Set(mixer.SetMixingPrefs(dwPrefs)); Log.Debug("VRM9: Turning on nonsquare mixing - " + hr.ToDXString()); hr.Set(mixer.SetMixingPrefs(dwPrefs)); } // Enable DecimateMask - this will effectively use only half of the input width & length if (xmlreader.GetValueAsBool("general", "dx9decimatemask", false)) { mixer.GetMixingPrefs(out dwPrefs); dwPrefs &= ~VMR9MixerPrefs.DecimateMask; dwPrefs |= VMR9MixerPrefs.DecimateOutput; hr.Set(mixer.SetMixingPrefs(dwPrefs)); Log.Debug("VRM9: Enable decimatemask - " + hr.ToDXString()); hr.Set(mixer.SetMixingPrefs(dwPrefs)); } // see D3DTEXTUREFILTERTYPE Enumerated Type documents for further information // MixerPref9_PointFiltering // MixerPref9_BiLinearFiltering // MixerPref9_AnisotropicFiltering // MixerPref9_PyramidalQuadFiltering // MixerPref9_GaussianQuadFiltering mixer.SetMixingPrefs(dwPrefs); mixer.GetMixingPrefs(out dwPrefs); dwPrefs &= ~VMR9MixerPrefs.FilteringMask; string filtermode9 = xmlreader.GetValueAsString("general", "dx9filteringmode", "Gaussian Quad Filtering"); if (filtermode9 == "Point Filtering") { dwPrefs |= VMR9MixerPrefs.PointFiltering; } else if (filtermode9 == "Bilinear Filtering") { dwPrefs |= VMR9MixerPrefs.BiLinearFiltering; } else if (filtermode9 == "Anisotropic Filtering") { dwPrefs |= VMR9MixerPrefs.AnisotropicFiltering; } else if (filtermode9 == "Pyrimidal Quad Filtering") { dwPrefs |= VMR9MixerPrefs.PyramidalQuadFiltering; } else { dwPrefs |= VMR9MixerPrefs.GaussianQuadFiltering; } hr.Set(mixer.SetMixingPrefs(dwPrefs)); Log.Debug("VRM9: Set filter mode - " + filtermode9 + " " + hr.ToDXString()); } } } _threadId = Thread.CurrentThread.ManagedThreadId; GUIGraphicsContext.Vmr9Active = true; g_vmr9 = this; Log.Debug("VMR9: Renderer successfully added"); return(true); }
protected bool GetInterfaces(string filename, int titleBD) { try { Log.Debug("BDPlayer: GetInterfaces()"); _graphBuilder = (IGraphBuilder)new FilterGraph(); _rotEntry = new DsROTEntry(_graphBuilder as IFilterGraph); filterConfig = GetFilterConfiguration(); if (filterConfig.AudioRenderer.Length > 0) { _audioRendererFilter = DirectShowUtil.AddAudioRendererToGraph(_graphBuilder, filterConfig.AudioRenderer, true); } BDReader reader = new BDReader(); _interfaceBDReader = reader as IBaseFilter; _ireader = reader as IBDReader; if (_interfaceBDReader == null || _ireader == null) { // todo: add exception return false; } // add the BD reader int hr = _graphBuilder.AddFilter(_interfaceBDReader, BD_READER_GRAPH_NAME); DsError.ThrowExceptionForHR(hr); Log.Debug("BDPlayer: Add BDReader to graph"); IFileSourceFilter interfaceFile = (IFileSourceFilter)_interfaceBDReader; LoadSettings(_ireader); _ireader.SetD3DDevice(DirectShowUtil.GetUnmanagedDevice(GUIGraphicsContext.DX9Device)); _ireader.SetBDReaderCallback(this); hr = interfaceFile.Load(filename, null); DsError.ThrowExceptionForHR(hr); Log.Debug("BDPlayer: BDReader loaded: {0}", filename); List<TitleInfo> titles = GetTitleInfoCollection(_ireader); while (true) { if (g_Player.ForcePlay && g_Player.SetResumeBDTitleState < g_Player.BdDefaultTitle) { if (titles.Count == 1) { _titleToPlay = 0; g_Player.SetResumeBDTitleState = g_Player.BdRemuxTitle; } else { _titleToPlay = g_Player.SetResumeBDTitleState; } _forceTitle = true; g_Player.ForcePlay = false; } else { if (titles.Count == 1) { // BD has only one title (remux one) _forceTitle = true; _titleToPlay = 0; g_Player.SetResumeBDTitleState = g_Player.BdRemuxTitle; if (g_Player.SetResumeBDTitleState == -1) { // user cancelled dialog titles.Dispose(); g_Player.Stop(); return false; } } else { _titleToPlay = SelectTitle(titles); g_Player.SetResumeBDTitleState = _titleToPlay; Log.Info("BDPlayer: BDReader _titleToPlay : {0}", _titleToPlay); if (_titleToPlay > -1) { // a specific title was selected _forceTitle = true; if (g_Player.SetResumeBDTitleState == -1) { // user cancelled dialog titles.Dispose(); g_Player.Stop(); return false; } } else { if (_titleToPlay == -1) { // user cancelled dialog g_Player.Stop(); titles.Dispose(); return false; } // user choose to display menu _forceTitle = false; } } } _ireader.ForceTitleBasedPlayback(_forceTitle, (uint)_titleToPlay); Log.Debug("BDPlayer: Starting BDReader"); eventBuffer.Clear(); hr = _ireader.Start(); if (hr != 0) { if (!_forceTitle) { Log.Error("BDPlayer: Failed to start file:{0} :0x{1:x}", filename, hr); continue; } Log.Error("BDPlayer: Failed to start in title based mode file:{0} :0x{1:x}", filename, hr); titles.Dispose(); return false; } else { Log.Info("BDPlayer: BDReader started"); } break; } titles.Dispose(); #region Filters Log.Info("BDPlayer: Adding filters"); _vmr9 = new VMR9Util(); _vmr9.AddVMR9(_graphBuilder); _vmr9.Enable(false); // Set VideoDecoder and VC1Override before adding filter in graph SetVideoDecoder(); SetVC1Override(); // Add preferred video filters UpdateFilters("Video"); // Add preferred audio filters UpdateFilters("Audio"); // Let the subtitle engine handle the proper filters try { SubtitleRenderer.GetInstance().AddSubtitleFilter(_graphBuilder); } catch (Exception e) { Log.Error(e); } #endregion #region PostProcessingEngine Detection IPostProcessingEngine postengine = PostProcessingEngine.GetInstance(true); if (!postengine.LoadPostProcessing(_graphBuilder)) { PostProcessingEngine.engine = new PostProcessingEngine.DummyEngine(); } #endregion #region render BDReader output pins Log.Info("BDPlayer: Render BDReader outputs"); if (_interfaceBDReader != null) { DirectShowUtil.RenderGraphBuilderOutputPins(_graphBuilder, _interfaceBDReader); } //remove InternalScriptRenderer as it takes subtitle pin disableISR(); //disable Closed Captions! disableCC(); //RemoveAudioR(); DirectShowUtil.RemoveUnusedFiltersFromGraph(_graphBuilder); #endregion _mediaCtrl = (IMediaControl)_graphBuilder; _mediaEvt = (IMediaEventEx)_graphBuilder; _mediaSeeking = (IMediaSeeking)_graphBuilder; try { SubtitleRenderer.GetInstance().SetPlayer(this); _dvbSubRenderer = SubtitleRenderer.GetInstance(); } catch (Exception e) { Log.Error(e); } _subtitleStream = (Player.TSReaderPlayer.ISubtitleStream)_interfaceBDReader; if (_subtitleStream == null) { Log.Error("BDPlayer: Unable to get ISubtitleStream interface"); } // if only dvb subs are enabled, pass null for ttxtDecoder _subSelector = new SubtitleSelector(_subtitleStream, _dvbSubRenderer, null); EnableSubtitle = _subtitlesEnabled; //Sync Audio Renderer SyncAudioRenderer(); if (!_vmr9.IsVMR9Connected) { Log.Error("BDPlayer: Failed vmr9 not connected"); return false; } _vmr9.SetDeinterlaceMode(); return true; } catch (Exception ex) { Log.Error("BDPlayer: Exception while creating DShow graph {0}", ex.Message); return false; } }
public PlaneScene(VMR9Util util) { // Log.Info("PlaneScene: ctor()"); _textureAddress = 0; _vmr9Util = util; // Number of vertex buffers must be same as numer of segments in non-linear stretch _vertexBuffers = new VertexBuffer[nlsSourcePartitioning.Length]; for (int i = 0; i < _vertexBuffers.Length; i++) { _vertexBuffers[i] = new VertexBuffer(typeof (CustomVertex.TransformedColoredTextured), 4, GUIGraphicsContext.DX9Device, 0, CustomVertex.TransformedColoredTextured.Format, GUIGraphicsContext.GetTexturePoolType()); } _blackImage = new GUIImage(0); _blackImage.SetFileName("black.png"); _blackImage.AllocResources(); _cropSettings = new CropSettings(); }
//public bool IsVMR9Connected #endregion #region public members /// <summary> /// Add VMR9 filter to graph and configure it /// </summary> /// <param name="graphBuilder"></param> public bool AddVMR9(IGraphBuilder graphBuilder) { if (!_useVmr9) { Log.Debug("VMR9: addvmr9 - vmr9 is deactivated"); return false; } if (_isVmr9Initialized) { Log.Debug("VMR9: addvmr9: vmr9 has already been initialized"); return false; } bool _useEvr = GUIGraphicsContext.IsEvr; if (_instanceCounter != 0) { Log.Error("VMR9: Multiple instances of VMR9 running!!!"); throw new Exception("VMR9Helper: Multiple instances of VMR9 running!!!"); } HResult hr; IntPtr hMonitor = Manager.GetAdapterMonitor(GUIGraphicsContext.DX9Device.DeviceCaps.AdapterOrdinal); IntPtr upDevice = DirectShowUtil.GetUnmanagedDevice(GUIGraphicsContext.DX9Device); _scene = new PlaneScene(this); _scene.Init(); if (_useEvr) { EvrInit(_scene, (uint)upDevice.ToInt32(), ref _vmr9Filter, (uint)hMonitor.ToInt32()); hr = new HResult(graphBuilder.AddFilter(_vmr9Filter, "Enhanced Video Renderer")); Log.Info("VMR9: added EVR Renderer to graph"); } else { _vmr9Filter = (IBaseFilter)new VideoMixingRenderer9(); Log.Info("VMR9: added Video Mixing Renderer 9 to graph"); Vmr9Init(_scene, (uint)upDevice.ToInt32(), _vmr9Filter, (uint)hMonitor.ToInt32()); hr = new HResult(graphBuilder.AddFilter(_vmr9Filter, "Video Mixing Renderer 9")); } if (_vmr9Filter == null) { Error.SetError("Unable to play movie", "Renderer could not be added"); Log.Error("VMR9: Renderer not installed / cannot be used!"); return false; } if (hr != 0) { if (_useEvr) { EvrDeinit(); } else { Vmr9Deinit(); } _scene.Stop(); _scene.Deinit(); _scene = null; DirectShowUtil.ReleaseComObject(_vmr9Filter); _vmr9Filter = null; Error.SetError("Unable to play movie", "Unable to initialize Renderer"); Log.Error("VMR9: Failed to add Renderer to filter graph"); return false; } _qualityInterface = _vmr9Filter as IQualProp; _vmr9MixerBitmapInterface = _vmr9Filter as IVMRMixerBitmap9; _graphBuilderInterface = graphBuilder; _instanceCounter++; _isVmr9Initialized = true; if (!_useEvr) { SetDeinterlacePrefs(); IVMRMixerControl9 mixer = _vmr9Filter as IVMRMixerControl9; if (mixer != null) { VMR9MixerPrefs dwPrefs; mixer.GetMixingPrefs(out dwPrefs); dwPrefs &= ~VMR9MixerPrefs.RenderTargetMask; dwPrefs |= VMR9MixerPrefs.RenderTargetYUV; // YUV saves graphics bandwith http://msdn2.microsoft.com/en-us/library/ms788177(VS.85).aspx hr.Set(mixer.SetMixingPrefs(dwPrefs)); Log.Debug("VMR9: Enabled YUV mixing - " + hr.ToDXString()); using (Settings xmlreader = new MPSettings()) { //Enable nonsquaremixing if (xmlreader.GetValueAsBool("general", "nonsquare", true)) { mixer.GetMixingPrefs(out dwPrefs); dwPrefs |= VMR9MixerPrefs.NonSquareMixing; hr.Set(mixer.SetMixingPrefs(dwPrefs)); Log.Debug("VRM9: Turning on nonsquare mixing - " + hr.ToDXString()); hr.Set(mixer.SetMixingPrefs(dwPrefs)); } // Enable DecimateMask - this will effectively use only half of the input width & length if (xmlreader.GetValueAsBool("general", "dx9decimatemask", false)) { mixer.GetMixingPrefs(out dwPrefs); dwPrefs &= ~VMR9MixerPrefs.DecimateMask; dwPrefs |= VMR9MixerPrefs.DecimateOutput; hr.Set(mixer.SetMixingPrefs(dwPrefs)); Log.Debug("VRM9: Enable decimatemask - " + hr.ToDXString()); hr.Set(mixer.SetMixingPrefs(dwPrefs)); } // see D3DTEXTUREFILTERTYPE Enumerated Type documents for further information // MixerPref9_PointFiltering // MixerPref9_BiLinearFiltering // MixerPref9_AnisotropicFiltering // MixerPref9_PyramidalQuadFiltering // MixerPref9_GaussianQuadFiltering mixer.SetMixingPrefs(dwPrefs); mixer.GetMixingPrefs(out dwPrefs); dwPrefs &= ~VMR9MixerPrefs.FilteringMask; string filtermode9 = xmlreader.GetValueAsString("general", "dx9filteringmode", "Gaussian Quad Filtering"); if (filtermode9 == "Point Filtering") { dwPrefs |= VMR9MixerPrefs.PointFiltering; } else if (filtermode9 == "Bilinear Filtering") { dwPrefs |= VMR9MixerPrefs.BiLinearFiltering; } else if (filtermode9 == "Anisotropic Filtering") { dwPrefs |= VMR9MixerPrefs.AnisotropicFiltering; } else if (filtermode9 == "Pyrimidal Quad Filtering") { dwPrefs |= VMR9MixerPrefs.PyramidalQuadFiltering; } else { dwPrefs |= VMR9MixerPrefs.GaussianQuadFiltering; } hr.Set(mixer.SetMixingPrefs(dwPrefs)); Log.Debug("VRM9: Set filter mode - " + filtermode9 + " " + hr.ToDXString()); } } } _threadId = Thread.CurrentThread.ManagedThreadId; GUIGraphicsContext.Vmr9Active = true; g_vmr9 = this; Log.Debug("VMR9: Renderer successfully added"); return true; }
/// <summary> /// If the url to be played can be buffered before starting playback, this function /// starts building a graph by adding the preferred video and audio render to it. /// This needs to be called on the MpMain Thread. /// </summary> /// <returns>true, if the url can be buffered (a graph was started), false if it can't be and null if an error occured building the graph</returns> public bool? PrepareGraph() { string sourceFilterName = GetSourceFilterName(m_strCurrentFile); if (!string.IsNullOrEmpty(sourceFilterName)) { graphBuilder = (IGraphBuilder)new FilterGraph(); _rotEntry = new DsROTEntry((IFilterGraph)graphBuilder); basicVideo = graphBuilder as IBasicVideo2; Vmr9 = new VMR9Util(); Vmr9.AddVMR9(graphBuilder); Vmr9.Enable(false); // set VMR9 back to NOT Active -> otherwise GUI is not refreshed while graph is building GUIGraphicsContext.Vmr9Active = false; // add the audio renderer using (Settings settings = new MPSettings()) { string audiorenderer = settings.GetValueAsString("movieplayer", "audiorenderer", "Default DirectSound Device"); DirectShowUtil.AddAudioRendererToGraph(graphBuilder, audiorenderer, false); } // set fields for playback mediaCtrl = (IMediaControl)graphBuilder; mediaEvt = (IMediaEventEx)graphBuilder; mediaSeek = (IMediaSeeking)graphBuilder; mediaPos = (IMediaPosition)graphBuilder; basicAudio = (IBasicAudio)graphBuilder; videoWin = (IVideoWindow)graphBuilder; // add the source filter IBaseFilter sourceFilter = null; try { if (sourceFilterName == OnlineVideos.MPUrlSourceFilter.Downloader.FilterName) { sourceFilter = FilterFromFile.LoadFilterFromDll("MPUrlSourceSplitter\\MPUrlSourceSplitter.ax", new Guid(OnlineVideos.MPUrlSourceFilter.Downloader.FilterCLSID), true); if (sourceFilter != null) Marshal.ThrowExceptionForHR(graphBuilder.AddFilter(sourceFilter, OnlineVideos.MPUrlSourceFilter.Downloader.FilterName)); } if (sourceFilter == null) { sourceFilter = DirectShowUtil.AddFilterToGraph(graphBuilder, sourceFilterName); } } catch (Exception ex) { Log.Instance.Warn("Error adding '{0}' filter to graph: {1}", sourceFilterName, ex.Message); return null; } finally { if (sourceFilter != null) DirectShowUtil.ReleaseComObject(sourceFilter, 2000); } return true; } else { return false; } }
private bool AutoRendering(bool wmvAudio) { try { // step 1: figure out the renderer of the graph to be removed int hr = graphBuilder.RenderFile(m_strCurrentFile, string.Empty); IEnumFilters enumFilters; hr = graphBuilder.EnumFilters(out enumFilters); do { int ffetched; IBaseFilter[] filters = new IBaseFilter[1]; hr = enumFilters.Next(1, filters, out ffetched); if (hr == 0 && ffetched > 0) { IBasicVideo2 localBasicVideo = filters[0] as IBasicVideo2; if (localBasicVideo != null) { graphBuilder.RemoveFilter(filters[0]); } DirectShowUtil.ReleaseComObject(filters[0]); } } while (hr == 0); DirectShowUtil.ReleaseComObject(enumFilters); // switch back to directx fullscreen mode Log.Info("VideoPlayerVMR9: Enabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 1, 0, null); GUIWindowManager.SendMessage(msg); // step 2: add the VMR9 in the graph // after enabeling exclusive mode, if done first it causes MediPortal to minimize if for example the "Windows key" is pressed while playing a video Vmr9 = new VMR9Util(); Vmr9.AddVMR9(graphBuilder); Vmr9.Enable(false); // render DirectShowUtil.RenderGraphBuilderOutputPins(graphBuilder, null); if (Vmr9 == null || !Vmr9.IsVMR9Connected) { Log.Error("VideoPlayer9: Failed to render file -> vmr9"); mediaCtrl = null; Cleanup(); return(false); } mediaCtrl = (IMediaControl)graphBuilder; mediaEvt = (IMediaEventEx)graphBuilder; mediaSeek = (IMediaSeeking)graphBuilder; mediaPos = (IMediaPosition)graphBuilder; basicAudio = (IBasicAudio)graphBuilder; videoWin = (IVideoWindow)graphBuilder; m_iVideoWidth = Vmr9.VideoWidth; m_iVideoHeight = Vmr9.VideoHeight; Vmr9.SetDeinterlaceMode(); return(true); } catch (Exception ex) { Error.SetError("Unable to play movie", "Unable build graph for VMR9"); Log.Error("VideoPlayer9: Exception while creating DShow graph {0} {1}", ex.Message, ex.StackTrace); Cleanup(); return(false); } }