Exemplo n.º 1
0
        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));
            }
        }
Exemplo n.º 2
0
        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));
            }
        }