/// <summary> /// Adds preferred audio/video codecs. /// </summary> protected virtual void AddPreferredCodecs() { VideoSettings settings = ServiceRegistration.Get <ISettingsManager>().Load <VideoSettings>(); if (settings == null) { return; } //IAMPluginControl is supported in Win7 and later only. DirectShowPluginControl dspc = null; IAMPluginControl pc = null; try { dspc = new DirectShowPluginControl(); pc = dspc as IAMPluginControl; if (pc != null) { // Set black list of codecs to ignore, they are known to cause issues like hangs and crashes // MPEG Audio Decoder if (settings.DisabledCodecs != null && settings.DisabledCodecs.Any()) { foreach (var disabledCodec in settings.DisabledCodecs) { ServiceRegistration.Get <ILogger>().Info("{0}: Disable codec '{1}'", PlayerTitle, disabledCodec.Name); pc.SetDisabled(disabledCodec.GetCLSID(), true); } } if (settings.Mpeg2Codec != null) { pc.SetPreferredClsid(MediaSubType.Mpeg2Video, settings.Mpeg2Codec.GetCLSID()); } if (settings.H264Codec != null) { pc.SetPreferredClsid(MediaSubType.H264, settings.H264Codec.GetCLSID()); } if (settings.AVCCodec != null) { pc.SetPreferredClsid(CodecHandler.MEDIASUBTYPE_AVC, settings.AVCCodec.GetCLSID()); } if (settings.HEVCCodec != null) { DsGuid clsid = settings.HEVCCodec.GetCLSID(); pc.SetPreferredClsid(CodecHandler.MEDIASUBTYPE_HVC1, clsid); pc.SetPreferredClsid(CodecHandler.MEDIASUBTYPE_HEVC, clsid); } if (settings.Splitter != null) { pc.SetPreferredClsid(Guid.Empty, settings.Splitter.GetCLSID()); } if (settings.AudioCodecLATMAAC != null) { pc.SetPreferredClsid(CodecHandler.MEDIASUBTYPE_LATM_AAC_AUDIO, settings.AudioCodecLATMAAC.GetCLSID()); } if (settings.AudioCodecAAC != null) { pc.SetPreferredClsid(CodecHandler.MEDIASUBTYPE_AAC_AUDIO, settings.AudioCodecAAC.GetCLSID()); } if (settings.AudioCodec != null) { DsGuid clsid = settings.AudioCodec.GetCLSID(); foreach (Guid guid in new[] { MediaSubType.Mpeg2Audio, MediaSubType.MPEG1AudioPayload, CodecHandler.WMMEDIASUBTYPE_MP3, CodecHandler.MEDIASUBTYPE_MPEG1_AUDIO, CodecHandler.MEDIASUBTYPE_MPEG2_AUDIO }) { pc.SetPreferredClsid(guid, clsid); } } } } catch (Exception ex) { ServiceRegistration.Get <ILogger>().Debug("{0}: Exception in IAMPluginControl: {1}", PlayerTitle, ex.ToString()); } finally { FilterGraphTools.TryRelease(ref dspc); } }
public BDPlayerBuilder() { BDPlayerSettings settings = ServiceRegistration.Get <ISettingsManager>().Load <BDPlayerSettings>(); if (settings.BDSourceFilter == null) { // Try to init settings with the first available source filter CodecInfo sourceFilter = BDSourceFilterConfig.SupportedSourceFilters.FirstOrDefault(codecInfo => FilterGraphTools.IsThisComObjectInstalled(new Guid(codecInfo.CLSID))); if (sourceFilter != null) { settings.BDSourceFilter = sourceFilter; ServiceRegistration.Get <ISettingsManager>().Save(settings); } } Enabled = settings.BDSourceFilter != null; if (Enabled) { LogInfo("Detected BluRay Source Filter '{0}' on the system.", settings.BDSourceFilter.Name); } else { LogWarn("No BluRay Source Filter was detected on the system."); } }
public virtual void Dispose() { FilterGraphTools.TryDispose(ref _resourceAccessor); FilterGraphTools.TryDispose(ref _resourceLocator); UnsubscribeFromMessages(); }
public void SetMediaItem(IResourceLocator locator, string mediaItemTitle, MediaItem mediaItem) { _mediaItem = mediaItem; // free previous opened resource FilterGraphTools.TryDispose(ref _resourceAccessor); FilterGraphTools.TryDispose(ref _rot); _state = PlayerState.Active; _isPaused = true; try { _resourceLocator = locator; _mediaItemTitle = mediaItemTitle; CreateResourceAccessor(); // Create a DirectShow FilterGraph CreateGraphBuilder(); // Add it in ROT (Running Object Table) for debug purpose, it allows to view the Graph from outside (i.e. graphedit) _rot = new DsROTEntry(_graphBuilder); // Add a notification handler (see WndProc) _instancePtr = IntPtr.Zero; if (_me != null) { _me.SetNotifyWindow(SkinContext.Form.Handle, WM_GRAPHNOTIFY, _instancePtr); } // Create the Allocator / Presenter object AddPresenter(); ServiceRegistration.Get <ILogger>().Debug("{0}: Adding audio renderer", PlayerTitle); AddAudioRenderer(); ServiceRegistration.Get <ILogger>().Debug("{0}: Adding preferred codecs", PlayerTitle); AddPreferredCodecs(); ServiceRegistration.Get <ILogger>().Debug("{0}: Adding source filter", PlayerTitle); AddSourceFilter(); ServiceRegistration.Get <ILogger>().Debug("{0}: Adding subtitle filter", PlayerTitle); SetSubtitleRenderer(); AddSubtitleFilter(true); ServiceRegistration.Get <ILogger>().Debug("{0}: Run graph", PlayerTitle); //This needs to be done here before we check if the evr pins are connected //since this method gives players the chance to render the last bits of the graph OnBeforeGraphRunning(); // Now run the graph, i.e. the DVD player needs a running graph before getting informations from dvd filter. int hr = _mc.Run(); new HRESULT(hr).Throw(); _initialized = true; OnGraphRunning(); } catch (Exception) { Shutdown(); throw; } }
protected override void OnBeforeGraphRunning() { FilterGraphTools.RenderOutputPins(_graphBuilder, _sourceFilter.GetFilter()); UpdateVideoFps(); }
/// <summary> /// Configure the graph to output the results to a video window. /// </summary> /// <remarks> /// The callback routines are invoked once for each sample. This allows for additional processing to /// be performed on the video or audio buffers. /// </remarks> /// <param name="windowHandle">Window handle to render to, or IntPtr.Zero to render to its own window</param> /// <param name="videoParticipants">Callback routine to be called for each video frame or null for no callback</param> /// <param name="audioParticipants">Callback routine to be called for each audio frame or null for no callback</param> private void RenderToWindow(IntPtr windowHandle, ICallbackParticipant[] videoParticipants, ICallbackParticipant[] audioParticipants) { int hr; IPin pin; IVideoWindow videoWindow; IAMTimelineObj group; IAMTimeline desTimeline = Timeline.DesTimeline; // Contains useful routines for creating the graph var graphBuilder = (ICaptureGraphBuilder2) new CaptureGraphBuilder2(); try { hr = graphBuilder.SetFiltergraph(Graph); DESError.ThrowExceptionForHR(hr); int NumGroups; hr = desTimeline.GetGroupCount(out NumGroups); DESError.ThrowExceptionForHR(hr); // Walk the groups. For DESCombine, there is one group that // contains all the video, and a second group for the audio. for (int i = 0; i < NumGroups; i++) { hr = desTimeline.GetGroup(out group, i); DESError.ThrowExceptionForHR(hr); try { // Inform the graph we will be previewing (rather than writing to disk) var pTLGroup = (IAMTimelineGroup)group; hr = pTLGroup.SetPreviewMode(true); DESError.ThrowExceptionForHR(hr); } finally { // Release the group Marshal.ReleaseComObject(group); } // Get the IPin for the current group hr = RenderEngine.GetGroupOutputPin(i, out pin); DESError.ThrowExceptionForHR(hr); try { // If this is the video pin if (FilterGraphTools.IsVideo(pin)) { // Get a video renderer var ibfVideoRenderer = (IBaseFilter) new VideoRenderer(); try { // Create a sample grabber, add it to the graph and connect it all up var mcb = new CallbackHandler(videoParticipants); RenderWindowHelper(graphBuilder, mcb, "Video", pin, ibfVideoRenderer); } finally { Marshal.ReleaseComObject(ibfVideoRenderer); } } else { // Get an audio renderer var ibfAudioRenderer = (IBaseFilter) new AudioRender(); try { // Create a sample grabber, add it to the graph and connect it all up var mcb = new CallbackHandler(audioParticipants); RenderWindowHelper(graphBuilder, mcb, "Audio", pin, ibfAudioRenderer); } finally { Marshal.ReleaseComObject(ibfAudioRenderer); } } } finally { Marshal.ReleaseComObject(pin); } } // Configure the video window videoWindow = (IVideoWindow)Graph; // If a window handle was supplied, use it if (windowHandle != IntPtr.Zero) { hr = videoWindow.put_Owner(windowHandle); DESError.ThrowExceptionForHR(hr); } else { // Use our own window hr = videoWindow.put_Caption(Resources.DefaultVideoRenderingWindowCaption); DESError.ThrowExceptionForHR(hr); // since no user interaction is allowed, remove // system menu and maximize/minimize buttons WindowStyle lStyle = 0; hr = videoWindow.get_WindowStyle(out lStyle); DESError.ThrowExceptionForHR(hr); lStyle &= ~(WindowStyle.MinimizeBox | WindowStyle.MaximizeBox | WindowStyle.SysMenu); hr = videoWindow.put_WindowStyle(lStyle); DESError.ThrowExceptionForHR(hr); } } finally { Marshal.ReleaseComObject(graphBuilder); } }
protected override void Decompose() { if (this.graphBuilder != null) { int hr = 0; OnGraphEnded(); this.epg.UnRegisterEvent(); // Decompose the graph try { hr = (this.graphBuilder as IMediaControl).StopWhenReady(); } catch { } try { hr = (this.graphBuilder as IMediaControl).Stop(); } catch { } try { hr = (this.graphBuilder2 as IMediaControl).StopWhenReady(); } catch { } try { hr = (this.graphBuilder2 as IMediaControl).Stop(); } catch { } RemoveHandlers(); FilterGraphTools.RemoveAllFilters(this.graphBuilder); FilterGraphTools.RemoveAllFilters(this.graphBuilder2); if (this.networkProvider != null) { Marshal.ReleaseComObject(this.networkProvider); } this.networkProvider = null; if (this.mpeg2Demux != null) { Marshal.ReleaseComObject(this.mpeg2Demux); } this.mpeg2Demux = null; if (this.mpeg2VideoStreamAnalyzer != null) { Marshal.ReleaseComObject(this.mpeg2VideoStreamAnalyzer); } this.mpeg2VideoStreamAnalyzer = null; if (this.tuner != null) { Marshal.ReleaseComObject(this.tuner); } this.tuner = null; if (this.capture != null) { Marshal.ReleaseComObject(this.capture); } this.capture = null; if (this.bdaTIF != null) { Marshal.ReleaseComObject(this.bdaTIF); } this.bdaTIF = null; if (this.bdaSecTab != null) { Marshal.ReleaseComObject(this.bdaSecTab); } this.bdaSecTab = null; if (this.audioDecoderFilter != null) { Marshal.ReleaseComObject(this.audioDecoderFilter); } this.audioDecoderFilter = null; if (this.videoH264DecoderFilter != null) { Marshal.ReleaseComObject(this.videoH264DecoderFilter); } this.videoH264DecoderFilter = null; if (this.videoMpeg2DecoderFilter != null) { Marshal.ReleaseComObject(this.videoMpeg2DecoderFilter); } this.videoMpeg2DecoderFilter = null; if (this.audioRenderer != null) { Marshal.ReleaseComObject(this.audioRenderer); } this.audioRenderer = null; if (this.videoRenderer != null) { Marshal.ReleaseComObject(this.videoRenderer); } this.videoRenderer = null; if (this.captureGraphBuilder != null) { Marshal.ReleaseComObject(this.captureGraphBuilder); } this.captureGraphBuilder = null; if (this.streamBufferSink != null) { Marshal.ReleaseComObject(this.streamBufferSink); } this.streamBufferSink = null; if (this.streamBufferSource != null) { Marshal.ReleaseComObject(this.streamBufferSource); } this.streamBufferSource = null; if (streamBufferConfigHKey != IntPtr.Zero) { RegCloseKey(streamBufferConfigHKey); streamBufferConfigHKey = IntPtr.Zero; } try { rot.Dispose(); } catch { } try { Marshal.ReleaseComObject(this.graphBuilder); this.graphBuilder = null; } catch { } try { rot2.Dispose(); } catch { } try { Marshal.ReleaseComObject(this.graphBuilder2); this.graphBuilder2 = null; } catch { } } }
private void ConnectStreamBufferSourceFilter() { IBaseFilter videoDecoder = this.H264DecoderDevice == null ? this.videoMpeg2DecoderFilter : this.videoH264DecoderFilter; //this.streamBufferSource as IStreamBufferConfigure IPin videoDvrOut = null, videoDecoderIn = null; try { videoDvrOut = DsFindPin.ByDirection(this.streamBufferSource, PinDirection.Output, 1); //TODO Create output pin for the StreamBufferSource videoDecoderIn = DsFindPin.ByDirection(videoDecoder, PinDirection.Input, 0); //AMMediaType mediaH264 = new AMMediaType(); //mediaH264.majorType = MediaType.Video; //mediaH264.subType = new Guid(0x8d2d71cb, 0x243f, 0x45e3, 0xb2, 0xd8, 0x5f, 0xd7, 0x96, 0x7e, 0xc0, 0x9b); //mediaH264.sampleSize = 0; //mediaH264.temporalCompression = false; //mediaH264.fixedSizeSamples = false; //mediaH264.unkPtr = IntPtr.Zero; //mediaH264.formatType = FormatType.Mpeg2Video; //MPEG2VideoInfo videoH264PinFormat = GetVideoH264PinFormat(); //mediaH264.formatSize = Marshal.SizeOf(videoH264PinFormat); //mediaH264.formatPtr = Marshal.AllocHGlobal(mediaH264.formatSize); //Marshal.StructureToPtr(videoH264PinFormat, mediaH264.formatPtr, false); ////int hr = videoDvrOut.Connect(videoDecoderIn, mediaH264); //int hr = videoDecoderIn.Connect(videoDvrOut, mediaH264); //Marshal.FreeHGlobal(mediaH264.formatPtr); //DsError.ThrowExceptionForHR(hr); //if (this.H264DecoderDevice != null) //{ // AMMediaType mediaH264 = new AMMediaType(); // mediaH264.majorType = MediaType.Video; // //mediaH264.subType = new Guid(0x8d2d71cb, 0x243f, 0x45e3, 0xb2, 0xd8, 0x5f, 0xd7, 0x96, 0x7e, 0xc0, 0x9b); // mediaH264.subType = new Guid(0x34363248, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); // mediaH264.sampleSize = 0; // mediaH264.temporalCompression = true; // false; // mediaH264.fixedSizeSamples = true; // false; // mediaH264.unkPtr = IntPtr.Zero; // mediaH264.formatType = FormatType.Mpeg2Video; // MPEG2VideoInfo videoH264PinFormat = GetVideoH264PinFormat(); // mediaH264.formatSize = Marshal.SizeOf(videoH264PinFormat); // mediaH264.formatPtr = Marshal.AllocHGlobal(mediaH264.formatSize); // Marshal.StructureToPtr(videoH264PinFormat, mediaH264.formatPtr, false); // //IPin pinDemuxerVideoH264; // //int hr = mpeg2Demultiplexer.CreateOutputPin(mediaH264, "H264", out pinDemuxerVideoH264); // //if (pinDemuxerVideoH264 != null) // //Marshal.ReleaseComObject(pinDemuxerVideoH264); // int hr = this.graphBuilder2.ConnectDirect(videoDvrOut, videoDecoderIn, mediaH264); // //hr = this.graphBuilder2.Connect(videoDvrOut, videoDecoderIn); // DsError.ThrowExceptionForHR(hr); // Marshal.FreeHGlobal(mediaH264.formatPtr); //} //else FilterGraphTools.ConnectFilters(this.graphBuilder2, videoDvrOut, videoDecoderIn, false); //int hr = this.graphBuilder2.Render(videoDvrOut); // H264 video stream cannot connect to H264 decoder (Cyberlink)!!! } finally { if (videoDvrOut != null) { Marshal.ReleaseComObject(videoDvrOut); } if (videoDecoderIn != null) { Marshal.ReleaseComObject(videoDecoderIn); } } IPin videoDecoderOut = null, videoVMRIn = null; try { videoDecoderOut = DsFindPin.ByDirection(videoDecoder, PinDirection.Output, 0); videoVMRIn = DsFindPin.ByDirection(this.videoRenderer, PinDirection.Input, 0); FilterGraphTools.ConnectFilters(this.graphBuilder2, videoDecoderOut, videoVMRIn, false); } finally { if (videoDecoderOut != null) { Marshal.ReleaseComObject(videoDecoderOut); } if (videoVMRIn != null) { Marshal.ReleaseComObject(videoVMRIn); } } IPin audioDvrOut = null, audioRendererIn = null; try { audioDvrOut = DsFindPin.ByDirection(this.streamBufferSource, PinDirection.Output, 0); audioRendererIn = DsFindPin.ByDirection(this.audioRenderer, PinDirection.Input, 0); FilterGraphTools.ConnectFilters(this.graphBuilder2, audioDvrOut, audioRendererIn, true); } finally { if (audioDvrOut != null) { Marshal.ReleaseComObject(audioDvrOut); } if (audioRendererIn != null) { Marshal.ReleaseComObject(audioRendererIn); } } }
private void ConnectStreamBufferSinkFilter() { IPin audioDemuxOut = null, audioDvrIn = null; try { audioDemuxOut = DsFindPin.ByDirection(this.mpeg2Demux, PinDirection.Output, 0); audioDvrIn = DsFindPin.ByDirection(this.streamBufferSink, PinDirection.Input, 0); FilterGraphTools.ConnectFilters(this.graphBuilder, audioDemuxOut, audioDvrIn, false); } finally { if (audioDemuxOut != null) { Marshal.ReleaseComObject(audioDemuxOut); } if (audioDvrIn != null) { Marshal.ReleaseComObject(audioDvrIn); } } //if (false) //Not working anymore on Windows 7!! this.mpeg2VideoStreamAnalyzer != null) //{ // IPin videoDemuxOut = null, videoVSAIn = null; // try // { // videoDemuxOut = DsFindPin.ByName(this.mpeg2Demux, this.H264DecoderDevice == null ? "MPG2" : "H264"); // videoVSAIn = DsFindPin.ByDirection(this.mpeg2VideoStreamAnalyzer, PinDirection.Input, 0); // FilterGraphTools.ConnectFilters(this.graphBuilder, videoDemuxOut, videoVSAIn, false); // } // finally // { // if (videoDemuxOut != null) Marshal.ReleaseComObject(videoDemuxOut); // if (videoVSAIn != null) Marshal.ReleaseComObject(videoVSAIn); // } // IPin videoVSAOut = null, videoDvrIn = null; // try // { // videoVSAOut = DsFindPin.ByDirection(this.mpeg2VideoStreamAnalyzer, PinDirection.Output, 0); // videoDvrIn = DsFindPin.ByDirection(this.streamBufferSink, PinDirection.Input, 1); // FilterGraphTools.ConnectFilters(this.graphBuilder, videoVSAOut, videoDvrIn, false); // } // finally // { // if (videoVSAOut != null) Marshal.ReleaseComObject(videoVSAOut); // if (videoDvrIn != null) Marshal.ReleaseComObject(videoDvrIn); // } //} //else //{ IPin videoDemuxOut = null, videoDvrIn = null; try { videoDemuxOut = DsFindPin.ByName(this.mpeg2Demux, this.H264DecoderDevice == null ? "MPG2" : "H264"); videoDvrIn = DsFindPin.ByDirection(this.streamBufferSink, PinDirection.Input, 1); FilterGraphTools.ConnectFilters(this.graphBuilder, videoDemuxOut, videoDvrIn, false); } finally { if (videoDemuxOut != null) { Marshal.ReleaseComObject(videoDemuxOut); } if (videoDvrIn != null) { Marshal.ReleaseComObject(videoDvrIn); } } //} }