Beispiel #1
0
        /// <summary>
        /// Releases the capture device
        /// </summary>
        private void Release()
        {
            // Stop the thread
            _worker = null;

            // Clear the event
            if (_stopSignal != null)
            {
                _stopSignal.Close();
                _stopSignal = null;
            }

            if (_graph != null)
            {
                _graph.Abort();
                _graph.Disconnect(_sourceObject.GetPin(PinDirection.Output, 0));
                _graph.Disconnect(_grabberObject.GetPin(PinDirection.Input, 0));
                _graph.RemoveFilter(_sourceObject);
                _graph.RemoveFilter(_grabberObject);
            }

            // Clean up
            _graph         = null;
            _sourceObject  = null;
            _grabberObject = null;
            _grabber       = null;
            _capGrabber    = null;
            _control       = null;
        }
Beispiel #2
0
        private void TryRenderSubpicture(IGraphBuilder pGraphBuilder, IPin subpictureOutPin, IPin videoOutPin, IPin videoRendererInputPin)
        {
            var subpictureFilter = GetSubpictureFilter(pGraphBuilder);

            if (subpictureFilter == null)
            {
                throw new Exception();
            }

            try
            {
                ConnectVideoToSubpictureFilter(pGraphBuilder, videoOutPin, subpictureFilter);
                ConnectSubpictureToSubpictureFilter(pGraphBuilder, subpictureOutPin, subpictureFilter);
                ConnectSubpictureFilterToRenderer(pGraphBuilder, subpictureFilter, videoRendererInputPin);

                CollectSubpictureStreamsInfo();
            }
            catch
            {
                pGraphBuilder.Disconnect(videoRendererInputPin);
                pGraphBuilder.Disconnect(subpictureOutPin);
                pGraphBuilder.Disconnect(videoOutPin);
                throw;
            }
            finally
            {
                Marshal.FinalReleaseComObject(subpictureFilter);
            }
        }
Beispiel #3
0
        /// <summary>
        ///  Removes all filters downstream from a filter from the graph.
        ///  This is called only by DerenderGraph() to remove everything
        ///  from the graph except the devices and compressors. The parameter
        ///  "removeFirstFilter" is used to keep a compressor (that should
        ///  be immediately downstream of the device) if one is begin used.
        /// </summary>
        void RemoveDownstream(IBaseFilter filter)
        {
            // Get a pin enumerator off the filter
            var hr = filter.EnumPins(out IEnumPins pinEnum);

            if (pinEnum == null)
            {
                return;
            }

            pinEnum.Reset();

            if (hr == 0)
            {
                // Loop through each pin
                var pins = new IPin[1];
                do
                {
                    // Get the next pin
                    hr = pinEnum.Next(1, pins, out int _);

                    if (hr == 0 && pins[0] != null)
                    {
                        // Get the pin it is connected to
                        pins[0].ConnectedTo(out IPin pinTo);

                        if (pinTo != null)
                        {
                            // Is this an input pin?
                            hr = pinTo.QueryPinInfo(out PinInfo info);

                            if (hr == 0 && info.dir == PinDirection.Input)
                            {
                                // Recurse down this branch
                                RemoveDownstream(info.filter);

                                // Disconnect
                                _graphBuilder.Disconnect(pinTo);
                                _graphBuilder.Disconnect(pins[0]);

                                // Remove this filter
                                // but don't remove the video or audio compressors
                                if (info.filter != _videoCompressorFilter)
                                {
                                    _graphBuilder.RemoveFilter(info.filter);
                                }
                            }

                            Marshal.ReleaseComObject(info.filter);
                            Marshal.ReleaseComObject(pinTo);
                        }

                        Marshal.ReleaseComObject(pins[0]);
                    }
                } while (hr == 0);

                Marshal.ReleaseComObject(pinEnum);
            }
        }
Beispiel #4
0
        protected void removeDownstream(IBaseFilter filter, bool removeFirstFilter)
        {
            // Get a pin enumerator off the filter
            IEnumPins pinEnum;
            int       hr = filter.EnumPins(out pinEnum);

            pinEnum.Reset();
            if ((hr == 0) && (pinEnum != null))
            {
                // Loop through each pin
                IPin[] pins = new IPin[1];
                int    f;
                do
                {
                    // Get the next pin
                    hr = pinEnum.Next(1, pins, out f);
                    if ((hr == 0) && (pins[0] != null))
                    {
                        // Get the pin it is connected to
                        IPin pinTo = null;
                        pins[0].ConnectedTo(out pinTo);
                        if (pinTo != null)
                        {
                            // Is this an input pin?
                            PinInfo info = new PinInfo();
                            hr = pinTo.QueryPinInfo(out info);
                            if ((hr == 0) && (info.dir == (PinDirection.Input)))
                            {
                                // Recurse down this branch
                                removeDownstream(info.filter, true);

                                // Disconnect
                                graphBuilder.Disconnect(pinTo);
                                graphBuilder.Disconnect(pins[0]);

                                // Remove this filter
                                // but don't remove the video or audio compressors
                                if ((info.filter != videoCompressorFilter) &&
                                    (info.filter != audioCompressorFilter))
                                {
                                    graphBuilder.RemoveFilter(info.filter);
                                }
                            }
                            Marshal.ReleaseComObject(info.filter);
                            Marshal.ReleaseComObject(pinTo);
                        }
                        Marshal.ReleaseComObject(pins[0]);
                    }
                }while (hr == 0);

                Marshal.ReleaseComObject(pinEnum);
                pinEnum = null;
            }
        }
Beispiel #5
0
        public static void Disconnect(IGraphBuilder pGraphBuilder, IPin pPin)
        {
            IPin pInputPin = null;

            if (pPin.ConnectedTo(out pInputPin) == DsHlp.S_OK)
            {
                pGraphBuilder.Disconnect(pInputPin);
                Marshal.ReleaseComObject(pInputPin);
            }

            pGraphBuilder.Disconnect(pPin);
        }
Beispiel #6
0
 public void Disconnect(IPin ipin)
 {
     try
     {
         int hr = graphBuilder.Disconnect(ipin);
         DsError.ThrowExceptionForHR(hr);
     }
     catch (COMException e)
     {
         ShowCOMException(e, "Error disconnecting pin");
     }
     catch
     {
         //MessageBox.Show(e.Message, "Error disconnecting pin");
     }
 }
        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);
        }
    public static IBaseFilter AddToGraph(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 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 filter not found! You need to install VSFilter");
          return null;
        }
        else
        {
          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;
    }