Page 1 of 1

[SOLUTION] Get List of available directshow devices(mingw)

Posted: Mon Jul 30, 2012 1:50 pm
by bawki
I have been looking into the ffmpeg source code a few hours now and found some references to a list of directshow capturing devices. Is that list somehow accessible via the API?
When using an avdict with key list_devices = true it displays a list in console, but obviously i cannot access this.
I know vlc gets the list via the winapi so does ffmpeg internally but it would be nice to have access to that list via the ffmpeg api rather than using the windows api.

Re: Get List of available directshow devices

Posted: Mon Jul 30, 2012 3:36 pm
by rogerdpack
a couple things to come to mind:
if you have access to an ffmpeg.exe, you could just run it and "parse" the command line output.
if you don't, you could just copy and paste that code into your program and run it.
I have no idea what constitutes "ok" and "not ok" public api's for the main dev's you'd probably have to ask them (ffmpeg-devel list).

Re: Get List of available directshow devices

Posted: Mon Jul 30, 2012 8:12 pm
by bawki
fixed in next post.

Re: Get List of available directshow devices

Posted: Mon Jul 30, 2012 8:50 pm
by bawki
works with mingw and qt4 :)


winsdk.pri:

Code: Select all

win32: {
    LIBS += -lStrmiids -lQuartz -lole32 -luuid -loleaut32
}
include that in your .pro file with include(winsdk.pri)

header file(where you want to use ffmpeg):

Code: Select all

DEFINE_GUID(CLSID_VideoInputDeviceCategory,0x860bb310,0x5d01,0x11d0,0xbd,0x3b,0x00,0xa0,0xc9,0x11,0xce,0x86);
cpp file:

Code: Select all

void listDevices()
{
    QList<QString> deviceNames;
    ICreateDevEnum *pDevEnum;
    HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,0,CLSCTX_INPROC_SERVER,IID_ICreateDevEnum,(void**)&pDevEnum);
    if(FAILED(hr))
        return;
    IEnumMoniker *pEnum;
    hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEnum,0);
    if(FAILED(hr))
    {
        return;
    }
    IMoniker *pMoniker = NULL;
    while(S_OK == pEnum->Next(1,&pMoniker,NULL))
    {
        IPropertyBag *pPropBag;
        LPOLESTR str = 0;
        hr = pMoniker->GetDisplayName(0,0,&str);
        if(SUCCEEDED(hr))
        {
            hr = pMoniker->BindToStorage(0,0,IID_IPropertyBag,(void**)&pPropBag);
            if(SUCCEEDED(hr))
            {
                VARIANT var;
                VariantInit(&var);
                hr = pPropBag->Read(L"FriendlyName",&var,0);
                QString fName = QString::fromWCharArray(var.bstrVal);
                deviceNames.append(fName);
            } else {
                qDebug() << "could not bind to storage";
            }
        }
    }
    if(deviceNames.size()>0)
    {
// I am using a QComboBox to list the devices, you can just use the QList<QString> deviceNames for your purpose
        ui->deviceListBox->addItems(deviceNames);
    }
}

void openInput()
{
        AVFormatContext *formatC = avformat_alloc_context();
        AVInputFormat *iformat = av_find_input_format("dshow");
        if(iformat)
        {
            qDebug() << "name: " << iformat->name;
            qDebug() << "device name: " << ui->deviceListBox->currentText().toAscii().constData();
            QString devName = "video=";
            devName += ui->deviceListBox->currentText();
            if(avformat_open_input(&formatC,devName.toAscii().constData(),iformat,NULL)!=0)
            {
                qDebug() << "could not open!";
                return;
            } else {
                qDebug() << "opened :D";
                qDebug() << "streams: " << formatC->nb_streams;
            }
        } else
            qDebug() << "no iformat";
}

Re: [SOLUTION] Get List of available directshow devices(ming

Posted: Mon Jul 30, 2012 9:47 pm
by rogerdpack
nice, thanks for the snippet.

Re: [SOLUTION] Get List of available directshow devices(ming

Posted: Tue Nov 13, 2012 6:45 pm
by rogerdpack
https://gist.github.com/3210277 may also be related (how to enumerate dshow devices) (no way to capture output logs though)

https://stackoverflow.com/questions/428 ... -windows-c

also http://ffmpeg.zeranoe.com/forum/viewtop ... ruby#p3291 has a link to demo ruby code I use to parse ffmpeg's stdout.

av_log_set_callback if you want to do it all with libav* and the equivalent of "ffmpeg -f dshow -list_devices true -i dummy"