Как отобразить диалоговое окно "Фильтр захвата видео" (настройки камеры, такие как яркость, экспозиция)?
Я делаю приложение для Windows, где я использую камеру. Я хочу разрешить пользователю изменять настройки камеры (VfwCaptureDialog_Source), как это обычно происходит в приложениях Skype или amcap. На данный момент я узнал, что это диалог от vfw, и его можно активировать из dshow api. Когда я делаю это из AmCap, он работает. Можете ли вы помочь мне заставить этот код работать для данной веб-камеры (требуется поддержка нескольких камер)? Я использую Qt и OpenCV при работе с камерой. В opencv просто указатель камеры используется для выбора нужной камеры. Индекс взят из Qt, где я могу получить хороший список имен камер. Я получаю из этого кода ошибку 1170: "Указанный набор свойств не существует в объекте"
//libs -lDxva2 -lstrmiids -lvfw32 -lole32 -loleaut32
#include <Windows.h>
#include "strmif.h"
#include "dshow.h"
#include "Vfw.h"
...
HRESULT hr ;
IGraphBuilder* graph= nullptr;
hr = CoCreateInstance( CLSID_FilterGraph, 0, CLSCTX_INPROC,IID_IGraphBuilder, (void **)&graph );
IMediaControl* ctrl = nullptr;
hr = graph->QueryInterface( IID_IMediaControl, (void **)&ctrl );
IMediaEventEx* mediaEvent=nullptr;
hr = graph->QueryInterface(IID_IMediaEvent, (LPVOID *) &mediaEvent);
ICreateDevEnum* devs = nullptr;
hr = CoCreateInstance (CLSID_SystemDeviceEnum, nullptr, CLSCTX_INPROC, IID_ICreateDevEnum, (void **) &devs);
IEnumMoniker* cams = nullptr;
hr = devs?devs->CreateClassEnumerator (CLSID_VideoInputDeviceCategory, &cams, 0):0;
IMoniker* mon = nullptr;
hr = cams?cams->Next (1, &mon, nullptr):0;
IBaseFilter* cam = nullptr;
hr = mon?mon->BindToObject(nullptr,nullptr,IID_IBaseFilter, (void**)&cam):0;
IEnumPins* pins = nullptr;
hr = cam?cam->EnumPins(&pins):0;
IPin* cap = nullptr;
hr = pins?pins->Next(1,&cap, nullptr):0;
IAMVfwCaptureDialogs *pVfw = nullptr;
hr = cap->QueryInterface(IID_IAMVfwCaptureDialogs, (void**)&pVfw);
if (SUCCEEDED(hr))
{
// Check if the device supports this dialog box.
if (S_OK == pVfw->HasDialog(VfwCaptureDialog_Source))
{
// Show the dialog box.
hr = pVfw->ShowDialog(VfwCaptureDialog_Source, HWND(this->winId()));
}
}
else
{
error("cap->QueryInterface");
}
1 ответ
Прежде всего, вы пропустили действительно важную часть. В вашем приложении Qt/OpenCV какой API используется и что именно у вас есть для данной веб-камеры. Если это видео для Windows, то вы должны посмотреть на VFW API в диалоговом интерфейсе. Если это DirectShow, то вы в основном не заинтересованы в диалогах VFW.
Предположительно вы взаимодействуете с камерами через DirectShow (ну, не имеет особого смысла использовать VFW, особенно для нескольких камер). Тогда я сомневаюсь, что AMCap использует именно тот путь кода, который вы упомянули в вопросе. Обратите внимание на исходный комментарий AMCap:
// we use this interface to bring up the 3 dialogs
// NOTE: Only the VfW capture filter supports this. This app only brings
// up dialogs for legacy VfW capture drivers, since only those have dialogs
hr = gcap.pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video, gcap.pVCap,
IID_IAMVfwCaptureDialogs, (void **)&gcap.pDlg);
С DirectShow вы, как правило, всплывает интерфейс конфигурации с ISpecifyPropertyPages
а также OleCreatePropertyFrame
, AMCap также имеет соответствующий код:
else if(id - MENU_DIALOG0 == gcap.iVCapDialogPos)
{
ISpecifyPropertyPages *pSpec;
CAUUID cauuid;
hr = gcap.pVCap->QueryInterface(IID_ISpecifyPropertyPages,
(void **)&pSpec);
if(hr == S_OK)
{
hr = pSpec->GetPages(&cauuid);
hr = OleCreatePropertyFrame(ghwndApp, 30, 30, NULL, 1,
(IUnknown **)&gcap.pVCap, cauuid.cElems,
(GUID *)cauuid.pElems, 0, 0, NULL);
CoTaskMemFree(cauuid.pElems);
pSpec->Release();
}
}
Отображение страниц свойств фильтра на MSDN должно быть даже более полезным для вас (у вас уже есть IBaseFilter
указатель интерфейса в вашем фрагменте кода в вопросе).