I do not think your problem is in video capture component itself nor FFMPEG. The main problem is that Directshow and VFW API to obtain image from camera is relatively slow. The speed can be improved by setting proper format of the image like:
- smaller resolution
- different color encoding (RGB 24bpp is not a good idea)
- using camera JPEG format (not all cameras support it)
Without JPEG output format I never got pass 15 fps even on small resolutions. Also my experience shows that DirectShow is slightly slower then VFW (at least for my cameras). However not all cameras provide a VFW driver :( anymore.
Also be sure to ensure USB bandwidth by using proper version of USB port and do not diminish its bandwidth with other devices on the same HUB !!!
This is what I use for camera capture (VFW I coded years ago) in Borland/Embarcadero BDS 2006 C++:
VideoCaptureVFW.h:
//---------------------------------------------------------------------------
//--- VFW Video Capture ver: 2.0 --------------------------------------------
//---------------------------------------------------------------------------
#ifndef _VideoCaptureVFW_h
#define _VideoCaptureVFW_h
//---------------------------------------------------------------------------
#include <vfw.h>
#include <jpeg.hpp>
#include <Clipbrd.hpp>
//---------------------------------------------------------------------------
const int _vfw_callbach_onframe=1; // bit mask for each callback
//---------------------------------------------------------------------------
#ifndef _TDirectMemoryStream
#define _TDirectMemoryStream
class TDirectMemoryStream:TMemoryStream // just for accessing protected SetPointer
{
public:
void SetMemory(BYTE *ptr,DWORD siz) { SetPointer(ptr,siz); Position=0; };
};
#endif
//---------------------------------------------------------------------------
#ifndef _avgfps
#define _avgfps
class avgfps
{
public:
int N,N2;
int frame,frame0;
double fps,t0,t1,dt,Ts;
avgfps()
{
N=40; N2=N<<1;
fps=0.0; t0=0.0; frame=0; frame0=0;
LARGE_INTEGER i;
QueryPerformanceFrequency(&i); Ts=1.0/double(i.QuadPart);
}
~avgfps() {}
void update()
{
double t;
LARGE_INTEGER i;
QueryPerformanceCounter(&i); t=double(i.QuadPart)*Ts; dt=t-t0;
if (frame<=0)
{
t0=t; t1=t;
dt=0.0;
frame=0;
frame0=0;
}
if (dt>1e-6) fps=double(frame0)/dt; else fps=0.0;
frame++; frame0++;
if (frame0==N ) t1=t;
if (frame0==N2) { t0=t1; t1=t; frame0=N; }
}
};
#endif
//---------------------------------------------------------------------------
class VideoCaptureVFW
{
private:
HWND hcap,hown; // video capture window
public:
int ins_ix,ins_use; // instance index and usage for callbacks class reference
CAPDRIVERCAPS driver_cp; // driver capabilities
CAPTUREPARMS capture; // capture setup
CAPSTATUS state;
BITMAPINFO format;
// on frame callback
avgfps fps; // average fps
TMemoryStream *mem; // just for loading jpg from memory without copy
Graphics::TBitmap *bmp; // grabbed frame
VideoCaptureVFW();
~VideoCaptureVFW();
void ins_rst();
void ins_inc();
void ins_dec();
void set_owner(HWND _hown);
AnsiString get_video_drivers();
void set_video_driver(int ix);
void dlg_source() { if(driver_cp.fHasDlgVideoSource) capDlgVideoSource(hcap); }
void dlg_format() { if(driver_cp.fHasDlgVideoFormat) capDlgVideoFormat(hcap); get_state(); get_format(); }
void dlg_display(){ if(driver_cp.fHasDlgVideoDisplay)capDlgVideoDisplay(hcap);}
void dlg_compress() { capDlgVideoCompression(hcap); }
void get_capabil(){ capDriverGetCaps (hcap,&driver_cp,sizeof(CAPDRIVERCAPS)); }
void get_setup() { capCaptureGetSetup(hcap,&capture,sizeof(CAPTUREPARMS)); }
void set_setup() { capCaptureSetSetup(hcap,&capture,sizeof(CAPTUREPARMS)); }
void get_state() { capGetStatus (hcap,&state,sizeof(CAPSTATUS)); }
void get_format() { capGetVideoFormat (hcap,&format,sizeof(BITMAPINFO)); }
void preview_start(){ capPreview(hcap,TRUE ); }
void preview_stop() { capPreview(hcap,FALSE); }
void grab_start() { set_callback_on_frame(); capGrabFrameNoStop(hcap); }
void grab_stop() { res_callback_on_frame(); }
void copy_to_clipboard() { capEditCopy(hcap); }
void set_callback_on_frame();
void res_callback_on_frame();
LRESULT _on_frame(HWND hwnd,LPVIDEOHDR hdr);
void (*on_frame)(VideoCaptureVFW &cap);
};
//---------------------------------------------------------------------------
// on frame
const int _VideoCaptureVFW_ins=32;
void* VideoCaptureVFW_ins[_VideoCaptureVFW_ins]=
{
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
};
int VideoCaptureVFW_ins_get()
{
for (int i=0;i<_VideoCaptureVFW_ins;i++)
if (VideoCaptureVFW_ins[i]==NULL) return i;
return -1;
}
LRESULT PASCAL VideoCaptureVFW00_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[ 0]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW01_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[ 1]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW02_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[ 2]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW03_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[ 3]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW04_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[ 4]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW05_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[ 5]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW06_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[ 6]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW07_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[ 7]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW08_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[ 8]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW09_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[ 9]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW10_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[10]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW11_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[11]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW12_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[12]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW13_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[13]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW14_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[14]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW15_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[15]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW16_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[16]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW17_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[17]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW18_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[18]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW19_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[19]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW20_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[20]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW21_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[21]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW22_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[22]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW23_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[23]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW24_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[24]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW25_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[25]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW26_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[26]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW27_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[27]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW28_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[28]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW29_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[29]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW30_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[30]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL VideoCaptureVFW31_on_frame(HWND hwnd,LPVIDEOHDR hdr) { return ((VideoCaptureVFW*)(VideoCaptureVFW_ins[31]))->_on_frame(hwnd,hdr); }
LRESULT PASCAL(*VideoCaptureVFW_on_frame[_VideoCaptureVFW_ins])(HWND hwnd,LPVIDEOHDR hdr)=
{
VideoCaptureVFW00_on_frame,
VideoCaptureVFW01_on_frame,
VideoCaptureVFW02_on_frame,
VideoCaptureVFW03_on_frame,
VideoCaptureVFW04_on_frame,
VideoCaptureVFW05_on_frame,
VideoCaptureVFW06_on_frame,
VideoCaptureVFW07_on_frame,
VideoCaptureVFW08_on_frame,
VideoCaptureVFW09_on_frame,
VideoCaptureVFW10_on_frame,
VideoCaptureVFW11_on_frame,
VideoCaptureVFW12_on_frame,
VideoCaptureVFW13_on_frame,
VideoCaptureVFW14_on_frame,
VideoCaptureVFW15_on_frame,
VideoCaptureVFW16_on_frame,
VideoCaptureVFW17_on_frame,
VideoCaptureVFW18_on_frame,
VideoCaptureVFW19_on_frame,
VideoCaptureVFW20_on_frame,
VideoCaptureVFW21_on_frame,
VideoCaptureVFW22_on_frame,
VideoCaptureVFW23_on_frame,
VideoCaptureVFW24_on_frame,
VideoCaptureVFW25_on_frame,
VideoCaptureVFW26_on_frame,
VideoCaptureVFW27_on_frame,
VideoCaptureVFW28_on_frame,
VideoCaptureVFW29_on_frame,
VideoCaptureVFW30_on_frame,
VideoCaptureVFW31_on_frame,
};
//---------------------------------------------------------------------------
VideoCaptureVFW::VideoCaptureVFW()
{
hcap=NULL;
hown=NULL;
ins_ix=-1; ins_use=0;
on_frame=NULL;
mem=new TMemoryStream();
bmp=new Graphics::TBitmap;
}
//---------------------------------------------------------------------------
VideoCaptureVFW::~VideoCaptureVFW()
{
capDriverDisconnect(hcap);
res_callback_on_frame();
if (mem) delete mem;
if (bmp) delete bmp;
}
//---------------------------------------------------------------------------
void VideoCaptureVFW::set_owner(HWND _hown)
{
hown=_hown;
hcap=capCreateCaptureWindow("",WS_CHILD|WS_VISIBLE,0,0,1,1,hown,1);
}
//---------------------------------------------------------------------------
AnsiString VideoCaptureVFW::get_video_drivers()
{
const int _size=256;
char drv_name[_size];
char drv_ver[_size];
char dev_name[_size];
AnsiString s0,s1,list;
int i;
list="";
for (i=0;;i++)
{
if (!capGetDriverDescription(i,drv_name,_size,drv_ver,_size)) break;
s0=drv_name;
s1=drv_ver;
list+=s0+" "+s1+"\n";
}
return list;
}
//---------------------------------------------------------------------------
void VideoCaptureVFW::set_video_driver(int ix)
{
if (hcap==NULL) return;
capDriverConnect(hcap,ix);
capDriverGetCaps(hcap,&driver_cp,sizeof(CAPDRIVERCAPS));
capCaptureGetSetup(hcap,&capture,sizeof(CAPTUREPARMS));
// capture.dwRequestMicroSecPerFrame=10; // 1/fps [us]
capCaptureSetSetup(hcap,&capture,sizeof(CAPTUREPARMS));
capPreviewRate(hcap,1); // set preview [ms]
capPreviewScale(hcap,FALSE); // stretching off
//preview_start();
}
//---------------------------------------------------------------------------
void VideoCaptureVFW::set_callback_on_frame()
{
if (ins_ix<0) ins_ix=VideoCaptureVFW_ins_get();
if (ins_ix<0) return;
VideoCaptureVFW_ins[ins_ix]=this;
ins_use|=_vfw_callbach_onframe;
capSetCallbackOnFrame(hcap,(void*)(VideoCaptureVFW_on_frame[ins_ix]));
}
//---------------------------------------------------------------------------
void VideoCaptureVFW::res_callback_on_frame()
{
if (ins_ix<0) return;
if (int(ins_use&_vfw_callbach_onframe))
{
ins_use^=_vfw_callbach_onframe;
capSetCallbackOnFrame(hcap,NULL);
}
if (ins_use) return;
VideoCaptureVFW_ins[ins_ix]=NULL;
ins_ix=-1;
}
//---------------------------------------------------------------------------
LRESULT VideoCaptureVFW::_on_frame(HWND hwnd,LPVIDEOHDR hdr)
{
fps.update();
int e=0;
if (hdr->dwBytesUsed<16) return 0; // ignore too small images
((TDirectMemoryStream*)(mem))->SetMemory(hdr->lpData,hdr->dwBytesUsed);
if ((hdr->lpData[6]=='J') // JPEG signature
&&(hdr->lpData[7]=='F')
&&(hdr->lpData[8]=='I')
&&(hdr->lpData[9]=='F'))
{
e=1;
TJPEGImage *jpg=new TJPEGImage;
jpg->LoadFromStream(mem);
bmp->Assign(jpg);
delete jpg;
} else
if ((hdr->lpData[0]=='B') // BMP signature
&&(hdr->lpData[1]=='M'))
{
e=1;
bmp->LoadFromStream(mem);
}
else{ // others
e=1;
copy_to_clipboard();
try {
bmp->LoadFromClipboardFormat(CF_BITMAP,Clipboard()->GetAsHandle(CF_BITMAP),NULL);
}
catch(char *str)
{
e=0;
int hnd=FileCreate("unsuproted_format.dat");
FileWrite(hnd,hdr->lpData,hdr->dwBytesUsed);
FileClose(hnd);
}
}
if (e)
{
if (on_frame) on_frame(*this);
}
return 0;
}
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
I have a small test app with this source code:
//$$---- Form CPP ----
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
// select API:
#define _capture_VFW
// #define _capture_DirectShow
//---------------------------------------------------------------------------
#ifdef _capture_VFW
#include "VideoCaptureVFW.h"
#endif
#ifdef _capture_DirectShow
#include "DirectX92\\VideoCaptureDirectShow.cpp"
#endif
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
Graphics::TBitmap *bmp=new Graphics::TBitmap;
int _callback=0;
int _frame=0;
int _update=false;
//---------------------------------------------------------------------------
#ifdef _capture_VFW
VideoCaptureVFW vfw;
void on_frame_VFW(VideoCaptureVFW &cap)
{
if (_callback) Form1->Canvas->Draw(0,26,cap.bmp);
else if (!_frame) { bmp->Assign(cap.bmp); _frame=1; }
}
#endif
//---------------------------------------------------------------------------
#ifdef _capture_DirectShow
VideoCaptureDirectShow dsh;
void on_frame_DirectShow(VideoCaptureDirectShow &cap)
{
if (_callback) Form1->Canvas->Draw(0,26,cap.bmp);
else if (!_frame) { bmp->Assign(cap.bmp); _frame=1; }
}
#endif
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner)
{
#ifdef _capture_VFW
pan_VFW->Visible=true;
vfw.set_owner(this->Handle);
cb_driver->Items->Clear();
cb_driver->Items->Text=vfw.get_video_drivers();
cb_driver->ItemIndex=0;
vfw.on_frame=on_frame_VFW;
vfw.set_video_driver(cb_driver->ItemIndex);
vfw.grab_start();
#endif
#ifdef _capture_DirectShow
pan_DirectShow->Visible=true;
cb_device->Items->Clear();
cb_device->Items->Text=dsh.get_devices();
dsh.on_frame=on_frame_DirectShow;
_update=1;
cb_device->ItemIndex=0;
_update=0;
cb_device->OnChange(this);
/*
dsh.Select(0);
dsh.Start();
dsh.Stop();
*/
#endif
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
#ifdef _capture_VFW
vfw.grab_stop();
#endif
#ifdef _capture_DirectShow
dsh.Stop();
#endif
delete bmp;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
if ((!_callback)&&(_frame)) { Canvas->Draw(0,26,bmp); _frame=0; }
#ifdef _capture_VFW
Caption=AnsiString().sprintf("frame: %2i fps: %2.1lf",vfw.fps.frame,vfw.fps.fps);
#endif
#ifdef _capture_DirectShow
Caption=AnsiString().sprintf("frame: %2i fps: %2.1lf",dsh.fps.frame,dsh.fps.fps);
#endif
}
//---------------------------------------------------------------------------
//--- VFW -------------------------------------------------------------------
//---------------------------------------------------------------------------
void __fastcall TForm1::bt_dialog_sourceClick(TObject *Sender)
{
#ifdef _capture_VFW
vfw.dlg_source();
#endif
}
void __fastcall TForm1::bt_dialog_formatClick(TObject *Sender)
{
#ifdef _capture_VFW
vfw.dlg_format();
#endif
}
void __fastcall TForm1::bt_dialog_displayClick(TObject *Sender)
{
#ifdef _capture_VFW
vfw.dlg_display();
#endif
}
void __fastcall TForm1::cb_driverChange(TObject *Sender)
{
#ifdef _capture_VFW
vfw.set_video_driver(cb_driver->ItemIndex);
vfw.grab_start();
#endif
}
//---------------------------------------------------------------------------
//--- DirectShow ------------------------------------------------------------
//---------------------------------------------------------------------------
void __fastcall TForm1::cb_deviceChange(TObject *Sender)
{
#ifdef _capture_DirectShow
if (_update) return;
_update=1;
dsh.Select(cb_device->ItemIndex);
cb_format->Items->Clear();
cb_format->Items->Text=dsh.get_formats();
if (cb_format->Items->Count)
cb_format->ItemIndex=0;
_update=0;
cb_format->OnChange(this);
#endif
}
//---------------------------------------------------------------------------
void __fastcall TForm1::cb_formatChange(TObject *Sender)
{
#ifdef _capture_DirectShow
if (_update) return;
_update=1;
dsh.set_format(cb_format->Text);
_update=0;
#endif
}
//---------------------------------------------------------------------------
Its single form app with few buttons and combo box lists for dialog boxes and configuration (you can mimic them or ignore them). Did not share the DirectShow as its too big for 30K limit and slower anyway (but ist just a header + lib file no 3th party components). I have these VCL components on the form:
TTimer *Timer1; // 10ms info text update
TPanel *pan_VFW; // just to hold the components for VFW
TSpeedButton *bt_dialog_source; // these 3 buttons configure VFW ...
TSpeedButton *bt_dialog_format;
TSpeedButton *bt_dialog_display;
TComboBox *cb_driver; // this selects VFW device
TPanel *pan_DirectShow; // just to hold DirectShow components
TComboBox *cb_device; // this selects DirectShow device
TComboBox *cb_format; // this selects DirectShow format
I encapsulated the VFW and DirectShow stuff into configuration #define
so you can ignore the DirectShow stuff completely.
Now when you use this you can play with resolution and formats to compare the fps to your DirectShow component grabber.
As you can see I do not use any 3th party components to grab image data from camera the VideoCaptureVFW.h
is the only stuff you need.
[Edit1]
Here is the link to the Demo containing both VFW
and DirectShow
examples (source and win32 binaries) in Embarcadero BDS2006 C++.
[Edit2] your unsupported format
The file size is exactly 1920*1080*3
Bytes which hints raw 24bpp RGB feed. When I tried to visualize it it works (and yes Y is flipped) see tyhe code (no components on form this time):
//$$---- Form CPP ----
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
Graphics::TBitmap *bmp=NULL;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner)
{
int xs=1920,ys=1080,x,y,a,hnd,siz;
BYTE *p,*dat=NULL;
// load frame
hnd=FileOpen("maybe_RGB24.dat",fmOpenRead);
siz=FileSeek(hnd,0,2); dat=new BYTE[siz];
FileSeek(hnd,0,0);
FileRead(hnd,dat,siz);
FileClose(hnd);
// convert RGB24 to 32bpp bitmap
bmp=new Graphics::TBitmap;
bmp->HandleType=bmDIB;
bmp->PixelFormat=pf32bit;
bmp->SetSize(xs,ys);
for (a=0,y=ys-1;y>=0;y--) // flip y
{
p=(BYTE*)bmp->ScanLine[y];
for (x=0;x<xs;x++)
{
p[0]=dat[a]; a++;
p[1]=dat[a]; a++;
p[2]=dat[a]; a++;
p[3]=0;
p+=4;
}
}
delete dat;
// resize form
ClientWidth=xs;
ClientHeight=ys;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
if (bmp) delete bmp; bmp=NULL;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender)
{
Canvas->Draw(0,0,bmp);
}
//---------------------------------------------------------------------------
And resulting screen:

beware I renamed the filename to maybe_RGB24.dat
. You could decode this file-format by the frame size alone but its info should be somewhere like in the
AM_MEDIA_TYPE* mt;
structure but do not ask me where exactly I have no clue as I did code this a long time ago and do not use DirectX since (as all my attempts in the past reveals its inferiority to other apis does not matter if its sound or gfx or grabbing...)