protected override void OnGraphTimerTick() { if (m_graph != null) { IBaseFilter sourceFilter = null; try { int result = m_graph.FindFilterByName(OnlineVideos.MPUrlSourceFilter.Downloader.FilterName, out sourceFilter); if (result == 0) { long total = 0, current = 0; ((IAMOpenProgress)sourceFilter).QueryProgress(out total, out current); m_BufferedPercent = (float)current / (float)total * 100.0f; InvokeBufferedPercentChanged(); } } catch (Exception ex) { OnlineVideos.Log.Warn("Error Quering Progress: {0}", ex.Message); } finally { if (sourceFilter != null) { Marshal.ReleaseComObject(sourceFilter); } } } base.OnGraphTimerTick(); }
public bool DisplayFilterPropPage(IntPtr hParent, string strFilter, bool bDisplay) { if (_graphBuilder == null) { return(false); } IBaseFilter pFilter; _graphBuilder.FindFilterByName(strFilter, out pFilter); if (pFilter == null) { return(false); } var bRet = false; var pProp = pFilter as ISpecifyPropertyPages; if (pProp != null) { CAUUID caGuid; var hr = pProp.GetPages(out caGuid); if (DsHlp.SUCCEEDED(hr) && caGuid.cElems > 0) { bRet = true; if (bDisplay) { // Show the page object pFilterUnk = pFilter; DsUtils.OleCreatePropertyFrame( hParent, // Parent window 0, 0, // Reserved strFilter, // Caption for the dialog box 1, // Number of objects (just the filter) ref pFilterUnk, // Array of object pointers. caGuid.cElems, // Number of property pages caGuid.pElems, // Array of property page CLSIDs 0, // Locale identifier 0, IntPtr.Zero // Reserved ); } } // Clean up if (caGuid.pElems != IntPtr.Zero) { Marshal.FreeCoTaskMem(caGuid.pElems); } } Marshal.ReleaseComObject(pFilter); return(bRet); }
private void Configure() { int hr; IGraphBuilder gb = null; AMDvdRenderStatus drs; IDvdGraphBuilder idgb = null; ICaptureGraphBuilder2 icgb = (ICaptureGraphBuilder2) new CaptureGraphBuilder2(); object o; IBaseFilter pFilter; // Get the IDvdGraphBuilder interface idgb = (IDvdGraphBuilder) new DvdGraphBuilder(); hr = idgb.RenderDvdVideoVolume(MyDisk, AMDvdGraphFlags.HWDecPrefer, out drs); DsError.ThrowExceptionForHR(hr); // If there is no dvd in the player, you get hr == S_FALSE (1) Debug.Assert(hr == 0, "Can't find dvd"); // Get an IFilterGraph interface hr = idgb.GetFiltergraph(out gb); DsError.ThrowExceptionForHR(hr); hr = icgb.SetFiltergraph(gb); DsError.ThrowExceptionForHR(hr); hr = gb.FindFilterByName("DVD Navigator", out pFilter); DsError.ThrowExceptionForHR(hr); hr = icgb.FindInterface(null, null, pFilter, typeof(IAMDecoderCaps).GUID, out o); DsError.ThrowExceptionForHR(hr); m_idc = (IAMDecoderCaps)o; }
private IBaseFilter GetSourceFilter() { IBaseFilter source; var hr = graphBuilder.FindFilterByName(SourceFilterName, out source); DsError.ThrowExceptionForHR(hr); return(source); }
private void Config() { IBaseFilter pFilter; IGraphBuilder gb = (IGraphBuilder) new FilterGraph(); m_mc = (IMediaControl)gb; int hr = gb.RenderFile(@"foo.avi", null); hr = gb.FindFilterByName("Video Renderer", out pFilter); IPin iPin = DsFindPin.ByDirection(pFilter, PinDirection.Input, 0); m_pc = iPin as IPinConnection; }
private void Config() { IGraphBuilder gb = (IGraphBuilder) new FilterGraph(); IBaseFilter pFilter; int hr = gb.RenderFile(@"nwn.mp1", null); DsError.ThrowExceptionForHR(hr); hr = gb.FindFilterByName("MPEG-I Stream Splitter", out pFilter); DsError.ThrowExceptionForHR(hr); m_ss = pFilter as IAMStreamSelect; }
private void PlayMovieInWindow() { int hr = 0; this.graphBuilder = (IGraphBuilder)new FilterGraph(); //Добавляем в граф нужный рендерер (Auto - graphBuilder сам выберет рендерер) Settings.VRenderers renderer = Settings.VideoRenderer; if (renderer == Settings.VRenderers.Overlay) { IBaseFilter add_vr = (IBaseFilter)new VideoRenderer(); hr = graphBuilder.AddFilter(add_vr, "Video Renderer"); DsError.ThrowExceptionForHR(hr); } else if (renderer == Settings.VRenderers.VMR7) { IBaseFilter add_vmr = (IBaseFilter)new VideoMixingRenderer(); hr = graphBuilder.AddFilter(add_vmr, "Video Renderer"); DsError.ThrowExceptionForHR(hr); } else if (renderer == Settings.VRenderers.VMR9) { IBaseFilter add_vmr9 = (IBaseFilter)new VideoMixingRenderer9(); hr = graphBuilder.AddFilter(add_vmr9, "Video Mixing Renderer 9"); DsError.ThrowExceptionForHR(hr); } else if (renderer == Settings.VRenderers.EVR) { //Создаём Win32-окно, т.к. использовать WPF-поверхность не получится VHost = new VideoHwndHost(); VHost.RepaintRequired += new EventHandler(VHost_RepaintRequired); VHostElement.Visibility = Visibility.Visible; VHostElement.Child = VHost; VHandle = VHost.Handle; //Добавляем и настраиваем EVR IBaseFilter add_evr = (IBaseFilter)new EnhancedVideoRenderer(); hr = graphBuilder.AddFilter(add_evr, "Enhanced Video Renderer"); DsError.ThrowExceptionForHR(hr); object obj; IMFGetService pGetService = null; pGetService = (IMFGetService)add_evr; hr = pGetService.GetService(MFServices.MR_VIDEO_RENDER_SERVICE, typeof(IMFVideoDisplayControl).GUID, out obj); MFError.ThrowExceptionForHR(hr); try { EVRControl = (IMFVideoDisplayControl)obj; } catch { Marshal.ReleaseComObject(obj); throw; } //Указываем поверхность hr = EVRControl.SetVideoWindow(VHandle); MFError.ThrowExceptionForHR(hr); //Сохраняем аспект hr = EVRControl.SetAspectRatioMode(MFVideoAspectRatioMode.PreservePicture); MFError.ThrowExceptionForHR(hr); } // Have the graph builder construct its the appropriate graph automatically hr = this.graphBuilder.RenderFile(this.filepath, null); DsError.ThrowExceptionForHR(hr); if (EVRControl == null) { //Ищем рендерер и ВКЛЮЧАЕМ соблюдение аспекта (рендерер сам подгонит картинку под размер окна, с учетом аспекта) IsRendererARFixed = false; IBaseFilter filter = null; graphBuilder.FindFilterByName("Video Renderer", out filter); if (filter != null) { IVMRAspectRatioControl vmr = filter as IVMRAspectRatioControl; if (vmr != null) { DsError.ThrowExceptionForHR(vmr.SetAspectRatioMode(VMRAspectRatioMode.LetterBox)); IsRendererARFixed = true; } } else { graphBuilder.FindFilterByName("Video Mixing Renderer 9", out filter); if (filter != null) { IVMRAspectRatioControl9 vmr9 = filter as IVMRAspectRatioControl9; if (vmr9 != null) { DsError.ThrowExceptionForHR(vmr9.SetAspectRatioMode(VMRAspectRatioMode.LetterBox)); IsRendererARFixed = true; } } } } else IsRendererARFixed = true; this.mediaControl = (IMediaControl)this.graphBuilder; this.mediaEventEx = (IMediaEventEx)this.graphBuilder; this.mediaSeeking = (IMediaSeeking)this.graphBuilder; this.mediaPosition = (IMediaPosition)this.graphBuilder; this.videoWindow = (EVRControl == null) ? this.graphBuilder as IVideoWindow : null; this.basicVideo = (EVRControl == null) ? this.graphBuilder as IBasicVideo : null; this.basicAudio = this.graphBuilder as IBasicAudio; this.basicAudio.put_Volume(VolumeSet); this.CheckIsAudioOnly(); if (!this.isAudioOnly) { if (videoWindow != null) { hr = this.videoWindow.put_Owner(this.source.Handle); DsError.ThrowExceptionForHR(hr); hr = this.videoWindow.put_MessageDrain(this.source.Handle); DsError.ThrowExceptionForHR(hr); hr = this.videoWindow.put_WindowStyle(DirectShowLib.WindowStyle.Child | DirectShowLib.WindowStyle.ClipSiblings | DirectShowLib.WindowStyle.ClipChildren); DsError.ThrowExceptionForHR(hr); } this.MoveVideoWindow(); } else { if (VHost != null) { VHost.Dispose(); VHost = null; VHandle = IntPtr.Zero; VHostElement.Child = null; VHostElement.Visibility = Visibility.Collapsed; } } hr = this.mediaEventEx.SetNotifyWindow(this.source.Handle, WMGraphNotify, IntPtr.Zero); DsError.ThrowExceptionForHR(hr); //Восстанавливаем старую позицию if (mediaload == MediaLoad.Update && oldpos != TimeSpan.Zero) { if (NaturalDuration >= oldpos) { hr = mediaPosition.put_CurrentPosition(oldpos.TotalSeconds); DsError.ThrowExceptionForHR(hr); } } //Восстанавливаем старый PlayState if (mediaload == MediaLoad.Update && (oldplaystate == PlayState.Paused || oldplaystate == PlayState.Stopped)) { hr = this.mediaControl.Pause(); DsError.ThrowExceptionForHR(hr); this.currentState = PlayState.Paused; this.SetPlayIcon(); } else { hr = this.mediaControl.Run(); DsError.ThrowExceptionForHR(hr); this.currentState = PlayState.Running; this.SetPauseIcon(); } AddFiltersToMenu(); }
/// <summary> build the capture graph for grabber. </summary> private void SetupGraph(string FileName) { int hr; // Get the graphbuilder object this.graphBuilder = new FilterGraph() as IGraphBuilder; this.mediaControl = this.graphBuilder as IMediaControl; this.mediaSeeking = this.graphBuilder as IMediaSeeking; this.mediaEvent = this.graphBuilder as IMediaEvent; try { // Get the SampleGrabber interface this.sampleGrabber = new SampleGrabber() as ISampleGrabber; this.sampleGrabberFilter = sampleGrabber as IBaseFilter; ConfigureSampleGrabber(sampleGrabber); // Add the frame grabber to the graph hr = graphBuilder.AddFilter(sampleGrabberFilter, "Ds.NET Sample Grabber"); DsError.ThrowExceptionForHR(hr); IBaseFilter aviSplitter = new AviSplitter() as IBaseFilter; // Add the aviSplitter to the graph hr = graphBuilder.AddFilter(aviSplitter, "Splitter"); DsError.ThrowExceptionForHR(hr); // Have the graph builder construct its appropriate graph automatically hr = this.graphBuilder.RenderFile(FileName, null); DsError.ThrowExceptionForHR(hr); #if DEBUG m_rot = new DsROTEntry(graphBuilder); #endif // Remove the video renderer filter IBaseFilter defaultVideoRenderer = null; graphBuilder.FindFilterByName("Video Renderer", out defaultVideoRenderer); graphBuilder.RemoveFilter(defaultVideoRenderer); // Disconnect anything that is connected // to the output of the sample grabber IPin iPinSampleGrabberOut = DsFindPin.ByDirection(sampleGrabberFilter, PinDirection.Output, 0); IPin iPinVideoIn; hr = iPinSampleGrabberOut.ConnectedTo(out iPinVideoIn); if (hr == 0) { // Disconnect the sample grabber output from the attached filters hr = iPinVideoIn.Disconnect(); DsError.ThrowExceptionForHR(hr); hr = iPinSampleGrabberOut.Disconnect(); DsError.ThrowExceptionForHR(hr); } else { // Try other way round because automatic renderer could not build // graph including the sample grabber IPin iPinAVISplitterOut = DsFindPin.ByDirection(aviSplitter, PinDirection.Output, 0); IPin iPinAVISplitterIn; hr = iPinAVISplitterOut.ConnectedTo(out iPinAVISplitterIn); DsError.ThrowExceptionForHR(hr); hr = iPinAVISplitterOut.Disconnect(); DsError.ThrowExceptionForHR(hr); hr = iPinAVISplitterIn.Disconnect(); DsError.ThrowExceptionForHR(hr); // Connect the avi splitter output to sample grabber IPin iPinSampleGrabberIn = DsFindPin.ByDirection(sampleGrabberFilter, PinDirection.Input, 0); hr = graphBuilder.Connect(iPinAVISplitterOut, iPinSampleGrabberIn); DsError.ThrowExceptionForHR(hr); } // Add the null renderer to the graph nullrenderer = new NullRenderer() as IBaseFilter; hr = graphBuilder.AddFilter(nullrenderer, "Null renderer"); DsError.ThrowExceptionForHR(hr); // Get the input pin of the null renderer IPin iPinNullRendererIn = DsFindPin.ByDirection(nullrenderer, PinDirection.Input, 0); // Connect the sample grabber to the null renderer hr = graphBuilder.Connect(iPinSampleGrabberOut, iPinNullRendererIn); DsError.ThrowExceptionForHR(hr); // Read and cache the image sizes SaveSizeInfo(sampleGrabber); this.GetFrameStepInterface(); } finally { } }
void SetupPlaybackGraph(string fname) { int hr; try { hr = graphBuilder.RenderFile(fname, null); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } AMMediaType media = new AMMediaType(); media.majorType = MediaType.Video; media.subType = MediaSubType.RGB24; media.formatType = FormatType.VideoInfo; // ??? hr = sampGrabber.SetMediaType(media); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } hr = graphBuilder.AddFilter(baseGrabFlt, "Ds.NET Grabber"); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } hr = graphBuilder.AddFilter(smartTee, "smartTee"); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } IBaseFilter renderer; hr = graphBuilder.FindFilterByName("Video Renderer", out renderer); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } IPin inPin; IPin srcPin; hr = DsUtils.GetPin(renderer, PinDirection.Input, out inPin, 0); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } hr = inPin.ConnectedTo(out srcPin); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } hr = srcPin.Disconnect(); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } hr = graphBuilder.RemoveFilter(renderer); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } Marshal.ReleaseComObject(renderer); Marshal.ReleaseComObject(inPin); hr = DsUtils.GetPin(smartTee, PinDirection.Input, out inPin, 0); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } hr = graphBuilder.Connect(srcPin, inPin); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } Marshal.ReleaseComObject(srcPin); Marshal.ReleaseComObject(inPin); srcPin = inPin = null; hr = DsUtils.GetPin(smartTee, PinDirection.Output, out srcPin, 1); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } // grabber Input hr = DsUtils.GetPin(baseGrabFlt, PinDirection.Input, out inPin, 0); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } // smartTee -> grabber hr = graphBuilder.Connect(srcPin, inPin); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } Marshal.ReleaseComObject(srcPin); Marshal.ReleaseComObject(inPin); srcPin = inPin = null; if (preview) { // grabber Input hr = DsUtils.GetPin(smartTee, PinDirection.Output, out srcPin, 0); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } hr = graphBuilder.Render(srcPin); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } Marshal.ReleaseComObject(srcPin); srcPin = null; } media = new AMMediaType(); hr = sampGrabber.GetConnectedMediaType(media); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } if ((media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero)) { throw new NotSupportedException("Unknown Grabber Media Format"); } videoInfoHeader = (VideoInfoHeader)Marshal.PtrToStructure(media.formatPtr, typeof(VideoInfoHeader)); Marshal.FreeCoTaskMem(media.formatPtr); media.formatPtr = IntPtr.Zero; //Modified according to the platform SDK, to capture the buffer hr = sampGrabber.SetBufferSamples(false); if (hr == 0) { hr = sampGrabber.SetOneShot(false); } if (hr == 0) { hr = sampGrabber.SetCallback(sampleGrabber, 1); } if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } } catch (Exception ee) { throw new Exception("Could not setup graph\r\n" + ee.Message); } }
/// <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> /// Find the overlay mixer and/or the VMR9 windowless filters /// and tell them we dont want a fixed Aspect Ratio /// Mediaportal handles AR itself /// </summary> /// <param name="graphBuilder"></param> public static void SetARMode(IGraphBuilder graphBuilder, AspectRatioMode ARRatioMode) { int hr; IBaseFilter overlay; graphBuilder.FindFilterByName("Overlay Mixer2", out overlay); if (overlay != null) { IPin iPin; overlay.FindPin("Input0", out iPin); if (iPin != null) { IMixerPinConfig pMC = iPin as IMixerPinConfig; if (pMC != null) { AspectRatioMode mode; hr = pMC.SetAspectRatioMode(ARRatioMode); hr = pMC.GetAspectRatioMode(out mode); //ReleaseComObject(pMC); } ReleaseComObject(iPin); } ReleaseComObject(overlay); } IEnumFilters enumFilters; hr = graphBuilder.EnumFilters(out enumFilters); if (hr >= 0 && enumFilters != null) { int iFetched; enumFilters.Reset(); IBaseFilter[] pBasefilter = new IBaseFilter[2]; do { pBasefilter = null; hr = enumFilters.Next(1, pBasefilter, out iFetched); if (hr == 0 && iFetched == 1 && pBasefilter[0] != null) { IVMRAspectRatioControl pARC = pBasefilter[0] as IVMRAspectRatioControl; if (pARC != null) { pARC.SetAspectRatioMode(VMRAspectRatioMode.None); } IVMRAspectRatioControl9 pARC9 = pBasefilter[0] as IVMRAspectRatioControl9; if (pARC9 != null) { pARC9.SetAspectRatioMode(VMRAspectRatioMode.None); } IEnumPins pinEnum; hr = pBasefilter[0].EnumPins(out pinEnum); if ((hr == 0) && (pinEnum != null)) { pinEnum.Reset(); IPin[] pins = new IPin[1]; int f; do { // Get the next pin hr = pinEnum.Next(1, pins, out f); if (f == 1 && hr == 0 && pins[0] != null) { IMixerPinConfig pMC = pins[0] as IMixerPinConfig; if (null != pMC) { pMC.SetAspectRatioMode(ARRatioMode); } ReleaseComObject(pins[0]); } } while (f == 1); ReleaseComObject(pinEnum); } ReleaseComObject(pBasefilter[0]); } } while (iFetched == 1 && pBasefilter[0] != null); ReleaseComObject(enumFilters); } }
private void SetupSampleGrabber() { if (_graph == null) { return; } int hr; //Get directsound filter IBaseFilter directSoundFilter; hr = _graph.FindFilterByName(DEFAULT_AUDIO_RENDERER_NAME, out directSoundFilter); DsError.ThrowExceptionForHR(hr); IPin rendererPinIn = DsFindPin.ByConnectionStatus(directSoundFilter, PinConnectedStatus.Connected, 0); if (rendererPinIn != null) { IPin audioPinOut; hr = rendererPinIn.ConnectedTo(out audioPinOut); DsError.ThrowExceptionForHR(hr); if (audioPinOut != null) { //Disconect audio decoder to directsound renderer hr = audioPinOut.Disconnect(); DsError.ThrowExceptionForHR(hr); hr = _graph.RemoveFilter(directSoundFilter); DsError.ThrowExceptionForHR(hr); //Add Sample Grabber ISampleGrabber sampleGrabber = new SampleGrabber() as ISampleGrabber; hr = sampleGrabber.SetCallback(this, 1); DsError.ThrowExceptionForHR(hr); AMMediaType media; media = new AMMediaType(); media.majorType = MediaType.Audio; media.subType = MediaSubType.PCM; media.formatType = FormatType.WaveEx; hr = sampleGrabber.SetMediaType(media); DsError.ThrowExceptionForHR(hr); IPin sampleGrabberPinIn = DsFindPin.ByDirection((IBaseFilter)sampleGrabber, PinDirection.Input, 0); IPin sampleGrabberPinOut = DsFindPin.ByDirection((IBaseFilter)sampleGrabber, PinDirection.Output, 0); hr = _graph.AddFilter((IBaseFilter)sampleGrabber, "SampleGrabber"); DsError.ThrowExceptionForHR(hr); PinInfo pinInfo; hr = audioPinOut.QueryPinInfo(out pinInfo); DsError.ThrowExceptionForHR(hr); FilterInfo filterInfo; hr = pinInfo.filter.QueryFilterInfo(out filterInfo); DsError.ThrowExceptionForHR(hr); hr = _graph.Connect(audioPinOut, sampleGrabberPinIn); DsError.ThrowExceptionForHR(hr); //Add null renderer NullRenderer nullRenderer = new NullRenderer(); hr = _graph.AddFilter((IBaseFilter)nullRenderer, "NullRenderer"); DsError.ThrowExceptionForHR(hr); IPin nullRendererPinIn = DsFindPin.ByDirection((IBaseFilter)nullRenderer, PinDirection.Input, 0); hr = _graph.Connect(sampleGrabberPinOut, nullRendererPinIn); DsError.ThrowExceptionForHR(hr); _audioEngine.Setup(this.GetSampleGrabberFormat(sampleGrabber)); } } }
private void PlayMovieInWindow(string filename) { fps = 0; int hr = 0; this.graphBuilder = (IGraphBuilder)new FilterGraph(); //Добавляем в граф нужный рендерер (Auto - graphBuilder сам выберет рендерер) Settings.VRenderers renderer = Settings.VideoRenderer; if (renderer == Settings.VRenderers.Overlay) { IBaseFilter add_vr = (IBaseFilter)new VideoRenderer(); hr = graphBuilder.AddFilter(add_vr, "Video Renderer"); DsError.ThrowExceptionForHR(hr); } else if (renderer == Settings.VRenderers.VMR7) { IBaseFilter add_vmr = (IBaseFilter)new VideoMixingRenderer(); hr = graphBuilder.AddFilter(add_vmr, "Video Renderer"); DsError.ThrowExceptionForHR(hr); } else if (renderer == Settings.VRenderers.VMR9) { IBaseFilter add_vmr9 = (IBaseFilter)new VideoMixingRenderer9(); hr = graphBuilder.AddFilter(add_vmr9, "Video Mixing Renderer 9"); DsError.ThrowExceptionForHR(hr); } else if (renderer == Settings.VRenderers.EVR) { //Создаём Win32-окно, т.к. использовать WPF-поверхность не получится VHost = new VideoHwndHost(); VHost.RepaintRequired += new EventHandler(VHost_RepaintRequired); VHostElement.Visibility = Visibility.Visible; VHostElement.Child = VHost; VHandle = VHost.Handle; //Добавляем и настраиваем EVR IBaseFilter add_evr = (IBaseFilter)new EnhancedVideoRenderer(); hr = graphBuilder.AddFilter(add_evr, "Enhanced Video Renderer"); DsError.ThrowExceptionForHR(hr); object obj; IMFGetService pGetService = null; pGetService = (IMFGetService)add_evr; hr = pGetService.GetService(MFServices.MR_VIDEO_RENDER_SERVICE, typeof(IMFVideoDisplayControl).GUID, out obj); MFError.ThrowExceptionForHR(hr); try { EVRControl = (IMFVideoDisplayControl)obj; } catch { Marshal.ReleaseComObject(obj); throw; } //Указываем поверхность hr = EVRControl.SetVideoWindow(VHandle); MFError.ThrowExceptionForHR(hr); //Отключаем сохранение аспекта hr = EVRControl.SetAspectRatioMode(MFVideoAspectRatioMode.None); MFError.ThrowExceptionForHR(hr); } // Have the graph builder construct its the appropriate graph automatically hr = this.graphBuilder.RenderFile(filename, null); DsError.ThrowExceptionForHR(hr); if (EVRControl == null) { //Ищем рендерер и отключаем соблюдение аспекта (аспект будет определяться размерами видео-окна) IBaseFilter filter = null; graphBuilder.FindFilterByName("Video Renderer", out filter); if (filter != null) { IVMRAspectRatioControl vmr = filter as IVMRAspectRatioControl; if (vmr != null) DsError.ThrowExceptionForHR(vmr.SetAspectRatioMode(VMRAspectRatioMode.None)); } else { graphBuilder.FindFilterByName("Video Mixing Renderer 9", out filter); if (filter != null) { IVMRAspectRatioControl9 vmr9 = filter as IVMRAspectRatioControl9; if (vmr9 != null) DsError.ThrowExceptionForHR(vmr9.SetAspectRatioMode(VMRAspectRatioMode.None)); } } } // QueryInterface for DirectShow interfaces this.mediaControl = (IMediaControl)this.graphBuilder; this.mediaEventEx = (IMediaEventEx)this.graphBuilder; this.mediaSeeking = (IMediaSeeking)this.graphBuilder; this.mediaPosition = (IMediaPosition)this.graphBuilder; // Query for video interfaces, which may not be relevant for audio files this.videoWindow = (EVRControl == null) ? this.graphBuilder as IVideoWindow : null; this.basicVideo = (EVRControl == null) ? this.graphBuilder as IBasicVideo : null; // Query for audio interfaces, which may not be relevant for video-only files this.basicAudio = this.graphBuilder as IBasicAudio; basicAudio.put_Volume(VolumeSet); //Ввод в ДиректШоу значения VolumeSet для установки громкости // Is this an audio-only file (no video component)? CheckIsAudioOnly(); if (!this.IsAudioOnly) { if (videoWindow != null) { // Setup the video window hr = this.videoWindow.put_Owner(this.source.Handle); DsError.ThrowExceptionForHR(hr); hr = this.videoWindow.put_MessageDrain(this.source.Handle); DsError.ThrowExceptionForHR(hr); hr = this.videoWindow.put_WindowStyle(DirectShowLib.WindowStyle.Child | DirectShowLib.WindowStyle.ClipSiblings | DirectShowLib.WindowStyle.ClipChildren); DsError.ThrowExceptionForHR(hr); //Определяем fps double AvgTimePerFrame; hr = basicVideo.get_AvgTimePerFrame(out AvgTimePerFrame); DsError.ThrowExceptionForHR(hr); fps = (1.0 / AvgTimePerFrame); } else if (EVRControl != null) { //Определяем fps DetermineEVRFPS(); } //Ловим ошибку Ависинта IsAviSynthError = false; if (NaturalDuration.TotalMilliseconds == 10000.0) { //Признаки ошибки: duration=10000.0 и fps=24 (округлённо) if ((int)fps == 24 || fps == 0) IsAviSynthError = true; } MoveVideoWindow(); } else { if (VHost != null) { VHost.Dispose(); VHost = null; VHandle = IntPtr.Zero; VHostElement.Child = null; VHostElement.Visibility = Visibility.Collapsed; VHostElement.Width = VHostElement.Height = 0; VHostElement.Margin = new Thickness(0); } //Ловим ошибку Ависинта 2 (когда нет видео окна) IsAviSynthError = (NaturalDuration.TotalMilliseconds == 10000.0); if (m.isvideo) { //Видео должно было быть.. PreviewError("NO VIDEO", Brushes.Gainsboro); } } //Если выше не удалось определить fps - берём значение из массива if (fps == 0) fps = Calculate.ConvertStringToDouble(m.outframerate); // Have the graph signal event via window callbacks for performance hr = this.mediaEventEx.SetNotifyWindow(this.source.Handle, WMGraphNotify, IntPtr.Zero); DsError.ThrowExceptionForHR(hr); if (mediaload == MediaLoad.update) //Перенесено из HandleGraphEvent, теперь позиция устанавливается до начала воспроизведения, т.е. за один заход, а не за два { if (NaturalDuration >= oldpos) //Позиционируем только если нужная позиция укладывается в допустимый диапазон mediaPosition.put_CurrentPosition(oldpos.TotalSeconds); //else // mediaPosition.put_CurrentPosition(NaturalDuration.TotalSeconds); //Ограничиваем позицию длиной клипа } // Run the graph to play the media file if (currentState == PlayState.Running) { //Продолжение воспроизведения, если статус до обновления был Running DsError.ThrowExceptionForHR(this.mediaControl.Run()); SetPauseIcon(); } else { //Запуск с паузы, если была пауза или это новое открытие файла DsError.ThrowExceptionForHR(this.mediaControl.Pause()); this.currentState = PlayState.Paused; SetPlayIcon(); } }
private void PlayMovieInWindow(string filename) { if (filename == string.Empty) return; int hr = 0; this.graphBuilder = (IGraphBuilder)new FilterGraph(); //Добавляем в граф нужный рендерер (Auto - graphBuilder сам выберет рендерер) Settings.VRenderers renderer = Settings.VideoRenderer; if (renderer == Settings.VRenderers.Overlay) { IBaseFilter add_vr = (IBaseFilter)new VideoRenderer(); hr = graphBuilder.AddFilter(add_vr, "Video Renderer"); DsError.ThrowExceptionForHR(hr); } else if (renderer == Settings.VRenderers.VMR7) { IBaseFilter add_vmr = (IBaseFilter)new VideoMixingRenderer(); hr = graphBuilder.AddFilter(add_vmr, "Video Renderer"); DsError.ThrowExceptionForHR(hr); } else if (renderer == Settings.VRenderers.VMR9) { IBaseFilter add_vmr9 = (IBaseFilter)new VideoMixingRenderer9(); hr = graphBuilder.AddFilter(add_vmr9, "Video Mixing Renderer 9"); DsError.ThrowExceptionForHR(hr); } else if (renderer == Settings.VRenderers.EVR) { //Создаём Win32-окно, т.к. использовать WPF-поверхность не получится VHost = new VideoHwndHost(); VHost.RepaintRequired += new EventHandler(VHost_RepaintRequired); VHostElement.Child = VHost; VHandle = VHost.Handle; //Добавляем и настраиваем EVR IBaseFilter add_evr = (IBaseFilter)new EnhancedVideoRenderer(); hr = graphBuilder.AddFilter(add_evr, "Enhanced Video Renderer"); DsError.ThrowExceptionForHR(hr); object obj; IMFGetService pGetService = null; pGetService = (IMFGetService)add_evr; hr = pGetService.GetService(MFServices.MR_VIDEO_RENDER_SERVICE, typeof(IMFVideoDisplayControl).GUID, out obj); MFError.ThrowExceptionForHR(hr); try { EVRControl = (IMFVideoDisplayControl)obj; } catch { Marshal.ReleaseComObject(obj); throw; } //Указываем поверхность hr = EVRControl.SetVideoWindow(VHandle); MFError.ThrowExceptionForHR(hr); //Отключаем сохранение аспекта hr = EVRControl.SetAspectRatioMode(MFVideoAspectRatioMode.None); MFError.ThrowExceptionForHR(hr); } // Have the graph builder construct its the appropriate graph automatically hr = this.graphBuilder.RenderFile(filename, null); DsError.ThrowExceptionForHR(hr); if (EVRControl == null) { //Ищем рендерер и отключаем соблюдение аспекта (аспект будет определяться размерами видео-окна) IBaseFilter filter = null; graphBuilder.FindFilterByName("Video Renderer", out filter); if (filter != null) { IVMRAspectRatioControl vmr = filter as IVMRAspectRatioControl; if (vmr != null) DsError.ThrowExceptionForHR(vmr.SetAspectRatioMode(VMRAspectRatioMode.None)); } else { graphBuilder.FindFilterByName("Video Mixing Renderer 9", out filter); if (filter != null) { IVMRAspectRatioControl9 vmr9 = filter as IVMRAspectRatioControl9; if (vmr9 != null) DsError.ThrowExceptionForHR(vmr9.SetAspectRatioMode(VMRAspectRatioMode.None)); } } } // QueryInterface for DirectShow interfaces this.mediaControl = (IMediaControl)this.graphBuilder; this.mediaEventEx = (IMediaEventEx)this.graphBuilder; this.mediaSeeking = (IMediaSeeking)this.graphBuilder; this.mediaPosition = (IMediaPosition)this.graphBuilder; // Query for video interfaces, which may not be relevant for audio files this.videoWindow = (EVRControl == null) ? this.graphBuilder as IVideoWindow : null; this.basicVideo = (EVRControl == null) ? this.graphBuilder as IBasicVideo : null; // Query for audio interfaces, which may not be relevant for video-only files this.basicAudio = this.graphBuilder as IBasicAudio; basicAudio.put_Volume(-(int)(10000 - Math.Pow(Settings.VolumeLevel, 1.0 / 5) * 10000)); //Громкость для ДиректШоу // Is this an audio-only file (no video component)? CheckIsAudioOnly(); if (!this.isAudioOnly) { //Определяем аспект, если он нам не известен if (in_ar == 0) { MediaInfoWrapper media = new MediaInfoWrapper(); media.Open(filepath); in_ar = media.Aspect; media.Close(); } if (videoWindow != null) { // Setup the video window hr = this.videoWindow.put_Owner(this.source.Handle); DsError.ThrowExceptionForHR(hr); hr = this.videoWindow.put_WindowStyle(DirectShowLib.WindowStyle.Child | DirectShowLib.WindowStyle.ClipSiblings | DirectShowLib.WindowStyle.ClipChildren); DsError.ThrowExceptionForHR(hr); } MoveVideoWindow(); } else { if (VHost != null) { VHost.Dispose(); VHost = null; VHandle = IntPtr.Zero; VHostElement.Child = null; } } // Have the graph signal event via window callbacks for performance hr = this.mediaEventEx.SetNotifyWindow(this.source.Handle, WMGraphNotify, IntPtr.Zero); DsError.ThrowExceptionForHR(hr); this.Focus(); // Run the graph to play the media file hr = this.mediaControl.Run(); DsError.ThrowExceptionForHR(hr); this.currentState = PlayState.Running; SetPauseIcon(); double duration = 0.0; hr = mediaPosition.get_Duration(out duration); DsError.ThrowExceptionForHR(hr); slider_pos.Maximum = duration; //Запускаем таймер обновления позиции if (timer != null) timer.Start(); }
/* * protected void InitAudioSampleGrabber() * { * // Get the graph builder * IGraphBuilder graphBuilder = (mediaControl as IGraphBuilder); * if (graphBuilder == null) * return; * * try * { * // Build the sample grabber * sampleGrabber = Activator.CreateInstance(Type.GetTypeFromCLSID(Filters.SampleGrabber, true)) * as ISampleGrabber; * * if (sampleGrabber == null) * return; * * // Add it to the filter graph * int hr = graphBuilder.AddFilter(sampleGrabber as IBaseFilter, "ProTONE_SampleGrabber"); * DsError.ThrowExceptionForHR(hr); * * AMMediaType mtAudio = new AMMediaType(); * mtAudio.majorType = MediaType.Audio; * mtAudio.subType = MediaSubType.PCM; * mtAudio.formatPtr = IntPtr.Zero; * * _actualAudioFormat = null; * * hr = sampleGrabber.SetMediaType(mtAudio); * DsError.ThrowExceptionForHR(hr); * * hr = sampleGrabber.SetBufferSamples(true); * DsError.ThrowExceptionForHR(hr); * * hr = sampleGrabber.SetOneShot(false); * DsError.ThrowExceptionForHR(hr); * * hr = sampleGrabber.SetCallback(this, 1); * DsError.ThrowExceptionForHR(hr); * * sampleAnalyzerMustStop.Reset(); * sampleAnalyzerThread = new Thread(new ThreadStart(SampleAnalyzerLoop)); * sampleAnalyzerThread.Priority = ThreadPriority.Highest; * sampleAnalyzerThread.Start(); * } * catch(Exception ex) * { * Logger.LogException(ex); * } * * rotEntry = new DsROTEntry(graphBuilder as IFilterGraph); * }*/ protected void InitAudioSampleGrabber_v2() { // Get the graph builder IGraphBuilder graphBuilder = (mediaControl as IGraphBuilder); if (graphBuilder == null) { return; } try { // Build the sample grabber sampleGrabber = Activator.CreateInstance(Type.GetTypeFromCLSID(Filters.SampleGrabber, true)) as ISampleGrabber; if (sampleGrabber == null) { return; } // Add it to the filter graph int hr = graphBuilder.AddFilter(sampleGrabber as IBaseFilter, "ProTONE_SampleGrabber_v2"); DsError.ThrowExceptionForHR(hr); IBaseFilter ffdAudioDecoder = null; IPin ffdAudioDecoderOutput = null; IPin soundDeviceInput = null; IPin sampleGrabberInput = null; IPin sampleGrabberOutput = null; IntPtr pSoundDeviceInput = IntPtr.Zero; // When using FFDShow, typically we'll find // a ffdshow Audio Decoder connected to the sound device filter // // i.e. [ffdshow Audio Decoder] --> [DirectSound Device] // // Our audio sample grabber supports only PCM sample input and output. // Its entire processing is based on this assumption. // // Thus need to insert the audio sample grabber between the ffdshow Audio Decoder and the sound device // because this is the only place where we can find PCM samples. The sound device only accepts PCM. // // So we need to turn this graph: // // .. -->[ffdshow Audio Decoder]-->[DirectSound Device] // // into this: // // .. -->[ffdshow Audio Decoder]-->[Sample grabber]-->[DirectSound Device] // // Actions to do to achieve the graph change: // // 1. Locate the ffdshow Audio Decoder in the graph // 2. Find its output pin and the pin that it's connected to // 3. Locate the input and output pins of sample grabber // 4. Disconnect the ffdshow Audio Decoder and its correspondent (sound device input pin) // 5. Connect the ffdshow Audio Decoder to sample grabber input // 6. Connect the sample grabber output to sound device input // that's all. // -------------- // 1. Locate the ffdshow Audio Decoder in the graph hr = graphBuilder.FindFilterByName("ffdshow Audio Decoder", out ffdAudioDecoder); DsError.ThrowExceptionForHR(hr); // 2. Find its output pin and the pin that it's connected to hr = ffdAudioDecoder.FindPin("Out", out ffdAudioDecoderOutput); DsError.ThrowExceptionForHR(hr); hr = ffdAudioDecoderOutput.ConnectedTo(out pSoundDeviceInput); DsError.ThrowExceptionForHR(hr); soundDeviceInput = new DSPin(pSoundDeviceInput).Value; // 3. Locate the input and output pins of sample grabber hr = (sampleGrabber as IBaseFilter).FindPin("In", out sampleGrabberInput); DsError.ThrowExceptionForHR(hr); hr = (sampleGrabber as IBaseFilter).FindPin("Out", out sampleGrabberOutput); DsError.ThrowExceptionForHR(hr); // 4. Disconnect the ffdshow Audio Decoder and its correspondent (sound device input pin) hr = ffdAudioDecoderOutput.Disconnect(); DsError.ThrowExceptionForHR(hr); hr = soundDeviceInput.Disconnect(); DsError.ThrowExceptionForHR(hr); // 5. Connect the ffdshow Audio Decoder to sample grabber input hr = graphBuilder.Connect(ffdAudioDecoderOutput, sampleGrabberInput); DsError.ThrowExceptionForHR(hr); // 6. Connect the sample grabber output to sound device input hr = graphBuilder.Connect(sampleGrabberOutput, soundDeviceInput); DsError.ThrowExceptionForHR(hr); AMMediaType mtAudio = new AMMediaType(); mtAudio.majorType = MediaType.Audio; mtAudio.subType = MediaSubType.PCM; mtAudio.formatPtr = IntPtr.Zero; _actualAudioFormat = null; sampleGrabber.SetMediaType(mtAudio); sampleGrabber.SetBufferSamples(true); sampleGrabber.SetOneShot(false); sampleGrabber.SetCallback(this, 1); sampleAnalyzerMustStop.Reset(); sampleAnalyzerThread = new Thread(new ThreadStart(SampleAnalyzerLoop)); sampleAnalyzerThread.Priority = ThreadPriority.Highest; sampleAnalyzerThread.Start(); } catch (Exception ex) { Logger.LogException(ex); } rotEntry = new DsROTEntry(graphBuilder as IFilterGraph); }