Beispiel #1
0
        public void AddPreferedCodecs(IGraphBuilder _graphBuilder)
        {
            // add preferred video & audio codecs
            string strVideoCodec    = "";
            string strAudioCodec    = "";
            string strAudiorenderer = "";
            int    intFilters       = 0;  // FlipGer: count custom filters
            string strFilters       = ""; // FlipGer: collect custom filters

            using (MediaPortal.Profile.Settings xmlreader = new MPSettings())
            {
                // FlipGer: load infos for custom filters
                int intCount = 0;
                while (xmlreader.GetValueAsString("dvdplayer", "filter" + intCount.ToString(), "undefined") != "undefined")
                {
                    if (xmlreader.GetValueAsBool("dvdplayer", "usefilter" + intCount.ToString(), false))
                    {
                        strFilters += xmlreader.GetValueAsString("dvdplayer", "filter" + intCount.ToString(), "undefined") + ";";
                        intFilters++;
                    }
                    intCount++;
                }
                strVideoCodec    = xmlreader.GetValueAsString("dvdplayer", "videocodec", "");
                strAudioCodec    = xmlreader.GetValueAsString("dvdplayer", "audiocodec", "");
                strAudiorenderer = xmlreader.GetValueAsString("dvdplayer", "audiorenderer", "Default DirectSound Device");
            }
            if (strVideoCodec.Length > 0)
            {
                DirectShowUtil.AddFilterToGraph(_graphBuilder, strVideoCodec);
            }
            if (strAudioCodec.Length > 0)
            {
                DirectShowUtil.AddFilterToGraph(_graphBuilder, strAudioCodec);
            }
            if (strAudiorenderer.Length > 0)
            {
                DirectShowUtil.AddAudioRendererToGraph(_graphBuilder, strAudiorenderer, false);
            }
            // FlipGer: add custom filters to graph
            string[] arrFilters = strFilters.Split(';');
            for (int i = 0; i < intFilters; i++)
            {
                DirectShowUtil.AddFilterToGraph(_graphBuilder, arrFilters[i]);
            }
        }
        /// <summary> create the used COM components and get the interfaces. </summary>
        private bool GetInterfaces()
        {
            int    iStage = 1;
            string audioDevice;

            using (Settings xmlreader = new MPSettings())
            {
                audioDevice = xmlreader.GetValueAsString("audioplayer", "sounddevice", "Default DirectSound Device");
            }
            //Type comtype = null;
            //object comobj = null;
            try
            {
                graphBuilder = (IGraphBuilder) new FilterGraph();
                iStage       = 5;
                DirectShowUtil.AddAudioRendererToGraph(graphBuilder, audioDevice, false);
                int hr = graphBuilder.RenderFile(m_strCurrentFile, null);
                if (hr != 0)
                {
                    Error.SetError("Unable to play file", "Missing codecs to play this file");
                    return(false);
                }
                iStage    = 6;
                mediaCtrl = (IMediaControl)graphBuilder;

                iStage     = 7;
                mediaEvt   = (IMediaEventEx)graphBuilder;
                iStage     = 8;
                mediaSeek  = (IMediaSeeking)graphBuilder;
                iStage     = 9;
                mediaPos   = (IMediaPosition)graphBuilder;
                iStage     = 10;
                basicAudio = graphBuilder as IBasicAudio;
                iStage     = 11;
                return(true);
            }
            catch (Exception ex)
            {
                Log.Info("Can not start {0} stage:{1} err:{2} stack:{3}",
                         m_strCurrentFile, iStage,
                         ex.Message,
                         ex.StackTrace);
                return(false);
            }
        }
        /// <summary>
        /// If the url to be played can be buffered before starting playback, this function
        /// starts building a graph by adding the preferred video and audio render to it.
        /// This needs to be called on the MpMain Thread.
        /// </summary>
        /// <returns>true, if the url can be buffered (a graph was started), false if it can't be and null if an error occured building the graph</returns>
        public bool?PrepareGraph()
        {
            //string sourceFilterName = SOURCE_FILTER_NAME; //GetSourceFilterName(m_strCurrentFile);

            if (!string.IsNullOrEmpty(sourceFilterName))
            {
                graphBuilder = (IGraphBuilder) new FilterGraph();
                _rotEntry    = new DsROTEntry((IFilterGraph)graphBuilder);

                Vmr9 = new VMR9Util();
                Vmr9.AddVMR9(graphBuilder);
                Vmr9.Enable(false);
                // set VMR9 back to NOT Active -> otherwise GUI is not refreshed while graph is building
                GUIGraphicsContext.Vmr9Active = false;

                // add the audio renderer
                using (Settings settings = new MPSettings())
                {
                    string audiorenderer = settings.GetValueAsString("movieplayer", "audiorenderer", "Default DirectSound Device");
                    DirectShowUtil.AddAudioRendererToGraph(graphBuilder, audiorenderer, false);
                }

                // set fields for playback
                mediaCtrl  = (IMediaControl)graphBuilder;
                mediaEvt   = (IMediaEventEx)graphBuilder;
                mediaSeek  = (IMediaSeeking)graphBuilder;
                mediaPos   = (IMediaPosition)graphBuilder;
                basicAudio = (IBasicAudio)graphBuilder;
                videoWin   = (IVideoWindow)graphBuilder;

                // add the source filter
                return(tryAddSourceFilter());
            }
            else
            {
                return(false);
            }
        }
Beispiel #4
0
        /// <summary> create the used COM components and get the interfaces. </summary>
        protected bool GetInterfaces()
        {
            VMR9Util.g_vmr9 = null;
            if (IsRadio == false)
            {
                Vmr9 = VMR9Util.g_vmr9 = new VMR9Util();

                // switch back to directx fullscreen mode
                Log.Info("RTSPPlayer: Enabling DX9 exclusive mode");
                GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 1, 0, null);
                GUIWindowManager.SendMessage(msg);
            }
            //Type comtype = null;
            //object comobj = null;

            DsRect rect = new DsRect();

            rect.top    = 0;
            rect.bottom = GUIGraphicsContext.form.Height;
            rect.left   = 0;
            rect.right  = GUIGraphicsContext.form.Width;


            try
            {
                graphBuilder = (IGraphBuilder) new FilterGraph();

                Log.Info("RTSPPlayer: add source filter");
                if (IsRadio == false)
                {
                    bool AddVMR9 = VMR9Util.g_vmr9 != null && VMR9Util.g_vmr9.AddVMR9(graphBuilder);
                    if (!AddVMR9)
                    {
                        Log.Error("RTSPPlayer:Failed to add VMR9 to graph");
                        return(false);
                    }
                    VMR9Util.g_vmr9.Enable(false);
                }

                _mpegDemux = (IBaseFilter) new MPEG2Demultiplexer();
                graphBuilder.AddFilter(_mpegDemux, "MPEG-2 Demultiplexer");

                _rtspSource = (IBaseFilter) new RtpSourceFilter();
                int hr = graphBuilder.AddFilter((IBaseFilter)_rtspSource, "RTSP Source Filter");
                if (hr != 0)
                {
                    Log.Error("RTSPPlayer:unable to add RTSP source filter:{0:X}", hr);
                    return(false);
                }

                // add preferred video & audio codecs
                Log.Info("RTSPPlayer: add video/audio codecs");
                string strVideoCodec               = "";
                string strAudioCodec               = "";
                string strAudiorenderer            = "";
                int    intFilters                  = 0;  // FlipGer: count custom filters
                string strFilters                  = ""; // FlipGer: collect custom filters
                string postProcessingFilterSection = "mytv";
                using (Settings xmlreader = new MPSettings())
                {
                    if (_mediaType == g_Player.MediaType.Video)
                    {
                        strVideoCodec               = xmlreader.GetValueAsString("movieplayer", "mpeg2videocodec", "");
                        strAudioCodec               = xmlreader.GetValueAsString("movieplayer", "mpeg2audiocodec", "");
                        strAudiorenderer            = xmlreader.GetValueAsString("movieplayer", "audiorenderer", "Default DirectSound Device");
                        postProcessingFilterSection = "movieplayer";
                    }
                    else
                    {
                        strVideoCodec               = xmlreader.GetValueAsString("mytv", "videocodec", "");
                        strAudioCodec               = xmlreader.GetValueAsString("mytv", "audiocodec", "");
                        strAudiorenderer            = xmlreader.GetValueAsString("mytv", "audiorenderer", "Default DirectSound Device");
                        postProcessingFilterSection = "mytv";
                    }
                    enableDvbSubtitles = xmlreader.GetValueAsBool("tvservice", "dvbsubtitles", false);
                    // FlipGer: load infos for custom filters
                    int intCount = 0;
                    while (xmlreader.GetValueAsString(postProcessingFilterSection, "filter" + intCount.ToString(), "undefined") !=
                           "undefined")
                    {
                        if (xmlreader.GetValueAsBool(postProcessingFilterSection, "usefilter" + intCount.ToString(), false))
                        {
                            strFilters +=
                                xmlreader.GetValueAsString(postProcessingFilterSection, "filter" + intCount.ToString(), "undefined") +
                                ";";
                            intFilters++;
                        }
                        intCount++;
                    }
                }
                string extension = Path.GetExtension(m_strCurrentFile).ToLowerInvariant();
                if (IsRadio == false)
                {
                    if (strVideoCodec.Length > 0)
                    {
                        DirectShowUtil.AddFilterToGraph(graphBuilder, strVideoCodec);
                    }
                }
                if (strAudioCodec.Length > 0)
                {
                    DirectShowUtil.AddFilterToGraph(graphBuilder, strAudioCodec);
                }

                if (enableDvbSubtitles == true)
                {
                    try
                    {
                        _subtitleFilter = SubtitleRenderer.GetInstance().AddSubtitleFilter(graphBuilder);
                        SubtitleRenderer.GetInstance().SetPlayer(this);
                        dvbSubRenderer = SubtitleRenderer.GetInstance();
                    }
                    catch (Exception e)
                    {
                        Log.Error(e);
                    }
                }

                Log.Debug("Is subtitle fitler null? {0}", (_subtitleFilter == null));
                // FlipGer: add custom filters to graph
                string[] arrFilters = strFilters.Split(';');
                for (int i = 0; i < intFilters; i++)
                {
                    DirectShowUtil.AddFilterToGraph(graphBuilder, arrFilters[i]);
                }
                if (strAudiorenderer.Length > 0)
                {
                    audioRendererFilter = DirectShowUtil.AddAudioRendererToGraph(graphBuilder, strAudiorenderer, false);
                }

                Log.Info("RTSPPlayer: load:{0}", m_strCurrentFile);
                IFileSourceFilter interfaceFile = (IFileSourceFilter)_rtspSource;
                if (interfaceFile == null)
                {
                    Log.Error("RTSPPlayer:Failed to get IFileSourceFilter");
                    return(false);
                }

                //Log.Info("RTSPPlayer: open file:{0}",filename);
                hr = interfaceFile.Load(m_strCurrentFile, null);
                if (hr != 0)
                {
                    Log.Error("RTSPPlayer:Failed to open file:{0} :0x{1:x}", m_strCurrentFile, hr);
                    return(false);
                }

                #region connect rtspsource->demux

                Log.Info("RTSPPlayer:connect rtspsource->mpeg2 demux");
                IPin pinTsOut = DsFindPin.ByDirection((IBaseFilter)_rtspSource, PinDirection.Output, 0);
                if (pinTsOut == null)
                {
                    Log.Info("RTSPPlayer:failed to find output pin of tsfilesource");
                    return(false);
                }
                IPin pinDemuxIn = DsFindPin.ByDirection(_mpegDemux, PinDirection.Input, 0);
                if (pinDemuxIn == null)
                {
                    Log.Info("RTSPPlayer:failed to find output pin of tsfilesource");
                    return(false);
                }

                hr = graphBuilder.Connect(pinTsOut, pinDemuxIn);
                if (hr != 0)
                {
                    Log.Info("RTSPPlayer:failed to connect rtspsource->mpeg2 demux:{0:X}", hr);
                    return(false);
                }
                DirectShowUtil.ReleaseComObject(pinTsOut);
                DirectShowUtil.ReleaseComObject(pinDemuxIn);

                #endregion

                #region render demux output pins

                if (IsRadio)
                {
                    Log.Info("RTSPPlayer:render audio demux outputs");
                    IEnumPins enumPins;
                    _mpegDemux.EnumPins(out enumPins);
                    IPin[] pins    = new IPin[2];
                    int    fetched = 0;
                    while (enumPins.Next(1, pins, out fetched) == 0)
                    {
                        if (fetched != 1)
                        {
                            break;
                        }
                        PinDirection direction;
                        pins[0].QueryDirection(out direction);
                        if (direction == PinDirection.Input)
                        {
                            continue;
                        }
                        IEnumMediaTypes enumMediaTypes;
                        pins[0].EnumMediaTypes(out enumMediaTypes);
                        AMMediaType[] mediaTypes = new AMMediaType[20];
                        int           fetchedTypes;
                        enumMediaTypes.Next(20, mediaTypes, out fetchedTypes);
                        for (int i = 0; i < fetchedTypes; ++i)
                        {
                            if (mediaTypes[i].majorType == MediaType.Audio)
                            {
                                graphBuilder.Render(pins[0]);
                                break;
                            }
                        }
                    }
                }
                else
                {
                    Log.Info("RTSPPlayer:render audio/video demux outputs");
                    IEnumPins enumPins;
                    _mpegDemux.EnumPins(out enumPins);
                    IPin[] pins    = new IPin[2];
                    int    fetched = 0;
                    while (enumPins.Next(1, pins, out fetched) == 0)
                    {
                        if (fetched != 1)
                        {
                            break;
                        }
                        PinDirection direction;
                        pins[0].QueryDirection(out direction);
                        if (direction == PinDirection.Input)
                        {
                            continue;
                        }
                        graphBuilder.Render(pins[0]);
                    }
                }

                #endregion

                // Connect DVB subtitle filter pins in the graph
                if (_mpegDemux != null && enableDvbSubtitles == true)
                {
                    IMpeg2Demultiplexer demuxer = _mpegDemux as IMpeg2Demultiplexer;
                    hr = demuxer.CreateOutputPin(GetTSMedia(), "Pcr", out _pinPcr);

                    if (hr == 0)
                    {
                        Log.Info("RTSPPlayer:_pinPcr OK");

                        IPin pDemuxerPcr  = DsFindPin.ByName(_mpegDemux, "Pcr");
                        IPin pSubtitlePcr = DsFindPin.ByName(_subtitleFilter, "Pcr");
                        hr = graphBuilder.Connect(pDemuxerPcr, pSubtitlePcr);
                    }
                    else
                    {
                        Log.Info("RTSPPlayer:Failed to create _pinPcr in demuxer:{0:X}", hr);
                    }

                    hr = demuxer.CreateOutputPin(GetTSMedia(), "Subtitle", out _pinSubtitle);
                    if (hr == 0)
                    {
                        Log.Info("RTSPPlayer:_pinSubtitle OK");

                        IPin pDemuxerSubtitle = DsFindPin.ByName(_mpegDemux, "Subtitle");
                        IPin pSubtitle        = DsFindPin.ByName(_subtitleFilter, "In");
                        hr = graphBuilder.Connect(pDemuxerSubtitle, pSubtitle);
                    }
                    else
                    {
                        Log.Info("RTSPPlayer:Failed to create _pinSubtitle in demuxer:{0:X}", hr);
                    }

                    hr = demuxer.CreateOutputPin(GetTSMedia(), "PMT", out _pinPMT);
                    if (hr == 0)
                    {
                        Log.Info("RTSPPlayer:_pinPMT OK");

                        IPin pDemuxerSubtitle = DsFindPin.ByName(_mpegDemux, "PMT");
                        IPin pSubtitle        = DsFindPin.ByName(_subtitleFilter, "PMT");
                        hr = graphBuilder.Connect(pDemuxerSubtitle, pSubtitle);
                    }
                    else
                    {
                        Log.Info("RTSPPlayer:Failed to create _pinPMT in demuxer:{0:X}", hr);
                    }
                }


                if (IsRadio == false)
                {
                    if (!VMR9Util.g_vmr9.IsVMR9Connected)
                    {
                        //VMR9 is not supported, switch to overlay
                        Log.Info("RTSPPlayer: vmr9 not connected");
                        _mediaCtrl = null;
                        Cleanup();
                        return(false);
                    }
                    VMR9Util.g_vmr9.SetDeinterlaceMode();
                }

                _mediaCtrl    = (IMediaControl)graphBuilder;
                mediaEvt      = (IMediaEventEx)graphBuilder;
                _mediaSeeking = (IMediaSeeking)graphBuilder;
                mediaPos      = (IMediaPosition)graphBuilder;
                basicAudio    = graphBuilder as IBasicAudio;
                //DirectShowUtil.SetARMode(graphBuilder,AspectRatioMode.Stretched);
                DirectShowUtil.EnableDeInterlace(graphBuilder);
                if (VMR9Util.g_vmr9 != null)
                {
                    m_iVideoWidth  = VMR9Util.g_vmr9.VideoWidth;
                    m_iVideoHeight = VMR9Util.g_vmr9.VideoHeight;
                }
                if (audioRendererFilter != null)
                {
                    Log.Info("RTSPPlayer9:set reference clock");
                    IMediaFilter    mp    = graphBuilder as IMediaFilter;
                    IReferenceClock clock = audioRendererFilter as IReferenceClock;
                    hr = mp.SetSyncSource(null);
                    hr = mp.SetSyncSource(clock);
                    Log.Info("RTSPPlayer9:set reference clock:{0:X}", hr);
                }
                Log.Info("RTSPPlayer: graph build successfull");
                return(true);
            }
            catch (Exception ex)
            {
                Error.SetError("Unable to play movie", "Unable build graph for VMR9");
                Log.Error("RTSPPlayer:exception while creating DShow graph {0} {1}", ex.Message, ex.StackTrace);
                CloseInterfaces();
                return(false);
            }
        }
Beispiel #5
0
        protected override bool GetInterfaces()
        {
            GetInterface = true;
            try
            {
                graphBuilder = (IGraphBuilder) new FilterGraph();
                _rotEntry    = new DsROTEntry((IFilterGraph)graphBuilder);
                int hr;
                filterConfig = GetFilterConfiguration();
                filterCodec  = GetFilterCodec();
                if (filterConfig.bAutoDecoderSettings)
                {
                    AutoRenderingCheck = true;
                    return(base.GetInterfaces());
                }


                string extension = Path.GetExtension(m_strCurrentFile).ToLowerInvariant();


                GUIMessage msg;
                if (extension == ".mpls" || extension == ".bdmv")
                {
                    filterConfig.bForceSourceSplitter = false;
                    filterConfig = GetFilterConfigurationBD();
                }

                //Manually add codecs based on file extension if not in auto-settings
                // switch back to directx fullscreen mode
                Log.Info("MyAnime3Player: Enabling DX9 exclusive mode");
                msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 1, 0, null);
                GUIWindowManager.SendMessage(msg);

                // add the VMR9 in the graph
                // after enabeling exclusive mode, if done first it causes MediPortal to minimize if for example the "Windows key" is pressed while playing a video
                if (extension != ".dts" && extension != ".mp3" && extension != ".mka" && extension != ".ac3")
                {
                    if (g_Player.MediaInfo != null && !g_Player.MediaInfo.MediaInfoNotloaded &&
                        !g_Player._mediaInfo.HasVideo)
                    {
                        AudioOnly = true;
                    }
                    else
                    {
                        Vmr9 = new VMR9Util();
                        Vmr9.AddVMR9(graphBuilder);
                        Vmr9.Enable(false);
                    }
                }
                else
                {
                    AudioOnly = true;
                }

                if (filterConfig.strsplitterfilter == LAV_SPLITTER_FILTER_SOURCE && filterConfig.bForceSourceSplitter)
                {
                    LoadLAVSplitter(LAV_SPLITTER_FILTER_SOURCE);
                    hr = graphBuilder.AddFilter(_interfaceSourceFilter, LAV_SPLITTER_FILTER_SOURCE);
                    DsError.ThrowExceptionForHR(hr);

                    Log.Debug("MyAnime3Player: Add LAVSplitter Source to graph");

                    IFileSourceFilter interfaceFile = (IFileSourceFilter)_interfaceSourceFilter;
                    hr = interfaceFile.Load(m_strCurrentFile, null);

                    if (hr != 0)
                    {
                        Error.SetError("Unable to play movie", "Unable build graph for VMR9");
                        Cleanup();
                        return(false);
                    }
                }
                else
                {
                    _interfaceSourceFilter = filterConfig.bForceSourceSplitter
                        ? DirectShowUtil.AddFilterToGraph(graphBuilder, filterConfig.strsplitterfilter)
                        : null;
                    if (_interfaceSourceFilter == null && !filterConfig.bForceSourceSplitter)
                    {
                        graphBuilder.AddSourceFilter(m_strCurrentFile, null, out _interfaceSourceFilter);
                    }
                    else
                    {
                        try
                        {
                            int result = ((IFileSourceFilter)_interfaceSourceFilter).Load(m_strCurrentFile, null);
                            if (result != 0)
                            {
                                graphBuilder.RemoveFilter(_interfaceSourceFilter);
                                DirectShowUtil.ReleaseComObject(_interfaceSourceFilter);
                                _interfaceSourceFilter = null;
                                graphBuilder.AddSourceFilter(m_strCurrentFile, null, out _interfaceSourceFilter);
                            }
                        }

                        catch (Exception ex)
                        {
                            Log.Error(
                                "MyAnime3Player: Exception loading Source Filter setup in setting in DShow graph , try to load by merit",
                                ex);
                            graphBuilder.RemoveFilter(_interfaceSourceFilter);
                            DirectShowUtil.ReleaseComObject(_interfaceSourceFilter);
                            _interfaceSourceFilter = null;
                            graphBuilder.AddSourceFilter(m_strCurrentFile, null, out _interfaceSourceFilter);
                        }
                    }

                    //Detection of File Source (Async.) as source filter, return true if found
                    IBaseFilter fileSyncbaseFilter = null;
                    DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.FilesyncSource, out fileSyncbaseFilter);
                    if (fileSyncbaseFilter == null)
                    {
                        graphBuilder.FindFilterByName("File Source (Async.)", out fileSyncbaseFilter);
                    }
                    if (fileSyncbaseFilter != null && filterConfig.bForceSourceSplitter)
                    {
                        FileSync = true;
                        DirectShowUtil.ReleaseComObject(fileSyncbaseFilter);
                        fileSyncbaseFilter = null;
                        if (filterConfig.strsplitterfilefilter == LAV_SPLITTER_FILTER)
                        {
                            LoadLAVSplitter(LAV_SPLITTER_FILTER);
                            hr = graphBuilder.AddFilter(Splitter, LAV_SPLITTER_FILTER);
                            DsError.ThrowExceptionForHR(hr);

                            Log.Debug("MyAnime3Player: Add LAVSplitter to graph");

                            if (hr != 0)
                            {
                                Error.SetError("Unable to play movie", "Unable build graph for VMR9");
                                Cleanup();
                                return(false);
                            }
                        }
                        else
                        {
                            Splitter = DirectShowUtil.AddFilterToGraph(graphBuilder, filterConfig.strsplitterfilefilter);
                        }
                    }
                }

                // Add preferred video filters
                UpdateFilters("Video");

                //Add Audio Renderer
                if (filterConfig.AudioRenderer.Length > 0 && filterCodec._audioRendererFilter == null)
                {
                    filterCodec._audioRendererFilter = DirectShowUtil.AddAudioRendererToGraph(graphBuilder,
                                                                                              filterConfig.AudioRenderer, false);
                }

                // Add preferred audio filters
                UpdateFilters("Audio");

                #region Set High Audio

                //Set High Resolution Output > 2 channels
                IBaseFilter baseFilter    = null;
                bool        FFDShowLoaded = false;
                graphBuilder.FindFilterByName("WMAudio Decoder DMO", out baseFilter);
                if (baseFilter != null && filterConfig.wmvAudio != false) //Also check configuration option enabled
                {
                    //Set the filter setting to enable more than 2 audio channels
                    const string g_wszWMACHiResOutput = "_HIRESOUTPUT";
                    object       val     = true;
                    IPropertyBag propBag = (IPropertyBag)baseFilter;
                    hr = propBag.Write(g_wszWMACHiResOutput, ref val);
                    if (hr != 0)
                    {
                        Log.Info("VideoPlayer9: Unable to turn WMAudio multichannel on. Reason: {0}", hr);
                    }
                    else
                    {
                        Log.Info("VideoPlayer9: WMAudio Decoder now set for > 2 audio channels");
                    }
                    if (!FFDShowLoaded)
                    {
                        IBaseFilter FFDShowAudio = DirectShowUtil.GetFilterByName(graphBuilder,
                                                                                  FFDSHOW_AUDIO_DECODER_FILTER);
                        if (FFDShowAudio != null)
                        {
                            DirectShowUtil.ReleaseComObject(FFDShowAudio);
                            FFDShowAudio = null;
                        }
                        else
                        {
                            _FFDShowAudio = DirectShowUtil.AddFilterToGraph(graphBuilder, FFDSHOW_AUDIO_DECODER_FILTER);
                        }
                        FFDShowLoaded = true;
                    }
                    DirectShowUtil.ReleaseComObject(baseFilter);
                    baseFilter = null;
                }

                #endregion

                if (_interfaceSourceFilter != null)
                {
                    DirectShowUtil.RenderGraphBuilderOutputPins(graphBuilder, _interfaceSourceFilter);
                }

                //Test and remove orphelin Audio Renderer
                //RemoveAudioR();

                //remove InternalScriptRenderer as it takes subtitle pin
                disableISR();

                //disable Closed Captions!
                disableCC();

                DirectShowUtil.RemoveUnusedFiltersFromGraph(graphBuilder);

                //remove orphelin audio renderer
                RemoveAudioR();

                //EnableClock();

                if ((Vmr9 == null || !Vmr9.IsVMR9Connected) && !AudioOnly)
                {
                    Log.Error("MyAnime3Player: Failed to render file -> vmr9");
                    mediaCtrl = null;
                    Cleanup();
                    return(false);
                }

                mediaCtrl  = (IMediaControl)graphBuilder;
                mediaEvt   = (IMediaEventEx)graphBuilder;
                mediaSeek  = (IMediaSeeking)graphBuilder;
                mediaPos   = (IMediaPosition)graphBuilder;
                basicAudio = (IBasicAudio)graphBuilder;
                videoWin   = (IVideoWindow)graphBuilder;
                if (Vmr9 != null)
                {
                    m_iVideoWidth  = Vmr9.VideoWidth;
                    m_iVideoHeight = Vmr9.VideoHeight;
                    Vmr9.SetDeinterlaceMode();
                }
                return(true);
            }
            catch (Exception ex)
            {
                Error.SetError("Unable to play movie", "Unable build graph for VMR9");
                Log.Error("MyAnime3Player: Exception while creating DShow graph {0} {1}", ex.Message, ex.StackTrace);
                Cleanup();
                return(false);
            }
        }
        /// <summary> create the used COM components and get the interfaces. </summary>
        protected override bool GetInterfaces(string filename)
        {
            Speed = 1;
            Log.Info("StreamBufferPlayer9: GetInterfaces()");

            //switch back to directx fullscreen mode

            //		Log.Info("StreamBufferPlayer9: switch to fullscreen mode");
            Log.Info("StreamBufferPlayer9: Enabling DX9 exclusive mode");
            GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 1, 0, null);

            GUIWindowManager.SendMessage(msg);

            //Log.Info("StreamBufferPlayer9: build graph");

            try
            {
                _graphBuilder = (IGraphBuilder) new FilterGraph();
                //Log.Info("StreamBufferPlayer9: add _vmr9");

                _vmr9 = new VMR9Util();
                _vmr9.AddVMR9(_graphBuilder);
                _vmr9.Enable(false);


                int hr;
                m_StreamBufferConfig = new StreamBufferConfig();
                streamConfig2        = m_StreamBufferConfig as IStreamBufferConfigure2;
                if (streamConfig2 != null)
                {
                    // setting the StreamBufferEngine registry key
                    IntPtr HKEY = (IntPtr) unchecked ((int)0x80000002L);
                    IStreamBufferInitialize pTemp = (IStreamBufferInitialize)streamConfig2;
                    IntPtr subKey = IntPtr.Zero;

                    RegOpenKeyEx(HKEY, "SOFTWARE\\MediaPortal", 0, 0x3f, out subKey);
                    hr = pTemp.SetHKEY(subKey);
                    hr = streamConfig2.SetFFTransitionRates(8, 32);
                    //Log.Info("set FFTransitionRates:{0:X}",hr);

                    int max, maxnon;
                    hr = streamConfig2.GetFFTransitionRates(out max, out maxnon);

                    streamConfig2.GetBackingFileCount(out _minBackingFiles, out _maxBackingFiles);
                    streamConfig2.GetBackingFileDuration(out _backingFileDuration);
                }
                //Log.Info("StreamBufferPlayer9: add sbe");

                // create SBE source
                _bufferSource = (IStreamBufferSource) new StreamBufferSource();
                if (_bufferSource == null)
                {
                    Log.Error("StreamBufferPlayer9:Failed to create instance of SBE (do you have WinXp SP1?)");
                    return(false);
                }


                IBaseFilter filter = (IBaseFilter)_bufferSource;
                hr = _graphBuilder.AddFilter(filter, "SBE SOURCE");
                if (hr != 0)
                {
                    Log.Error("StreamBufferPlayer9:Failed to add SBE to graph");
                    return(false);
                }

                IFileSourceFilter fileSource = (IFileSourceFilter)_bufferSource;
                if (fileSource == null)
                {
                    Log.Error("StreamBufferPlayer9:Failed to get IFileSourceFilter");
                    return(false);
                }


                //Log.Info("StreamBufferPlayer9: open file:{0}",filename);
                hr = fileSource.Load(filename, null);
                if (hr != 0)
                {
                    Log.Error("StreamBufferPlayer9:Failed to open file:{0} :0x{1:x}", filename, hr);
                    return(false);
                }


                //Log.Info("StreamBufferPlayer9: add codecs");
                // add preferred video & audio codecs
                string strVideoCodec    = "";
                string strAudioCodec    = "";
                string strAudioRenderer = "";
                int    intFilters       = 0;  // FlipGer: count custom filters
                string strFilters       = ""; // FlipGer: collect custom filters
                using (Settings xmlreader = new MPSettings())
                {
                    // FlipGer: load infos for custom filters
                    int intCount = 0;
                    while (xmlreader.GetValueAsString("mytv", "filter" + intCount.ToString(), "undefined") != "undefined")
                    {
                        if (xmlreader.GetValueAsBool("mytv", "usefilter" + intCount.ToString(), false))
                        {
                            strFilters += xmlreader.GetValueAsString("mytv", "filter" + intCount.ToString(), "undefined") + ";";
                            intFilters++;
                        }
                        intCount++;
                    }
                    strVideoCodec    = xmlreader.GetValueAsString("mytv", "videocodec", "");
                    strAudioCodec    = xmlreader.GetValueAsString("mytv", "audiocodec", "");
                    strAudioRenderer = xmlreader.GetValueAsString("mytv", "audiorenderer", "Default DirectSound Device");
                    string strValue = xmlreader.GetValueAsString("mytv", "defaultar", "Normal");
                    GUIGraphicsContext.ARType = Util.Utils.GetAspectRatio(strValue);
                }
                if (strVideoCodec.Length > 0)
                {
                    _videoCodecFilter = DirectShowUtil.AddFilterToGraph(_graphBuilder, strVideoCodec);
                }
                if (strAudioCodec.Length > 0)
                {
                    _audioCodecFilter = DirectShowUtil.AddFilterToGraph(_graphBuilder, strAudioCodec);
                }
                if (strAudioRenderer.Length > 0)
                {
                    _audioRendererFilter = DirectShowUtil.AddAudioRendererToGraph(_graphBuilder, strAudioRenderer, true);
                }
                // FlipGer: add custom filters to graph
                customFilters = new IBaseFilter[intFilters];
                string[] arrFilters = strFilters.Split(';');
                for (int i = 0; i < intFilters; i++)
                {
                    customFilters[i] = DirectShowUtil.AddFilterToGraph(_graphBuilder, arrFilters[i]);
                }

                // render output pins of SBE
                DirectShowUtil.RenderOutputPins(_graphBuilder, (IBaseFilter)fileSource);

                _mediaCtrl     = (IMediaControl)_graphBuilder;
                _mediaEvt      = (IMediaEventEx)_graphBuilder;
                _mediaSeeking  = _bufferSource as IStreamBufferMediaSeeking;
                _mediaSeeking2 = _bufferSource as IStreamBufferMediaSeeking2;
                if (_mediaSeeking == null)
                {
                    Log.Error("Unable to get IMediaSeeking interface#1");
                }
                if (_mediaSeeking2 == null)
                {
                    Log.Error("Unable to get IMediaSeeking interface#2");
                }
                if (_audioRendererFilter != null)
                {
                    IMediaFilter    mp    = _graphBuilder as IMediaFilter;
                    IReferenceClock clock = _audioRendererFilter as IReferenceClock;
                    hr = mp.SetSyncSource(clock);
                }

                // Set the IBasicAudioInterface

                _basicAudio = (IBasicAudio)_graphBuilder;

                //        Log.Info("StreamBufferPlayer9:SetARMode");
                //        DirectShowUtil.SetARMode(_graphBuilder,AspectRatioMode.Stretched);

                //Log.Info("StreamBufferPlayer9: set Deinterlace");

                if (!_vmr9.IsVMR9Connected)
                {
                    //_vmr9 is not supported, switch to overlay
                    Log.Info("StreamBufferPlayer9: switch to overlay");
                    _mediaCtrl = null;
                    Cleanup();
                    return(base.GetInterfaces(filename));
                }
                _pinVmr9ConnectedTo = _vmr9.PinConnectedTo;
                _vmr9.SetDeinterlaceMode();
                return(true);
            }
            catch (Exception ex)
            {
                Log.Error("StreamBufferPlayer9:exception while creating DShow graph {0} {1}", ex.Message, ex.StackTrace);
                return(false);
            }
        }
Beispiel #7
0
        /// <summary>
        /// If the url to be played can be buffered before starting playback, this function
        /// starts building a graph by adding the preferred video and audio render to it.
        /// This needs to be called on the MpMain Thread.
        /// </summary>
        /// <returns>true, if the url can be buffered (a graph was started), false if it can't be and null if an error occured building the graph</returns>
        public bool?PrepareGraph()
        {
            string sourceFilterName = GetSourceFilterName(m_strCurrentFile);

            if (!string.IsNullOrEmpty(sourceFilterName))
            {
                graphBuilder = (IGraphBuilder) new FilterGraph();
                _rotEntry    = new DsROTEntry((IFilterGraph)graphBuilder);

                basicVideo = graphBuilder as IBasicVideo2;

                Vmr9 = new VMR9Util();
                Vmr9.AddVMR9(graphBuilder);
                Vmr9.Enable(false);
                // set VMR9 back to NOT Active -> otherwise GUI is not refreshed while graph is building
                GUIGraphicsContext.Vmr9Active = false;

                // add the audio renderer
                using (Settings settings = new MPSettings())
                {
                    string audiorenderer = settings.GetValueAsString("movieplayer", "audiorenderer", "Default DirectSound Device");
                    DirectShowUtil.AddAudioRendererToGraph(graphBuilder, audiorenderer, false);
                }

                // set fields for playback
                mediaCtrl  = (IMediaControl)graphBuilder;
                mediaEvt   = (IMediaEventEx)graphBuilder;
                mediaSeek  = (IMediaSeeking)graphBuilder;
                mediaPos   = (IMediaPosition)graphBuilder;
                basicAudio = (IBasicAudio)graphBuilder;
                videoWin   = (IVideoWindow)graphBuilder;

                // add the source filter
                IBaseFilter sourceFilter = null;
                try
                {
                    if (sourceFilterName == OnlineVideos.MPUrlSourceFilter.Downloader.FilterName)
                    {
                        sourceFilter = FilterFromFile.LoadFilterFromDll("MPUrlSourceSplitter\\MPUrlSourceSplitter.ax", new Guid(OnlineVideos.MPUrlSourceFilter.Downloader.FilterCLSID), true);
                        if (sourceFilter != null)
                        {
                            Marshal.ThrowExceptionForHR(graphBuilder.AddFilter(sourceFilter, OnlineVideos.MPUrlSourceFilter.Downloader.FilterName));
                        }
                    }
                    if (sourceFilter == null)
                    {
                        sourceFilter = DirectShowUtil.AddFilterToGraph(graphBuilder, sourceFilterName);
                    }
                }
                catch (Exception ex)
                {
                    Log.Instance.Warn("Error adding '{0}' filter to graph: {1}", sourceFilterName, ex.Message);
                    return(null);
                }
                finally
                {
                    if (sourceFilter != null)
                    {
                        DirectShowUtil.ReleaseComObject(sourceFilter, 2000);
                    }
                }
                return(true);
            }
            else
            {
                return(false);
            }
        }
Beispiel #8
0
        public bool Play(string fileName, Control parent, out string ErrorOrSplitter)
        {
            ErrorOrSplitter = "";
            int hr;

            _parentControl = parent;

            _graphBuilder = (IFilterGraph2) new FilterGraph();
            _rotEntry     = new DsROTEntry(_graphBuilder);

            // add the video renderer (evr does not seem to work here)
            IBaseFilter vmr9Renderer = DirectShowUtil.AddFilterToGraph(_graphBuilder, "Video Mixing Renderer 9");

            ((IVMRAspectRatioControl9)vmr9Renderer).SetAspectRatioMode(VMRAspectRatioMode.LetterBox);
            DirectShowUtil.ReleaseComObject(vmr9Renderer, 2000);

            // add the audio renderer
            IBaseFilter audioRenderer = DirectShowUtil.AddAudioRendererToGraph(_graphBuilder, MPSettings.Instance.GetValueAsString("movieplayer", "audiorenderer", "Default DirectSound Device"), false);

            DirectShowUtil.ReleaseComObject(audioRenderer, 2000);

            // add the source filter
            string sourceFilterName = OnlineVideos.MediaPortal1.Player.OnlineVideosPlayer.GetSourceFilterName(fileName);

            if (string.IsNullOrEmpty(sourceFilterName))
            {
                return(false);
            }
            IBaseFilter sourceFilter = null;

            try
            {
                sourceFilter = DirectShowUtil.AddFilterToGraph(_graphBuilder, sourceFilterName);
            }
            catch (Exception ex)
            {
                ErrorOrSplitter = ex.Message;
                return(false);
            }

            hr = ((IFileSourceFilter)sourceFilter).Load(fileName, null);

            if (hr != 0)
            {
                ErrorOrSplitter = DirectShowLib.DsError.GetErrorText(hr);
                DirectShowUtil.ReleaseComObject(sourceFilter, 2000);
                return(false);
            }

            // wait for our filter to buffer before rendering the pins
            OnlineVideos.MPUrlSourceFilter.IFilterState filterState = sourceFilter as OnlineVideos.MPUrlSourceFilter.IFilterState;

            if (filterState != null)
            {
                bool ready = false;

                while ((!ready) && (hr == 0))
                {
                    hr = filterState.IsFilterReadyToConnectPins(out ready);

                    System.Threading.Thread.Sleep(25);
                }
            }

            if (hr != 0)
            {
                ErrorOrSplitter = DirectShowLib.DsError.GetErrorText(hr);
                DirectShowUtil.ReleaseComObject(sourceFilter, 2000);
                return(false);
            }

            OnlineVideos.MediaPortal1.Player.OnlineVideosPlayer.AddPreferredFilters(_graphBuilder, sourceFilter);

            // try to connect the filters
            int       numConnected = 0;
            IEnumPins pinEnum;

            hr = sourceFilter.EnumPins(out pinEnum);
            if ((hr == 0) && (pinEnum != null))
            {
                pinEnum.Reset();
                IPin[] pins = new IPin[1];
                int    iFetched;
                int    iPinNo = 0;
                do
                {
                    iPinNo++;
                    hr = pinEnum.Next(1, pins, out iFetched);
                    if (hr == 0)
                    {
                        if (iFetched == 1 && pins[0] != null)
                        {
                            PinDirection pinDir;
                            pins[0].QueryDirection(out pinDir);
                            if (pinDir == PinDirection.Output)
                            {
                                hr = _graphBuilder.Render(pins[0]);
                                if (hr == 0)
                                {
                                    numConnected++;
                                    IPin connectedPin;
                                    if (pins[0].ConnectedTo(out connectedPin) == 0 && connectedPin != null)
                                    {
                                        PinInfo connectedPinInfo;
                                        connectedPin.QueryPinInfo(out connectedPinInfo);
                                        FilterInfo connectedFilterInfo;
                                        connectedPinInfo.filter.QueryFilterInfo(out connectedFilterInfo);
                                        DirectShowUtil.ReleaseComObject(connectedPin, 2000);
                                        IBaseFilter connectedFilter;
                                        if (connectedFilterInfo.pGraph.FindFilterByName(connectedFilterInfo.achName, out connectedFilter) == 0 && connectedFilter != null)
                                        {
                                            var codecInfo = GetCodecInfo(connectedFilter, connectedFilterInfo.achName);
                                            if (codecInfo != null)
                                            {
                                                if (string.IsNullOrEmpty(ErrorOrSplitter))
                                                {
                                                    ErrorOrSplitter = codecInfo.ToString();
                                                }
                                                else
                                                {
                                                    ErrorOrSplitter += ", " + codecInfo.ToString();
                                                }
                                            }
                                            DirectShowUtil.ReleaseComObject(connectedFilter);
                                        }
                                    }
                                }
                            }
                            DirectShowUtil.ReleaseComObject(pins[0], 2000);
                        }
                    }
                } while (iFetched == 1);
            }
            DirectShowUtil.ReleaseComObject(pinEnum, 2000);

            if (numConnected > 0)
            {
                _videoWin = _graphBuilder as IVideoWindow;
                if (_videoWin != null)
                {
                    _videoWin.put_Owner(_parentControl.Handle);
                    _videoWin.put_WindowStyle((WindowStyle)((int)WindowStyle.Child + (int)WindowStyle.ClipSiblings + (int)WindowStyle.ClipChildren));
                    _videoWin.SetWindowPosition(_parentControl.ClientRectangle.X, _parentControl.ClientRectangle.Y, _parentControl.ClientRectangle.Width, _parentControl.ClientRectangle.Height);
                    _videoWin.put_Visible(OABool.True);
                }

                _mediaCtrl = (IMediaControl)_graphBuilder;
                hr         = _mediaCtrl.Run();

                mediaEvents = (IMediaEventEx)_graphBuilder;
                // Have the graph signal event via window callbacks for performance
                mediaEvents.SetNotifyWindow(_parentControl.FindForm().Handle, WMGraphNotify, IntPtr.Zero);

                _parentControl.SizeChanged += _parentControl_SizeChanged;
                return(true);
            }
            else
            {
                ErrorOrSplitter = string.Format("Could not render output pins of {0}", sourceFilterName);
                DirectShowUtil.ReleaseComObject(sourceFilter, 2000);
                Stop();
                return(false);
            }
        }
        /// <summary> create the used COM components and get the interfaces. </summary>
        protected override bool GetInterfaces(string filename)
        {
            Log.Info("TSReaderPlayer: GetInterfaces()");
            try
            {
                string strAudioRenderer = "";
                int    intFilters       = 0;  // FlipGer: count custom filters
                string strFilters       = ""; // FlipGer: collect custom filters

                LoadMyTvFilterSettings(ref intFilters, ref strFilters, ref strVideoCodec, ref strAudioCodec,
                                       ref strAACAudioCodec, ref strDDPLUSAudioCodec, ref strH264VideoCodec,
                                       ref strAudioRenderer,
                                       ref enableDVBBitmapSubtitles, ref enableDVBTtxtSubtitles, ref relaxTsReader);

                _graphBuilder = (IGraphBuilder) new FilterGraph();
                _rotEntry     = new DsROTEntry((IFilterGraph)_graphBuilder);

                if (strAudioRenderer.Length > 0) //audio renderer must be in graph before audio switcher
                {
                    _audioRendererFilter = DirectShowUtil.AddAudioRendererToGraph(_graphBuilder, strAudioRenderer, true);
                }

                #region add AudioSwitcher

                if (enableMPAudioSwitcher) //audio switcher must be in graph before tsreader audiochangecallback
                {
                    _audioSwitcherFilter = DirectShowUtil.AddFilterToGraph(_graphBuilder, "MediaPortal AudioSwitcher");
                    if (_audioSwitcherFilter == null)
                    {
                        Log.Error("TSReaderPlayer: Failed to add AudioSwitcher to graph");
                    }
                }

                #endregion

                #region add TsReader

                TsReader reader = new TsReader();
                _fileSource        = (IBaseFilter)reader;
                _ireader           = (ITSReader)reader;
                _interfaceTSReader = _fileSource;
                _ireader.SetRelaxedMode(relaxTsReader); // enable/disable continousity filtering
                _ireader.SetTsReaderCallback(this);
                _ireader.SetRequestAudioChangeCallback(this);
                Log.Info("TSReaderPlayer: Add TsReader to graph");
                int hr = _graphBuilder.AddFilter((IBaseFilter)_fileSource, "TsReader");
                DsError.ThrowExceptionForHR(hr);

                #endregion

                #region load file in TsReader

                IFileSourceFilter interfaceFile = (IFileSourceFilter)_fileSource;
                if (interfaceFile == null)
                {
                    Log.Error("TSReaderPlayer: Failed to get IFileSourceFilter");
                    Cleanup();
                    return(false);
                }
                Log.Info("TSReaderPlayer: Open file: {0}", filename);
                hr = interfaceFile.Load(filename, null);
                if (hr != 0)
                {
                    Log.Error("TSReaderPlayer: Failed to open file:{0} :0x{1:x}", filename, hr);
                    Cleanup();
                    return(false);
                }

                #endregion

                #region add codecs

                Log.Info("TSReaderPlayer: Add codecs");
                // add preferred video & audio codecs
                MatchFilters("Video");
                MatchFilters("Audio");

                // does .ts file contain video?
                // default is _isRadio=false which prevents recorded radio file playing
                if (!_videoFormat.IsValid)
                {
                    _isRadio = true;
                }

                if (!_isRadio)
                {
                    _vmr9 = new VMR9Util();
                    _vmr9.AddVMR9(_graphBuilder);
                    _vmr9.Enable(false);

                    DirectShowUtil.AddFilterToGraph(_graphBuilder, videoFilter);
                    if (enableDVBBitmapSubtitles)
                    {
                        try
                        {
                            SubtitleRenderer.GetInstance().AddSubtitleFilter(_graphBuilder);
                        }
                        catch (Exception e)
                        {
                            Log.Error(e);
                        }
                    }
                }

                DirectShowUtil.AddFilterToGraph(_graphBuilder, audioFilter);

                // FlipGer: add custom filters to graph
                string[] arrFilters = strFilters.Split(';');
                for (int i = 0; i < intFilters; i++)
                {
                    DirectShowUtil.AddFilterToGraph(_graphBuilder, arrFilters[i]);
                }

                #endregion

                #region PostProcessingEngine Detection

                IPostProcessingEngine postengine = PostProcessingEngine.GetInstance(true);
                if (!postengine.LoadPostProcessing(_graphBuilder))
                {
                    PostProcessingEngine.engine = new PostProcessingEngine.DummyEngine();
                }

                #endregion

                #region render TsReader output pins

                Log.Info("TSReaderPlayer: Render TsReader outputs");
                if (_isRadio)
                {
                    IEnumPins enumPins;
                    hr = _fileSource.EnumPins(out enumPins);
                    DsError.ThrowExceptionForHR(hr);
                    IPin[] pins    = new IPin[1];
                    int    fetched = 0;
                    while (enumPins.Next(1, pins, out fetched) == 0)
                    {
                        if (fetched != 1)
                        {
                            break;
                        }
                        PinDirection direction;
                        pins[0].QueryDirection(out direction);
                        if (direction == PinDirection.Output)
                        {
                            IEnumMediaTypes enumMediaTypes;
                            pins[0].EnumMediaTypes(out enumMediaTypes);
                            AMMediaType[] mediaTypes = new AMMediaType[20];
                            int           fetchedTypes;
                            enumMediaTypes.Next(20, mediaTypes, out fetchedTypes);
                            for (int i = 0; i < fetchedTypes; ++i)
                            {
                                if (mediaTypes[i].majorType == MediaType.Audio)
                                {
                                    hr = _graphBuilder.Render(pins[0]);
                                    DsError.ThrowExceptionForHR(hr);
                                    break;
                                }
                            }
                        }
                        DirectShowUtil.ReleaseComObject(pins[0]);
                    }
                    DirectShowUtil.ReleaseComObject(enumPins);
                }
                else
                {
                    DirectShowUtil.RenderGraphBuilderOutputPins(_graphBuilder, _fileSource);
                }
                DirectShowUtil.RemoveUnusedFiltersFromGraph(_graphBuilder);

                #endregion

                _mediaCtrl    = (IMediaControl)_graphBuilder;
                _mediaEvt     = (IMediaEventEx)_graphBuilder;
                _mediaSeeking = (IMediaSeeking)_graphBuilder;
                if (_mediaSeeking == null)
                {
                    Log.Error("TSReaderPlayer: Unable to get IMediaSeeking interface");
                }
                _audioStream = (IAudioStream)_fileSource;
                if (_audioStream == null)
                {
                    Log.Error("TSReaderPlayer: Unable to get IAudioStream interface");
                }
                _audioSelector = new AudioSelector(_audioStream);

                if (!_isRadio)
                {
                    if (enableDVBTtxtSubtitles || enableDVBBitmapSubtitles)
                    {
                        try
                        {
                            SubtitleRenderer.GetInstance().SetPlayer(this);
                            _dvbSubRenderer = SubtitleRenderer.GetInstance();
                        }
                        catch (Exception e)
                        {
                            Log.Error(e);
                        }
                    }
                    if (enableDVBBitmapSubtitles)
                    {
                        _subtitleStream = (ISubtitleStream)_fileSource;
                        if (_subtitleStream == null)
                        {
                            Log.Error("TSReaderPlayer: Unable to get ISubtitleStream interface");
                        }
                    }
                    if (enableDVBTtxtSubtitles)
                    {
                        //Log.Debug("TSReaderPlayer: Obtaining TeletextSource");
                        _teletextSource = (ITeletextSource)_fileSource;
                        if (_teletextSource == null)
                        {
                            Log.Error("TSReaderPlayer: Unable to get ITeletextSource interface");
                        }
                        Log.Debug("TSReaderPlayer: Creating Teletext Receiver");
                        TeletextSubtitleDecoder ttxtDecoder = new TeletextSubtitleDecoder(_dvbSubRenderer);
                        _ttxtReceiver = new TeletextReceiver(_teletextSource, ttxtDecoder);
                        // regardless of whether dvb subs are enabled, the following call is okay
                        // if _subtitleStream is null the subtitle will just not setup for bitmap subs
                        _subSelector = new SubtitleSelector(_subtitleStream, _dvbSubRenderer, ttxtDecoder);
                    }
                    else if (enableDVBBitmapSubtitles)
                    {
                        // if only dvb subs are enabled, pass null for ttxtDecoder
                        _subSelector = new SubtitleSelector(_subtitleStream, _dvbSubRenderer, null);
                    }
                }
                if (_audioRendererFilter != null)
                {
                    //Log.Info("TSReaderPlayer:set reference clock");
                    IMediaFilter    mp    = (IMediaFilter)_graphBuilder;
                    IReferenceClock clock = (IReferenceClock)_audioRendererFilter;
                    hr = mp.SetSyncSource(null);
                    hr = mp.SetSyncSource(clock);
                    //Log.Info("TSReaderPlayer:set reference clock:{0:X}", hr);
                    _basicAudio = (IBasicAudio)_graphBuilder;
                }
                if (!_isRadio)
                {
                    IBaseFilter basefilter;
                    _graphBuilder.FindFilterByName("Line 21 Decoder", out basefilter);
                    if (basefilter == null)
                    {
                        _graphBuilder.FindFilterByName("Line21 Decoder", out basefilter);
                    }
                    if (basefilter == null)
                    {
                        _graphBuilder.FindFilterByName("Line 21 Decoder 2", out basefilter);
                    }
                    if (basefilter != null)
                    {
                        Log.Info("TSreaderPlayer: Line21 Decoder (Closed Captions), in use"); //: {0}", showClosedCaptions);
                        _line21Decoder = (IAMLine21Decoder)basefilter;
                        if (_line21Decoder != null)
                        {
                            AMLine21CCState state = AMLine21CCState.Off;
                            hr = _line21Decoder.SetServiceState(state);
                            if (hr == 0)
                            {
                                Log.Info("TSReaderPlayer: Closed Captions state change successful");
                            }
                            else
                            {
                                Log.Info("TSReaderPlayer: Failed to change Closed Captions state");
                            }
                        }
                    }
                    if (!_vmr9.IsVMR9Connected)
                    {
                        Log.Error("TSReaderPlayer: Failed vmr9 not connected");
                        Cleanup();
                        return(false);
                    }
                    DirectShowUtil.EnableDeInterlace(_graphBuilder);
                    _vmr9.SetDeinterlaceMode();
                }

                using (MPSettings xmlreader = new MPSettings())
                {
                    int lastSubIndex = xmlreader.GetValueAsInt("tvservice", "lastsubtitleindex", 0);
                    Log.Debug("TSReaderPlayer: Last subtitle index: {0}", lastSubIndex);
                    CurrentSubtitleStream = lastSubIndex;
                }
                return(true);
            }
            catch (Exception ex)
            {
                Log.Error("TSReaderPlayer: Exception while creating DShow graph {0}", ex.Message);
                Cleanup();
                return(false);
            }
        }
        /// <summary> create the used COM components and get the interfaces. </summary>
        protected override bool GetInterfaces()
        {
            try
            {
                graphBuilder = (IGraphBuilder) new FilterGraph();
                _rotEntry    = new DsROTEntry((IFilterGraph)graphBuilder);
                // add preferred video & audio codecs
                int    hr;
                int    intFilters        = 0; // FlipGer: count custom filters
                string strVideoCodec     = "";
                string strH264VideoCodec = "";
                string strAudioCodec     = "";
                string strAACAudioCodec  = "";
                string strAudiorenderer  = "";
                string strFilters        = ""; // FlipGer: collect custom filters
                bool   wmvAudio;
                bool   autoloadSubtitles;
                bool   bAutoDecoderSettings = false;

                using (Settings xmlreader = new MPSettings())
                {
                    bAutoDecoderSettings = xmlreader.GetValueAsBool("movieplayer", "autodecodersettings", false);
                    strVideoCodec        = xmlreader.GetValueAsString("movieplayer", "mpeg2videocodec", "");
                    strH264VideoCodec    = xmlreader.GetValueAsString("movieplayer", "h264videocodec", "");
                    strAudioCodec        = xmlreader.GetValueAsString("movieplayer", "mpeg2audiocodec", "");
                    strAACAudioCodec     = xmlreader.GetValueAsString("movieplayer", "aacaudiocodec", "");
                    strAudiorenderer     = xmlreader.GetValueAsString("movieplayer", "audiorenderer", "Default DirectSound Device");
                    wmvAudio             = xmlreader.GetValueAsBool("movieplayer", "wmvaudio", false);
                    autoloadSubtitles    = xmlreader.GetValueAsBool("subtitles", "enabled", false);
                    // FlipGer: load infos for custom filters
                    int intCount = 0;
                    while (xmlreader.GetValueAsString("movieplayer", "filter" + intCount.ToString(), "undefined") != "undefined")
                    {
                        if (xmlreader.GetValueAsBool("movieplayer", "usefilter" + intCount.ToString(), false))
                        {
                            strFilters += xmlreader.GetValueAsString("movieplayer", "filter" + intCount.ToString(), "undefined") + ";";
                            intFilters++;
                        }
                        intCount++;
                    }
                }

                if (bAutoDecoderSettings)
                {
                    return(AutoRendering(wmvAudio));
                }

                //Manually add codecs based on file extension if not in auto-settings
                // switch back to directx fullscreen mode
                Log.Info("VideoPlayerVMR9: Enabling DX9 exclusive mode");
                GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 1, 0, null);
                GUIWindowManager.SendMessage(msg);

                // add the VMR9 in the graph
                // after enabeling exclusive mode, if done first it causes MediPortal to minimize if for example the "Windows key" is pressed while playing a video
                Vmr9 = new VMR9Util();
                Vmr9.AddVMR9(graphBuilder);
                Vmr9.Enable(false);

                IBaseFilter source = null;
                graphBuilder.AddSourceFilter(m_strCurrentFile, null, out source);
                string extension = Path.GetExtension(m_strCurrentFile).ToLower();

                switch (extension)
                {
                case ".wmv":
                case ".asf":
                {
                    //strVideoCodec = "WMVideo Decoder DMO"; //allow e.g. ffdshow usage
                    strH264VideoCodec = "";
                    strAudioCodec     = "WMAudio Decoder DMO"; // multichannel audio needs this filter
                    strAACAudioCodec  = "";
                    break;
                }

                case ".mkv":
                case ".m2ts":
                case ".mp4":
                {
                    strVideoCodec = "";
                    break;
                }

                default:
                    strH264VideoCodec = "";
                    strAACAudioCodec  = "";
                    break;
                }

                if (!string.IsNullOrEmpty(strVideoCodec))
                {
                    DirectShowUtil.AddFilterToGraph(graphBuilder, strVideoCodec);
                }
                if (!string.IsNullOrEmpty(strH264VideoCodec) && strVideoCodec != strH264VideoCodec)
                {
                    DirectShowUtil.AddFilterToGraph(graphBuilder, strH264VideoCodec);
                }
                if (!string.IsNullOrEmpty(strAudioCodec))
                {
                    DirectShowUtil.AddFilterToGraph(graphBuilder, strAudioCodec);
                }
                if (!string.IsNullOrEmpty(strAACAudioCodec) && strAudioCodec != strAACAudioCodec)
                {
                    DirectShowUtil.AddFilterToGraph(graphBuilder, strAACAudioCodec);
                }

                if (strAudiorenderer.Length > 0)
                {
                    DirectShowUtil.AddAudioRendererToGraph(graphBuilder, strAudiorenderer, false);
                }
                //We now add custom filters after the Audio Renderer as AC3Filter failed to connect otherwise.
                //FlipGer: add custom filters to graph
                string[] arrFilters = strFilters.Split(';');
                for (int i = 0; i < intFilters; i++)
                {
                    DirectShowUtil.AddFilterToGraph(graphBuilder, arrFilters[i]);
                }

                //Set High Resolution Output > 2 channels
                IBaseFilter baseFilter    = null;
                bool        FFDShowLoaded = false;
                graphBuilder.FindFilterByName("WMAudio Decoder DMO", out baseFilter);
                if (baseFilter != null && wmvAudio != false) //Also check configuration option enabled
                {
                    //Set the filter setting to enable more than 2 audio channels
                    const string g_wszWMACHiResOutput = "_HIRESOUTPUT";
                    object       val     = true;
                    IPropertyBag propBag = (IPropertyBag)baseFilter;
                    hr = propBag.Write(g_wszWMACHiResOutput, ref val);
                    if (hr != 0)
                    {
                        Log.Info("VideoPlayerVMR9: Unable to turn WMAudio multichannel on. Reason: {0}", hr);
                    }
                    else
                    {
                        Log.Info("VideoPlayerVMR9: WMAudio Decoder now set for > 2 audio channels");
                    }
                    if (!FFDShowLoaded)
                    {
                        IBaseFilter FFDShowAudio = DirectShowUtil.GetFilterByName(graphBuilder, FFDSHOW_AUDIO_DECODER_FILTER);
                        if (FFDShowAudio != null)
                        {
                            DirectShowUtil.ReleaseComObject(FFDShowAudio);
                            FFDShowAudio = null;
                        }
                        else
                        {
                            _FFDShowAudio = DirectShowUtil.AddFilterToGraph(graphBuilder, FFDSHOW_AUDIO_DECODER_FILTER);
                        }
                        FFDShowLoaded = true;
                    }
                    DirectShowUtil.ReleaseComObject(baseFilter);
                    baseFilter = null;
                }

                #region load external audio streams

                // check if current "File" is a file... it could also be a URL
                // Directory.Getfiles, ... will other give us an exception
                if (File.Exists(m_strCurrentFile))
                {
                    //load audio file (ac3, dts, mka, mp3) only with if the name matches partially with video file.
                    string[] audioFiles = Directory.GetFiles(Path.GetDirectoryName(m_strCurrentFile),
                                                             Path.GetFileNameWithoutExtension(m_strCurrentFile) + "*.*");
                    bool audioSwitcherLoaded = false;
                    foreach (string file in audioFiles)
                    {
                        switch (Path.GetExtension(file))
                        {
                        case ".mp3":
                        case ".dts":
                        case ".mka":
                        case ".ac3":
                            if (!audioSwitcherLoaded)
                            {
                                IBaseFilter switcher = DirectShowUtil.GetFilterByName(graphBuilder, MEDIAPORTAL_AUDIOSWITCHER_FILTER);
                                if (switcher != null)
                                {
                                    DirectShowUtil.ReleaseComObject(switcher);
                                    switcher = null;
                                }
                                else
                                {
                                    _audioSwitcher = DirectShowUtil.AddFilterToGraph(graphBuilder, MEDIAPORTAL_AUDIOSWITCHER_FILTER);
                                }
                                audioSwitcherLoaded = true;
                            }

                            _AudioSourceFilter = DirectShowUtil.AddFilterToGraph(graphBuilder, FILE_SYNC_FILTER);
                            int result = ((IFileSourceFilter)_AudioSourceFilter).Load(file, null);

                            //Force using LAVFilter
                            _AudioExtSplitterFilter = DirectShowUtil.AddFilterToGraph(graphBuilder, LAV_SPLITTER_FILTER);

                            if (result != 0 || _AudioExtSplitterFilter == null)
                            {
                                if (_AudioSourceFilter != null)
                                {
                                    graphBuilder.RemoveFilter(_AudioSourceFilter);
                                    DirectShowUtil.ReleaseComObject(_AudioSourceFilter);
                                    _AudioSourceFilter = null;
                                }
                                if (_AudioExtSplitterFilter != null)
                                {
                                    graphBuilder.RemoveFilter(_AudioExtSplitterFilter);
                                    DirectShowUtil.ReleaseComObject(_AudioExtSplitterFilter);
                                    _AudioExtSplitterFilter = null;
                                }
                                //Trying Add Audio decoder in graph
                                AddFilterToGraphAndRelease(strAudioCodec);
                                graphBuilder.RenderFile(file, string.Empty);
                                Log.Debug("VideoPlayerVMR9 : External audio file loaded \"{0}\"", file);
                                AudioExternal = true;
                                break;
                            }

                            //Add Audio decoder in graph
                            _AudioExtFilter = DirectShowUtil.AddFilterToGraph(graphBuilder, strAudioCodec);

                            //Connect Filesource with the splitter
                            IPin pinOutAudioExt1 = DsFindPin.ByDirection((IBaseFilter)_AudioSourceFilter, PinDirection.Output, 0);
                            IPin pinInAudioExt2  = DsFindPin.ByDirection((IBaseFilter)_AudioExtSplitterFilter, PinDirection.Input, 0);
                            hr = graphBuilder.Connect(pinOutAudioExt1, pinInAudioExt2);

                            //Connect Splitter with the Audio Decoder
                            IPin pinOutAudioExt3 = DsFindPin.ByDirection((IBaseFilter)_AudioExtSplitterFilter, PinDirection.Output, 0);
                            IPin pinInAudioExt4  = DsFindPin.ByDirection((IBaseFilter)_AudioExtFilter, PinDirection.Input, 0);
                            hr = graphBuilder.Connect(pinOutAudioExt3, pinInAudioExt4);

                            //Render outpin from Audio Decoder
                            DirectShowUtil.RenderUnconnectedOutputPins(graphBuilder, _AudioExtFilter);

                            //Cleanup External Audio (Release)
                            if (_AudioSourceFilter != null)
                            {
                                DirectShowUtil.ReleaseComObject(_AudioSourceFilter);
                                _AudioSourceFilter = null;
                            }
                            if (_AudioExtSplitterFilter != null)
                            {
                                DirectShowUtil.ReleaseComObject(_AudioExtSplitterFilter);
                                _AudioExtSplitterFilter = null;
                            }
                            if (_AudioExtFilter != null)
                            {
                                DirectShowUtil.ReleaseComObject(_AudioExtFilter);
                                _AudioExtFilter = null;
                            }
                            if (pinOutAudioExt1 != null)
                            {
                                DirectShowUtil.ReleaseComObject(pinOutAudioExt1);
                                pinOutAudioExt1 = null;
                            }
                            if (pinInAudioExt2 != null)
                            {
                                DirectShowUtil.ReleaseComObject(pinInAudioExt2);
                                pinInAudioExt2 = null;
                            }
                            if (pinOutAudioExt3 != null)
                            {
                                DirectShowUtil.ReleaseComObject(pinOutAudioExt3);
                                pinOutAudioExt3 = null;
                            }
                            if (pinInAudioExt4 != null)
                            {
                                DirectShowUtil.ReleaseComObject(pinInAudioExt4);
                                pinInAudioExt4 = null;
                            }

                            Log.Debug("VideoPlayerVMR9 : External audio file loaded \"{0}\"", file);
                            AudioExternal = true;
                            break;
                        }
                    }
                }

                #endregion

                DirectShowUtil.RenderUnconnectedOutputPins(graphBuilder, source);
                if (source != null)
                {
                    DirectShowUtil.ReleaseComObject(source);
                    source = null;
                }
                DirectShowUtil.RemoveUnusedFiltersFromGraph(graphBuilder);

                if (Vmr9 == null || !Vmr9.IsVMR9Connected)
                {
                    Log.Error("VideoPlayer9: Failed to render file -> vmr9");
                    mediaCtrl = null;
                    Cleanup();
                    return(false);
                }

                mediaCtrl      = (IMediaControl)graphBuilder;
                mediaEvt       = (IMediaEventEx)graphBuilder;
                mediaSeek      = (IMediaSeeking)graphBuilder;
                mediaPos       = (IMediaPosition)graphBuilder;
                basicAudio     = (IBasicAudio)graphBuilder;
                videoWin       = (IVideoWindow)graphBuilder;
                m_iVideoWidth  = Vmr9.VideoWidth;
                m_iVideoHeight = Vmr9.VideoHeight;
                Vmr9.SetDeinterlaceMode();
                return(true);
            }
            catch (Exception ex)
            {
                Error.SetError("Unable to play movie", "Unable build graph for VMR9");
                Log.Error("VideoPlayer9: Exception while creating DShow graph {0} {1}", ex.Message, ex.StackTrace);
                Cleanup();
                return(false);
            }
        }