vlc_linux/vlc-3.0.16/modules/access/dshow/dshow.cpp
/* FindCaptureDevices:: This Function had two purposes :
    Returns the list of capture devices when p_listdevices != NULL
    Creates an IBaseFilter when p_devicename corresponds to an existing devname
   These actions *may* be requested whith a single call.
*/
: This Function had two purposes :
Returns the list of capture devices when p_listdevices != NULL
Creates an IBaseFilter when p_devicename corresponds to an existing devname
These actions *may* be requested whith a single call.
: This Function had two purposes : Returns the list of capture devices when p_listdevices ! = NULL Creates an IBaseFilter when p_devicename corresponds to an existing devname These actions * may * be requested whith a single call .
static ComPtr<IBaseFilter>
FindCaptureDevice( vlc_object_t *p_this, std::string *p_devicename,
                   std::list<std::string> *p_listdevices, bool b_audio )
{
    ComPtr<IBaseFilter> p_base_filter;
    ComPtr<IMoniker> p_moniker;
    ULONG i_fetched;
    HRESULT hr;
    std::list<std::string> devicelist;
    ComPtr<ICreateDevEnum> p_dev_enum;
    hr = CoCreateInstance( CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
                           IID_ICreateDevEnum, (void**)p_dev_enum.GetAddressOf() );
    if( FAILED(hr) )
    {
        msg_Err( p_this, "failed to create the device enumerator (0x%lx)", hr);
        return p_base_filter;
    }
    ComPtr<IEnumMoniker> p_class_enum;
    if( !b_audio )
        hr = p_dev_enum->CreateClassEnumerator( CLSID_VideoInputDeviceCategory,
                                                p_class_enum.GetAddressOf(), 0 );
    else
        hr = p_dev_enum->CreateClassEnumerator( CLSID_AudioInputDeviceCategory,
                                                p_class_enum.GetAddressOf(), 0 );
    if( FAILED(hr) )
    {
        msg_Err( p_this, "failed to create the class enumerator (0x%lx)", hr );
        return p_base_filter;
    }
    if( p_class_enum == NULL )
    {
        msg_Err( p_this, "no %s capture device was detected", ( b_audio ? "audio" : "video" ) );
        return p_base_filter;
    }
    while( p_class_enum->Next( 1, p_moniker.ReleaseAndGetAddressOf(), &i_fetched ) == S_OK )
    {
        ComPtr<IPropertyBag> p_bag;
        hr = p_moniker->BindToStorage( 0, 0, IID_IPropertyBag,
                                       (void**)p_bag.GetAddressOf() );
        if( SUCCEEDED(hr) )
        {
            VARIANT var;
            var.vt = VT_BSTR;
            hr = p_bag->Read( L"FriendlyName", &var, NULL );
            if( SUCCEEDED(hr) )
            {
                char *p_buf = FromWide( var.bstrVal );
                std::string devname(p_buf);
                free( p_buf) ;
                int dup = 0;
                std::list<std::string>::const_iterator iter = devicelist.begin();
                std::list<std::string>::const_iterator end = devicelist.end();
                std::string ordevname = devname ;
                while ( iter != end )
                {
                    if( 0 == (*iter).compare( devname ) )
                    { 
                         char seq[16];
                         snprintf(seq, 16, " #%d", ++dup);
                         devname = ordevname + seq;
                         iter = devicelist.begin();
                    }
                    else
                         ++iter;
                }
                devicelist.push_back( devname );
                if( p_devicename && *p_devicename == devname )
                {
                    msg_Dbg( p_this, "asked for %s, binding to %s", p_devicename->c_str() , devname.c_str() ) ;
                    hr = p_moniker->BindToObject( NULL, 0, IID_IBaseFilter,
                                                  (void**)p_base_filter.GetAddressOf() );
                    if( FAILED(hr) )
                    {
                        msg_Err( p_this, "couldn't bind moniker to filter "
                                 "object (0x%lx)", hr );
                        return NULL;
                    }
                    return p_base_filter;
                }
            }
        }
    }
    if( p_listdevices ) {
        devicelist.sort();
        *p_listdevices = devicelist;
    }
    return p_base_filter;
}
static ComPtr < IBaseFilter > FindCaptureDevice ( vlc_object_t * p_this , std :: string * p_devicename , std :: list < std :: string > * p_listdevices , bool b_audio ) { ComPtr < IBaseFilter > p_base_filter ; ComPtr < IMoniker > p_moniker ; ULONG i_fetched ; HRESULT hr ; std :: list < std :: string > devicelist ; ComPtr < ICreateDevEnum > p_dev_enum ; hr = CoCreateInstance ( CLSID_SystemDeviceEnum , NULL , CLSCTX_INPROC , IID_ICreateDevEnum , ( void * * ) p_dev_enum . GetAddressOf ( ) ) ; if ( FAILED ( hr ) ) { msg_Err ( p_this , " " , hr ) ; return p_base_filter ; } ComPtr < IEnumMoniker > p_class_enum ; if ( ! b_audio ) hr = p_dev_enum -> CreateClassEnumerator ( CLSID_VideoInputDeviceCategory , p_class_enum . GetAddressOf ( ) , 0 ) ; else hr = p_dev_enum -> CreateClassEnumerator ( CLSID_AudioInputDeviceCategory , p_class_enum . GetAddressOf ( ) , 0 ) ; if ( FAILED ( hr ) ) { msg_Err ( p_this , " " , hr ) ; return p_base_filter ; } if ( p_class_enum == NULL ) { msg_Err ( p_this , " " , ( b_audio ? " " : " " ) ) ; return p_base_filter ; } while ( p_class_enum -> Next ( 1 , p_moniker . ReleaseAndGetAddressOf ( ) , & i_fetched ) == S_OK ) { ComPtr < IPropertyBag > p_bag ; hr = p_moniker -> BindToStorage ( 0 , 0 , IID_IPropertyBag , ( void * * ) p_bag . GetAddressOf ( ) ) ; if ( SUCCEEDED ( hr ) ) { VARIANT var ; var . vt = VT_BSTR ; hr = p_bag -> Read ( L" " , & var , NULL ) ; if ( SUCCEEDED ( hr ) ) { char * p_buf = FromWide ( var . bstrVal ) ; std :: string devname ( p_buf ) ; free ( p_buf ) ; int dup = 0 ; std :: list < std :: string > :: const_iterator iter = devicelist . begin ( ) ; std :: list < std :: string > :: const_iterator end = devicelist . end ( ) ; std :: string ordevname = devname ; while ( iter != end ) { if ( 0 == ( * iter ) . compare ( devname ) ) { char seq [ 16 ] ; snprintf ( seq , 16 , " " , ++ dup ) ; devname = ordevname + seq ; iter = devicelist . begin ( ) ; } else ++ iter ; } devicelist . push_back ( devname ) ; if ( p_devicename && * p_devicename == devname ) { msg_Dbg ( p_this , " " , p_devicename -> c_str ( ) , devname . c_str ( ) ) ; hr = p_moniker -> BindToObject ( NULL , 0 , IID_IBaseFilter , ( void * * ) p_base_filter . GetAddressOf ( ) ) ; if ( FAILED ( hr ) ) { msg_Err ( p_this , " " " " , hr ) ; return NULL ; } return p_base_filter ; } } } } if ( p_listdevices ) { devicelist . sort ( ) ; * p_listdevices = devicelist ; } return p_base_filter ; }
FindCaptureDevices:: This Function had two purposes :
Returns the list of capture devices when p_listdevices != NULL
Creates an IBaseFilter when p_devicename corresponds to an existing devname
These actions *may* be requested whith a single call.
FindCaptureDevices :: This Function had two purposes : Returns the list of capture devices when p_listdevices ! = NULL Creates an IBaseFilter when p_devicename corresponds to an existing devname These actions * may * be requested whith a single call .
/* Create the system device enumerator */ /* Create an enumerator for the video capture devices */ /* If there are no enumerators for the requested type, then
     * CreateClassEnumerator will succeed, but p_class_enum will be NULL */ /* Enumerate the devices */ /* Note that if the Next() call succeeds but there are no monikers,
     * it will return S_FALSE (which is not a failure). Therefore, we check
     * that the return code is S_OK instead of using SUCCEEDED() macro. */ /* Getting the property page to get the device name */ /* find out if this name is already used by a previously found device */ /* devname is on the list. Try another name with sequence
                         number apended and then rescan until a unique entry is found*/ /* NULL possibly means we don't need BindMoniker BindCtx ?? */