////////////////////////////////////////////////////// void TestDirectory() { int hr; int pulDActualSize; StringBuilder sb = new StringBuilder(255, 255); StringBuilder sb2 = new StringBuilder(255, 255); hr = m_imc.Stop(); hr = m_idc2.SetOption(DvdOptionFlag.ResetOnStop, true); DsError.ThrowExceptionForHR(hr); hr = m_idc2.SetOption(DvdOptionFlag.NotifyParentalLevelChange, true); DsError.ThrowExceptionForHR(hr); hr = m_idi2.GetDVDDirectory(sb, 255, out pulDActualSize); DsError.ThrowExceptionForHR(hr); hr = m_idc2.SetDVDDirectory(null); DsError.ThrowExceptionForHR(hr); Thread.Sleep(500); hr = m_imc.Stop(); DsError.ThrowExceptionForHR(hr); // Map to a different drive. One that has multiple streams, angles, etc hr = m_idc2.SetDVDDirectory(OtherDisk); DsError.ThrowExceptionForHR(hr); hr = m_idi2.GetDVDDirectory(sb2, 255, out pulDActualSize); DsError.ThrowExceptionForHR(hr); StartGraph(); }
/// <summary> /// Adds the DVDNavigator filter to the graph and sets the input path. /// </summary> protected override void AddSourceFilter() { ServiceRegistration.Get <ILogger>().Debug("DvdPlayer.AddSourceFilter"); _pendingCmd = true; _dvdbasefilter = (IBaseFilter) new DVDNavigator(); if (_dvdbasefilter == null) { throw new Exception("Failed to add DVD Navigator!"); } _graphBuilder.AddFilter(_dvdbasefilter, DVD_NAVIGATOR); _dvdInfo = _dvdbasefilter as IDvdInfo2; if (_dvdInfo == null) { throw new Exception("Failed to get IDvdInfo2 from DVDNavigator!"); } _dvdCtrl = _dvdbasefilter as IDvdControl2; if (_dvdCtrl == null) { throw new Exception("Failed to get IDvdControl2 from DVDNavigator!"); } if (!IsLocalFilesystemResource) { throw new IllegalCallException("The DVDPlayer can only play local file system resources"); } using (((ILocalFsResourceAccessor)_resourceAccessor).EnsureLocalFileSystemAccess()) { string path = ((ILocalFsResourceAccessor)_resourceAccessor).LocalFileSystemPath; // check if path is a drive root (like D:), otherwise append VIDEO_TS // MediaItem always contains the parent folder. Add the required VIDEO_TS subfolder. if (!String.IsNullOrEmpty(path) && !path.EndsWith(Path.VolumeSeparatorChar.ToString())) { path = Path.Combine(path, "VIDEO_TS"); } int hr = _dvdCtrl.SetDVDDirectory(path); if (hr != 0) { throw new Exception("Failed to set DVD directory!"); } } _dvdCtrl.SetOption(DvdOptionFlag.HMSFTimeCodeEvents, true); // use new HMSF timecode format _dvdCtrl.SetOption(DvdOptionFlag.ResetOnStop, false); _mediaEvt = _graphBuilder as IMediaEventEx; if (_mediaEvt != null) { IScreenControl screenControl = ServiceRegistration.Get <IScreenControl>(); _mediaEvt.SetNotifyWindow(screenControl.MainWindowHandle, WM_DVD_EVENT, _instancePtr); } SetDefaultLanguages(); }
public void DoTests() { IDvdGraphBuilder idgb = GetDvdGraph(); try { PopulateMembers(idgb); StartGraph(); // These routines can be tested with testme.iso. If you've got // nero, you can use NeroDrive to mount the iso file as a dvd drive. Otherwise // burn the file to a dvd for testing. TestGetCurrentDomain(); TestGetTotalTitleTime(); TestGetCurrent(); TestDiskInfo(); TestTitle(); TestButton(); TestMisc(); /// These routines need a fancier dvd than I can make with my dvd software. I've tested /// using "The Thomas Crown Affair". Note that TestDirectory changes the drive from MyDisk /// to OtherDisk. // Map to a different drive. One that has multiple streams, angles, etc int hr; hr = m_imc.Stop(); DsError.ThrowExceptionForHR(hr); hr = m_idc2.SetDVDDirectory(OtherDisk); DsError.ThrowExceptionForHR(hr); StartGraph(); TestStrings(); TestMenuLang(); TestAudio(); TestSubPic(); } finally { if (m_ROT != null) { m_ROT.Dispose(); } if (idgb != null) { Marshal.ReleaseComObject(idgb); idgb = null; } if (m_idi2 != null) { Marshal.ReleaseComObject(m_idi2); m_idi2 = null; } if (m_idc2 != null) { Marshal.ReleaseComObject(m_idc2); m_idc2 = null; } } }
void PreviewInit() { m_dvdNav = (IBaseFilter) new DVDNavigator(); m_dvdCtrl = m_dvdNav as IDvdControl2; int hr = m_dvdCtrl.SetDVDDirectory(Disk.VIDEO_TS); DsError.ThrowExceptionForHR(hr); m_dvdInfo = m_dvdCtrl as IDvdInfo2; m_filterGraph = (IGraphBuilder) new FilterGraph(); hr = m_filterGraph.AddFilter(m_dvdNav, "DVD Navigator"); DsError.ThrowExceptionForHR(hr); m_renderer = (IBaseFilter) new VideoMixingRenderer9(); IVMRFilterConfig9 filterConfig = (IVMRFilterConfig9)m_renderer; hr = filterConfig.SetRenderingMode(VMR9Mode.Renderless); DsError.ThrowExceptionForHR(hr); hr = filterConfig.SetNumberOfStreams(1); DsError.ThrowExceptionForHR(hr); hr = m_filterGraph.AddFilter(m_renderer, "Video Mix 9"); DsError.ThrowExceptionForHR(hr); IPin videoPin; hr = m_dvdNav.FindPin("Video", out videoPin); DsError.ThrowExceptionForHR(hr); IPin audioPin; hr = m_dvdNav.FindPin("AC3", out audioPin); DsError.ThrowExceptionForHR(hr); //hr = m_filterGraph.Render(videoPin); //DsError.ThrowExceptionForHR(hr); //hr = m_filterGraph.Render(audioPin); //DsError.ThrowExceptionForHR(hr); //IMediaControl mediaCtrl = (IMediaControl)m_filterGraph; //hr = mediaCtrl.Run(); //DsError.ThrowExceptionForHR(hr); //hr = m_dvdCtrl.SetOption(DvdOptionFlag.EnableNonblockingAPIs, true); //DsError.ThrowExceptionForHR(hr); //m_dvdCtrl.SetOption(DvdOptionFlag.ResetOnStop, true); }
private void InitializeDvd(string path) { /* The DVDControl2 interface lets us control DVD features */ _mDvdControl = _dvdNav as IDvdControl2; if (_mDvdControl == null) { throw new Exception("Could not QueryInterface the IDvdControl2 interface"); } /* QueryInterface the DVDInfo2 */ _mDvdInfo = _dvdNav as IDvdInfo2; var videoTsPath = Path.Combine(path, "video_ts"); if (Directory.Exists(videoTsPath)) { path = videoTsPath; } /* If a Dvd directory has been set then use it, if not, let DShow find the Dvd */ var hr = _mDvdControl.SetDVDDirectory(path); DsError.ThrowExceptionForHR(hr); /* This gives us the DVD time in Hours-Minutes-Seconds-Frame time format, and other options */ hr = _mDvdControl.SetOption(DvdOptionFlag.HMSFTimeCodeEvents, true); DsError.ThrowExceptionForHR(hr); /* If the graph stops, resume at the same point */ _mDvdControl.SetOption(DvdOptionFlag.ResetOnStop, false); hr = m_graph.AddFilter(_dvdNav, "DVD Navigator"); DsError.ThrowExceptionForHR(hr); //int uTitle = 1; //dma = new DvdMenuAttributes(); //dta = new DvdTitleAttributes(); //m_dvdInfo.GetTitleAttributes(uTitle, out dma, dta); //int iX = dta.VideoAttributes.aspectX; //int iY = dta.VideoAttributes.aspectY; //DvdIsLetterBoxed = dta.VideoAttributes.isSourceLetterboxed; //int sX = dta.VideoAttributes.sourceResolutionX; //int sY = dta.VideoAttributes.sourceResolutionY; }
private void InitializeDvd(string path) { int hr = m_graph.AddFilter(_sourceFilter, "DVD Navigator"); DsError.ThrowExceptionForHR(hr); /* The DVDControl2 interface lets us control DVD features */ _mDvdControl = _sourceFilter as IDvdControl2; if (_mDvdControl == null) throw new Exception("Could not QueryInterface the IDvdControl2 interface"); var videoTsPath = Path.Combine(path, "video_ts"); if (Directory.Exists(videoTsPath)) { path = videoTsPath; } /* If a Dvd directory has been set then use it, if not, let DShow find the Dvd */ hr = _mDvdControl.SetDVDDirectory(path); DsError.ThrowExceptionForHR(hr); /* This gives us the DVD time in Hours-Minutes-Seconds-Frame time format, and other options */ hr = _mDvdControl.SetOption(DvdOptionFlag.HMSFTimeCodeEvents, true); DsError.ThrowExceptionForHR(hr); /* If the graph stops, resume at the same point */ _mDvdControl.SetOption(DvdOptionFlag.ResetOnStop, false); /* QueryInterface the DVDInfo2 */ //dvdInfo = _sourceFilter as IDvdInfo2; //int uTitle = 1; //dma = new DvdMenuAttributes(); //dta = new DvdTitleAttributes(); //m_dvdInfo.GetTitleAttributes(uTitle, out dma, dta); //int iX = dta.VideoAttributes.aspectX; //int iY = dta.VideoAttributes.aspectY; //DvdIsLetterBoxed = dta.VideoAttributes.isSourceLetterboxed; //int sX = dta.VideoAttributes.sourceResolutionX; //int sY = dta.VideoAttributes.sourceResolutionY; }
/// <summary> /// Builds the DVD DirectShow graph /// </summary> private void BuildGraph() { try { FreeResources(); int hr; /* Create our new graph */ m_graph = (IGraphBuilder)new FilterGraphNoThread(); #if DEBUG m_rot = new DsROTEntry(m_graph); #endif /* We are going to use the VMR9 for now. The EVR does not * seem to work with the interactive menus yet. It should * play Dvds fine otherwise */ var rendererType = VideoRendererType.VideoMixingRenderer9; /* Creates and initializes a new renderer ready to render to WPF */ m_renderer = CreateVideoRenderer(rendererType, m_graph, 2); /* Do some VMR9 specific stuff */ if (rendererType == VideoRendererType.VideoMixingRenderer9) { var mixer = m_renderer as IVMRMixerControl9; if(mixer != null) { VMR9MixerPrefs dwPrefs; mixer.GetMixingPrefs(out dwPrefs); dwPrefs &= ~VMR9MixerPrefs.RenderTargetMask; dwPrefs |= VMR9MixerPrefs.RenderTargetYUV; /* Enable this line to prefer YUV */ //hr = mixer.SetMixingPrefs(dwPrefs); } } /* Create a new DVD Navigator. */ var dvdNav = (IBaseFilter)new DVDNavigator(); /* The DVDControl2 interface lets us control DVD features */ m_dvdControl = dvdNav as IDvdControl2; if (m_dvdControl == null) throw new Exception("Could not QueryInterface the IDvdControl2 interface"); /* QueryInterface the DVDInfo2 */ m_dvdInfo = dvdNav as IDvdInfo2; /* If a Dvd directory has been set then use it, if not, let DShow find the Dvd */ if (!string.IsNullOrEmpty(DvdDirectory)) { hr = m_dvdControl.SetDVDDirectory(DvdDirectory); DsError.ThrowExceptionForHR(hr); } /* This gives us the DVD time in Hours-Minutes-Seconds-Frame time format, and other options */ hr = m_dvdControl.SetOption(DvdOptionFlag.HMSFTimeCodeEvents, true); DsError.ThrowExceptionForHR(hr); /* If the graph stops, resume at the same point */ m_dvdControl.SetOption(DvdOptionFlag.ResetOnStop, false); hr = m_graph.AddFilter(dvdNav, "DVD Navigator"); DsError.ThrowExceptionForHR(hr); IPin dvdVideoPin = null; IPin dvdAudioPin = null; IPin dvdSubPicturePin = null; IPin dvdNavPin; int i = 0; /* Loop all the output pins on the DVD Navigator, trying to find which pins are which. * We could more easily find the pins by name, but this is more fun...and more flexible * if we ever want to use a 3rd party DVD navigator that used different pin names */ while ((dvdNavPin = DsFindPin.ByDirection(dvdNav, PinDirection.Output, i)) != null) { var mediaTypes = new AMMediaType[1]; IntPtr pFetched = IntPtr.Zero; IEnumMediaTypes mediaTypeEnum; dvdNavPin.EnumMediaTypes(out mediaTypeEnum); /* Loop over each of the mediaTypes of each pin */ while (mediaTypeEnum.Next(1, mediaTypes, pFetched) == 0) { AMMediaType mediaType = mediaTypes[0]; /* This will be the video stream pin */ if (mediaType.subType == MediaSubType.Mpeg2Video) { /* Keep the ref and we'll work with it later */ dvdVideoPin = dvdNavPin; break; } /* This will be the audio stream pin */ if (mediaType.subType == MediaSubType.DolbyAC3 || mediaType.subType == MediaSubType.Mpeg2Audio) { /* Keep the ref and we'll work with it later */ dvdAudioPin = dvdNavPin; break; } /* This is the Dvd sub picture pin. This generally * shows overlays for Dvd menus and sometimes closed captions */ if (mediaType.subType == DVD_SUBPICTURE_TYPE) { /* Keep the ref and we'll work with it later */ dvdSubPicturePin = dvdNavPin; break; } } mediaTypeEnum.Reset(); Marshal.ReleaseComObject(mediaTypeEnum); i++; } /* This is the windowed renderer. This is *NEEDED* in order * for interactive menus to work with the other VMR9 in renderless mode */ var dummyRenderer = (IBaseFilter)new VideoMixingRenderer9(); var dummyRendererConfig = (IVMRFilterConfig9)dummyRenderer; /* In order for this interactive menu trick to work, the VMR9 * must be set to Windowed. We will make sure the window is hidden later on */ hr = dummyRendererConfig.SetRenderingMode(VMR9Mode.Windowed); DsError.ThrowExceptionForHR(hr); hr = dummyRendererConfig.SetNumberOfStreams(1); DsError.ThrowExceptionForHR(hr); hr = m_graph.AddFilter(dummyRenderer, "Dummy Windowed"); DsError.ThrowExceptionForHR(hr); if (dvdAudioPin != null) { /* This should render out to the default audio device. We * could modify this code here to go out any audio * device, such as SPDIF or another sound card */ hr = m_graph.Render(dvdAudioPin); DsError.ThrowExceptionForHR(hr); } /* Get the first input pin on our dummy renderer */ m_dummyRendererPin = DsFindPin.ByConnectionStatus(dummyRenderer, /* Filter to search */ PinConnectedStatus.Unconnected, 0); /* Get an available pin on our real renderer */ IPin rendererPin = DsFindPin.ByConnectionStatus(m_renderer, /* Filter to search */ PinConnectedStatus.Unconnected, 0); /* Pin index */ /* Connect the pin to the renderer */ hr = m_graph.Connect(dvdVideoPin, rendererPin); DsError.ThrowExceptionForHR(hr); /* Get the next available pin on our real renderer */ rendererPin = DsFindPin.ByConnectionStatus(m_renderer, /* Filter to search */ PinConnectedStatus.Unconnected, 0); /* Pin index */ /* Render the sub picture, which will connect * the DVD navigator to the codec, not the renderer */ hr = m_graph.Render(dvdSubPicturePin); DsError.ThrowExceptionForHR(hr); /* These are the subtypes most likely to be our dvd subpicture */ var preferedSubpictureTypes = new[]{MediaSubType.ARGB4444, MediaSubType.AI44, MediaSubType.AYUV, MediaSubType.ARGB32}; IPin dvdSubPicturePinOut = null; /* Find what should be the subpicture pin out */ foreach (var guidType in preferedSubpictureTypes) { dvdSubPicturePinOut = FindPinInGraphByMediaType(guidType, /* GUID of the media type being searched for */ PinDirection.Output, m_graph); /* Our current graph */ if (dvdSubPicturePinOut != null) break; } if (dvdSubPicturePinOut == null) throw new Exception("Could not find the sub picture pin out"); /* Here we connec thte Dvd sub picture pin to the video renderer. * This enables the overlays on Dvd menus and some closed * captions to be rendered. */ hr = m_graph.Connect(dvdSubPicturePinOut, rendererPin); DsError.ThrowExceptionForHR(hr); /* Search for the Line21 out in the graph */ IPin line21Out = FindPinInGraphByMediaType(MediaType.AuxLine21Data, PinDirection.Output, m_graph); if (line21Out == null) throw new Exception("Could not find the Line21 pin out"); /* We connect our line21Out out in to the dummy renderer * this is what ultimatly makes interactive DVDs work with * VMR9 in renderless (for WPF) */ hr = m_graph.Connect(line21Out, m_dummyRendererPin); DsError.ThrowExceptionForHR(hr); /* This is the dummy renderers Win32 window. */ m_dummyRenderWindow = dummyRenderer as IVideoWindow; if (m_dummyRenderWindow == null) throw new Exception("Could not QueryInterface for IVideoWindow"); ConfigureDummyWindow(); /* Setup our base classes with this filter graph */ SetupFilterGraph(m_graph); /* Sets the NaturalVideoWidth/Height */ SetNativePixelSizes(m_renderer); } catch (Exception ex) { FreeResources(); InvokeMediaFailed(new MediaFailedEventArgs(ex.Message, ex)); return; } InvokeMediaOpened(); }
/// <summary> /// DVD Code - Play DVD /// </summary> /// <param name="db1"></param> public void PlayDVD(DBTrackInfo db1) { DBLocalMedia mediaToPlay = db1.LocalMedia[0]; if (mediaToPlay.State != MediaState.Online) mediaToPlay.Mount(); while (mediaToPlay.State != MediaState.Online) { Thread.Sleep(1000); }; string dvdNavigator = ""; string dslibdvdnavMonikerString = @"@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{1FFD2F97-0C57-4E21-9FC1-60DF6C6D20BF}"; Log.Info("finding dslibdvdnav filter"); IBaseFilter filter = Marshal.BindToMoniker(dslibdvdnavMonikerString) as IBaseFilter; if (filter != null) { Log.Info("dslibdvdnav filter found!"); DirectShowUtil.ReleaseComObject(filter); filter = null; using (MediaPortal.Profile.Settings xmlreader = mvCentralCore.MediaPortalSettings) { xmlreader.SetValue("dvdplayer", "navigator", "dslibdvdnav"); dvdNavigator = xmlreader.GetValueAsString("dvdplayer", "navigator", "DVD Navigator"); } } else Log.Info("dslibdvdnav filter not found using mp default one!"); MediaPortal.Player.g_Player.Play(mediaToPlay.GetVideoPath()); // reset setting back to original if (dvdNavigator == "dslibdvdnav") using (MediaPortal.Profile.Settings xmlreader = mvCentralCore.MediaPortalSettings) { xmlreader.SetValue("dvdplayer", "navigator", "DVD Navigator"); } PurgeEntries(); l1 = ROTClass.GetFilterGraphsFromROT(); foreach (DSGrapheditROTEntry e1 in l1) { logger.Info(e1.ToString()); _graphBuilder = e1.ConnectToROTEntry() as IGraphBuilder; _dvdbasefilter = DirectShowUtil.GetFilterByName(_graphBuilder, dvdNavigator); _dvdCtrl = _dvdbasefilter as IDvdControl2; _dvdCtrl.SetOption(DvdOptionFlag.HMSFTimeCodeEvents, true); // use new HMSF timecode format _dvdCtrl.SetOption(DvdOptionFlag.ResetOnStop, false); _dvdCtrl.SetDVDDirectory(mediaToPlay.GetVideoPath()); DirectShowUtil.RenderOutputPins(_graphBuilder, _dvdbasefilter); _basicVideo = _graphBuilder as IBasicVideo2; _mediaCtrl = _graphBuilder as IMediaControl; //hr = _mediaCtrl.Run(); //hr = _mediaCtrl.Pause(); //_offsetseek = (ulong)seekbar.Value; TimeSpan t1 = TimeSpan.FromMilliseconds(0); TimeSpan t2 = TimeSpan.Parse(db1.OffsetTime); t1 = t1.Add(t2); // t1 = TimeSpan.Parse(db1.PlayTime); t2 = t2.Add(TimeSpan.Parse(db1.PlayTime)); DvdHMSFTimeCode t3 = mvCentralUtils.ConvertToDvdHMSFTimeCode(t1); DvdHMSFTimeCode t4 = mvCentralUtils.ConvertToDvdHMSFTimeCode(t2); //if (state == FilterState.Stopped) int hr = _mediaCtrl.Run(); hr = _dvdCtrl.PlayAtTimeInTitle(db1.TitleID, t3, DvdCmdFlags.Flush | DvdCmdFlags.Block, out _cmdOption); // hr = _dvdCtrl.PlayPeriodInTitleAutoStop(6, t3, t4, DvdCmdFlags.Flush | DvdCmdFlags.Block, out _cmdOption); DsError.ThrowExceptionForHR(hr); //int hr = _dvdCtrl.PlayChaptersAutoStop(1, db1.ChapterID, 1, 0, out _cmdOption); //DsError.ThrowExceptionForHR(hr); } }
/// <summary> create the used COM components and get the interfaces. </summary> protected virtual bool GetDVDInterfaces(string path) { int hr; //Type comtype = null; object comobj = null; _freeNavigator = true; _dvdInfo = null; _dvdCtrl = null; bool useAC3Filter = false; string dvdNavigator = ""; string aspectRatioMode = ""; string displayMode = ""; _videoPref = DvdPreferredDisplayMode.DisplayContentDefault; using (MediaPortal.Profile.Settings xmlreader = new MPSettings()) { dvdNavigator = xmlreader.GetValueAsString("dvdplayer", "navigator", "DVD Navigator"); aspectRatioMode = xmlreader.GetValueAsString("dvdplayer", "armode", "").ToLower(); dvdNavigator = "dslibdvdnav"; if (aspectRatioMode == "crop") { arMode = AspectRatioMode.Crop; } if (aspectRatioMode == "letterbox") { arMode = AspectRatioMode.LetterBox; } if (aspectRatioMode == "stretch") { arMode = AspectRatioMode.Stretched; } //if ( aspectRatioMode == "stretch" ) arMode = AspectRatioMode.zoom14to9; if (aspectRatioMode == "follow stream") { arMode = AspectRatioMode.StretchedAsPrimary; } useAC3Filter = xmlreader.GetValueAsBool("dvdplayer", "ac3", false); displayMode = xmlreader.GetValueAsString("dvdplayer", "displaymode", "").ToLower(); if (displayMode == "default") { _videoPref = DvdPreferredDisplayMode.DisplayContentDefault; } if (displayMode == "16:9") { _videoPref = DvdPreferredDisplayMode.Display16x9; } if (displayMode == "4:3 pan scan") { _videoPref = DvdPreferredDisplayMode.Display4x3PanScanPreferred; } if (displayMode == "4:3 letterbox") { _videoPref = DvdPreferredDisplayMode.Display4x3LetterBoxPreferred; } } try { _dvdGraph = (IDvdGraphBuilder) new DvdGraphBuilder(); hr = _dvdGraph.GetFiltergraph(out _graphBuilder); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } _rotEntry = new DsROTEntry((IFilterGraph)_graphBuilder); _vmr9Filter = (IBaseFilter) new VideoMixingRenderer9(); IVMRFilterConfig9 config = _vmr9Filter as IVMRFilterConfig9; hr = config.SetNumberOfStreams(1); hr = config.SetRenderingMode(VMR9Mode.Windowless); windowlessCtrl = (IVMRWindowlessControl9)_vmr9Filter; windowlessCtrl.SetVideoClippingWindow(this.panVideoWin.Handle); // config.SetRenderingPrefs(VMR9RenderPrefs. _graphBuilder.AddFilter(_vmr9Filter, "Video Mixing Renderer 9"); // _vmr7 = new VMR7Util(); // _vmr7.AddVMR7(_graphBuilder); try { _dvdbasefilter = DirectShowUtil.AddFilterToGraph(_graphBuilder, dvdNavigator); if (_dvdbasefilter != null) { IDvdControl2 cntl = (IDvdControl2)_dvdbasefilter; if (cntl != null) { _dvdInfo = (IDvdInfo2)cntl; _dvdCtrl = (IDvdControl2)cntl; if (path != null) { if (path.Length != 0) { cntl.SetDVDDirectory(path); } } _dvdCtrl.SetOption(DvdOptionFlag.HMSFTimeCodeEvents, true); // use new HMSF timecode format _dvdCtrl.SetOption(DvdOptionFlag.ResetOnStop, false); AddPreferedCodecs(_graphBuilder); DirectShowUtil.RenderOutputPins(_graphBuilder, _dvdbasefilter); // _videoWin = _graphBuilder as IVideoWindow; _freeNavigator = false; } //DirectShowUtil.ReleaseComObject( _dvdbasefilter); _dvdbasefilter = null; } } catch (Exception ex) { string strEx = ex.Message; } Guid riid; if (_dvdInfo == null) { riid = typeof(IDvdInfo2).GUID; hr = _dvdGraph.GetDvdInterface(riid, out comobj); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } _dvdInfo = (IDvdInfo2)comobj; comobj = null; } if (_dvdCtrl == null) { riid = typeof(IDvdControl2).GUID; hr = _dvdGraph.GetDvdInterface(riid, out comobj); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } _dvdCtrl = (IDvdControl2)comobj; comobj = null; } _mediaCtrl = (IMediaControl)_graphBuilder; _mediaEvt = (IMediaEventEx)_graphBuilder; _basicAudio = _graphBuilder as IBasicAudio; _mediaPos = (IMediaPosition)_graphBuilder; _mediaSeek = (IMediaSeeking)_graphBuilder; _mediaStep = (IVideoFrameStep)_graphBuilder; _basicVideo = _graphBuilder as IBasicVideo2; _videoWin = _graphBuilder as IVideoWindow; // disable Closed Captions! IBaseFilter baseFilter; _graphBuilder.FindFilterByName("Line 21 Decoder", out baseFilter); if (baseFilter == null) { _graphBuilder.FindFilterByName("Line21 Decoder", out baseFilter); } if (baseFilter != null) { _line21Decoder = (IAMLine21Decoder)baseFilter; if (_line21Decoder != null) { AMLine21CCState state = AMLine21CCState.Off; hr = _line21Decoder.SetServiceState(state); if (hr == 0) { logger.Info("DVDPlayer:Closed Captions disabled"); } else { logger.Info("DVDPlayer:failed 2 disable Closed Captions"); } } } /* * // get video window * if (_videoWin==null) * { * riid = typeof( IVideoWindow ).GUID; * hr = _dvdGraph.GetDvdInterface( ref riid, out comobj ); * if( hr < 0 ) * Marshal.ThrowExceptionForHR( hr ); * _videoWin = (IVideoWindow) comobj; comobj = null; * } */ // GetFrameStepInterface(); DirectShowUtil.SetARMode(_graphBuilder, arMode); DirectShowUtil.EnableDeInterlace(_graphBuilder); //m_ovMgr = new OVTOOLLib.OvMgrClass(); //m_ovMgr.SetGraph(_graphBuilder); return(true); } catch (Exception) { //MessageBox.Show( this, "Could not get interfaces\r\n" + ee.Message, "DVDPlayer.NET", MessageBoxButtons.OK, MessageBoxIcon.Stop ); CloseDVDInterfaces(); return(false); } finally { if (comobj != null) { DirectShowUtil.ReleaseComObject(comobj); } comobj = null; } }
/// <summary> /// Adds the file source filter to the graph. /// </summary> protected override void AddFileSource() { ServiceRegistration.Get<ILogger>().Debug("DvdPlayer.AddFileSource"); _pendingCmd = true; _dvdbasefilter = (IBaseFilter) new DVDNavigator(); _graphBuilder.AddFilter(_dvdbasefilter, DVD_NAVIGATOR); if (_dvdbasefilter == null) throw new Exception("Failed to add DVD Navigator!"); _dvdInfo = _dvdbasefilter as IDvdInfo2; _dvdCtrl = _dvdbasefilter as IDvdControl2; if (_dvdCtrl == null) throw new Exception("Failed to access DVD Control!"); string path = SourcePathOrUrl; // check if path is a drive root (like D:), otherwise append VIDEO_TS // MediaItem always contains the parent folder. Add the required VIDEO_TS subfolder. if (!String.IsNullOrEmpty(path) && !path.EndsWith(Path.VolumeSeparatorChar.ToString())) path = Path.Combine(path, "VIDEO_TS"); int hr = _dvdCtrl.SetDVDDirectory(path); if (hr != 0) throw new Exception("Failed to set DVD directory!"); _dvdCtrl.SetOption(DvdOptionFlag.HMSFTimeCodeEvents, true); // use new HMSF timecode format _dvdCtrl.SetOption(DvdOptionFlag.ResetOnStop, false); _mediaEvt = _graphBuilder as IMediaEventEx; if (_mediaEvt != null) { IScreenControl screenControl = ServiceRegistration.Get<IScreenControl>(); _mediaEvt.SetNotifyWindow(screenControl.MainWindowHandle, WM_DVD_EVENT, _instancePtr); } SetDefaultLanguages(); }
/// <summary> /// Builds the DVD DirectShow graph /// </summary> private void BuildGraph() { try { FreeResources(); int hr; /* Create our new graph */ m_graph = (IGraphBuilder) new FilterGraphNoThread(); #if DEBUG m_rot = new DsROTEntry(m_graph); #endif /* We are going to use the VMR9 for now. The EVR does not * seem to work with the interactive menus yet. It should * play Dvds fine otherwise */ var rendererType = VideoRendererType.VideoMixingRenderer9; /* Creates and initializes a new renderer ready to render to WPF */ m_renderer = CreateVideoRenderer(rendererType, m_graph, 2); /* Do some VMR9 specific stuff */ if (rendererType == VideoRendererType.VideoMixingRenderer9) { var mixer = m_renderer as IVMRMixerControl9; if (mixer != null) { VMR9MixerPrefs dwPrefs; mixer.GetMixingPrefs(out dwPrefs); dwPrefs &= ~VMR9MixerPrefs.RenderTargetMask; dwPrefs |= VMR9MixerPrefs.RenderTargetYUV; /* Enable this line to prefer YUV */ //hr = mixer.SetMixingPrefs(dwPrefs); } } /* Create a new DVD Navigator. */ var dvdNav = (IBaseFilter) new DVDNavigator(); /* The DVDControl2 interface lets us control DVD features */ m_dvdControl = dvdNav as IDvdControl2; if (m_dvdControl == null) { throw new Exception("Could not QueryInterface the IDvdControl2 interface"); } /* QueryInterface the DVDInfo2 */ m_dvdInfo = dvdNav as IDvdInfo2; /* If a Dvd directory has been set then use it, if not, let DShow find the Dvd */ if (!string.IsNullOrEmpty(DvdDirectory)) { hr = m_dvdControl.SetDVDDirectory(DvdDirectory); DsError.ThrowExceptionForHR(hr); } /* This gives us the DVD time in Hours-Minutes-Seconds-Frame time format, and other options */ hr = m_dvdControl.SetOption(DvdOptionFlag.HMSFTimeCodeEvents, true); DsError.ThrowExceptionForHR(hr); /* If the graph stops, resume at the same point */ m_dvdControl.SetOption(DvdOptionFlag.ResetOnStop, false); hr = m_graph.AddFilter(dvdNav, "DVD Navigator"); DsError.ThrowExceptionForHR(hr); IPin dvdVideoPin = null; IPin dvdAudioPin = null; IPin dvdSubPicturePin = null; IPin dvdNavPin; int i = 0; /* Loop all the output pins on the DVD Navigator, trying to find which pins are which. * We could more easily find the pins by name, but this is more fun...and more flexible * if we ever want to use a 3rd party DVD navigator that used different pin names */ while ((dvdNavPin = DsFindPin.ByDirection(dvdNav, PinDirection.Output, i)) != null) { var mediaTypes = new AMMediaType[1]; IntPtr pFetched = IntPtr.Zero; IEnumMediaTypes mediaTypeEnum; dvdNavPin.EnumMediaTypes(out mediaTypeEnum); /* Loop over each of the mediaTypes of each pin */ while (mediaTypeEnum.Next(1, mediaTypes, pFetched) == 0) { AMMediaType mediaType = mediaTypes[0]; /* This will be the video stream pin */ if (mediaType.subType == MediaSubType.Mpeg2Video) { /* Keep the ref and we'll work with it later */ dvdVideoPin = dvdNavPin; break; } /* This will be the audio stream pin */ if (mediaType.subType == MediaSubType.DolbyAC3 || mediaType.subType == MediaSubType.Mpeg2Audio) { /* Keep the ref and we'll work with it later */ dvdAudioPin = dvdNavPin; break; } /* This is the Dvd sub picture pin. This generally * shows overlays for Dvd menus and sometimes closed captions */ if (mediaType.subType == DVD_SUBPICTURE_TYPE) { /* Keep the ref and we'll work with it later */ dvdSubPicturePin = dvdNavPin; break; } } mediaTypeEnum.Reset(); Marshal.ReleaseComObject(mediaTypeEnum); i++; } /* This is the windowed renderer. This is *NEEDED* in order * for interactive menus to work with the other VMR9 in renderless mode */ var dummyRenderer = (IBaseFilter) new VideoMixingRenderer9(); var dummyRendererConfig = (IVMRFilterConfig9)dummyRenderer; /* In order for this interactive menu trick to work, the VMR9 * must be set to Windowed. We will make sure the window is hidden later on */ hr = dummyRendererConfig.SetRenderingMode(VMR9Mode.Windowed); DsError.ThrowExceptionForHR(hr); hr = dummyRendererConfig.SetNumberOfStreams(1); DsError.ThrowExceptionForHR(hr); hr = m_graph.AddFilter(dummyRenderer, "Dummy Windowed"); DsError.ThrowExceptionForHR(hr); if (dvdAudioPin != null) { /* This should render out to the default audio device. We * could modify this code here to go out any audio * device, such as SPDIF or another sound card */ hr = m_graph.Render(dvdAudioPin); DsError.ThrowExceptionForHR(hr); } /* Get the first input pin on our dummy renderer */ m_dummyRendererPin = DsFindPin.ByConnectionStatus(dummyRenderer, /* Filter to search */ PinConnectedStatus.Unconnected, 0); /* Get an available pin on our real renderer */ IPin rendererPin = DsFindPin.ByConnectionStatus(m_renderer, /* Filter to search */ PinConnectedStatus.Unconnected, 0); /* Pin index */ /* Connect the pin to the renderer */ hr = m_graph.Connect(dvdVideoPin, rendererPin); DsError.ThrowExceptionForHR(hr); /* Get the next available pin on our real renderer */ rendererPin = DsFindPin.ByConnectionStatus(m_renderer, /* Filter to search */ PinConnectedStatus.Unconnected, 0); /* Pin index */ /* Render the sub picture, which will connect * the DVD navigator to the codec, not the renderer */ hr = m_graph.Render(dvdSubPicturePin); DsError.ThrowExceptionForHR(hr); /* These are the subtypes most likely to be our dvd subpicture */ var preferedSubpictureTypes = new[] { MediaSubType.ARGB4444, MediaSubType.AI44, MediaSubType.AYUV, MediaSubType.ARGB32 }; IPin dvdSubPicturePinOut = null; /* Find what should be the subpicture pin out */ foreach (var guidType in preferedSubpictureTypes) { dvdSubPicturePinOut = FindPinInGraphByMediaType(guidType, /* GUID of the media type being searched for */ PinDirection.Output, m_graph); /* Our current graph */ if (dvdSubPicturePinOut != null) { break; } } if (dvdSubPicturePinOut == null) { throw new Exception("Could not find the sub picture pin out"); } /* Here we connec thte Dvd sub picture pin to the video renderer. * This enables the overlays on Dvd menus and some closed * captions to be rendered. */ hr = m_graph.Connect(dvdSubPicturePinOut, rendererPin); DsError.ThrowExceptionForHR(hr); /* Search for the Line21 out in the graph */ IPin line21Out = FindPinInGraphByMediaType(MediaType.AuxLine21Data, PinDirection.Output, m_graph); if (line21Out == null) { throw new Exception("Could not find the Line21 pin out"); } /* We connect our line21Out out in to the dummy renderer * this is what ultimatly makes interactive DVDs work with * VMR9 in renderless (for WPF) */ hr = m_graph.Connect(line21Out, m_dummyRendererPin); DsError.ThrowExceptionForHR(hr); /* This is the dummy renderers Win32 window. */ m_dummyRenderWindow = dummyRenderer as IVideoWindow; if (m_dummyRenderWindow == null) { throw new Exception("Could not QueryInterface for IVideoWindow"); } ConfigureDummyWindow(); /* Setup our base classes with this filter graph */ SetupFilterGraph(m_graph); /* Sets the NaturalVideoWidth/Height */ //SetNativePixelSizes(m_renderer); } catch (Exception ex) { FreeResources(); InvokeMediaFailed(new MediaFailedEventArgs(ex.Message, ex)); return; } InvokeMediaOpened(); }
/// <summary> /// Adds the DVDNavigator filter to the graph and sets the input path. /// </summary> protected override void AddSourceFilter() { ServiceRegistration.Get<ILogger>().Debug("DvdPlayer.AddSourceFilter"); _pendingCmd = true; _dvdbasefilter = (IBaseFilter) new DVDNavigator(); _graphBuilder.AddFilter(_dvdbasefilter, DVD_NAVIGATOR); if (_dvdbasefilter == null) throw new Exception("Failed to add DVD Navigator!"); _dvdInfo = _dvdbasefilter as IDvdInfo2; _dvdCtrl = _dvdbasefilter as IDvdControl2; if (_dvdCtrl == null) throw new Exception("Failed to access DVD Control!"); // get a local file system path - will mount via DOKAN when resource is not on the local system ILocalFsResourceAccessor lfsr; if (!_resourceLocator.TryCreateLocalFsAccessor(out lfsr)) throw new IllegalCallException("The DvDPlayer can only play file system resources"); string path = lfsr.LocalFileSystemPath; // check if path is a drive root (like D:), otherwise append VIDEO_TS // MediaItem always contains the parent folder. Add the required VIDEO_TS subfolder. if (!String.IsNullOrEmpty(path) && !path.EndsWith(Path.VolumeSeparatorChar.ToString())) path = Path.Combine(path, "VIDEO_TS"); int hr = _dvdCtrl.SetDVDDirectory(path); if (hr != 0) throw new Exception("Failed to set DVD directory!"); _dvdCtrl.SetOption(DvdOptionFlag.HMSFTimeCodeEvents, true); // use new HMSF timecode format _dvdCtrl.SetOption(DvdOptionFlag.ResetOnStop, false); _mediaEvt = _graphBuilder as IMediaEventEx; if (_mediaEvt != null) { IScreenControl screenControl = ServiceRegistration.Get<IScreenControl>(); _mediaEvt.SetNotifyWindow(screenControl.MainWindowHandle, WM_DVD_EVENT, _instancePtr); } SetDefaultLanguages(); }
void PreviewInit() { m_dvdNav = (IBaseFilter)new DVDNavigator(); m_dvdCtrl = m_dvdNav as IDvdControl2; int hr = m_dvdCtrl.SetDVDDirectory(Disk.VIDEO_TS); DsError.ThrowExceptionForHR(hr); m_dvdInfo = m_dvdCtrl as IDvdInfo2; m_filterGraph = (IGraphBuilder)new FilterGraph(); hr = m_filterGraph.AddFilter(m_dvdNav, "DVD Navigator"); DsError.ThrowExceptionForHR(hr); m_renderer = (IBaseFilter)new VideoMixingRenderer9(); IVMRFilterConfig9 filterConfig = (IVMRFilterConfig9)m_renderer; hr = filterConfig.SetRenderingMode(VMR9Mode.Renderless); DsError.ThrowExceptionForHR(hr); hr = filterConfig.SetNumberOfStreams(1); DsError.ThrowExceptionForHR(hr); hr = m_filterGraph.AddFilter(m_renderer, "Video Mix 9"); DsError.ThrowExceptionForHR(hr); IPin videoPin; hr = m_dvdNav.FindPin("Video", out videoPin); DsError.ThrowExceptionForHR(hr); IPin audioPin; hr = m_dvdNav.FindPin("AC3", out audioPin); DsError.ThrowExceptionForHR(hr); //hr = m_filterGraph.Render(videoPin); //DsError.ThrowExceptionForHR(hr); //hr = m_filterGraph.Render(audioPin); //DsError.ThrowExceptionForHR(hr); //IMediaControl mediaCtrl = (IMediaControl)m_filterGraph; //hr = mediaCtrl.Run(); //DsError.ThrowExceptionForHR(hr); //hr = m_dvdCtrl.SetOption(DvdOptionFlag.EnableNonblockingAPIs, true); //DsError.ThrowExceptionForHR(hr); //m_dvdCtrl.SetOption(DvdOptionFlag.ResetOnStop, true); }