private void CreateFilters() { isValid = true; // grabber grabberVideo = new GrabberVideo(this); grabberAudio = new GrabberAudio(this); // objects graphObject = null; grabberObjectVideo = null; grabberObjectAudio = null; int sourceBaseVideoPinIndex = 0; try { // get type for filter graph Type type = Type.GetTypeFromCLSID(Clsid.FilterGraph); if (type == null) { throw new ApplicationException("Failed creating filter graph"); } // create filter graph graphObject = Activator.CreateInstance(type); graph = (IGraphBuilder)graphObject; // create source device's object if (fileName.ToLower().EndsWith(".wmv")) { type = Type.GetTypeFromCLSID(Clsid.WMASFReader); if (type == null) { throw new ApplicationException("Failed creating ASF Reader filter"); } sourceBase = (IBaseFilter)Activator.CreateInstance(type); IFileSourceFilter sourceFile = (IFileSourceFilter)sourceBase; sourceFile.Load(fileName, null); graph.AddFilter(sourceBase, "source"); sourceBaseVideoPinIndex = 1; } else { graph.AddSourceFilter(fileName, "source", out sourceBase); if (sourceBase == null) { try { type = Type.GetTypeFromCLSID(Clsid.AsyncReader); if (type == null) { throw new ApplicationException("Failed creating Async Reader filter"); } sourceBase = (IBaseFilter)Activator.CreateInstance(type); IFileSourceFilter sourceFile = (IFileSourceFilter)sourceBase; sourceFile.Load(fileName, null); graph.AddFilter(sourceBase, "source"); } catch { throw new ApplicationException("Failed creating source filter"); } } sourceBaseVideoPinIndex = 0; } // get type for sample grabber type = Type.GetTypeFromCLSID(Clsid.SampleGrabber); if (type == null) { throw new ApplicationException("Failed creating sample grabber"); } // create sample grabber grabberObjectVideo = Activator.CreateInstance(type); sampleGrabberVideo = (ISampleGrabber)grabberObjectVideo; grabberBaseVideo = (IBaseFilter)grabberObjectVideo; // add grabber filters to graph graph.AddFilter(grabberBaseVideo, "grabberVideo"); // set media type AMMediaType mediaType = new AMMediaType { MajorType = MediaType.Video, SubType = MediaSubType.ARGB32 /* MediaSubType.RGB24 */ }; ; sampleGrabberVideo.SetMediaType(mediaType); // connect pins IPin outPin = Tools.GetOutPin(sourceBase, sourceBaseVideoPinIndex); IPin inPin = Tools.GetInPin(grabberBaseVideo, 0); if (graph.Connect(outPin, inPin) < 0) { throw new ApplicationException("Failed connecting sourceBase to grabberBaseVideo"); } Marshal.ReleaseComObject(outPin); Marshal.ReleaseComObject(inPin); // get media type if (sampleGrabberVideo.GetConnectedMediaType(mediaType) == 0) { VideoInfoHeader vih = (VideoInfoHeader)Marshal.PtrToStructure(mediaType.FormatPtr, typeof(VideoInfoHeader)); grabberVideo.Width = vih.BmiHeader.Width; grabberVideo.Height = vih.BmiHeader.Height; mediaType.Dispose(); } if (useAudioGrabber) { // ***************************************************************** // ******** Add the audio grabber to monitor audio peaks *********** bool audioGrabberIsConnected = false; Tools.FilterInfo2 filterInfo2 = Tools.GetNextFilter(sourceBase, PinDirection.Output, 0); foreach (Tools.PinInfo2 pinInfo2 in filterInfo2.Pins) { if (pinInfo2.PinInfo.Direction == PinDirection.Output) { if (!Tools.IsPinConnected(pinInfo2.Pin)) { try { graph.Render(pinInfo2.Pin); AMMediaType mt = new AMMediaType(); pinInfo2.Pin.ConnectionMediaType(mt); if (mt.MajorType == MediaType.Audio) { // Obtain a reference to the filter connected to the audio output of the video splitter (usually, this is the audio decoder) Tools.FilterInfo2 decoderFilterInfo2 = Tools.GetNextFilter(pinInfo2.PinInfo.Filter, PinDirection.Output, 0); // Remove all the filters connected to the audio decoder filter System.Collections.Generic.List <Tools.FilterInfo2> filtersInfo2 = new System.Collections.Generic.List <Tools.FilterInfo2>(); Tools.FilterInfo2 testFilterInfo2 = Tools.GetNextFilter(decoderFilterInfo2.Filter, PinDirection.Output, 0); while (true) { filtersInfo2.Add(testFilterInfo2); testFilterInfo2 = Tools.GetNextFilter(testFilterInfo2.Filter, PinDirection.Output, 0); if (testFilterInfo2.Filter == null) { break; } } foreach (Tools.FilterInfo2 fi2 in filtersInfo2) { graph.RemoveFilter(fi2.Filter); fi2.Release(); } // get type for sample grabber type = Type.GetTypeFromCLSID(Clsid.SampleGrabber); if (type == null) { throw new ApplicationException("Failed creating audio sample grabber"); } // create sample grabber grabberObjectAudio = Activator.CreateInstance(type); sampleGrabberAudio = (ISampleGrabber)grabberObjectAudio; grabberBaseAudio = (IBaseFilter)grabberObjectAudio; // add grabber filters to graph graph.AddFilter(grabberBaseAudio, "grabberAudio"); // set media type AMMediaType mediaTypeAudio = new AMMediaType { MajorType = MediaType.Audio, SubType = MediaSubType.PCM, FormatType = FormatType.WaveEx }; sampleGrabberAudio.SetMediaType(mediaTypeAudio); outPin = Tools.GetOutPin(decoderFilterInfo2.Filter, 0); inPin = Tools.GetInPin(grabberBaseAudio, 0); if (graph.Connect(outPin, inPin) < 0) { throw new ApplicationException("Failed connecting filter to grabberBaseAudio"); } Marshal.ReleaseComObject(outPin); Marshal.ReleaseComObject(inPin); // Finally, connect the grabber to the audio renderer outPin = Tools.GetOutPin(grabberBaseAudio, 0); graph.Render(outPin); mt = new AMMediaType(); outPin.ConnectionMediaType(mt); if (!Tools.IsPinConnected(outPin)) { throw new ApplicationException("Failed obtaining media audio information"); } wavFormat = new WaveFormatEx(); Marshal.PtrToStructure(mt.FormatPtr, wavFormat); Marshal.ReleaseComObject(outPin); // configure sample grabber sampleGrabberAudio.SetBufferSamples(false); sampleGrabberAudio.SetOneShot(false); sampleGrabberAudio.SetCallback(grabberAudio, 1); audioGrabberIsConnected = true; break; } } catch { } } } } filterInfo2.Release(); if (!audioGrabberIsConnected) { foreach (Tools.PinInfo2 pinInfo2 in Tools.GetPins(sourceBase)) { if (!Tools.IsPinConnected(pinInfo2.Pin)) { foreach (AMMediaType mt in Tools.GetMediaTypes(pinInfo2.Pin)) { if (mt.MajorType == MediaType.Audio) { // create sample grabber grabberObjectAudio = Activator.CreateInstance(type); sampleGrabberAudio = (ISampleGrabber)grabberObjectAudio; grabberBaseAudio = (IBaseFilter)grabberObjectAudio; // add grabber filters to graph graph.AddFilter(grabberBaseAudio, "grabberAudio"); // set media type AMMediaType mediaTypeAudio = new AMMediaType { MajorType = MediaType.Audio, SubType = MediaSubType.PCM, FormatType = FormatType.WaveEx }; sampleGrabberAudio.SetMediaType(mediaTypeAudio); inPin = Tools.GetInPin(grabberBaseAudio, 0); if (graph.Connect(pinInfo2.Pin, inPin) < 0) { throw new ApplicationException("Failed connecting sourceBase to grabberBaseVideo"); } Marshal.ReleaseComObject(inPin); // Finally, connect the grabber to the audio renderer outPin = Tools.GetOutPin(grabberBaseAudio, 0); graph.Render(outPin); AMMediaType amt = new AMMediaType(); outPin.ConnectionMediaType(amt); if (!Tools.IsPinConnected(outPin)) { throw new ApplicationException("Failed obtaining media audio information"); } wavFormat = new WaveFormatEx(); Marshal.PtrToStructure(amt.FormatPtr, wavFormat); Marshal.ReleaseComObject(outPin); // configure sample grabber sampleGrabberAudio.SetBufferSamples(false); sampleGrabberAudio.SetOneShot(false); sampleGrabberAudio.SetCallback(grabberAudio, 1); audioGrabberIsConnected = true; break; } } } } } // ***************************************************************** } // let's do the rendering, if we don't need to prevent freezing if (!preventFreezing) { // render pin graph.Render(Tools.GetOutPin(grabberBaseVideo, 0)); // configure video window IVideoWindow window = (IVideoWindow)graphObject; window.put_AutoShow(false); window = null; } // configure sample grabber sampleGrabberVideo.SetBufferSamples(false); sampleGrabberVideo.SetOneShot(false); sampleGrabberVideo.SetCallback(grabberVideo, 1); // disable clock, if someone requested it if (!referenceClockEnabled) { IMediaFilter mediaFilter = (IMediaFilter)graphObject; mediaFilter.SetSyncSource(null); } // get media control mediaControl = (IMediaControl)graphObject; // get media seek control mediaSeekControl = (IMediaSeeking)graphObject; // get media events' interface mediaEvent = (IMediaEventEx)graphObject; // get media audio control basicAudio = (IBasicAudio)graphObject; } catch (Exception exception) { DestroyFilters(); // provide information to clients VideoSourceError?.Invoke(this, new VideoSourceErrorEventArgs(exception.Message)); } }
private void CreateFilters(Guid audioSubType) { isValid = false; int r; // grabber grabberAudio = new GrabberAudio(this); // objects graphObject = null; grabberObjectAudio = null; try { // get type for filter graph Type type = Type.GetTypeFromCLSID(Clsid.FilterGraph); if (type == null) { throw new ApplicationException("Failed creating filter graph"); } // create filter graph graphObject = Activator.CreateInstance(type); graph = (IGraphBuilder)graphObject; // create source device's object r = graph.AddSourceFilter(fileName, "source", out sourceBase); if (sourceBase == null) { throw new ApplicationException("Failed creating source filter"); } // get type for sample grabber type = Type.GetTypeFromCLSID(Clsid.SampleGrabber); if (type == null) { throw new ApplicationException("Failed creating sample grabber"); } // create sample grabber grabberObjectAudio = Activator.CreateInstance(type); sampleGrabberAudio = (ISampleGrabber)grabberObjectAudio; grabberBaseAudio = (IBaseFilter)grabberObjectAudio; // add grabber filters to graph r = graph.AddFilter(grabberBaseAudio, "grabberAudio"); // set media type AMMediaType mediaType = new AMMediaType { MajorType = MediaType.Audio, SubType = audioSubType, FormatType = FormatType.WaveEx }; r = sampleGrabberAudio.SetMediaType(mediaType); // render pin // TODO: Improve this! We can't always assume that the second pin will always be the audio pin -- we need to find it. IPin sbPin = Tools.GetOutPin(sourceBase, 1); if (sbPin == null) { sbPin = Tools.GetOutPin(sourceBase, 0); } r = graph.Render(sbPin); IPin outPin = Tools.GetOutPin(grabberBaseAudio, 0); AMMediaType mt = new AMMediaType(); r = outPin.ConnectionMediaType(mt); if (!Tools.IsPinConnected(outPin)) { throw new ApplicationException("Failed obtaining media information"); } // disable clock, if someone requested it if (!referenceClockEnabled) { IMediaFilter mediaFilter = (IMediaFilter)graphObject; r = mediaFilter.SetSyncSource(null); } wavFormat = new WaveFormatEx(); Marshal.PtrToStructure(mt.FormatPtr, wavFormat); Marshal.ReleaseComObject(outPin); // configure sample grabber r = sampleGrabberAudio.SetBufferSamples(false); r = sampleGrabberAudio.SetOneShot(false); r = sampleGrabberAudio.SetCallback(grabberAudio, 1); if (useNullRenderer) { // Get a list of all the filters connected to the sample grabber List <Tools.FilterInfo2> filtersInfo2 = new List <Tools.FilterInfo2>(); Tools.FilterInfo2 testFilterInfo2 = Tools.GetNextFilter(grabberBaseAudio, PinDirection.Output, 0); while (true) { filtersInfo2.Add(testFilterInfo2); testFilterInfo2 = Tools.GetNextFilter(testFilterInfo2.Filter, PinDirection.Output, 0); if (testFilterInfo2.Filter == null) { break; } } // Remove the last filter, the audio renderer r = graph.RemoveFilter(filtersInfo2[filtersInfo2.Count - 1].Filter); // create null renderer type = Type.GetTypeFromCLSID(Clsid.NullRenderer); if (type == null) { throw new ApplicationException("Failed creating null renderer"); } nullRendererObjectAudio = Activator.CreateInstance(type); IBaseFilter nullRendererAudio = (IBaseFilter)nullRendererObjectAudio; // add grabber filters to graph r = graph.AddFilter(nullRendererAudio, "nullRenderer"); //outPin = Tools.GetOutPin(filtersInfo2[filtersInfo2.Count - 2].Filter, 0); outPin = Tools.GetOutPin(grabberBaseAudio, 0); IPin inPin = Tools.GetInPin(nullRendererAudio, 0); if (graph.Connect(outPin, inPin) < 0) { throw new ApplicationException("Failed obtaining media audio information"); } Marshal.ReleaseComObject(outPin); Marshal.ReleaseComObject(inPin); } // configure video window IVideoWindow window = (IVideoWindow)graphObject; if (window != null) { window.put_AutoShow(false); window = null; } // get media control mediaControl = (IMediaControl)graphObject; // get media seek control mediaSeekControl = (IMediaSeeking)graphObject; mediaSeekControl.SetTimeFormat(TimeFormat.MediaTime); // get media events' interface mediaEvent = (IMediaEventEx)graphObject; // get media audio control basicAudio = (IBasicAudio)graphObject; isValid = true; } catch (Exception exception) { DestroyFilters(); // provide information to clients AudioSourceError?.Invoke(this, new AudioSourceErrorEventArgs(exception.Message)); } }