tanvon++

August 30, 2008

Enumerating DirectShow Filters

Filed under: DirectShow, DirectShow Filters, Enum, Filters, Filters Enumeration, System Device Enumerator — Tags: , , — tanvon malik @ 11:06 am

System Device Enumerator

Wether you locating for a particular filter or want to enumerate all the filters on a system. The System Device Enumerator is a big help. Enumeration of DirectShow filters can be achieved with the help of System Device Enumerator. It is COM object. which expose ICreateDevEnum interface. It means first you have to create the System Device Enumerator object, then you will grab its interface ICreateDevEnum , this interface exposes just one method CreateClassEnumerator this method actually creates  enumerator, which can be used to enumerate the filters in a specific Filter Category, or can be used to enumerate all the Filter Categories on a users system.

Filter Categories

Filter in DirectShow are divided in the categories . Every category has its own class identifier called a CLSID. With the help of this CLSID it is easy to enumerate the filters of that specific class.

But first of all how to enumerate those categories, for this purpose there is a CLSID_ActiveMovieCategories CLSID. With it one can easily enumerate the categories which has filters in them.

HRESULT hr;
    ICreateDevEnum *pSysDevEnum = NULL;
    hr = CoCreateInstance(CLSID_SystemDeviceEnum,
                           NULL, CLSCTX_INPROC_SERVER,
                           IID_ICreateDevEnum, (void **)&pSysDevEnum);
    if (FAILED(hr))
    {
        return hr;
    }
    IEnumMoniker *pEnumCat = NULL;
    hr = pSysDevEnum->CreateClassEnumerator(
                       (GUID)CLSID_ActiveMovieCategories, &pEnumCat, 0);
    if (hr == S_OK)
    {
        // Enumerate the monikers.
        IMoniker *pMoniker = NULL;
        ULONG cFetched;
        while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)
        {
            IPropertyBag *pPropBag;
            hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
                (void **)&pPropBag);
            if (SUCCEEDED(hr))
            {
                VARIANT varName, varCLSID;
                VariantInit(&varName);
                VariantInit(&varCLSID);
                hr = pPropBag->Read(L"FriendlyName", &varName, 0);
                if (SUCCEEDED(hr))
                {
                    hr = pPropBag->Read(L"CLSID", &varCLSID, 0);
                    if (SUCCEEDED(hr))
                    {
                        GUID clsid;
                        if (SUCCEEDED(CLSIDFromString(varCLSID.bstrVal,
                                                               &clsid)))
                        {
                            EnumFilters(clsid, hparent);

 

this snippet of code shows how to enumerate all the filter categories. Now you have all the filter categories it is time to enumerate the filters in those filter categories.

bool CEnumFiltersDlg::EnumFilters(GUID clsid, HTREEITEM hparent)
{
        // Create the System Device Enumerator.
    HRESULT hr;
    ICreateDevEnum *pSysDevEnum = NULL;
    hr = CoCreateInstance(CLSID_SystemDeviceEnum,
                           NULL, CLSCTX_INPROC_SERVER,
                           IID_ICreateDevEnum, (void **)&pSysDevEnum);
    if (FAILED(hr))
    {
        return hr;
    }
    IEnumMoniker *pEnumCat = NULL;
    hr = pSysDevEnum->CreateClassEnumerator((GUID)clsid, &pEnumCat, 0);
    if (hr == S_OK)
    {
        IMoniker *pMoniker = NULL;
        ULONG cFetched;
        while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)
        {
            IPropertyBag *pPropBag;
            hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
                (void **)&pPropBag);
            if (SUCCEEDED(hr))
            {
            // To retrieve the filter's friendly name, do the following:
                VARIANT varName;
                VariantInit(&varName);
                hr = pPropBag->Read(L"FriendlyName", &varName, 0);
                if (SUCCEEDED(hr))
                {
                    // Display the name in your UI somehow.
                    TVINSERTSTRUCT tvInsert;
                    tvInsert.hParent = hparent;
                    tvInsert.hInsertAfter = NULL;
                    tvInsert.item.mask = TVIF_TEXT;
                    CString str(varName.bstrVal);
                    tvInsert.item.pszText = str.GetBuffer();
                    str.ReleaseBuffer();
                    mFiltersTree.InsertItem(&tvInsert);
                }

                VariantClear(&varName);
                pPropBag->Release();
            }
            pMoniker->Release();
        }
        pEnumCat->Release();
    }
    pSysDevEnum->Release();

    mFiltersTree.SortChildren(hparent);
    return true;
}

Here clsid parameter passed is the CLSID of the filter category whom  to enumerate.

NOTEenumerate DirectShow Filters

       this sample don’t enumerate the DMOs on a system as the Graph Edit utility enumerates in its insert filter function. I will try to add it later.

code can be found here

August 27, 2008

DirectShow which SDK to use ?

Filed under: DirectShow, DirectShow Filters, Filters — Tags: — tanvon malik @ 5:15 am

The DirectShow was part of the DirectX SDK , then it was removed from the DirectX SDK and was made part of the Platform SDK, But now that Platform SDK has been replaced by Windows SDK. The latest Windows SDK is the Microsoft Windows SDK for Windows Server 2008 and .NET Framework 3.5, released February, 2008.

August 16, 2008

System Device Enumerator

Filed under: DirectShow, DirectShow Filters — Tags: , — tanvon malik @ 6:21 pm

Another interesting question on tanvon Yahoo Group is,
” Could any one tell me how to go about listing all the DirectShow
Filter Categories so that i can list the filters under each category.”
There are two ways to enumerate the filters the Filter Mapper way and the System Device Enumerator way.
Here I will explain the System Device Enumerator.
The System Device Enumerator is a COM object, which implements the ICreateDevEnum interface,
this intreface exposes only a single method CreateClassEnumerator. This is the method which creates the enumerator object and returns its IEnumMoniker interface, but enumerate what
HRESULT CreateClassEnumerator(
  REFCLSID clsidDeviceClass,
  IEnumMoniker **ppEnumMoniker,
  DWORD dwFlags
);
The first parameter is the class identifier (CLSID) of the device category. these categories are defined in the Dshow.h header file. (e.g. CLSID_LegacyAmFilterCategory , CLSID_AudioRendererCategory ). This is the place to notice that you have to specify which category you want to enumerate.
Once you have the IEnumMoniker, now you can use its methods to easily enumerate the device category. Just call IEnumMoniker::Next  method, this will return an IMoniker interface with this interface you can get the “Friendly Name” of the filter or you can instanciate the filter itself.
For an example see http://msdn.microsoft.com/en-us/library/ms787871(VS.85).aspx

For the URDU version see http://directshow.wordpress.com/2008/08/16/system-device-enumerator/

August 15, 2008

Intelligent Connect

Filed under: DirectShow, DirectShow Filters — Tags: , , — tanvon malik @ 4:57 pm

As a member of yahoo group asked about the so called non-intelligent connect .
Adding and connecting distinct filter in the filter graph manually.
Actually there are many small functions which need to be taken care, So this
may take a little longer to understand, So keep reading this series of blog entries about
connecting filter without intelligent connect in DirectShow.

Intelligent Connect
 There are some intelligent algorithms behind this, Which
share the burden of the programmer. Suppose for a little time what
hassle is hidden behind it. Once the  IGraphBuilder::RenderFile()
is called the Filter Graph Manager searches for the suitable source filter
which can read and understand the format of media file. Then it tries to
search for a filter which can decode or parse that data (this data is called Media Samples in the DirectShow)
which the source filter will handle to it (through transport), The media sample format which is said the Media Type in the DirectShow
must be same that both filters will understand otherwise the connection will fail,
and Filter Graph Manager will drop that filter and will search for another filter which
will handle the samples with the specified Media Type.
Then Filter Graph Manager will try to load other filters to complete the Filter Graph.
At the end it will load the default Renderer to Display the contents on the screen.
and will connect that with the entire filter graph build previously.

DirectShow in Urdu

Filed under: DirectShow — Tags: — tanvon malik @ 6:19 am

I am going to keep a new blog DirectShow.WordPress.com . This blog will be and is in Urdu language about definitely DirectShow. I will try to keep my both blogs in synch with each other.

Blog at WordPress.com.