Здравствуйте. Есть видеокамера с WDM драйвером. Формат вывода RGB24.
Как сохранить/восстановить настройки фильтра (т.е. самой камеры), я сделал как написано где то на этом форуме (через IPersistStream). При этом сохраняются такие настройки как контрастность,яркость и тд и тп.
Проблема встала при сохранении/восстановлении формата видео. Нужно чтобы программа при запуске восстанавливала разрешение картинки (там по умолчанию всегда ставится 2136 на 1602 а мне надо например 640 на 480 (он камерой тоже поддерживается).
Эти настройки изменяются в диалоге настроек пина. Ни интерфейс IPin ни IAMStreamConfig не имеют IPersistStream (хотя IAMStreamConfig как раз и имеет диалог настроек).
Пробовал делать через IAMStreamConfig->GetFormat (сохраняю в ини), потом опять GetFormat, потом смера настройка формата данными из ини, потом IAMStreamConfig->SetFormat. Не работает. Точнее настройки пина захвата вроде меняются, а вот при pGrabber->GetConnectedMediaType(&mt) структура mt не соотв нужной.
Как это вообще можно реализовать или что я делаю не так?
Вот только не понял. Почитал тут ещё на wonderu так получается что мне мало того что надо конфигурировать выходной пин фильтра захвата, так ещё и копировать потом эту настройку во входной пин семпл граббера. И только потом всё это дело соединять?
Я создаю фильтр захвата как описано в DirectShow SDK, через enumerator устр-в. Перед добавлением на граф делаю гетформат потом меняю его настройки из ини потом сет формат. Потом соотв pGraph->AddFilter(pCap, L"Capture Filter");
При pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,pCap, pSG_Filter,pNull ) выдаёт сообщ что у вас запущен дебаггер просьба его выкл и тд и тп. Потом появл окно ЦПУ ( я в Билдере 6-ом программирую), а там всё по 0 (по личному опыту это вроде значит что где то косяк). Уже не понимаю вообще в чём дело. Структуру заполняю полностью, то есть как поля стр-ры AM_MEDIA_TYPE так и поля VIDEOINFOHEADER входящего в эту стр-ру. Всю голову себе уже сломал.
В общем просто поменять формат у меня не получилось. По этому сделал так:
после добавления на граф фильтра захвата подгружаю нужное разрешение след образом:
IAMStreamConfig *pSC;
HRESULT hr = pBuild->FindInterface(&PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video, pCap,
IID_IAMStreamConfig, (void **)&pSC);
if (hr!=S_OK)
return false;
GUID mediatype=MEDIATYPE_Video;//тип медиаданных, напр видео
GUID mediasubtype=MEDIASUBTYPE_RGB24;//поддип медиаданных, напр RGB24
GUID formattype=FORMAT_VideoInfo;
int iCount, iSize,needW,needH;
VIDEO_STREAM_CONFIG_CAPS scc;
AM_MEDIA_TYPE *pmt;
TIniFile *ini;
ini = new TIniFile(GetCurrentDir()+"\\Settings.ini");
needW=ini->ReadInteger("VIDEOINFOHEADER","biWidth",640);//треб. ширина
needH=ini->ReadInteger("VIDEOINFOHEADER","biHeight",480);//треб. высота
delete ini;
hr = pSC->GetNumberOfCapabilities(&iCount, &iSize);//получаем список возможн режимов камеры
if (sizeof(scc) != iSize)
{
// This is not the structure we were expecting.
return false;
}
for (int i=0;i<iCount;i++)
{
hr = pSC->GetStreamCaps(i, &pmt, reinterpret_cast<BYTE*>(&scc));
if (hr == S_OK)
{
if (pmt->formattype==formattype&&pmt->majortype==mediatype&&pmt->subtype==mediasubtype)
{
VIDEOINFOHEADER *pVih = reinterpret_cast<VIDEOINFOHEADER*>(pmt->pbFormat);
if ((pVih->bmiHeader.biWidth == needW)&&(pVih->bmiHeader.biHeight == needH))
{
hr = pSC->SetFormat(pmt);
break;
};
};
};
};
Не знаю на сколько правильно, но только так у меня действительно заработало.
И ещё, если при рендер филтерс вылезает ошибка с WinIce/SoftIce то скорей всего это из-за NERO, по крайней мере так написано было в msdn-форуме.
Может кому нибудь и пригодится.
HeaveN :
если при рендер филтерс вылезает ошибка с WinIce/SoftIce то скорей всего это из-за NERO
Я бы по-другому сказал. При RenderFilters() граф пытается вставлять фильтры, чтобы соединить пины, которые не соединяются напрямую. А пытается он вставлять фильтры с высоким параметром merit. Многие программы ставят с собой фильтры, в которых есть защита от отладчика. Поэтому если Nero ставит фильтры с высоким merit и с защитой от отладчика, то с большой вероятностью не будет работать автоматическая сборка графа (RenderPin и т.п.) при запущенном отладчике.
Вообще, граф лучше собирать вручную, без автосборщиков, т.к. на разных системах их поведение может быть разным, в зависимости от установленных фильтров.
Ну я на граф в ручную ставлю только фильтр захвата, Sample Grabber и Null Renderer. А сам граф при рендере добавляет smart tee. Причём как ни странно он добавляет одни и те же фильтры как с имеющимися фильтрами Nero так и без них.
А про высокий merit это да, это суть процесса, я просто написал чё мне в частности помогло.
//вот тут пытаюсь создать массив данных кадров видеопотока, но ничего не получается
long Size = 0;
hr = pGrabber->GetCurrentBuffer(&Size, NULL);
unsigned char *pBuffer;
pBuffer = new unsigned char[Size];
hr = pGrabber->GetCurrentBuffer(&Size, (long*)pBuffer);