public void GetMainStreamSubtype(Action <AMMediaType> inspect) { var pPin = DsUtils.GetPin(_sourceFilter, PinDirection.Output, true); if (pPin != null) { IEnumMediaTypes pEnumTypes; var hr = pPin.EnumMediaTypes(out pEnumTypes); if (hr == DsHlp.S_OK) { IntPtr ptr; int cFetched; if (pEnumTypes.Next(1, out ptr, out cFetched) == DsHlp.S_OK) { AMMediaType mt = (AMMediaType)Marshal.PtrToStructure(ptr, typeof(AMMediaType)); inspect(mt); DsUtils.FreeFormatBlock(ptr); Marshal.FreeCoTaskMem(ptr); } Marshal.ReleaseComObject(pEnumTypes); } Marshal.ReleaseComObject(pPin); } }
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); } }
public void RenderAudio(IGraphBuilder pGraphBuilder, IBaseFilter splitter) { var pPin = DsUtils.GetPin(splitter, PinDirection.Output, new[] { MediaType.Audio }); if (pPin != null) { _streamSelect = splitter as IAMStreamSelect; if (_streamSelect != null && BuildSoundRenderer(pGraphBuilder)) { var pInputPin = DsUtils.GetPin(_directSoundBaseFilter, PinDirection.Input); var hr = pGraphBuilder.Connect(pPin, pInputPin); Marshal.ReleaseComObject(pInputPin); if (hr == DsHlp.S_OK || hr == DsHlp.VFW_S_PARTIAL_RENDER) { _audioStreams.AddRange(_streamSelect.GetSelectableStreams().Where(s => s.MajorType == MediaType.Audio)); } else { pGraphBuilder.RemoveFilter(_directSoundBaseFilter); Marshal.FinalReleaseComObject(_directSoundBaseFilter); _directSoundBaseFilter = null; _basicAudio = null; } } Marshal.ReleaseComObject(pPin); } }
// 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); } }
private void InsureSourceOutPin() { _sourceOutPin = DsUtils.GetPin(_sourceFilter, PinDirection.Output, new[] { MediaType.Stream, MediaType.Video }); if (_sourceOutPin == null) { throw new FilterGraphBuilderException(GraphBuilderError.CantPlayFile); } }
private static IPin GetInputPin(IBaseFilter subpictureFilter) { var pin = DsUtils.GetPin(subpictureFilter, PinDirection.Input); if (pin == null) { throw new Exception(); } return(pin); }
private static IPin GetOutputPin(IBaseFilter subpictureFilter) { var pin = DsUtils.GetPin(subpictureFilter, PinDirection.Output, new[] { MediaType.Video }); if (pin == null) { throw new Exception(); } return(pin); }
public static bool CanHandle(IBaseFilter splitter) { var result = false; var pPin = DsUtils.GetPin(splitter, PinDirection.Output, new[] { MediaType.Audio }); if (pPin != null) { Marshal.ReleaseComObject(pPin); result = true; } return(result); }
public IPin GetConnectedSourcePin() { IPin sourcePin = null; if (BaseFilter != null) { IPin pPin; if ((pPin = DsUtils.GetPin(BaseFilter, PinDirection.Input, true)) != null) { pPin.ConnectedTo(out sourcePin); Marshal.ReleaseComObject(pPin); } } return(sourcePin); }
public static void EnumPins(this IBaseFilter filter, PinDirection direction, bool connected, Action <IPin, AMMediaType> action) { var nPinsToSkip = 0; IPin pPin; while ((pPin = DsUtils.GetPin(filter, direction, connected, nPinsToSkip)) != null) { nPinsToSkip++; var pin = pPin; pPin.EnumMediaTypes(mt => action(pin, mt)); Marshal.ReleaseComObject(pPin); } }
public static bool CanHandle(IBaseFilter splitter) { var result = false; var pPin = DsUtils.GetPin(splitter, PinDirection.Output, new[] { MediaType.Audio }); if (pPin != null) { Marshal.ReleaseComObject(pPin); var pStreamSelect = splitter as IAMStreamSelect; if (pStreamSelect != null) { result = pStreamSelect.GetSelectableStreams().Any(s => s.MajorType == MediaType.Audio); } } return(result); }
public IPin GetInputPin() { IPin pPin = null; if (BaseFilter != null) { // try unconnected pins first pPin = DsUtils.GetPin(BaseFilter, PinDirection.Input); if (pPin == null) { // let's try connected pins if ((pPin = DsUtils.GetPin(BaseFilter, PinDirection.Input, true)) != null) { DsUtils.Disconnect(GraphBuilder, pPin); } } } return(pPin); }
public void RenderSubpicture(IGraphBuilder pGraphBuilder, IBaseFilter splitter, IRenderer renderer) { var pPin = DsUtils.GetPin(splitter, PinDirection.Output, new[] { MediaType.Subtitle }); if (pPin != null) { try { _streamSelect = splitter as IAMStreamSelect; if (_streamSelect != null) { TryRenderSubpicture(pGraphBuilder, pPin, renderer); } } finally { Marshal.ReleaseComObject(pPin); } } }
private bool GetPins(out IPin rendererInputPin, out IPin decoderOutPin) { bool bRet = false; rendererInputPin = decoderOutPin = null; if (BaseFilter != null && (rendererInputPin = DsUtils.GetPin(BaseFilter, PinDirection.Input, true)) != null) { int hr = rendererInputPin.ConnectedTo(out decoderOutPin); if (hr == DsHlp.S_OK) { DsUtils.Disconnect(GraphBuilder, rendererInputPin); bRet = true; } else { Marshal.ReleaseComObject(rendererInputPin); rendererInputPin = null; } } return(bRet); }
void SetupPlaybackGraph(string fname) { int hr; try { hr = graphBuilder.RenderFile(fname, null); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } AMMediaType media = new AMMediaType(); media.majorType = MediaType.Video; media.subType = MediaSubType.RGB24; media.formatType = FormatType.VideoInfo; // ??? hr = sampGrabber.SetMediaType(media); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } hr = graphBuilder.AddFilter(baseGrabFlt, "Ds.NET Grabber"); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } hr = graphBuilder.AddFilter(smartTee, "smartTee"); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } IBaseFilter renderer; hr = graphBuilder.FindFilterByName("Video Renderer", out renderer); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } IPin inPin; IPin srcPin; hr = DsUtils.GetPin(renderer, PinDirection.Input, out inPin, 0); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } hr = inPin.ConnectedTo(out srcPin); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } hr = srcPin.Disconnect(); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } hr = graphBuilder.RemoveFilter(renderer); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } Marshal.ReleaseComObject(renderer); Marshal.ReleaseComObject(inPin); hr = DsUtils.GetPin(smartTee, PinDirection.Input, out inPin, 0); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } hr = graphBuilder.Connect(srcPin, inPin); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } Marshal.ReleaseComObject(srcPin); Marshal.ReleaseComObject(inPin); srcPin = inPin = null; hr = DsUtils.GetPin(smartTee, PinDirection.Output, out srcPin, 1); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } // grabber Input hr = DsUtils.GetPin(baseGrabFlt, PinDirection.Input, out inPin, 0); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } // smartTee -> grabber hr = graphBuilder.Connect(srcPin, inPin); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } Marshal.ReleaseComObject(srcPin); Marshal.ReleaseComObject(inPin); srcPin = inPin = null; if (preview) { // grabber Input hr = DsUtils.GetPin(smartTee, PinDirection.Output, out srcPin, 0); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } hr = graphBuilder.Render(srcPin); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } Marshal.ReleaseComObject(srcPin); srcPin = null; } media = new AMMediaType(); hr = sampGrabber.GetConnectedMediaType(media); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } if ((media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero)) { throw new NotSupportedException("Unknown Grabber Media Format"); } videoInfoHeader = (VideoInfoHeader)Marshal.PtrToStructure(media.formatPtr, typeof(VideoInfoHeader)); Marshal.FreeCoTaskMem(media.formatPtr); media.formatPtr = IntPtr.Zero; //Modified according to the platform SDK, to capture the buffer hr = sampGrabber.SetBufferSamples(false); if (hr == 0) { hr = sampGrabber.SetOneShot(false); } if (hr == 0) { hr = sampGrabber.SetCallback(sampleGrabber, 1); } if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } } catch (Exception ee) { throw new Exception("Could not setup graph\r\n" + ee.Message); } }
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); }