// 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); } }
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); }