Пример #1
0
    //public bool IsVMR9Connected

    #endregion

    #region public members

    /// <summary>
    /// Add VMR9 filter to graph and configure it
    /// </summary>
    /// <param name="graphBuilder"></param>
    public bool AddVMR9(IGraphBuilder graphBuilder)
    {
      if (!_useVmr9)
      {
        Log.Debug("VMR9: addvmr9 - vmr9 is deactivated");
        return false;
      }
      if (_isVmr9Initialized)
      {
        Log.Debug("VMR9: addvmr9: vmr9 has already been initialized");
        return false;
      }

      bool _useEvr = GUIGraphicsContext.IsEvr;

      if (_instanceCounter != 0)
      {
        Log.Error("VMR9: Multiple instances of VMR9 running!!!");
        throw new Exception("VMR9Helper: Multiple instances of VMR9 running!!!");
      }

      HResult hr;
      IntPtr hMonitor = Manager.GetAdapterMonitor(GUIGraphicsContext.DX9Device.DeviceCaps.AdapterOrdinal);
      IntPtr upDevice = DirectShowUtil.GetUnmanagedDevice(GUIGraphicsContext.DX9Device);

      _scene = new PlaneScene(this);
      _scene.Init();

      if (_useEvr)
      {
        EvrInit(_scene, (uint)upDevice.ToInt32(), ref _vmr9Filter, (uint)hMonitor.ToInt32());
        hr = new HResult(graphBuilder.AddFilter(_vmr9Filter, "Enhanced Video Renderer"));
        Log.Info("VMR9: added EVR Renderer to graph");
      }
      else
      {
        _vmr9Filter = (IBaseFilter)new VideoMixingRenderer9();
        Log.Info("VMR9: added Video Mixing Renderer 9 to graph");

        Vmr9Init(_scene, (uint)upDevice.ToInt32(), _vmr9Filter, (uint)hMonitor.ToInt32());
        hr = new HResult(graphBuilder.AddFilter(_vmr9Filter, "Video Mixing Renderer 9"));
      }

      if (_vmr9Filter == null)
      {
        Error.SetError("Unable to play movie", "Renderer could not be added");
        Log.Error("VMR9: Renderer not installed / cannot be used!");
        return false;
      }

      if (hr != 0)
      {
        if (_useEvr)
        {
          EvrDeinit();
        }
        else
        {
          Vmr9Deinit();
        }
        _scene.Stop();
        _scene.Deinit();
        _scene = null;

        DirectShowUtil.ReleaseComObject(_vmr9Filter);
        _vmr9Filter = null;
        Error.SetError("Unable to play movie", "Unable to initialize Renderer");
        Log.Error("VMR9: Failed to add Renderer to filter graph");
        return false;
      }

      _qualityInterface = _vmr9Filter as IQualProp;
      _vmr9MixerBitmapInterface = _vmr9Filter as IVMRMixerBitmap9;
      _graphBuilderInterface = graphBuilder;
      _instanceCounter++;
      _isVmr9Initialized = true;
      if (!_useEvr)
      {
        SetDeinterlacePrefs();

        IVMRMixerControl9 mixer = _vmr9Filter as IVMRMixerControl9;
        if (mixer != null)
        {
          VMR9MixerPrefs dwPrefs;
          mixer.GetMixingPrefs(out dwPrefs);
          dwPrefs &= ~VMR9MixerPrefs.RenderTargetMask;

          dwPrefs |= VMR9MixerPrefs.RenderTargetYUV;
          // YUV saves graphics bandwith  http://msdn2.microsoft.com/en-us/library/ms788177(VS.85).aspx
          hr.Set(mixer.SetMixingPrefs(dwPrefs));
          Log.Debug("VMR9: Enabled YUV mixing - " + hr.ToDXString());

          using (Settings xmlreader = new MPSettings())
          {
            //Enable nonsquaremixing
            if (xmlreader.GetValueAsBool("general", "nonsquare", true))
            {
              mixer.GetMixingPrefs(out dwPrefs);
              dwPrefs |= VMR9MixerPrefs.NonSquareMixing;
              hr.Set(mixer.SetMixingPrefs(dwPrefs));
              Log.Debug("VRM9: Turning on nonsquare mixing - " + hr.ToDXString());
              hr.Set(mixer.SetMixingPrefs(dwPrefs));
            }

            // Enable DecimateMask - this will effectively use only half of the input width & length
            if (xmlreader.GetValueAsBool("general", "dx9decimatemask", false))
            {
              mixer.GetMixingPrefs(out dwPrefs);
              dwPrefs &= ~VMR9MixerPrefs.DecimateMask;
              dwPrefs |= VMR9MixerPrefs.DecimateOutput;
              hr.Set(mixer.SetMixingPrefs(dwPrefs));
              Log.Debug("VRM9: Enable decimatemask - " + hr.ToDXString());
              hr.Set(mixer.SetMixingPrefs(dwPrefs));
            }

            // see  D3DTEXTUREFILTERTYPE Enumerated Type documents for further information
            // MixerPref9_PointFiltering
            // MixerPref9_BiLinearFiltering
            // MixerPref9_AnisotropicFiltering
            // MixerPref9_PyramidalQuadFiltering
            // MixerPref9_GaussianQuadFiltering

            mixer.SetMixingPrefs(dwPrefs);
            mixer.GetMixingPrefs(out dwPrefs);
            dwPrefs &= ~VMR9MixerPrefs.FilteringMask;
            string filtermode9 = xmlreader.GetValueAsString("general", "dx9filteringmode", "Gaussian Quad Filtering");
            if (filtermode9 == "Point Filtering")
            {
              dwPrefs |= VMR9MixerPrefs.PointFiltering;
            }
            else if (filtermode9 == "Bilinear Filtering")
            {
              dwPrefs |= VMR9MixerPrefs.BiLinearFiltering;
            }
            else if (filtermode9 == "Anisotropic Filtering")
            {
              dwPrefs |= VMR9MixerPrefs.AnisotropicFiltering;
            }
            else if (filtermode9 == "Pyrimidal Quad Filtering")
            {
              dwPrefs |= VMR9MixerPrefs.PyramidalQuadFiltering;
            }
            else
            {
              dwPrefs |= VMR9MixerPrefs.GaussianQuadFiltering;
            }

            hr.Set(mixer.SetMixingPrefs(dwPrefs));
            Log.Debug("VRM9: Set filter mode - " + filtermode9 + " " + hr.ToDXString());
          }
        }
      }
      _threadId = Thread.CurrentThread.ManagedThreadId;
      GUIGraphicsContext.Vmr9Active = true;
      g_vmr9 = this;
      Log.Debug("VMR9: Renderer successfully added");
      return true;
    }
Пример #2
0
    /// <summary>
    /// Add VMR9 filter to graph and configure it
    /// </summary>
    /// <param name="graphBuilder"></param>
    public bool AddVMR9(IGraphBuilder graphBuilder)
    {
      try
      {
        // Read settings
        using (Settings xmlreader = new MPSettings())
        {
          UseMadVideoRenderer = xmlreader.GetValueAsBool("general", "useMadVideoRenderer", false);
          UseEVRMadVRForTV = xmlreader.GetValueAsBool("general", "useEVRMadVRForTV", false);
          UseMadVideoRenderer3D = xmlreader.GetValueAsBool("general", "useMadVideoRenderer3D", false);
        }
        Log.Debug("VMR9: addvmr9 - thread : {0}", Thread.CurrentThread.Name);
        if (!_useVmr9)
        {
          Log.Debug("VMR9: addvmr9 - vmr9 is deactivated");
          return false;
        }
        if (_isVmr9Initialized)
        {
          Log.Debug("VMR9: addvmr9: vmr9 has already been initialized");
          return false;
        }

        if (_instanceCounter != 0)
        {
          Log.Error("VMR9: Multiple instances of VMR9 running!!!");
          throw new Exception("VMR9Helper: Multiple instances of VMR9 running!!!");
        }

        HResult hr;
        IntPtr hMonitor = Manager.GetAdapterMonitor(GUIGraphicsContext.DX9Device.DeviceCaps.AdapterOrdinal);
        IntPtr upDevice = DirectShowUtil.GetUnmanagedDevice(GUIGraphicsContext.DX9Device);

        _scene = new PlaneScene(this);

        // Check if need to set EVR for LiveTV when using madVR
        if (UseMadVideoRenderer)
        {
          if (UseEVRMadVRForTV && g_Player.IsTimeShifting)
          {
            GUIGraphicsContext.VideoRenderer = GUIGraphicsContext.VideoRendererType.EVR;
          }
          else
          {
            GUIGraphicsContext.VideoRenderer = GUIGraphicsContext.VideoRendererType.madVR;
          }
        }

        if (GUIGraphicsContext.VideoRenderer == GUIGraphicsContext.VideoRendererType.madVR)
        {
          // Process frames to clear D3D dialog window
          GUIWindowManager.MadVrProcess();
          //_scene.MadVrRenderTarget = GUIGraphicsContext.DX9Device.GetRenderTarget(0);
          //MadVrRenderTargetVMR9 = GUIGraphicsContext.DX9Device.GetRenderTarget(0);
        }
        _scene.Init();

        if (GUIGraphicsContext.VideoRenderer == GUIGraphicsContext.VideoRendererType.EVR)
        {
          // Fix RDP Screen out of bound (force to use AdapterOrdinal to 0 if adapter number are out of bounds)
          int AdapterOrdinal = GUIGraphicsContext.DX9Device.DeviceCaps.AdapterOrdinal;
          if (AdapterOrdinal >= Screen.AllScreens.Length)
          {
            AdapterOrdinal = Screen.AllScreens.Length - 1;
            Log.Info("VMR9: adapter number out of bounds");
          }
          if (GUIGraphicsContext.currentMonitorIdx != -1)
          {
            if ((OSInfo.OSInfo.Win7OrLater() &&
                 Screen.AllScreens[AdapterOrdinal].Primary) || OSInfo.OSInfo.Win8OrLater())
            {
              EvrInit(_scene, (uint) upDevice.ToInt32(), ref _vmr9Filter, (uint) hMonitor.ToInt32(),
                GUIGraphicsContext.currentMonitorIdx, false, false);
            }
            else
            {
              EvrInit(_scene, (uint) upDevice.ToInt32(), ref _vmr9Filter, (uint) hMonitor.ToInt32(),
                GUIGraphicsContext.currentMonitorIdx, true, true);
              Log.Debug("VMR9: force disable vsync and bias correction for Win7 or lower - current primary is : {0}",
                Screen.AllScreens[AdapterOrdinal].Primary);
            }
          }
          else
          {
            if ((OSInfo.OSInfo.Win7OrLater() &&
                 Screen.AllScreens[AdapterOrdinal].Primary) || OSInfo.OSInfo.Win8OrLater())
            {
              EvrInit(_scene, (uint) upDevice.ToInt32(), ref _vmr9Filter, (uint) hMonitor.ToInt32(),
                AdapterOrdinal, false, false);
            }
            else
            {
              EvrInit(_scene, (uint) upDevice.ToInt32(), ref _vmr9Filter, (uint) hMonitor.ToInt32(),
                AdapterOrdinal, true, true);
              Log.Debug("VMR9: force disable vsync and bias correction for Win7 or lower - current primary is : {0}",
                Screen.AllScreens[AdapterOrdinal].Primary);
            }
          }
          hr = new HResult(graphBuilder.AddFilter(_vmr9Filter, "Enhanced Video Renderer"));

          // Adding put_Owner here.
          IVideoWindow videoWin = (IVideoWindow)graphBuilder;
          videoWin.put_Owner(GUIGraphicsContext.ActiveForm);

          Log.Info("VMR9: added EVR Renderer to graph");
        }
        else if (GUIGraphicsContext.VideoRenderer == GUIGraphicsContext.VideoRendererType.madVR)
        {
          GUIGraphicsContext.MadVrOsd = false;
          GUIGraphicsContext.MadVrStop = false;
          IMediaControl mPMediaControl = (IMediaControl) graphBuilder;
          var backbuffer = GUIGraphicsContext.DX9Device.PresentationParameters;
          MadInit(_scene, backbuffer.BackBufferWidth, backbuffer.BackBufferHeight, (uint) upDevice.ToInt32(),
            (uint) GUIGraphicsContext.ActiveForm.ToInt32(), ref _vmr9Filter, mPMediaControl);
          hr = new HResult(graphBuilder.AddFilter(_vmr9Filter, "madVR"));
          Log.Info("VMR9: added madVR Renderer to graph");
          backbuffer.SafeDispose();
          //IVideoWindow videoWin = (IVideoWindow)graphBuilder;
          //videoWin.put_Owner(GUIGraphicsContext.ActiveForm);
          //videoWin.put_WindowStyle((WindowStyle)((int)WindowStyle.Child + (int)WindowStyle.ClipChildren + (int)WindowStyle.ClipSiblings));
          //videoWin.put_MessageDrain(GUIGraphicsContext.ActiveForm);
        }
        else
        {
          _vmr9Filter = (IBaseFilter) new VideoMixingRenderer9();
          Log.Info("VMR9: added Video Mixing Renderer 9 to graph");

          Vmr9Init(_scene, (uint) upDevice.ToInt32(), _vmr9Filter, (uint) hMonitor.ToInt32());
          hr = new HResult(graphBuilder.AddFilter(_vmr9Filter, "Video Mixing Renderer 9"));
        }

        if (_vmr9Filter == null)
        {
          Error.SetError("Unable to play movie", "Renderer could not be added");
          Log.Error("VMR9: Renderer not installed / cannot be used!");
          _scene.Stop();
          _scene.Deinit();
          _scene = null;
          return false;
        }

        if (hr != 0)
        {
          if (GUIGraphicsContext.VideoRenderer == GUIGraphicsContext.VideoRendererType.EVR)
          {
            EvrDeinit();
          }
          else if (GUIGraphicsContext.VideoRenderer == GUIGraphicsContext.VideoRendererType.madVR)
          {
            Log.Error("VMR9: MadDeinit - thread : {0}", Thread.CurrentThread.Name);
            GC.Collect();
            MadDeinit();
            GC.Collect();
            DirectShowUtil.FinalReleaseComObject(_vmr9Filter);
            Thread.Sleep(200);
            RestoreGuiForMadVr();
          }
          else
          {
            Vmr9Deinit();
          }

          _scene.Stop();
          _scene.Deinit();
          _scene = null;

          DirectShowUtil.FinalReleaseComObject(_vmr9Filter);
          _vmr9Filter = null;
          Error.SetError("Unable to play movie", "Unable to initialize Renderer");
          Log.Error("VMR9: Failed to add Renderer to filter graph");
          return false;
        }

        _graphBuilder = graphBuilder;
        _instanceCounter++;
        _isVmr9Initialized = true;
        if (GUIGraphicsContext.VideoRenderer == GUIGraphicsContext.VideoRendererType.VMR9)
        {
          _qualityInterface = _vmr9Filter as IQualProp;
          _vmr9MixerBitmapInterface = _vmr9Filter as IVMRMixerBitmap9;

          Log.Debug("VMR9: SetDeinterlacePrefs() for VMR9 mode");
          SetDeinterlacePrefs();

          IVMRMixerControl9 mixer = _vmr9Filter as IVMRMixerControl9;
          if (mixer != null)
          {
            VMR9MixerPrefs dwPrefs;
            mixer.GetMixingPrefs(out dwPrefs);
            dwPrefs &= ~VMR9MixerPrefs.RenderTargetMask;

            dwPrefs |= VMR9MixerPrefs.RenderTargetYUV;
            // YUV saves graphics bandwith  http://msdn2.microsoft.com/en-us/library/ms788177(VS.85).aspx
            hr.Set(mixer.SetMixingPrefs(dwPrefs));
            Log.Debug("VMR9: Enabled YUV mixing - " + hr.ToDXString());

            using (Settings xmlreader = new MPSettings())
            {
              //Enable nonsquaremixing
              if (xmlreader.GetValueAsBool("general", "nonsquare", true))
              {
                mixer.GetMixingPrefs(out dwPrefs);
                dwPrefs |= VMR9MixerPrefs.NonSquareMixing;
                hr.Set(mixer.SetMixingPrefs(dwPrefs));
                Log.Debug("VRM9: Turning on nonsquare mixing - " + hr.ToDXString());
                hr.Set(mixer.SetMixingPrefs(dwPrefs));
              }

              // Enable DecimateMask - this will effectively use only half of the input width & length
              if (xmlreader.GetValueAsBool("general", "dx9decimatemask", false))
              {
                mixer.GetMixingPrefs(out dwPrefs);
                dwPrefs &= ~VMR9MixerPrefs.DecimateMask;
                dwPrefs |= VMR9MixerPrefs.DecimateOutput;
                hr.Set(mixer.SetMixingPrefs(dwPrefs));
                Log.Debug("VRM9: Enable decimatemask - " + hr.ToDXString());
                hr.Set(mixer.SetMixingPrefs(dwPrefs));
              }

              // see  D3DTEXTUREFILTERTYPE Enumerated Type documents for further information
              // MixerPref9_PointFiltering
              // MixerPref9_BiLinearFiltering
              // MixerPref9_AnisotropicFiltering
              // MixerPref9_PyramidalQuadFiltering
              // MixerPref9_GaussianQuadFiltering

              mixer.SetMixingPrefs(dwPrefs);
              mixer.GetMixingPrefs(out dwPrefs);
              dwPrefs &= ~VMR9MixerPrefs.FilteringMask;
              string filtermode9 = xmlreader.GetValueAsString("general", "dx9filteringmode", "Gaussian Quad Filtering");
              if (filtermode9 == "Point Filtering")
              {
                dwPrefs |= VMR9MixerPrefs.PointFiltering;
              }
              else if (filtermode9 == "Bilinear Filtering")
              {
                dwPrefs |= VMR9MixerPrefs.BiLinearFiltering;
              }
              else if (filtermode9 == "Anisotropic Filtering")
              {
                dwPrefs |= VMR9MixerPrefs.AnisotropicFiltering;
              }
              else if (filtermode9 == "Pyrimidal Quad Filtering")
              {
                dwPrefs |= VMR9MixerPrefs.PyramidalQuadFiltering;
              }
              else
              {
                dwPrefs |= VMR9MixerPrefs.GaussianQuadFiltering;
              }

              hr.Set(mixer.SetMixingPrefs(dwPrefs));
              Log.Debug("VRM9: Set filter mode - " + filtermode9 + " " + hr.ToDXString());
            }
          }
        }
        _threadId = Thread.CurrentThread.ManagedThreadId;
        GUIGraphicsContext.Vmr9Active = true;
        g_vmr9 = this;
        Log.Debug("VMR9: Renderer successfully added");
      }
      catch (Exception)
      {
        _scene.Stop();
        _scene.Deinit();
        _scene = null;
        return false;
      }
      return true;
    }
Пример #3
0
    /// <summary> handling the very first start of dvd playback. </summary>
    private bool FirstPlayDvd(string file)
    {
      int hr;

      try
      {
        _pendingCmd = true;
        UpdateMenu();
        CloseInterfaces();
        string path = null;
        _currentFile = file;

        if (Util.VirtualDirectory.IsImageFile(System.IO.Path.GetExtension(file)))
          file = DaemonTools.GetVirtualDrive() + @"\VIDEO_TS\VIDEO_TS.IFO";

        // Cyberlink navigator needs E:\\VIDEO_TS formatted path with double \
        path = file.Replace(@"\\", @"\").Replace(Path.GetFileName(file), "").Replace(@"\", @"\\");

        if (!GetInterfaces(path))
        {
          Log.Error("DVDPlayer:Unable getinterfaces()");
          CloseInterfaces();
          return false;
        }

        using (Settings xmlreader = new MPSettings())
        {
          _defaultAudioLanguage = xmlreader.GetValueAsString("dvdplayer", "audiolanguage", "english");
          _defaultSubtitleLanguage = xmlreader.GetValueAsString("dvdplayer", "subtitlelanguage", "english");
          _forceSubtitles = xmlreader.GetValueAsBool("dvdplayer", "showsubtitles", true);
          _showClosedCaptions = xmlreader.GetValueAsBool("dvdplayer", "showclosedcaptions", false);
        }

        SetDefaultLanguages();

        hr = _mediaEvt.SetNotifyWindow(GUIGraphicsContext.ActiveForm, WM_DVD_EVENT, IntPtr.Zero);
        if (hr != 0)
        {
          Log.Error("DVDPlayer:Unable to SetNotifyWindow 0x{0:X}", hr);
        }

        if (_videoWin != null)
        {
          if (hr == 0)
          {
            hr = _videoWin.put_Owner(GUIGraphicsContext.ActiveForm);
            if (hr != 0)
            {
              Log.Error("DVDPlayer:Unable to set window owner 0x{0:X}", hr);
            }
          }
          if (hr == 0)
          {
            hr = _videoWin.put_WindowStyle((WindowStyle)((int)WindowStyle.Child +
                                                         (int)WindowStyle.ClipChildren + (int)WindowStyle.ClipSiblings));
            if (hr != 0)
            {
              Log.Error("DVDPlayer:Unable to set window style 0x{0:X}", hr);
            }
          }
        }

        if (hr != 0)
        {
          Log.Error("DVDPlayer:Unable to set options()");
          CloseInterfaces();
          return false;
        }
        if (_basicVideo != null)
        {
          _basicVideo.SetDefaultSourcePosition();
          _basicVideo.SetDefaultDestinationPosition();
        }
        if (_videoWin != null)
        {
          _videoWin.SetWindowPosition(0, 0, GUIGraphicsContext.Width, GUIGraphicsContext.Height);
        }

        hr = _mediaCtrl.Run();
        if (hr < 0 || hr > 1)
        {
          HResult hrdebug = new HResult(hr);
          Log.Info(hrdebug.ToDXString());
          Log.Error("DVDPlayer:Unable to start playing() 0x:{0:X}", hr);
          CloseInterfaces();
          return false;
        }
        //DsUtils.DumpFilters(_graphBuilder);

        DvdDiscSide side;
        int titles, numOfVolumes, volume;
        hr = _dvdInfo.GetDVDVolumeInfo(out numOfVolumes, out volume, out side, out titles);
        if (hr < 0)
        {
          Log.Error("DVDPlayer:Unable to get dvdvolumeinfo 0x{0:X}", hr);
          CloseInterfaces();
          return false; // can't read disc
        }
        else
        {
          if (titles <= 0)
          {
            Log.Error("DVDPlayer:DVD does not contain any titles? {0}", titles);
            //return false;
          }
        }

        if (_videoWin != null)
        {
          hr = _videoWin.put_MessageDrain(GUIGraphicsContext.ActiveForm);
        }

        hr = _dvdCtrl.SelectVideoModePreference(_videoPref);
        DvdVideoAttributes videoAttr;
        hr = _dvdInfo.GetCurrentVideoAttributes(out videoAttr);
        _videoWidth = videoAttr.sourceResolutionX;
        _videoHeight = videoAttr.sourceResolutionY;

        _state = PlayState.Playing;
        VMR9Util.g_vmr9.EVRSetDVDMenuState(false);

        _pendingCmd = false;
        Log.Info("DVDPlayer:Started playing()");
        if (_currentFile == string.Empty)
        {
          for (int i = 0; i <= 26; ++i)
          {
            string dvd = String.Format("{0}:", (char)('A' + i));
            if (Util.Utils.IsDVD(dvd))
            {
              _currentFile = String.Format(@"{0}:\VIDEO_TS\VIDEO_TS.IFO", (char)('A' + i));
              if (File.Exists(_currentFile))
              {
                break;
              }
            }
          }
        }
        return true;
      }
      catch (Exception ex)
      {
        Log.Error("DVDPlayer:Could not start DVD:{0} {1} {2}", ex.Message, ex.Source, ex.StackTrace);
        CloseInterfaces();
        return false;
      }
    }
Пример #4
0
    public static IBaseFilter AddAudioRendererToGraph(IGraphBuilder graphBuilder, string strFilterName,
                                                      bool setAsReferenceClock)
    {
      try
      {
        IPin pinOut = null;
        IBaseFilter NewFilter = null;
        IEnumFilters enumFilters;
        HResult hr = new HResult(graphBuilder.EnumFilters(out enumFilters));
        Log.Info("DirectShowUtils: First try to insert new audio renderer {0} ", strFilterName);
        // next add the new one...
        foreach (Filter filter in Filters.AudioRenderers)
        {
          if (String.Compare(filter.Name, strFilterName, true) == 0)
          {
            Log.Info("DirectShowUtils: Found audio renderer");
            NewFilter = (IBaseFilter)Marshal.BindToMoniker(filter.MonikerString);
            hr.Set(graphBuilder.AddFilter(NewFilter, strFilterName));
            if (hr < 0)
            {
              Log.Error("DirectShowUtils: unable to add filter:{0} to graph", strFilterName);
              NewFilter = null;
            }
            else
            {
              Log.Debug("DirectShowUtils: added filter:{0} to graph", strFilterName);
              if (pinOut != null)
              {
                hr.Set(graphBuilder.Render(pinOut));
                if (hr == 0)
                {
                  Log.Info(" pinout rendererd");
                }
                else
                {
                  Log.Error(" failed: pinout render");
                }
              }
              if (setAsReferenceClock)
              {
                hr.Set((graphBuilder as IMediaFilter).SetSyncSource(NewFilter as IReferenceClock));
                if (hr != 0)
                {
                  Log.Warn("setAsReferenceClock sync source " + hr.ToDXString());
                }
              }
              return NewFilter;
            }
          } //if (String.Compare(filter.Name,strFilterName,true) ==0)
        } //foreach (Filter filter in filters.AudioRenderers)
        if (NewFilter == null)
        {
          Log.Error("DirectShowUtils: failed filter {0} not found", strFilterName);
        }
      }
      catch {}
      Log.Info("DirectShowUtils: First try to insert new audio renderer {0} failed ", strFilterName);

      try
      {
        IPin pinOut = null;
        IBaseFilter NewFilter = null;
        Log.Info("add filter:{0} to graph clock:{1}", strFilterName, setAsReferenceClock);

        //check first if audio renderer exists!
        bool bRendererExists = false;
        foreach (Filter filter in Filters.AudioRenderers)
        {
          if (String.Compare(filter.Name, strFilterName, true) == 0)
          {
            bRendererExists = true;
            Log.Info("DirectShowUtils: found renderer - {0}", filter.Name);
          }
        }
        if (!bRendererExists)
        {
          Log.Error("FAILED: audio renderer:{0} doesnt exists", strFilterName);
          return null;
        }

        // first remove all audio renderers
        bool bAllRemoved = false;
        bool bNeedAdd = true;
        IEnumFilters enumFilters;
        HResult hr = new HResult(graphBuilder.EnumFilters(out enumFilters));

        if (hr >= 0 && enumFilters != null)
        {
          int iFetched;
          enumFilters.Reset();
          while (!bAllRemoved)
          {
            IBaseFilter[] pBasefilter = new IBaseFilter[2];
            hr.Set(enumFilters.Next(1, pBasefilter, out iFetched));
            if (hr < 0 || iFetched != 1 || pBasefilter[0] == null)
            {
              break;
            }

            foreach (Filter filter in Filters.AudioRenderers)
            {
              Guid classId1;
              Guid classId2;

              pBasefilter[0].GetClassID(out classId1);
              //Log.Info("Filter Moniker string -  " + filter.Name);
              if (filter.Name == "ReClock Audio Renderer")
              {
                Log.Warn(
                  "Reclock is installed - if this method fails, reinstall and regsvr32 /u reclock and then uninstall");
                //   return null;
              }

              try
              {
                NewFilter = (IBaseFilter)Marshal.BindToMoniker(filter.MonikerString);
                if (NewFilter == null)
                {
                  Log.Info("NewFilter = null");
                  continue;
                }
              }
              catch (Exception e)
              {
                Log.Info("Exception in BindToMoniker({0}): {1}", filter.MonikerString, e.Message);
                continue;
              }
              NewFilter.GetClassID(out classId2);
              ReleaseComObject(NewFilter);
              NewFilter = null;

              if (classId1.Equals(classId2))
              {
                if (filter.Name == strFilterName)
                {
                  Log.Info("filter already in graph");

                  if (setAsReferenceClock)
                  {
                    hr.Set((graphBuilder as IMediaFilter).SetSyncSource(pBasefilter[0] as IReferenceClock));
                    if (hr != 0)
                    {
                      Log.Warn("setAsReferenceClock sync source " + hr.ToDXString());
                    }
                  }
                  ReleaseComObject(pBasefilter[0]);
                  pBasefilter[0] = null;
                  bNeedAdd = false;
                  break;
                }
                else
                {
                  Log.Info("remove " + filter.Name + " from graph");
                  pinOut = FindSourcePinOf(pBasefilter[0]);
                  graphBuilder.RemoveFilter(pBasefilter[0]);
                  bAllRemoved = true;
                  break;
                }
              } //if (classId1.Equals(classId2))
            } //foreach (Filter filter in filters.AudioRenderers)
            if (pBasefilter[0] != null)
            {
              ReleaseComObject(pBasefilter[0]);
            }
          } //while(!bAllRemoved)
          ReleaseComObject(enumFilters);
        } //if (hr>=0 && enumFilters!=null)
        Log.Info("DirectShowUtils: Passed removing audio renderer");
        if (!bNeedAdd)
        {
          return null;
        }
        // next add the new one...
        foreach (Filter filter in Filters.AudioRenderers)
        {
          if (String.Compare(filter.Name, strFilterName, true) == 0)
          {
            Log.Info("DirectShowUtils: Passed finding Audio Renderer");
            NewFilter = (IBaseFilter)Marshal.BindToMoniker(filter.MonikerString);
            hr.Set(graphBuilder.AddFilter(NewFilter, strFilterName));
            if (hr < 0)
            {
              Log.Error("failed:unable to add filter:{0} to graph", strFilterName);
              NewFilter = null;
            }
            else
            {
              Log.Debug("added filter:{0} to graph", strFilterName);
              if (pinOut != null)
              {
                hr.Set(graphBuilder.Render(pinOut));
                if (hr == 0)
                {
                  Log.Info(" pinout rendererd");
                }
                else
                {
                  Log.Error(" failed: pinout render");
                }
              }
              if (setAsReferenceClock)
              {
                hr.Set((graphBuilder as IMediaFilter).SetSyncSource(NewFilter as IReferenceClock));
                if (hr != 0)
                {
                  Log.Warn("setAsReferenceClock sync source " + hr.ToDXString());
                }
              }
              return NewFilter;
            }
          } //if (String.Compare(filter.Name,strFilterName,true) ==0)
        } //foreach (Filter filter in filters.AudioRenderers)
        if (NewFilter == null)
        {
          Log.Error("failed filter:{0} not found", strFilterName);
        }
      }
      catch (Exception ex)
      {
        Log.Error("DirectshowUtil. Failed to add filter:{0} to graph :{1} {2} {3}",
                  strFilterName, ex.Message, ex.Source, ex.StackTrace);
      }
      return null;
    }