/// <summary>
    /// Gets the filter configuration object from the user configuration
    /// </summary>
    /// <returns></returns>
    protected virtual BDFilterConfig GetFilterConfiguration()
    {
      BDFilterConfig filterConfig = new BDFilterConfig();

      using (Settings xmlreader = new MPSettings())
      {

        // get pre-defined filter setup
        filterConfig.VideoMPEG = xmlreader.GetValueAsString("bdplayer", "mpeg2videocodec", "");
        filterConfig.Audio = xmlreader.GetValueAsString("bdplayer", "mpeg2audiocodec", "");
        //filterConfig.AudioAAC = xmlreader.GetValueAsString("bdplayer", "aacaudiocodec", "");
        //filterConfig.AudioDDPlus = xmlreader.GetValueAsString("bdplayer", "ddplusaudiocodec", "");
        filterConfig.VideoH264 = xmlreader.GetValueAsString("bdplayer", "h264videocodec", "");
        filterConfig.VideoVC1 = xmlreader.GetValueAsString("bdplayer", "vc1videocodec", "");
        filterConfig.AudioRenderer = xmlreader.GetValueAsString("bdplayer", "audiorenderer", "Default DirectSound Device");

        // get AR setting
        filterConfig.AR = Util.Utils.GetAspectRatio(xmlreader.GetValueAsString("bdplayerAR", "defaultar", "Normal"));
        //GUIGraphicsContext.ARType = Util.Utils.GetAspectRatio(strValue);

        // get post-processing filter setup
        int i = 0;
        while (xmlreader.GetValueAsString("bdplayer", "filter" + i, "undefined") != "undefined")
        {
          if (xmlreader.GetValueAsBool("bdplayer", "usefilter" + i, false))
          {
            filterConfig.OtherFilters.Add(xmlreader.GetValueAsString("bdplayer", "filter" + i, "undefined"));
          }
          i++;
        }
      }

      return filterConfig;
    }
    protected bool GetInterfaces(string filename, int titleBD)
    {
      try
      {
        Log.Debug("BDPlayer: GetInterfaces()");

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

        filterConfig = GetFilterConfiguration();

        if (filterConfig.AudioRenderer.Length > 0)
        {
          _audioRendererFilter = DirectShowUtil.AddAudioRendererToGraph(_graphBuilder, filterConfig.AudioRenderer, true);
        }

        BDReader reader = new BDReader();
        _interfaceBDReader = reader as IBaseFilter;
        _ireader = reader as IBDReader;

        if (_interfaceBDReader == null || _ireader == null)
        {
          // todo: add exception
          return false;
        }

        // add the BD reader
        int hr = _graphBuilder.AddFilter(_interfaceBDReader, BD_READER_GRAPH_NAME);
        DsError.ThrowExceptionForHR(hr);

        Log.Debug("BDPlayer: Add BDReader to graph");

        IFileSourceFilter interfaceFile = (IFileSourceFilter)_interfaceBDReader;

        LoadSettings(_ireader);
        _ireader.SetD3DDevice(DirectShowUtil.GetUnmanagedDevice(GUIGraphicsContext.DX9Device));
        _ireader.SetBDReaderCallback(this);

        hr = interfaceFile.Load(filename, null);

        DsError.ThrowExceptionForHR(hr);

        Log.Debug("BDPlayer: BDReader loaded: {0}", filename);

        List<TitleInfo> titles = GetTitleInfoCollection(_ireader);

        while (true)
        {
          if (g_Player.ForcePlay && g_Player.SetResumeBDTitleState < g_Player.BdDefaultTitle)
          {
            if (titles.Count == 1)
            {
              _titleToPlay = 0;
              g_Player.SetResumeBDTitleState = g_Player.BdRemuxTitle;
            }
            else
            {
              _titleToPlay = g_Player.SetResumeBDTitleState;
            }
            _forceTitle = true;
            g_Player.ForcePlay = false;
          }
          else
          {
            if (titles.Count == 1)
            {
              // BD has only one title (remux one)
              _forceTitle = true;
              _titleToPlay = 0;
              g_Player.SetResumeBDTitleState = g_Player.BdRemuxTitle;

              if (g_Player.SetResumeBDTitleState == -1)
              {
                // user cancelled dialog
                titles.Dispose();
                g_Player.Stop();
                return false;
              }
            }
            else
            {
              _titleToPlay = SelectTitle(titles);
              g_Player.SetResumeBDTitleState = _titleToPlay;
              Log.Info("BDPlayer: BDReader _titleToPlay : {0}", _titleToPlay);
              if (_titleToPlay > -1)
              {
                // a specific title was selected
                _forceTitle = true;

                if (g_Player.SetResumeBDTitleState == -1)
                {
                  // user cancelled dialog
                  titles.Dispose();
                  g_Player.Stop();
                  return false;
                }
              }
              else
              {
                if (_titleToPlay == -1)
                {
                  // user cancelled dialog
                  g_Player.Stop();
                  titles.Dispose();
                  return false;
                }

                // user choose to display menu
                _forceTitle = false;
              }
            }
          }

          _ireader.ForceTitleBasedPlayback(_forceTitle, (uint)_titleToPlay);

          Log.Debug("BDPlayer: Starting BDReader");
          eventBuffer.Clear();
          hr = _ireader.Start();
          if (hr != 0)
          {

            if (!_forceTitle)
            {
              Log.Error("BDPlayer: Failed to start file:{0} :0x{1:x}", filename, hr);
              continue;
            }

            Log.Error("BDPlayer: Failed to start in title based mode file:{0} :0x{1:x}", filename, hr);
            titles.Dispose();
            return false;
          }
          else
          {
            Log.Info("BDPlayer: BDReader started");
          }

          break;
        }

        titles.Dispose();

        #region Filters

        Log.Info("BDPlayer: Adding filters");

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

        // Set VideoDecoder and VC1Override before adding filter in graph
        SetVideoDecoder();
        SetVC1Override();

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

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

        // Let the subtitle engine handle the proper filters
        try
        {
          SubtitleRenderer.GetInstance().AddSubtitleFilter(_graphBuilder);
        }
        catch (Exception e)
        {
          Log.Error(e);
        }
        
        #endregion

        #region PostProcessingEngine Detection

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

        #endregion

        #region render BDReader output pins

        Log.Info("BDPlayer: Render BDReader outputs");

        if (_interfaceBDReader != null)
        {
          DirectShowUtil.RenderGraphBuilderOutputPins(_graphBuilder, _interfaceBDReader);
        }
        
        //remove InternalScriptRenderer as it takes subtitle pin
        disableISR();

        //disable Closed Captions!
        disableCC();

        //RemoveAudioR();

        DirectShowUtil.RemoveUnusedFiltersFromGraph(_graphBuilder);

        #endregion

        _mediaCtrl = (IMediaControl)_graphBuilder;
        _mediaEvt = (IMediaEventEx)_graphBuilder;
        _mediaSeeking = (IMediaSeeking)_graphBuilder;

        try
        {
          SubtitleRenderer.GetInstance().SetPlayer(this);
          _dvbSubRenderer = SubtitleRenderer.GetInstance();
        }
        catch (Exception e)
        {
          Log.Error(e);
        }

        _subtitleStream = (Player.TSReaderPlayer.ISubtitleStream)_interfaceBDReader;
        if (_subtitleStream == null)
        {
          Log.Error("BDPlayer: Unable to get ISubtitleStream interface");
        }

        // if only dvb subs are enabled, pass null for ttxtDecoder
        _subSelector = new SubtitleSelector(_subtitleStream, _dvbSubRenderer, null);
        EnableSubtitle = _subtitlesEnabled;

        //Sync Audio Renderer
        SyncAudioRenderer();

        if (!_vmr9.IsVMR9Connected)
        {
          Log.Error("BDPlayer: Failed vmr9 not connected");
          return false;
        }
        _vmr9.SetDeinterlaceMode();
        return true;
      }
      catch (Exception ex)
      {
        Log.Error("BDPlayer: Exception while creating DShow graph {0}", ex.Message);
        return false;
      }
    }
    /// <summary>
    /// Gets the filter configuration object from the user configuration
    /// </summary>
    /// <returns></returns>
    protected virtual BDFilterConfig GetFilterConfiguration()
    {
      BDFilterConfig filterConfig = new BDFilterConfig();

      using (Settings xmlreader = new MPSettings())
      {

        // get pre-defined filter setup
        filterConfig.VideoMPEG = xmlreader.GetValueAsString("bdplayer", "mpeg2videocodec", "");
        filterConfig.Audio = xmlreader.GetValueAsString("bdplayer", "mpeg2audiocodec", "");
        //filterConfig.AudioAAC = xmlreader.GetValueAsString("bdplayer", "aacaudiocodec", "");
        //filterConfig.AudioDDPlus = xmlreader.GetValueAsString("bdplayer", "ddplusaudiocodec", "");
        filterConfig.VideoH264 = xmlreader.GetValueAsString("bdplayer", "h264videocodec", "");
        filterConfig.VideoVC1 = xmlreader.GetValueAsString("bdplayer", "vc1videocodec", "");
        filterConfig.AudioRenderer = xmlreader.GetValueAsString("bdplayer", "audiorenderer", "Default DirectSound Device");

        // get AR setting
        filterConfig.AR = Util.Utils.GetAspectRatio(xmlreader.GetValueAsString("mytv", "defaultar", "Normal"));
        //GUIGraphicsContext.ARType = Util.Utils.GetAspectRatio(strValue);  
      }

      return filterConfig;
    }