thedeemon.com forum
November 21, 2009, 03:01:18 AM *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
News: Last GraphEditPlus version: 1.3.4   Last Video Enhancer version: 1.9.3
 
   Home   Help Search Login Register  
Pages: [1]
  Print  
Author Topic: EnumPins returns no pins - solved  (Read 603 times)
armin
Newbie
*

Karma: +2/-0
Posts: 2


View Profile
« on: March 10, 2009, 12:14:43 PM »

Hello all
I was building a graph loader from a xml translated .GRF file and I was not able to connect the pins. I used the created code from GraphEditPlus but it did not work sometimes on ceratain graphs.
Now I found a working solution:
My first graph loader created the filters by CLSID:

Code:

            // Code created by GraphEditPlus after loading the graph from GRF file.

            Guid CLSID_WMVideoDecoderDMO = new Guid("{94297043-BD82-4DFD-B0DE-8177739C6D20}"); //qasf.dll
            Guid CLSID_WMAudioDecoderDMO = new Guid("{94297043-BD82-4DFD-B0DE-8177739C6D20}"); //qasf.dll
            ...

            //add WMVideo Decoder DMO
            IBaseFilter pWMVideoDecoderDMO = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_WMVideoDecoderDMO));
            hr = pGraph.AddFilter(pWMVideoDecoderDMO, "WMVideo Decoder DMO");
            checkHR(hr, "Can't add WMVideo Decoder DMO to graph");

            //add WMAudio Decoder DMO
            IBaseFilter pWMAudioDecoderDMO = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_WMAudioDecoderDMO));
            hr = pGraph.AddFilter(pWMAudioDecoderDMO, "WMAudio Decoder DMO");
            checkHR(hr, "Can't add WMAudio Decoder DMO to graph");

Such loaded filters did not all eumerate pins! (and failed to connect as a result)

Then I realized that some filters with different names have the same CLSID:

Code:
<name>WMAudio Decoder DMO</name><guid>{94297043-BD82-4DFD-B0DE-8177739C6D20}</guid>
<name>WMVideo Decoder DMO</name><guid>{94297043-BD82-4DFD-B0DE-8177739C6D20}</guid>

To get pin enumerating filters you have to load them by DisplayName (see other created C# code from GraphEditPlus)

FriendlyName: "WMAudio Decoder DMO"
DisplayName: "@device:dmo:{2EEB4ADF-4578-4D10-BCA7-BB955F56320A}{57F2DB8B-E6BB-4513-9D43-DCD2A6593125}"

Code:
       
            //add WMAudio Decoder DMO
            IBaseFilter pWMAudioDecoderDMO = CreateFilter(@"@device:dmo:{2EEB4ADF-4578-4D10-BCA7-BB955F56320A}{57F2DB8B-E6BB-4513-9D43-DCD2A6593125}");
            hr = pGraph.AddFilter(pWMAudioDecoderDMO, "WMAudio Decoder DMO");
            checkHR(hr, "Can't add WMAudio Decoder DMO to graph");

            //add WMAudio Encoder DMO
            IBaseFilter pWMAudioEncoderDMO = CreateFilter(@"@device:dmo:{70F598E9-F4AB-495A-99E2-A7C4D3D89ABF}{33D9A761-90C8-11D0-BD43-00A0C911CE86}");
            hr = pGraph.AddFilter(pWMAudioEncoderDMO, "WMAudio Encoder DMO");
            checkHR(hr, "Can't add WMAudio Encoder DMO to graph");
            .....
            public static IBaseFilter CreateFilter(string displayName)
            {
                .....
                hr = CreateBindCtx( 0, out bindCtx );
                Marshal.ThrowExceptionForHR( hr );

                int eaten;
                hr = MkParseDisplayName( bindCtx, displayName, out eaten, out moniker );
                Marshal.ThrowExceptionForHR( hr );

                Guid guid = typeof( IBaseFilter ).GUID;
                object obj;
                moniker.BindToObject( bindCtx, null, ref guid, out obj );
                filter = ( IBaseFilter ) obj;
                ....
            }

To get the DisplayName you have to enumerate all categories and their filters of the system:

Code:
            // Enumerate all categories:
            DsDevice[] devices = DsDevice.GetDevicesOfCat( FilterCategory.ActiveMovieCategories );
            foreach ( DsDevice device in devices )
            {
                CategoryInfo ci = new CategoryInfo( );
                ci.name = device.Name;
                ci.guid = GetCLSID( device );
                categories.Add( ci );
            }

Now foreach through all CategoryInfo with EnumFiltersByCategory(..)

Code:

        public static FilterInfo[] EnumFiltersByCategory( string category_GUID, string category_friendlyName )
        {
            List<FilterInfo> filterInfos = new List<FilterInfo>( 128 );           
            DsDevice[] devices = DsDevice.GetDevicesOfCat( new Guid( category_GUID ) );

            foreach ( DsDevice device in devices )
            {
                FilterInfo fi = new FilterInfo( );
                fi.name = device.Name;   // friendlyName
                fi.displayName = device.DevicePath;
                fi.guid = GetCLSID( device );
                fi.category = category_friendlyName;
                filterInfos.Add( fi );
            }
            return filterInfos.ToArray( );
        }

I hope this may help other to develop filter graphs. It took me two days research to figure that out.

Armin
Logged
Dee Mon
Administrator
Full Member
*****

Karma: +5/-0
Posts: 207



View Profile WWW
« Reply #1 on: March 10, 2009, 02:19:18 PM »

Thank you for this post! I learned from it a lot: first, I didn't realize that WM* Decoder DMOs had the same CLSID, and second, usage of DsDevice class (I usually exploit ICreateDevEnum and IEnumMoniker).
Logged
malikcis
Newbie
*

Karma: +0/-0
Posts: 4


View Profile
« Reply #2 on: August 14, 2009, 02:23:14 PM »

Hi,

I have the same problem.
Is there a more elegant way to add the filter without enumarating (I have some memory leak issues doing that)?
It is not clear to me how two filters can have same GUID? From my understanding this should not be (GUID = globally unique identifier)
Thanks,

Logged
Pages: [1]
  Print  
 
Jump to:  

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