Пример #1
0
        public static bool DisconnectPin(IGraphBuilder graphBuilder, IPin pin)
        {
            IPin    other;
            int     hr = pin.ConnectedTo(out other);
            bool    allDisconnected = true;
            PinInfo info;

            pin.QueryPinInfo(out info);
            DsUtils.FreePinInfo(info);

            if (hr == 0 && other != null)
            {
                other.QueryPinInfo(out info);
                if (!DisconnectAllPins(graphBuilder, info.filter))
                {
                    allDisconnected = false;
                }
                hr = pin.Disconnect();
                if (hr != 0)
                {
                    allDisconnected = false;
                }
                hr = other.Disconnect();
                if (hr != 0)
                {
                    allDisconnected = false;
                }
                DsUtils.FreePinInfo(info);
                Marshal.ReleaseComObject(other);
            }
            else
            {
            }
            return(allDisconnected);
        }
Пример #2
0
        public int Disconnect()
        {
            try
            {
                OnDisconnect();

                if (_ConnectedPin != null)
                {
                    _ConnectedPin.BeginFlush();
                    //_ConnectedPin.EndOfStream(); // deadlock - dont do this.
                    _ConnectedPin.Disconnect();
                    _ConnectedPin.EndFlush();
                }

                if (_ConnectedPin != null &&
                    Marshal.IsComObject(_ConnectedPin))
                {
                    GC.ReRegisterForFinalize(_ConnectedPin);
                    Marshal.FinalReleaseComObject(_ConnectedPin);
                }

                _ConnectedPin = null;
            }
            catch (Exception x)
            {
                Debug.WriteLine("Failed to disconnect pin " + x);
            }

            return((int)HRESULT.S_OK);            // Disconnect must not fail
        }
Пример #3
0
 public static void DisconnectAll(this IPin pin)
 {
     foreach (var c in pin.Connections)
     {
         pin.Disconnect(c);
     }
 }
Пример #4
0
        public static void tビデオレンダラをグラフから除去する(IGraphBuilder graphBuilder)
        {
            int hr = 0;

            IBaseFilter videoRenderer      = null;
            IPin        renderInputPin     = null;
            IPin        connectedOutputPin = null;

            try
            {
                // videoRenderer を探す。

                CDirectShow.tビデオレンダラとその入力ピンを探して返す(graphBuilder, out videoRenderer, out renderInputPin);
                if (videoRenderer == null || renderInputPin == null)
                {
                    return;                             // なかった
                }
                #region [ renderInputPin へ接続している前段の出力ピン connectedOutputPin を探す。 ]
                //-----------------
                renderInputPin.ConnectedTo(out connectedOutputPin);
                //-----------------
                #endregion

                if (connectedOutputPin == null)
                {
                    return;                             // なかった
                }
                // 前段の出力ピンとビデオレンダラの入力ピンを切断する。双方向から切断しないとグラフから切り離されないので注意。

                renderInputPin.Disconnect();
                connectedOutputPin.Disconnect();


                // ビデオレンダラをグラフから除去。

                graphBuilder.RemoveFilter(videoRenderer);
            }
            finally
            {
                CCommon.tReleaseComObject(ref connectedOutputPin);
                CCommon.tReleaseComObject(ref renderInputPin);
                CCommon.tReleaseComObject(ref videoRenderer);
            }
        }
Пример #5
0
        /// <summary>
        /// Disconnects a single Pin.
        /// </summary>
        /// <param name="graphBuilder">IGraphBuilder</param>
        /// <param name="pin">Pin to disconnect</param>
        /// <returns>True if successful</returns>
        bool DisconnectPin(IGraphBuilder graphBuilder, IPin pin)
        {
            IntPtr other_ptr;
            int    hr = pin.ConnectedTo(out other_ptr);
            bool   allDisconnected = true;

            if (hr == 0 && other_ptr != IntPtr.Zero)
            {
                IPin    other = Marshal.GetObjectForIUnknown(other_ptr) as IPin;
                PinInfo info;
                pin.QueryPinInfo(out info);
                ServiceRegistration.Get <ILogger>().Info("Disconnecting pin {0}", info.name);
                FilterGraphTools.FreePinInfo(info);

                other.QueryPinInfo(out info);
                if (!DisconnectAllPins(graphBuilder, info.filter))
                {
                    allDisconnected = false;
                }

                FilterGraphTools.FreePinInfo(info);

                hr = pin.Disconnect();
                if (hr != 0)
                {
                    allDisconnected = false;
                    ServiceRegistration.Get <ILogger>().Error("Error disconnecting: {0:x}", hr);
                }
                hr = other.Disconnect();
                if (hr != 0)
                {
                    allDisconnected = false;
                    ServiceRegistration.Get <ILogger>().Error("Error disconnecting other: {0:x}", hr);
                }
                Marshal.ReleaseComObject(other);
            }
            else
            {
                ServiceRegistration.Get <ILogger>().Info("  Not connected");
            }
            return(allDisconnected);
        }
Пример #6
0
        public static IBaseFilter AddToGraph(IGraphBuilder graphBuilder)
        {
            IBaseFilter vob = null;

            using (Settings xmlreader = new MPSettings())
            {
                string engineType = xmlreader.GetValueAsString("subtitles", "engine", "DirectVobSub");
                XySubFilter = engineType.Equals("XySubFilter");
            }

            if (!XySubFilter)
            {
                DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.DirectVobSubAutoload, out vob);
                if (vob == null)
                {
                    //Try the "normal" filter then.
                    DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.DirectVobSubNormal, out vob);
                }
            }
            else
            {
                //Try the XySubFilter "autoload" filter.
                DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.XySubFilterAutoload, out vob);
                if (vob != null)
                {
                    return(vob);
                }

                //Try the XySubFilter "normal" filter then.
                DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.XySubFilterNormal, out vob);
                if (vob != null)
                {
                    return(vob);
                }

                vob = DirectShowUtil.AddFilterToGraph(graphBuilder, "XySubFilter");
                if (vob == null)
                {
                    Log.Warn("VideoPlayerVMR9: DirectVobSub or XySubFilter filter not found! You need to install XySubFilter");
                    return(null);
                }
                Log.Debug("VideoPlayerVMR9: VobSub filter added to graph");
                return(vob);
            }

            //if the directvobsub filter has not been added to the graph. (i.e. with evr)
            //we add a bit more intelligence to determine if subtitles are enabled.
            //and if subtitles are present for the video / movie then we add it if necessary to the graph.
            if (vob == null)
            {
                Log.Info("VideoPlayerVMR9: No VobSub filter in the current graph");
                //the filter has not been added lets check if it should be added or not.
                //add the filter to the graph
                vob = DirectShowUtil.AddFilterToGraph(graphBuilder, "DirectVobSub");
                if (vob == null)
                {
                    Log.Warn("VideoPlayerVMR9: DirectVobSub or XySubFilter filter not found! You need to install VSFilter");
                    return(null);
                }
                Log.Debug("VideoPlayerVMR9: VobSub filter added to graph");
            }
            else // VobSub already loaded
            {
                return(vob);
            }

            // Check if Haali Media Splitter is in the graph.
            IBaseFilter hms = null;

            DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.HaaliGuid, out hms);
            if (hms == null)
            {
                DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.MPCMatroska, out hms);
            }
            if (hms == null)
            {
                DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.MPCMatroskaSource, out hms);
            }
            if (hms == null)
            {
                DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.LAVFilter, out hms);
            }
            if (hms == null)
            {
                DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.LAVFilterSource, out hms);
            }
            if (hms != null)
            {
                IPin pinSubTo = null;
                // It is. Connect it' subtitle output pin (if any) to Vobsub's subtitle input.
                pinSubTo = DirectShowUtil.FindPin(hms, PinDirection.Output, "Subtitle");
                if (pinSubTo == null)
                {
                    while (true)
                    {
                        IPin freeSubtitle = DirectShowUtil.FindFirstFreePinSub(hms, PinDirection.Output, "");
                        IPin freeVobSub   = DirectShowUtil.FindFirstFreePin(vob, PinDirection.Input, "Input");
                        if (freeSubtitle != null && freeVobSub != null)
                        {
                            Log.Debug("VideoPlayerVMR9: Connecting Matroska's subtitle output to VobSub's input.");
                            graphBuilder.Connect(freeSubtitle, freeVobSub);
                            DirectShowUtil.ReleaseComObject(freeSubtitle);
                            freeSubtitle = null;
                            DirectShowUtil.ReleaseComObject(freeVobSub);
                            freeVobSub = null;
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                DirectShowUtil.ReleaseComObject(hms);
                hms = null;
                if (pinSubTo != null)
                {
                    Log.Debug("VideoPlayerVMR9: Connecting Haali's subtitle output to VobSub's input.");
                    // Try to render pins
                    IPin pinVobSubSub = DirectShowUtil.FindPin(vob, PinDirection.Input, "Input");
                    // If pinSubTo is already connected (disconnect it)
                    graphBuilder.Disconnect(pinSubTo);
                    graphBuilder.Connect(pinSubTo, pinVobSubSub);
                    DirectShowUtil.ReleaseComObject(pinSubTo);
                    pinSubTo = null;
                    DirectShowUtil.ReleaseComObject(pinVobSubSub);
                    pinVobSubSub = null;
                }
            }

            // Now check if vobsub's video input is not connected.
            // Check only if vmr9 is connected (render was successful).
            VMR9Util Vmr9 = VMR9Util.g_vmr9;

            if (Vmr9.IsVMR9Connected)
            {
                Log.Debug("VideoPlayerVMR9: Connect VobSub's video pins");

                IPin pinVobSubVideoIn  = DsFindPin.ByDirection(vob, PinDirection.Input, 0);
                IPin pinVobSubVideoOut = DsFindPin.ByDirection(vob, PinDirection.Output, 0);

                // This is the pin that we will connect to vobsub's input.
                IPin pinVideoTo   = Vmr9.PinConnectedTo;
                IPin pinVideoFrom = null;
                pinVideoTo.ConnectedTo(out pinVideoFrom);
                pinVideoTo.Disconnect();
                pinVideoFrom.Disconnect();
                //Now make connection to VobSub
                int hr = graphBuilder.Connect(pinVideoTo, pinVobSubVideoIn);
                //hr = graphBuilder.Render(pinVideoFrom);
                if (hr != 0)
                {
                    Log.Error("VideoPlayerVMR9: could not connect Vobsub's input video pin");
                    return(null);
                }
                hr = graphBuilder.Connect(pinVobSubVideoOut, pinVideoFrom);
                //hr = graphBuilder.Render(pinVobSubVideoOut);
                if (hr != 0)
                {
                    Log.Error("VideoPlayerVMR9: could not connect Vobsub's output video pin");
                    return(null);
                }

                Log.Debug("VideoPlayerVMR9: Vobsub's video pins connected");
                DirectShowUtil.ReleaseComObject(pinVideoTo);
                pinVideoTo = null;
                DirectShowUtil.ReleaseComObject(pinVobSubVideoIn);
                pinVobSubVideoIn = null;
                DirectShowUtil.ReleaseComObject(pinVobSubVideoOut);
                pinVobSubVideoOut = null;
                DirectShowUtil.ReleaseComObject(pinVideoFrom);
                pinVideoFrom = null;
            }
            Vmr9 = null;
            return(vob);
        }
Пример #7
0
        public static bool DisconnectPin(IGraphBuilder graphBuilder, IPin pin)
        {
            IPin other;
            int hr = pin.ConnectedTo(out other);
            bool allDisconnected = true;
            PinInfo info;
            pin.QueryPinInfo(out info);
            DsUtils.FreePinInfo(info);

            if (hr == 0 && other != null)
            {
                other.QueryPinInfo(out info);
                if (!DisconnectAllPins(graphBuilder, info.filter))
                {
                    allDisconnected = false;
                }
                hr = pin.Disconnect();
                if (hr != 0)
                {
                    allDisconnected = false;

                }
                hr = other.Disconnect();
                if (hr != 0)
                {
                    allDisconnected = false;

                }
                DsUtils.FreePinInfo(info);
                Marshal.ReleaseComObject(other);
            }
            else
            {

            }
            return allDisconnected;
        }
Пример #8
0
    private static bool TryConnect(IGraphBuilder graphBuilder, string filtername, IPin outputPin, IBaseFilter to)
    {
      bool ret = false;
      int hr;
      FilterInfo info;
      PinInfo outputInfo;

      to.QueryFilterInfo(out info);
      ReleaseComObject(info.pGraph);

      outputPin.QueryPinInfo(out outputInfo);
      DsUtils.FreePinInfo(outputInfo);

      if (info.achName.Equals(filtername))
      {
        return false; //do not connect to self
      }
      Log.Debug("Testing filter: {0}", info.achName);

      IEnumPins enumPins;
      IPin[] pins = new IPin[1];
      to.EnumPins(out enumPins);
      do
      {
        int pinsFetched;
        hr = enumPins.Next(1, pins, out pinsFetched);
        if (hr != 0 || pinsFetched == 0)
        {
          break;
        }
        PinDirection direction;
        pins[0].QueryDirection(out direction);
        if (direction == PinDirection.Input && !HasConnection(pins[0])) // && TestMediaTypes(outputPin, pins[0]))
        {
          PinInfo pinInfo;
          pins[0].QueryPinInfo(out pinInfo);
          DsUtils.FreePinInfo(pinInfo);
          Log.Debug("Testing compatibility to {0}",
                    pinInfo.name);
          //ListMediaTypes(pins[0]);
          //hr =  outputPin.Connect(pins[0], null);
          hr = graphBuilder.ConnectDirect(outputPin, pins[0], null);
          if (hr == 0)
          {
            Log.Debug("Connection succeeded");
            if (RenderOutputPins(graphBuilder, to))
            {
              Log.Info("Successfully rendered pin {0}:{1} to {2}:{3}.",
                       filtername, outputInfo.name, info.achName, pinInfo.name);
              ret = true;
              ReleaseComObject(pins[0]);
              break;
            }
            else
            {
              Log.Debug("Rendering got stuck. Trying next filter, and disconnecting {0}!", outputInfo.name);
              outputPin.Disconnect();
              pins[0].Disconnect();
            }
          }
          else
          {
            Log.Debug("Could not connect, filters are not compatible: {0:x}", hr);
          }
        }
        ReleaseComObject(pins[0]);
      } while (true);
      ReleaseComObject(enumPins);
      if (!ret)
      {
        Log.Debug("Dead end. Could not successfully connect pin {0} to filter {1}!", outputInfo.name, info.achName);
      }
      return ret;
    }
Пример #9
0
        public static void tオーディオレンダラをNullレンダラに変えてフォーマットを取得する(IGraphBuilder graphBuilder, out WaveFormat wfx, out byte[] wfx拡張データ)
        {
            int hr = 0;

            IBaseFilter audioRenderer              = null;
            IPin        rendererInputPin           = null;
            IPin        rendererConnectedOutputPin = null;
            IBaseFilter nullRenderer         = null;
            IPin        nullRendererInputPin = null;

            wfx      = null;
            wfx拡張データ = new byte[0];

            try
            {
                // audioRenderer を探す。

                audioRenderer = CDirectShow.tオーディオレンダラを探して返す(graphBuilder);
                if (audioRenderer == null)
                {
                    return;                             // なかった
                }
                #region [ 音量ゼロで一度再生する。(オーディオレンダラの入力ピンMediaTypeが、接続時とは異なる「正しいもの」に変わる可能性があるため。)]
                //-----------------
                {
                    // ここに来た時点で、グラフのビデオレンダラは無効化(NullRendererへの置換や除去など)しておくこと。
                    // さもないと、StopWhenReady() 時に一瞬だけ Activeウィンドウが表示されてしまう。

                    var mediaCtrl  = (IMediaControl)graphBuilder;
                    var basicAudio = (IBasicAudio)graphBuilder;

                    basicAudio.put_Volume(-10000);                              // 最小音量


                    // グラフを再生してすぐ止める。(Paused → Stopped へ遷移する)

                    mediaCtrl.StopWhenReady();


                    // グラフが Stopped に遷移完了するまで待つ。(StopWhenReady() はグラフが Stopped になるのを待たずに帰ってくる。)

                    FilterState fs = FilterState.Paused;
                    hr = CWin32.S_FALSE;
                    while (fs != FilterState.Stopped || hr != CWin32.S_OK)
                    {
                        hr = mediaCtrl.GetState(10, out fs);
                    }


                    // 終了処理。

                    basicAudio.put_Volume(0);                                           // 最大音量

                    basicAudio = null;
                    mediaCtrl  = null;
                }
                //-----------------
                #endregion

                // audioRenderer の入力ピンを探す。

                rendererInputPin = t最初の入力ピンを探して返す(audioRenderer);
                if (rendererInputPin == null)
                {
                    return;
                }


                // WAVEフォーマットを取得し、wfx 引数へ格納する。

                var type = new AMMediaType();
                hr = rendererInputPin.ConnectionMediaType(type);
                DsError.ThrowExceptionForHR(hr);
                try
                {
                    wfx = new WaveFormat();

                    #region [ type.formatPtr から wfx に、拡張領域を除くデータをコピーする。]
                    //-----------------
                    var wfxTemp = new WaveFormatEx();                           // SharpDX.Multimedia.WaveFormat は Marshal.PtrToStructure() で使えないので、それが使える DirectShowLib.WaveFormatEx を介して取得する。(面倒…)
                    Marshal.PtrToStructure(type.formatPtr, (object)wfxTemp);

                    wfx = WaveFormat.CreateCustomFormat((WaveFormatEncoding)wfxTemp.wFormatTag, wfxTemp.nSamplesPerSec, wfxTemp.nChannels, wfxTemp.nAvgBytesPerSec, wfxTemp.nBlockAlign, wfxTemp.wBitsPerSample);
                    //-----------------
                    #endregion
                    #region [ 拡張領域が存在するならそれを wfx拡張データ に格納する。 ]
                    //-----------------
                    int nWaveFormatEx本体サイズ = 16 + 2;                     // sizeof( WAVEFORMAT ) + sizof( WAVEFORMATEX.cbSize )
                    int nはみ出しサイズbyte       = type.formatSize - nWaveFormatEx本体サイズ;

                    if (nはみ出しサイズbyte > 0)
                    {
                        wfx拡張データ = new byte[nはみ出しサイズbyte];
                        var hGC = GCHandle.Alloc(wfx拡張データ, GCHandleType.Pinned);                                // 動くなよー
                        unsafe
                        {
                            byte *src = (byte *)type.formatPtr.ToPointer();
                            byte *dst = (byte *)hGC.AddrOfPinnedObject().ToPointer();
                            CWin32.CopyMemory(dst, src + nWaveFormatEx本体サイズ, (uint)nはみ出しサイズbyte);
                        }
                        hGC.Free();
                    }
                    //-----------------
                    #endregion
                }
                finally
                {
                    if (type != null)
                    {
                        DsUtils.FreeAMMediaType(type);
                    }
                }


                // audioRenderer につながる出力ピンを探す。

                hr = rendererInputPin.ConnectedTo(out rendererConnectedOutputPin);
                DsError.ThrowExceptionForHR(hr);


                // audioRenderer をグラフから切断する。

                rendererInputPin.Disconnect();
                rendererConnectedOutputPin.Disconnect();


                // audioRenderer をグラフから除去する。

                hr = graphBuilder.RemoveFilter(audioRenderer);
                DsError.ThrowExceptionForHR(hr);


                // nullRenderer を作成し、グラフに追加する。

                nullRenderer = (IBaseFilter) new NullRenderer();
                hr           = graphBuilder.AddFilter(nullRenderer, "Audio Null Renderer");
                DsError.ThrowExceptionForHR(hr);


                // nullRenderer の入力ピンを探す。

                hr = nullRenderer.FindPin("In", out nullRendererInputPin);
                DsError.ThrowExceptionForHR(hr);


                // nullRenderer をグラフに接続する。

                hr = rendererConnectedOutputPin.Connect(nullRendererInputPin, null);
                DsError.ThrowExceptionForHR(hr);
            }
            finally
            {
                CCommon.tReleaseComObject(ref nullRendererInputPin);
                CCommon.tReleaseComObject(ref nullRenderer);
                CCommon.tReleaseComObject(ref rendererConnectedOutputPin);
                CCommon.tReleaseComObject(ref rendererInputPin);
                CCommon.tReleaseComObject(ref audioRenderer);
            }
        }
Пример #10
0
        public static void RemoveFromGraph(IGraphBuilder graphBuilder)
        {
            IBaseFilter vob = null;

            DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.DirectVobSubAutoload, out vob);
            if (vob == null)
            {
                //Try the "normal" filter then.
                DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.DirectVobSubNormal, out vob);
                if (vob == null)
                {
                    return;
                }
            }

            Log.Info("VideoPlayerVMR9: DirectVobSub in graph, removing...");
            // Check where video inputs are connected
            IPin pinVideoIn  = DsFindPin.ByDirection(vob, PinDirection.Input, 0);
            IPin pinVideoOut = DsFindPin.ByDirection(vob, PinDirection.Output, 0);

            //find directvobsub's video output pin source input pin
            IPin pinVideoTo = null;

            pinVideoOut.ConnectedTo(out pinVideoTo);
            //find directvobsub's video input pin source output pin
            IPin pinVideoFrom = null;

            pinVideoIn.ConnectedTo(out pinVideoFrom);

            int hr;

            if (pinVideoFrom != null)
            {
                hr = pinVideoFrom.Disconnect();
                if (hr != 0)
                {
                    Log.Error("VideoPlayerVMR9: DirectVobSub failed disconnecting source pin");
                }
            }

            if (pinVideoTo != null)
            {
                hr = pinVideoTo.Disconnect();
                if (hr != 0)
                {
                    Log.Error("VideoPlayerVMR9: DirectVobSub failed disconnecting destination pin");
                }
            }

            //remove the DirectVobSub filter from the graph
            graphBuilder.RemoveFilter(vob);
            DirectShowUtil.ReleaseComObject(vob);
            vob = null;

            //reconnect the source output pin to the vmr9/evr filter
            hr = graphBuilder.Connect(pinVideoFrom, pinVideoTo);
            //hr = graphBuilder.Render(pinVideoFrom);

            DirectShowUtil.ReleaseComObject(pinVideoFrom);
            pinVideoFrom = null;
            DirectShowUtil.ReleaseComObject(pinVideoTo);
            pinVideoTo = null;
            DirectShowUtil.ReleaseComObject(pinVideoOut);
            pinVideoOut = null;
            DirectShowUtil.ReleaseComObject(pinVideoIn);
            pinVideoIn = null;

            if (hr != 0)
            {
                Log.Error("VideoPlayerVMR9: Could not connect video out to video renderer: {0}", hr);
            }
            else
            {
                Log.Debug("VideoPlayerVMR9: DirectVobSub graph rebuild finished");
            }
        }
        public void SetUpForTs(ISampleGrabberCB grabber, int methodToCall)
        {
            FilterGraphTools.DisconnectPins(mpeg2Demux);
            //FilterGraphTools.DisconnectPins(demodulator);
            FilterGraphTools.DisconnectPins(audioRenderer);
            FilterGraphTools.DisconnectPins(videoRenderer);
            //graphBuilder.RemoveFilter(audioRenderer);
            //graphBuilder.RemoveFilter(videoRenderer);

            sampleGrabber = (ISampleGrabber) new SampleGrabber();
            AMMediaType media = new AMMediaType();

            media.majorType  = MediaType.Stream;
            media.subType    = MediaSubType.Mpeg2Transport;
            media.formatType = FormatType.MpegStreams;
            sampleGrabber.SetOneShot(false);
            sampleGrabber.SetBufferSamples(true);
            int hr = sampleGrabber.SetMediaType(media);

            DsError.ThrowExceptionForHR(hr);

            graphBuilder.AddFilter((IBaseFilter)sampleGrabber, "Sample Grabber");

            nullRenderer = (IBaseFilter) new NullRenderer();
            graphBuilder.AddFilter(nullRenderer, "NULL Renderer");


            IPin pinIn  = DsFindPin.ByName((IBaseFilter)sampleGrabber, "Input");
            IPin pinOut = DsFindPin.ByDirection(capture, PinDirection.Output, 0);

            IEnumMediaTypes eMedia;

            pinOut.EnumMediaTypes(out eMedia);

            AMMediaType[] mediaTypes = new AMMediaType[1];
            eMedia.Next(mediaTypes.Length, mediaTypes, IntPtr.Zero);

            hr = sampleGrabber.SetMediaType(mediaTypes[0]);
            DsError.ThrowExceptionForHR(hr);

            pinOut.Disconnect();
            PinInfo info;

            pinOut.QueryPinInfo(out info);


            hr = graphBuilder.ConnectDirect(pinOut, pinIn, mediaTypes[0]);
            //hr = graphBuilder.Connect(pinOut, pinIn);
            DsError.ThrowExceptionForHR(hr);

            // Release the Pin
            Marshal.ReleaseComObject(pinIn);

            pinIn  = DsFindPin.ByName(nullRenderer, "In");
            pinOut = DsFindPin.ByName((IBaseFilter)sampleGrabber, "Output");

            hr = graphBuilder.Connect(pinOut, pinIn);
            DsError.ThrowExceptionForHR(hr);

            sampleGrabber.SetCallback(grabber, methodToCall);

            // Release the Pin
            Marshal.ReleaseComObject(pinIn);
            pinIn = null;
        }
Пример #12
0
    /// <summary>
    /// Disconnects a single Pin.
    /// </summary>
    /// <param name="graphBuilder">IGraphBuilder</param>
    /// <param name="pin">Pin to disconnect</param>
    /// <returns>True if successful</returns>
    bool DisconnectPin(IGraphBuilder graphBuilder, IPin pin)
    {
      IntPtr other_ptr;
      int hr = pin.ConnectedTo(out other_ptr);
      bool allDisconnected = true;
      if (hr == 0 && other_ptr != IntPtr.Zero)
      {
        IPin other = Marshal.GetObjectForIUnknown(other_ptr) as IPin;
        PinInfo info;
        pin.QueryPinInfo(out info);
        ServiceRegistration.Get<ILogger>().Info("Disconnecting pin {0}", info.name);
        FilterGraphTools.FreePinInfo(info);

        other.QueryPinInfo(out info);
        if (!DisconnectAllPins(graphBuilder, info.filter))
          allDisconnected = false;

        FilterGraphTools.FreePinInfo(info);

        hr = pin.Disconnect();
        if (hr != 0)
        {
          allDisconnected = false;
          ServiceRegistration.Get<ILogger>().Error("Error disconnecting: {0:x}", hr);
        }
        hr = other.Disconnect();
        if (hr != 0)
        {
          allDisconnected = false;
          ServiceRegistration.Get<ILogger>().Error("Error disconnecting other: {0:x}", hr);
        }
        Marshal.ReleaseComObject(other);
      }
      else
      {
        ServiceRegistration.Get<ILogger>().Info("  Not connected");
      }
      return allDisconnected;
    }
        /*
         * protected void InitAudioSampleGrabber()
         * {
         *  // Get the graph builder
         *  IGraphBuilder graphBuilder = (mediaControl as IGraphBuilder);
         *  if (graphBuilder == null)
         *      return;
         *
         *  try
         *  {
         *      // Build the sample grabber
         *      sampleGrabber = Activator.CreateInstance(Type.GetTypeFromCLSID(Filters.SampleGrabber, true))
         *          as ISampleGrabber;
         *
         *      if (sampleGrabber == null)
         *          return;
         *
         *      // Add it to the filter graph
         *      int hr = graphBuilder.AddFilter(sampleGrabber as IBaseFilter, "ProTONE_SampleGrabber");
         *      DsError.ThrowExceptionForHR(hr);
         *
         *      AMMediaType mtAudio = new AMMediaType();
         *      mtAudio.majorType = MediaType.Audio;
         *      mtAudio.subType = MediaSubType.PCM;
         *      mtAudio.formatPtr = IntPtr.Zero;
         *
         *      _actualAudioFormat = null;
         *
         *      hr = sampleGrabber.SetMediaType(mtAudio);
         *      DsError.ThrowExceptionForHR(hr);
         *
         *      hr = sampleGrabber.SetBufferSamples(true);
         *      DsError.ThrowExceptionForHR(hr);
         *
         *      hr = sampleGrabber.SetOneShot(false);
         *      DsError.ThrowExceptionForHR(hr);
         *
         *      hr = sampleGrabber.SetCallback(this, 1);
         *      DsError.ThrowExceptionForHR(hr);
         *
         *      sampleAnalyzerMustStop.Reset();
         *      sampleAnalyzerThread = new Thread(new ThreadStart(SampleAnalyzerLoop));
         *      sampleAnalyzerThread.Priority = ThreadPriority.Highest;
         *      sampleAnalyzerThread.Start();
         *  }
         *  catch(Exception ex)
         *  {
         *      Logger.LogException(ex);
         *  }
         *
         *  rotEntry = new DsROTEntry(graphBuilder as IFilterGraph);
         * }*/

        protected void InitAudioSampleGrabber_v2()
        {
            // Get the graph builder
            IGraphBuilder graphBuilder = (mediaControl as IGraphBuilder);

            if (graphBuilder == null)
            {
                return;
            }

            try
            {
                // Build the sample grabber
                sampleGrabber = Activator.CreateInstance(Type.GetTypeFromCLSID(Filters.SampleGrabber, true))
                                as ISampleGrabber;

                if (sampleGrabber == null)
                {
                    return;
                }

                // Add it to the filter graph
                int hr = graphBuilder.AddFilter(sampleGrabber as IBaseFilter, "ProTONE_SampleGrabber_v2");
                DsError.ThrowExceptionForHR(hr);

                IBaseFilter ffdAudioDecoder = null;

                IPin   ffdAudioDecoderOutput = null;
                IPin   soundDeviceInput      = null;
                IPin   sampleGrabberInput    = null;
                IPin   sampleGrabberOutput   = null;
                IntPtr pSoundDeviceInput     = IntPtr.Zero;

                // When using FFDShow, typically we'll find
                // a ffdshow Audio Decoder connected to the sound device filter
                //
                // i.e. [ffdshow Audio Decoder] --> [DirectSound Device]
                //
                // Our audio sample grabber supports only PCM sample input and output.
                // Its entire processing is based on this assumption.
                //
                // Thus need to insert the audio sample grabber between the ffdshow Audio Decoder and the sound device
                // because this is the only place where we can find PCM samples. The sound device only accepts PCM.
                //
                // So we need to turn this graph:
                //
                // .. -->[ffdshow Audio Decoder]-->[DirectSound Device]
                //
                // into this:
                //
                // .. -->[ffdshow Audio Decoder]-->[Sample grabber]-->[DirectSound Device]
                //
                // Actions to do to achieve the graph change:
                //
                // 1. Locate the ffdshow Audio Decoder in the graph
                // 2. Find its output pin and the pin that it's connected to
                // 3. Locate the input and output pins of sample grabber
                // 4. Disconnect the ffdshow Audio Decoder and its correspondent (sound device input pin)
                // 5. Connect the ffdshow Audio Decoder to sample grabber input
                // 6. Connect the sample grabber output to sound device input
                // that's all.

                // --------------
                // 1. Locate the ffdshow Audio Decoder in the graph
                hr = graphBuilder.FindFilterByName("ffdshow Audio Decoder", out ffdAudioDecoder);
                DsError.ThrowExceptionForHR(hr);

                // 2. Find its output pin and the pin that it's connected to
                hr = ffdAudioDecoder.FindPin("Out", out ffdAudioDecoderOutput);
                DsError.ThrowExceptionForHR(hr);

                hr = ffdAudioDecoderOutput.ConnectedTo(out pSoundDeviceInput);
                DsError.ThrowExceptionForHR(hr);

                soundDeviceInput = new DSPin(pSoundDeviceInput).Value;

                // 3. Locate the input and output pins of sample grabber
                hr = (sampleGrabber as IBaseFilter).FindPin("In", out sampleGrabberInput);
                DsError.ThrowExceptionForHR(hr);

                hr = (sampleGrabber as IBaseFilter).FindPin("Out", out sampleGrabberOutput);
                DsError.ThrowExceptionForHR(hr);

                // 4. Disconnect the ffdshow Audio Decoder and its correspondent (sound device input pin)
                hr = ffdAudioDecoderOutput.Disconnect();
                DsError.ThrowExceptionForHR(hr);

                hr = soundDeviceInput.Disconnect();
                DsError.ThrowExceptionForHR(hr);

                // 5. Connect the ffdshow Audio Decoder to sample grabber input
                hr = graphBuilder.Connect(ffdAudioDecoderOutput, sampleGrabberInput);
                DsError.ThrowExceptionForHR(hr);

                // 6. Connect the sample grabber output to sound device input
                hr = graphBuilder.Connect(sampleGrabberOutput, soundDeviceInput);
                DsError.ThrowExceptionForHR(hr);


                AMMediaType mtAudio = new AMMediaType();
                mtAudio.majorType = MediaType.Audio;
                mtAudio.subType   = MediaSubType.PCM;
                mtAudio.formatPtr = IntPtr.Zero;

                _actualAudioFormat = null;

                sampleGrabber.SetMediaType(mtAudio);
                sampleGrabber.SetBufferSamples(true);
                sampleGrabber.SetOneShot(false);
                sampleGrabber.SetCallback(this, 1);

                sampleAnalyzerMustStop.Reset();
                sampleAnalyzerThread          = new Thread(new ThreadStart(SampleAnalyzerLoop));
                sampleAnalyzerThread.Priority = ThreadPriority.Highest;
                sampleAnalyzerThread.Start();
            }
            catch (Exception ex)
            {
                Logger.LogException(ex);
            }

            rotEntry = new DsROTEntry(graphBuilder as IFilterGraph);
        }
Пример #14
0
        /// <summary> build the capture graph for grabber. </summary>
        private void SetupGraph(string FileName)
        {
            int hr;

            // Get the graphbuilder object
            this.graphBuilder = new FilterGraph() as IGraphBuilder;
            this.mediaControl = this.graphBuilder as IMediaControl;
            this.mediaSeeking = this.graphBuilder as IMediaSeeking;
            this.mediaEvent   = this.graphBuilder as IMediaEvent;

            try
            {
                // Get the SampleGrabber interface
                this.sampleGrabber       = new SampleGrabber() as ISampleGrabber;
                this.sampleGrabberFilter = sampleGrabber as IBaseFilter;

                ConfigureSampleGrabber(sampleGrabber);

                // Add the frame grabber to the graph
                hr = graphBuilder.AddFilter(sampleGrabberFilter, "Ds.NET Sample Grabber");
                DsError.ThrowExceptionForHR(hr);

                IBaseFilter aviSplitter = new AviSplitter() as IBaseFilter;

                // Add the aviSplitter to the graph
                hr = graphBuilder.AddFilter(aviSplitter, "Splitter");
                DsError.ThrowExceptionForHR(hr);

                // Have the graph builder construct its appropriate graph automatically
                hr = this.graphBuilder.RenderFile(FileName, null);
                DsError.ThrowExceptionForHR(hr);

#if DEBUG
                m_rot = new DsROTEntry(graphBuilder);
#endif

                // Remove the video renderer filter
                IBaseFilter defaultVideoRenderer = null;
                graphBuilder.FindFilterByName("Video Renderer", out defaultVideoRenderer);
                graphBuilder.RemoveFilter(defaultVideoRenderer);

                // Disconnect anything that is connected
                // to the output of the sample grabber
                IPin iPinSampleGrabberOut = DsFindPin.ByDirection(sampleGrabberFilter, PinDirection.Output, 0);
                IPin iPinVideoIn;
                hr = iPinSampleGrabberOut.ConnectedTo(out iPinVideoIn);

                if (hr == 0)
                {
                    // Disconnect the sample grabber output from the attached filters
                    hr = iPinVideoIn.Disconnect();
                    DsError.ThrowExceptionForHR(hr);

                    hr = iPinSampleGrabberOut.Disconnect();
                    DsError.ThrowExceptionForHR(hr);
                }
                else
                {
                    // Try other way round because automatic renderer could not build
                    // graph including the sample grabber
                    IPin iPinAVISplitterOut = DsFindPin.ByDirection(aviSplitter, PinDirection.Output, 0);
                    IPin iPinAVISplitterIn;
                    hr = iPinAVISplitterOut.ConnectedTo(out iPinAVISplitterIn);
                    DsError.ThrowExceptionForHR(hr);

                    hr = iPinAVISplitterOut.Disconnect();
                    DsError.ThrowExceptionForHR(hr);

                    hr = iPinAVISplitterIn.Disconnect();
                    DsError.ThrowExceptionForHR(hr);

                    // Connect the avi splitter output to sample grabber
                    IPin iPinSampleGrabberIn = DsFindPin.ByDirection(sampleGrabberFilter, PinDirection.Input, 0);
                    hr = graphBuilder.Connect(iPinAVISplitterOut, iPinSampleGrabberIn);
                    DsError.ThrowExceptionForHR(hr);
                }

                // Add the null renderer to the graph
                nullrenderer = new NullRenderer() as IBaseFilter;
                hr           = graphBuilder.AddFilter(nullrenderer, "Null renderer");
                DsError.ThrowExceptionForHR(hr);

                // Get the input pin of the null renderer
                IPin iPinNullRendererIn = DsFindPin.ByDirection(nullrenderer, PinDirection.Input, 0);

                // Connect the sample grabber to the null renderer
                hr = graphBuilder.Connect(iPinSampleGrabberOut, iPinNullRendererIn);
                DsError.ThrowExceptionForHR(hr);

                // Read and cache the image sizes
                SaveSizeInfo(sampleGrabber);

                this.GetFrameStepInterface();
            }
            finally
            {
            }
        }
Пример #15
0
        public static void RemoveFromGraph(IGraphBuilder graphBuilder)
        {
            IBaseFilter vob = null;

            using (Settings xmlreader = new MPSettings())
            {
                string engineType = xmlreader.GetValueAsString("subtitles", "engine", "DirectVobSub");
                XySubFilter = engineType.Equals("XySubFilter");
            }

            if (!XySubFilter)
            {
                DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.DirectVobSubAutoload, out vob);
                if (vob == null)
                {
                    //Try the "normal" filter then.
                    DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.DirectVobSubNormal, out vob);
                }
            }

            if (vob == null)
            {
                DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.XySubFilterAutoload, out vob);
                if (vob != null)
                {
                    //remove the XySubFilter filter from the graph
                    graphBuilder.RemoveFilter(vob);
                    DirectShowUtil.ReleaseComObject(vob);
                    vob = null;
                    return;
                }

                //Try the XySubFilter "normal" filter then.
                DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.XySubFilterNormal, out vob);
                if (vob != null)
                {
                    //remove the XySubFilter filter from the graph
                    graphBuilder.RemoveFilter(vob);
                    DirectShowUtil.ReleaseComObject(vob);
                    vob = null;
                }
                return;
            }

            Log.Info("VideoPlayerVMR9: DirectVobSub in graph, removing...");
            // Check where video inputs are connected
            IPin pinVideoIn  = DsFindPin.ByDirection(vob, PinDirection.Input, 0);
            IPin pinVideoOut = DsFindPin.ByDirection(vob, PinDirection.Output, 0);

            //find directvobsub's video output pin source input pin
            IPin pinVideoTo = null;

            if (pinVideoOut != null)
            {
                pinVideoOut.ConnectedTo(out pinVideoTo);
            }

            //find directvobsub's video input pin source output pin
            IPin pinVideoFrom = null;

            if (pinVideoIn != null)
            {
                pinVideoIn.ConnectedTo(out pinVideoFrom);
            }

            int hr = 0;

            if (pinVideoFrom != null)
            {
                hr = pinVideoFrom.Disconnect();
                if (hr != 0)
                {
                    Log.Error("VideoPlayerVMR9: DirectVobSub failed disconnecting source pin");
                }
            }

            if (pinVideoTo != null)
            {
                hr = pinVideoTo.Disconnect();
                if (hr != 0)
                {
                    Log.Error("VideoPlayerVMR9: DirectVobSub failed disconnecting destination pin");
                }
            }

            //remove the DirectVobSub filter from the graph
            graphBuilder.RemoveFilter(vob);
            DirectShowUtil.ReleaseComObject(vob);
            vob = null;

            //reconnect the source output pin to the vmr9/evr filter
            if (pinVideoFrom != null)
            {
                if (pinVideoTo != null)
                {
                    hr = graphBuilder.Connect(pinVideoFrom, pinVideoTo);
                }
                //hr = graphBuilder.Render(pinVideoFrom);
                DirectShowUtil.ReleaseComObject(pinVideoFrom);
                pinVideoFrom = null;
            }

            if (pinVideoTo != null)
            {
                DirectShowUtil.ReleaseComObject(pinVideoTo);
                pinVideoTo = null;
            }
            if (pinVideoOut != null)
            {
                DirectShowUtil.ReleaseComObject(pinVideoOut);
                pinVideoOut = null;
            }

            if (pinVideoIn != null)
            {
                DirectShowUtil.ReleaseComObject(pinVideoIn);
                pinVideoIn = null;
            }

            if (hr != 0)
            {
                Log.Error("VideoPlayerVMR9: Could not connect video out to video renderer: {0}", hr);
            }
            else
            {
                Log.Debug("VideoPlayerVMR9: DirectVobSub graph rebuild finished");
            }
        }
Пример #16
0
        public void TestConnectDisconnectConnectedToConnectionMediaType()
        {
            int         hr;
            IBaseFilter aviSplitter  = null;
            IBaseFilter ibfAVISource = null;
            IPin        pinIn        = null;
            IPin        pinOut       = null;

            IFilterGraph2 graphBuilder = new FilterGraph() as IFilterGraph2;

            try
            {
                ibfAVISource = new AsyncReader() as IBaseFilter;

                // Add it to the graph
                hr = graphBuilder.AddFilter(ibfAVISource, "Ds.NET AsyncReader");
                Marshal.ThrowExceptionForHR(hr);

                // Set the file name
                IFileSourceFilter fsf = ibfAVISource as IFileSourceFilter;
                hr = fsf.Load(@"foo.avi", null);
                Marshal.ThrowExceptionForHR(hr);
                pinOut = DsFindPin.ByDirection(ibfAVISource, PinDirection.Output, 0);

                // Get the avi splitter
                aviSplitter = (IBaseFilter) new AviSplitter();

                // Add it to the graph
                hr = graphBuilder.AddFilter(aviSplitter, "Ds.NET AviSplitter");
                Marshal.ThrowExceptionForHR(hr);
                pinIn = DsFindPin.ByDirection(aviSplitter, PinDirection.Input, 0);

                Assert.IsNotNull(pinOut);
                Assert.IsNotNull(pinIn);

                // Test Connect
                hr = pinOut.Connect(pinIn, null);
                Marshal.ThrowExceptionForHR(hr);


                // Test ConnectedTo
                IPin pinConnect;
                hr = pinOut.ConnectedTo(out pinConnect);
                Marshal.ThrowExceptionForHR(hr);
                Assert.AreEqual(pinIn, pinConnect);


                // Test ConnectionMediaType
                AMMediaType mediaType = new AMMediaType();
                hr = pinIn.ConnectionMediaType(mediaType);
                Marshal.ThrowExceptionForHR(hr);
                Assert.IsNotNull(mediaType);
                Assert.IsNotNull(mediaType.majorType);

                // Test Disconnect
                hr = pinOut.Disconnect();
                Marshal.ThrowExceptionForHR(hr);
            }
            finally
            {
                Marshal.ReleaseComObject(graphBuilder);
            }
        }
Пример #17
0
 public static bool DisconnectPin(IGraphBuilder graphBuilder, IPin pin)
 {
   IPin other;
   int hr = pin.ConnectedTo(out other);
   bool allDisconnected = true;
   PinInfo info;
   pin.QueryPinInfo(out info);
   DsUtils.FreePinInfo(info);
   Log.Info("Disconnecting pin {0}", info.name);
   if (hr == 0 && other != null)
   {
     other.QueryPinInfo(out info);
     if (!DisconnectAllPins(graphBuilder, info.filter))
     {
       allDisconnected = false;
     }
     hr = pin.Disconnect();
     if (hr != 0)
     {
       allDisconnected = false;
       Log.Error("Error disconnecting: {0:x}", hr);
     }
     hr = other.Disconnect();
     if (hr != 0)
     {
       allDisconnected = false;
       Log.Error("Error disconnecting other: {0:x}", hr);
     }
     DsUtils.FreePinInfo(info);
     ReleaseComObject(other);
   }
   else
   {
     Log.Info("  Not connected");
   }
   return allDisconnected;
 }