Доброго дня всем.Имеется у меня ОГРОМНАЯ просьба к коллегам-программерам или просто хорошим (но талантливым в программировании) человекам
.
У меня БОЛЬШАЯ проблема с программированием видеокамеры, то есть с видеозахватом кадров с последующим сохранением. Вот уже больше года, как бьюсь. Это не смешно уже стало. Дело в том, что с веб-камерой, задача моментально решилась средствами DirectShow, в частности набор DSPack все замечательно зделал. И качество фоток прекрасное. Но у начальства (не непосредственного, а то что выше) лбы дубовые, а мозги толоконные или вообще высохли. И приобрели они вероятно по очень хорошей цене (полагаю 8-ми значная сумма там в BLR, а может просто им подарили...) кучу металлома под гордым названием "фотостанция". Это собственно комп Celeron 300/RAM, 256Mb (чудо современной техники, что в нем хорошего, то это его вес - вместе с 17" ЭЛТ (!) монитором потянет на килограмм 40), но с достаточно дорогой видеокартой и цифровой аналоговой камерой. Симпатичный глаз такой на штативе, с кейпадом, для управления поворотами. Изображение с нее хуже чем с вебки, но вид у нее видите ли солиднее... Нет слов. Но дело надо зделать, вопрос чести. Я все перепробовал, где понятие хоть какое-то имею. В том числе и напрямую через "AVICAP32.DLL" и через DirectShow.pas напрямую используя определенные там интерфейсы. Не идет окаянная...
Считаю, проблема или с правильным построением графа фильтров, либо с контакты (IPin) нужно в ручную как-то коннектить или другие фильтры использовать. Но последние варианты (IPin или не стандартные фильтры), мне не доступен - нет понятия о принципе и отсутствие опыта работы с устройствами. А может возраст уже...
У меня же пока получается лишь "телевизор без антены" или вообще ничего на видеоконтроле или error типа "деление на нуль"/"контакты не присоединены".
Камера что используется CNB DSP 220x (CNB Digital Signal Procesor). Карта видеозахвата - ATI Radeon 9000 Pro All-in-Wonder. Название устройства видеозахвата - ATI Rage Theater Video Capture.
Я догадываюсь, что нужно как-то через WDM-драйвер напрямую инициализировать камеру или карту, а далее работать средствами DirectShow. Но как это зделать? Далее я приведу три куска кода - больше ничего путного не наработал и не нашел нигде. У всех либо "все идет", либо ехидно ёрничают - по типу сами такие великие программеры, что разработали все интерфейсы и методы, а на деле же выдрали где-то из инета или "знакомые" подсказали.
В общем признателен буду за помощь. Мне достоверно известно, что есть умники в Минске где-то, что смогли зделать эту камеры, правда в CBuilder (я в Delphi работаю), но не играет роли - можно и в CBuilder. Если кто знает, как, но не хочет даром отдавать - могу заплатить. Из своего кармана естественно и это не жертва организации (пусть горит она синим пламенем), а нужно мне лично.
Вот мои (основные) наработки.1. С ручной записью параметров видеорежима. procedure TfrmDxMedia.RunCapture;
var
m_VideoType: PAMMediaType;
hr: HResult;
StreamConfig: IAMStreamConfig;
begin
try
StreamConfig := NIL;
m_VideoType := nil;
FilterGraph.ClearGraph();
FilterGraph.Active := False;
StrDev := TStringList.Create();
SysDev:= TSysDevEnum.Create(CLSID_VideoInputDeviceCategory);
Filter.BaseFilter.Moniker := SysDev.GetMoniker(0); //устройство все равно единственное
Filter.FilterGraph := FilterGraph();
FilterGraph.Active := True;
with FilterGraph as ICaptureGraphBuilder2 do begin
hr := FindInterface(@PIN_CATEGORY_CAPTURE,
@MEDIATYPE_Video,
Filter as IBaseFilter,
IID_IAMStreamConfig, StreamConfig);
end;
if SUCCEEDED(hr) then begin
StreamConfig.GetFormat(m_VideoType);
PVideoInfoHeader(m_VideoType.pbFormat)^.bmiHeader.biWidth := 320; //Это основной
PVideoInfoHeader(m_VideoType.pbFormat)^.bmiHeader.biHeight := 240; //видеорежим
PVideoInfoHeader(m_VideoType.pbFormat)^.bmiHeader.biBitCount := 16; //камеры CNB DSP 220x
// PVideoInfoHeader(m_VideoType.pbFormat)^.AvgTimePerFrame:= 10000000 div 25; //25 fps - нет смысла
with PVideoInfoHeader(m_VideoType.pbFormat)^.bmiHeader do
m_VideoType.lSampleSize := biWidth * biHeight * biBitCount;
PVideoInfoHeader(m_VideoType.pbFormat)^.bmiHeader.biSizeImage :=
m_VideoType.lSampleSize;
m_VideoType.subtype := MEDIASUBTYPE_UYVY; //такой тип данных у этой камеры
end;
SampleGrabber.MediaType.InitMediaType();
SampleGrabber.MediaType.AMMediaType.majortype := m_VideoType.majortype;
SampleGrabber.MediaType.AMMediaType.subtype := m_VideoType.subtype;
SampleGrabber.MediaType.AMMediaType.bFixedSizeSamples := m_VideoType.bFixedSizeSamples;
SampleGrabber.MediaType.AMMediaType.bTemporalCompression := m_VideoType.bTemporalCompression;
SampleGrabber.MediaType.AMMediaType.lSampleSize := m_VideoType.lSampleSize;
SampleGrabber.MediaType.AMMediaType.formattype := m_VideoType.formattype;
SampleGrabber.MediaType.AMMediaType.pUnk := m_VideoType.pUnk;
SampleGrabber.MediaType.AMMediaType.cbFormat := m_VideoType.cbFormat;
SampleGrabber.MediaType.AMMediaType.pbFormat := m_VideoType.pbFormat;
SampleGrabber.UpdateMediaType(); //пробую обновить тип медиаданных - без этого все тоже.
// ShowMessage(intTostr((PVideoInfoHeader(SampleGrabber.MediaType.AMMediaType.pbFormat)^.bmiHeader.biWidth)));
// - 320 пикселей как и записывали.
// ShowMessage(intTostr(SizeOf(SampleGrabber.MediaType.AMMediaType^))); - 72 байта
m_VideoType := nil;
StreamConfig := nil;
with FilterGraph as ICaptureGraphBuilder2 do begin
//пробовалось - @PIN_CATEGORY_PREVIEW - на вэбкамере идет, на CNB нет вообще ничего
//даже "шипения" на медиаконтроле
RenderStream(nil{@PIN_CATEGORY_CAPTURE}, @MEDIATYPE_Video, //nil,
Filter as IBaseFilter,
SampleGrabber as IBaseFilter,
VideoWindow as IbaseFilter);
end;
FilterGraph.Play();
except
{}
end;
end;
2. С записью видеорежима передаваемого как параметр (номер по itemindex c combobox'a).procedure TfrmDxMedia.RunCapture(iMode: integer);
var
PinList: TPinList;
begin
try
FilterGraph.Active := true;
if Filter.FilterGraph <> nil then begin
PinList := TPinList.Create(Filter as IBaseFilter);
with (PinList.First as IAMStreamConfig) do
SetFormat(CVideoMediaTypes.Items[iMode].AMMediaType^); //формат видеоданных
PinList.Free();
end;
with FilterGraph as IcaptureGraphBuilder2 do begin
//закоментироаны варианты - эксперименты - все без толку.
{ if Filter.BaseFilter.DataLength > 0 then
RenderStream(@PIN_CATEGORY_PREVIEW, nil, Filter as IBaseFilter,
nil , VideoWindow as IBaseFilter);}
{ if Filter.BaseFilter.DataLength > 0 then
RenderStream(@PIN_CATEGORY_CAPTURE, nil, Filter as IBaseFilter,
nil , VideoWindow as IBaseFilter);}
{ if Filter.BaseFilter.DataLength > 0 then
RenderStream(nil, nil, Filter as IBaseFilter,
nil , VideoWindow as IBaseFilter);}
if Filter.BaseFilter.DataLength > 0 then begin
RenderStream(nil, @MEDIATYPE_Video, Filter as IBaseFilter,
SampleGrabber as IBaseFilter, VideoWindow as IbaseFilter);
end;
end;
FilterGraph.Play();
except
end;
end;
3. Найденный мной вариант в сети. Пишут, что именно для ATI Rage Theater Video Capture. Но это у них все ok, а не у меня.procedure TfrmDxMedia.RunCapture(iMode: integer);
var
PinList: TPinList;
CamPrev: IPin;
hr: HResult;
NullRenderer: IBaseFilter;
begin
try
if not FilterGraph.Active then FilterGraph.Active := true;
if Filter.FilterGraph <> nil then begin
PinList := TPinList.Create(Filter as IBaseFilter);
with (PinList.First as IAMStreamConfig) do
SetFormat(CVideoMediaTypes.Items[iMode].AMMediaType^);
PinList.Free();
end;
with FilterGraph as ICaptureGraphBuilder2 do begin
hr := FindPin(Filter as IBaseFilter, PINDIR_OUTPUT,
@PIN_CATEGORY_VIDEOPORT, nil, True, 0, CamPrev );
if ( hr = S_OK ) then begin
RenderStream(nil, nil, CamPrev, nil, VideoWindow as IBaseFilter);
Renderstream(nil, nil, Filter as IBaseFilter,
SampleGrabber as IBaseFilter, NullRenderer as IBaseFilter);
//пробовал и так эту строчку:
//SampleGrabber as IBaseFilter, VideoWindow as IBaseFilter);
//и так:
//SampleGrabber as IBaseFilter, nil);
// и даже так: nil, nil);
end else begin // just a std preview pin
RenderStream(@PIN_CATEGORY_PREVIEW, nil, Filter as IBaseFilter,
SampleGrabber as IBaseFilter, VideoWindow as IBaseFilter);
end;
CamPrev:= nil;
end;
FilterGraph.Play();
except
end
end;
Это все что есть у меня. Остальное вариации на эти же темы. DotNet (С#, VB) не пойдет - железо (вот уже где правильное название для этой так называемой "станции") слабое. Но камера 100% рабочая, ибо есть демка на CBuilder (от тех умников из Минска). Но код разумеется зажали - ноу-хау, понимаете ли...
Все три варианта на У-РА идут с вебки, но с DSP все они = 0.