Легко
Осваивать ничего и не надо. Я, например, разбирался с DirectShow большей частью на примерах из Дельфи и C#, не зная ни того ни другого. Важно понять принцип построения графа.
Я прикрепил проект, в котором экспериментировал с фильтром ProxyTrans. Кстати есть ещё фильтры CalibFilter, для настройки(калибровки) камеры по "шахматной доске", и SyncFilter для синхронизации 2х камер, что тоже должно представлять немалый интерес для нелёгкого дела роботостроения
Только с ними я ещё не разбирался.
Добавлено спустя 20 часов 24 минуты 53 секунды:Фильтр ProxyTrans и работа с 2-мя камерамиЯ разобрался, что вместо того, чтобы получать массив фильтров видеозахвата в функции FindMyCaptureDevice для нескольких одинаковых камер, можно получить конкретный фильтр для конкретной камеры. Но для этого необходимо величать каждую камеру по полному имени-отчеству(DisplayName), вместо прозвища (FriendlyName). Например в моём случае для 2х камер FriendlyName="Logitech QuickCam for Notebooks Deluxe", т.е. одинаковое. А вот DisplayName для 1-ой = "@device:pnp:\\\\?\\usb#vid_046d&pid_08a9&mi_00#6&196e7674&1&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\\global", для 2-ой = "@device:pnp:\\\\?\\usb#vid_046d&pid_08a9&mi_00#7&2c141bb7&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\\global". Как говорится, найдите 10 отличий
Посмотреть эти названия можно в Диспетчере Устройств, а лучше в утилите GraphEdit, откуда я их и скопировал.
После изменения имён, правда, придётся переделать и процедуру FindMyCaptureDevice, например так:
- Код: Выделить всё • Развернуть
HRESULT FindMyCaptureDevice(IBaseFilter **pF, char *szFilterName)
{
ICreateDevEnum *pSysDevEnum;
IMoniker *pMoniker;
IPropertyBag *pProp;
IEnumMoniker *pEnumMoniker;
IBaseFilter *pFilter;
ULONG cFetched;
LPOLESTR lpostrDisplayName=NULL;
LPSTR szDisplayName;
HRESULT hResult = S_OK;
USES_CONVERSION;
hResult = CoCreateInstance( CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, ( void ** )&pSysDevEnum );
if( FAILED(hResult) )
{
MessageBox(NULL, "Создание экземпляра перечислителя устройств не удалось.", "Error", MB_ICONERROR | MB_OK);
return hResult;
}
hResult = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumMoniker, 0);
if( FAILED(hResult) )
{
MessageBox(NULL, "Получение интерфейса перечислителя видеустройств не удалось.", "Error", MB_ICONERROR | MB_OK);
return hResult;
}
while( pEnumMoniker->Next(1, &pMoniker, &cFetched) == S_OK )
{
//получение интерфйса хранилища
hResult = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pProp);
//получаем системное имя устройства
pMoniker->GetDisplayName(NULL, NULL, &lpostrDisplayName);
szDisplayName = OLE2A(lpostrDisplayName);
if (SUCCEEDED(hResult) && (lstrcmp(szDisplayName, szFilterName) == 0))
{
//получение интерфейса нужного устройства
hResult = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pFilter);
*pF = pFilter;
(*pF)->AddRef();
break;
}
pMoniker = NULL;
hResult = S_FALSE;
}
pEnumMoniker->Release();
pSysDevEnum->Release();
return hResult;
}