Infognition forum
September 23, 2019, 04:52:21 PM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: Last Video Enhancer version: 2.2
 
   Home   Help Search Login Register  
Pages: [1]
  Print  
Author Topic: Cleanup filters when done?  (Read 7593 times)
ronin
Newbie
*

Karma: +0/-0
Posts: 1


View Profile
« on: May 19, 2009, 11:41:01 AM »

Hi,

I'm using the generated code to build a graph that records a AC3-file to MP2.

It works fine, but when the filter is done, I want to move the MP2 file to a new location, the file seems to be locked by the dump filter.

I'm trying to figure out how I can clean-up when the eventCode.completed has been reached. Any ideas?

        public override void Work()
        {
            try
            {
                IGraphBuilder graph = (IGraphBuilder)new FilterGraph();
                Console.WriteLine("Building graph...");

                BuildGraph(graph, _file.Path, _file.Folder.Path + "\\" + _file.Name + ".mp2");
                Console.WriteLine("Running...");
                IMediaControl mediaControl = (IMediaControl)graph;
                IMediaEvent mediaEvent = (IMediaEvent)graph;
                int hr = mediaControl.Run();
                checkHR(hr, "Can't run the graph");
                bool stop = false;
                while (!stop)
                {
                    System.Threading.Thread.Sleep(500);
                    Console.Write(".");
                    EventCode ev;
                    IntPtr p1, p2;
                    if (mediaEvent.GetEvent(out ev, out p1, out p2, 0) == 0)
                    {
                        if (ev == EventCode.Complete || ev == EventCode.UserAbort)
                        {
                            Console.WriteLine("Done!");
                            stop = true;
                        }
                        else
                            if (ev == EventCode.ErrorAbort)
                            {
                                Console.WriteLine("An error occured: HRESULT={0:X}", p1);
                                mediaControl.Stop();
                                stop = true;
                            }
                        mediaEvent.FreeEventParams(ev, p1, p2);
                    }
                }
            }
            catch (COMException ex)
            {
                Console.WriteLine("COM error: " + ex.ToString());
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error: " + ex.ToString());
            }
            base.Work();
        }

        static void checkHR(int hr, string msg)
        {
            if (hr < 0)
            {
                Console.WriteLine(msg);
                DsError.ThrowExceptionForHR(hr);
            }
        }

        static void BuildGraph(IGraphBuilder pGraph, string srcFile1, string dstFile1)
        {
            int hr = 0;

            //graph builder
            ICaptureGraphBuilder2 pBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
            hr = pBuilder.SetFiltergraph(pGraph);
            checkHR(hr, "Can't SetFiltergraph");

            Guid CLSID_AC3ParserFilter = new Guid("{280A3020-86CF-11D1-ABE6-00A0C905F375}"); //mpg2splt.ax
            Guid CLSID_AC3Filter = new Guid("{A753A1EC-973E-4718-AF8E-A3F554D45C44}"); //ac3filter.ax
            Guid CLSID_ElecardLayerIIAudioEncoder = new Guid("{15BEBB32-5BB5-42B6-B45A-BA49F78BA19F}"); //elaenc.ax
            Guid CLSID_Dump = new Guid("{36A5F770-FE4C-11CE-A8ED-00AA002FEAB5}"); //DUMP.AX

            //add File Source (Async.)
            IBaseFilter pFileSourceAsync = (IBaseFilter)new AsyncReader();
            hr = pGraph.AddFilter(pFileSourceAsync, "File Source (Async.)");
            checkHR(hr, "Can't add File Source (Async.) to graph");
            //set source filename
            IFileSourceFilter pFileSourceAsync_src = pFileSourceAsync as IFileSourceFilter;
            if (pFileSourceAsync_src == null)
                checkHR(unchecked((int)0x80004002), "Can't get IFileSourceFilter");
            hr = pFileSourceAsync_src.Load(srcFile1, null);
            checkHR(hr, "Can't load file");

            //add AC3 Parser Filter
            IBaseFilter pAC3ParserFilter = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_AC3ParserFilter));
            hr = pGraph.AddFilter(pAC3ParserFilter, "AC3 Parser Filter");
            checkHR(hr, "Can't add AC3 Parser Filter to graph");

            //connect File Source (Async.) and AC3 Parser Filter
            hr = pGraph.ConnectDirect(GetPin(pFileSourceAsync, "Output"), GetPin(pAC3ParserFilter, "Input"), null);
            checkHR(hr, "Can't connect File Source (Async.) and AC3 Parser Filter");

            var regKeyAppRoot = Registry.CurrentUser.OpenSubKey("Software\\AC3Filter", true);
            var regKeyPreset = Registry.CurrentUser.OpenSubKey("Software\\AC3Filter\\preset\\Default", true);

            regKeyAppRoot.SetValue("master", "3.16228");
            regKeyPreset.SetValue("master", "3.16228");

            //add AC3Filter
            IBaseFilter pAC3Filter = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_AC3Filter));
            hr = pGraph.AddFilter(pAC3Filter, "AC3Filter");
            checkHR(hr, "Can't add AC3Filter to graph");

            //connect AC3 Parser Filter and AC3Filter
            hr = pGraph.ConnectDirect(GetPin(pAC3ParserFilter, "AC3"), GetPin(pAC3Filter, "In"), null);
            checkHR(hr, "Can't connect AC3 Parser Filter and AC3Filter");

            //add Elecard Layer II Audio Encoder
            IBaseFilter pElecardLayerIIAudioEncoder = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_ElecardLayerIIAudioEncoder));
            hr = pGraph.AddFilter(pElecardLayerIIAudioEncoder, "Elecard Layer II Audio Encoder");
            checkHR(hr, "Can't add Elecard Layer II Audio Encoder to graph");

            //connect AC3Filter and Elecard Layer II Audio Encoder
            hr = pGraph.ConnectDirect(GetPin(pAC3Filter, "Out"), GetPin(pElecardLayerIIAudioEncoder, "XForm In"), null);
            checkHR(hr, "Can't connect AC3Filter and Elecard Layer II Audio Encoder");

            //add Dump
            IBaseFilter pDump = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_Dump));
            hr = pGraph.AddFilter(pDump, "Dump");
            checkHR(hr, "Can't add Dump to graph");
            //set destination filename
            IFileSinkFilter pDump_sink = pDump as IFileSinkFilter;
            if (pDump_sink == null)
                checkHR(unchecked((int)0x80004002), "Can't get IFileSinkFilter");
            hr = pDump_sink.SetFileName(dstFile1, null);
            checkHR(hr, "Can't set filename");

            //connect Elecard Layer II Audio Encoder and Dump
            hr = pGraph.ConnectDirect(GetPin(pElecardLayerIIAudioEncoder, "XForm Out"), GetPin(pDump, "Input"), null);
            checkHR(hr, "Can't connect Elecard Layer II Audio Encoder and Dump");

        }

        static IPin GetPin(IBaseFilter filter, string pinname)
        {
            IEnumPins epins;
            int hr = filter.EnumPins(out epins);
            checkHR(hr, "Can't enumerate pins");
            IntPtr fetched = Marshal.AllocCoTaskMem(4);
            IPin[] pins = new IPin[1];
            while (epins.Next(1, pins, fetched) == 0)
            {
                PinInfo pinfo;
                pins[0].QueryPinInfo(out pinfo);
                bool found = (pinfo.name == pinname);
                DsUtils.FreePinInfo(pinfo);
                if (found)
                    return pins[0];
            }
            checkHR(-1, "Pin not found");
            return null;
        }
Logged
Dee Mon
Administrator
Hero Member
*****

Karma: +13/-0
Posts: 753



View Profile WWW
« Reply #1 on: May 25, 2009, 07:29:39 AM »

To clear and free everything you need to remove all filters from the graph by enumerating them and calling graphBuilder.RemoveFilter() and  Marshal.ReleaseComObject(), then clear all pointers to the graph except the main one and call Marshal.ReleaseComObject() on it.
Logged
mnieber
Newbie
*

Karma: +1/-0
Posts: 1


View Profile
« Reply #2 on: December 03, 2010, 01:31:27 PM »

Dee Mon, many thanks, this tip has helped me to eliminate a problem that has been a real pain.
If anyone should need it, I post the code to clean up the graph (it seems that you need to iterate first and then release the filters, because otherwise the iteration does not return all the filters).

This code comes with no guarantees, but it seems to work for me.

                        // Enumerate all filters and release them...
                        IEnumFilters enumFilters;
                        m_FilterGraph.EnumFilters(out enumFilters);
                        IBaseFilter[] filters = new IBaseFilter[1];
                        List<IBaseFilter> deadFilters = new List<IBaseFilter>();
                        while (enumFilters.Next(filters.Length, filters, IntPtr.Zero) == 0)
                            deadFilters.Add(filters[0]);

                        foreach (var deadFilter in deadFilters)
                        {
                            m_FilterGraph.RemoveFilter(deadFilter);
                            Marshal.ReleaseComObject(deadFilter);
                        }

                        // Now release the graph itself
                        Marshal.ReleaseComObject(m_FilterGraph);
                        m_FilterGraph = null;
Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.13 | SMF © 2006-2011, Simple Machines LLC Valid XHTML 1.0! Valid CSS!