// disconnect all connected audio out pins and remove unused filters
        private void StripSplitter(IGraphBuilder pGraphBuilder)
        {
            if (_splitterFilter != null)
            {
                IPin pPin  = null;
                int  nSkip = 0;

                while ((pPin = DsUtils.GetPin(_splitterFilter, PinDirection.Output, true, nSkip)) != null)
                {
                    if (DsUtils.IsMediaTypeSupported(pPin, MediaType.Audio) == 0 ||
                        DsUtils.IsMediaTypeSupported(pPin, MediaType.Subtitle) == 0)
                    {
                        // this connected pin supports audio or subpicture type!
                        DsUtils.Disconnect(pGraphBuilder, pPin);
                    }
                    else
                    {
                        nSkip++;
                    }
                    Marshal.ReleaseComObject(pPin);
                } // end of while

                DsUtils.RemoveRedundantFilters(_sourceFilter, pGraphBuilder);
            }
        }
        public void RenderAudio(IGraphBuilder pGraphBuilder, IBaseFilter splitter)
        {
            IPin pPin;

            var nSkip = 0;

            while ((pPin = DsUtils.GetPin(splitter, PinDirection.Output, false, nSkip)) != null)
            {
                if (DsUtils.IsMediaTypeSupported(pPin, MediaType.Audio) == 0)
                {
                    // this unconnected pin supports audio type!
                    // let's render it!
                    if (BuildSoundRenderer(pGraphBuilder))
                    {
                        var pInputPin = DsUtils.GetPin(_directSoundBaseFilters.Last(), PinDirection.Input);
                        var hr        = pGraphBuilder.Connect(pPin, pInputPin);
                        Marshal.ReleaseComObject(pInputPin);
                        if (hr == DsHlp.S_OK || hr == DsHlp.VFW_S_PARTIAL_RENDER)
                        {
                            if (_directSoundBaseFilters.Count == 8)
                            {
                                Marshal.ReleaseComObject(pPin);
                                break; // out of while cycle
                            }
                        }
                        else
                        {
                            var pBaseFilter = _directSoundBaseFilters.Last();
                            pGraphBuilder.RemoveFilter(pBaseFilter);
                            Marshal.ReleaseComObject(pBaseFilter);

                            _basicAudioInterfaces.RemoveAt(_basicAudioInterfaces.Count - 1);
                            _directSoundBaseFilters.RemoveAt(_directSoundBaseFilters.Count - 1);

                            nSkip++;
                        }
                    }
                    else
                    {
                        // could not create/add DirectSound filter
                        Marshal.ReleaseComObject(pPin);
                        break; // out of while cycle
                    }
                }
                else
                {
                    nSkip++;
                }
                Marshal.ReleaseComObject(pPin);
            } // end of while

            _currentAudioStream = 0;
            _audioStreamsCount  = _basicAudioInterfaces.Count;
            const int lVolume = -10000;

            for (var i = 1; i < _audioStreamsCount; i++)
            {
                _basicAudioInterfaces[i].put_Volume(lVolume);
            }
        }
Esempio n. 3
0
        private static RendererBase TryGetUnknownRenderer(IGraphBuilder pGraphBuilder)
        {
            // this is the last resort
            RendererBase renderer = null;

            IEnumFilters pEnum = null;
            IBaseFilter  pFilter;
            int          cFetched;

            int hr = pGraphBuilder.EnumFilters(out pEnum);

            if (DsHlp.SUCCEEDED(hr))
            {
                bool bFound = false;
                while (!bFound && pEnum.Next(1, out pFilter, out cFetched) == DsHlp.S_OK)
                {
                    IPin pPin = null;
                    // there should be no output pins
                    if ((pPin = DsUtils.GetPin(pFilter, PinDirection.Output, false)) != null)
                    {
                        // there is an unconnected output pin, this is not a renderer
                        Marshal.ReleaseComObject(pPin);
                    }
                    else if ((pPin = DsUtils.GetPin(pFilter, PinDirection.Output, true)) != null)
                    {
                        // there is a connected output pin, this is not a renderer
                        Marshal.ReleaseComObject(pPin);
                    }
                    else
                    {
                        // let's check the input pins: there must be at least one connected of type 'video'
                        int nSkip = 0;
                        while ((pPin = DsUtils.GetPin(pFilter, PinDirection.Input, true, nSkip)) != null)
                        {
                            if (DsUtils.IsMediaTypeSupported(pPin, MediaType.Video) == 0)
                            {
                                // there is connected input pin of type 'video'; this looks like a renderer
                                Marshal.ReleaseComObject(pPin);
                                renderer            = GetRenderer(Renderer.VR); // let's just default it VR
                                renderer.BaseFilter = pFilter;
                                bFound = true;
                                break;
                            }
                            else
                            {
                                nSkip++;
                                Marshal.ReleaseComObject(pPin);
                            }
                        }
                    }

                    if (!bFound)
                    {
                        Marshal.ReleaseComObject(pFilter);
                    }
                }

                Marshal.ReleaseComObject(pEnum);
            }

            return(renderer);
        }
        // this function should be called AFTER the video stream has been rendered
        // but before rendering the audio streams
        // however, it will try to find the splitter even if video wasn't rendered
        private bool FindSplitter(IGraphBuilder pGraphBuilder)
        {
            if (_splitterFilter != null)
            {
                DsUtils.RemoveRedundantFilters(_sourceFilter, pGraphBuilder);
                return(true);
            }

            IEnumFilters pEnumFilters = null;
            IBaseFilter  pFilter      = null;
            int          cFetched;
            bool         bSplitterFound = false;

            int hr = pGraphBuilder.EnumFilters(out pEnumFilters);

            if (DsHlp.FAILED(hr))
            {
                return(false);
            }

            IPin pPin;
            int  nFilters = 0;
            bool bCanRelease;

            while ((pEnumFilters.Next(1, out pFilter, out cFetched) == DsHlp.S_OK))
            {
                nFilters++;
                bCanRelease = true;
                pPin        = DsUtils.GetPin(pFilter, PinDirection.Output, false, 0);
                if (pPin != null)
                {
                    if (DsUtils.IsMediaTypeSupported(pPin, MediaType.Audio) == 0 ||
                        DsUtils.IsMediaTypeSupported(pPin, MediaType.Subtitle) == 0)
                    {
                        //this unconnected pin supports audio or subpicture type!
                        bSplitterFound  = true;
                        bCanRelease     = false;
                        _splitterFilter = pFilter;
                    }
                    Marshal.ReleaseComObject(pPin);
                }

                //let's have a look at another filter
                if (bCanRelease)
                {
                    Marshal.ReleaseComObject(pFilter);
                }

                if (bSplitterFound)
                {
                    break;
                }
            }

            Marshal.ReleaseComObject(pEnumFilters);

            if (!bSplitterFound)
            {
                if (nFilters > 3)
                {
                    pPin = DsUtils.GetPin(_sourceFilter, PinDirection.Output, true, 0);
                    if (pPin != null)
                    {
                        IPin pInputPin;
                        hr = pPin.ConnectedTo(out pInputPin);
                        if (hr == DsHlp.S_OK)
                        {
                            PinInfo info = new PinInfo();
                            hr = pInputPin.QueryPinInfo(out info);
                            if (hr == DsHlp.S_OK)
                            {
                                _splitterFilter = info.pFilter;
                                bSplitterFound  = true;
                            }
                            Marshal.ReleaseComObject(pInputPin);
                        }
                        Marshal.ReleaseComObject(pPin);
                    }
                }
                else
                {
                    _splitterFilter = _sourceFilter;
                    bSplitterFound  = true;
                }
            }

            StripSplitter(pGraphBuilder);
            return(bSplitterFound);
        }