Ejemplo n.º 1
0
        /// <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);
            }
        }
Ejemplo n.º 2
0
        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.");
            }
        }
Ejemplo n.º 3
0
 public virtual void Dispose()
 {
     FilterGraphTools.TryDispose(ref _resourceAccessor);
     FilterGraphTools.TryDispose(ref _resourceLocator);
     UnsubscribeFromMessages();
 }
Ejemplo n.º 4
0
        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;
            }
        }
Ejemplo n.º 5
0
 protected override void OnBeforeGraphRunning()
 {
     FilterGraphTools.RenderOutputPins(_graphBuilder, _sourceFilter.GetFilter());
     UpdateVideoFps();
 }
Ejemplo n.º 6
0
        /// <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);
                }
            }
            //}
        }