Thank you very much for looking into it Ian, switching bits back and forth in DBPro is very much my least favoured option - while I do appreciate the possibilies to do so
Yea, there's some tricks to it - the luminance is the easier one to make out - that's what my sample is based on.
I've made a rough dump of the image data into a file "image.YUY2" The image captured at 640x480, 16bit
The code to generate the file included again, in case you'd want to hold up a piece of colored paper in front of your webcam:
// PREVIEW FRAME:
gosub initialize_video
global pointer as dword
global frame as dword
handle=start_cam(0,0,1,0,get dbpro window())
do
if spacekey() then stop_cam(handle) : sleep 2000 : end
set window title "Nothing's happening: "+str$(timer())
loop
function sub(a)
errormessage "yield"
endfunction
function start_cam(hnd,VIDEOSOURCE,VIDEOFORMAT,VIDEOCOMPRESSION,owner)
hHwnd=call dll(avicap32,"capCreateCaptureWindowA","Capture",1342177280,0,0,1,1,owner,1)
print "hHwnd 1 ",hHwnd
call dll user32,"SendMessageA",hHwnd,WM_CAP_DRIVER_CONNECT,0,0
if VIDEOSOURCE then call dll user32,"SendMessageA",hHwnd,WM_CAP_DLG_VIDEOSOURCE,0,0
if VIDEOFORMAT then call dll user32,"SendMessageA",hHwnd,WM_CAP_DLG_VIDEOFORMAT,0,0
if VIDEOCOMPRESSION then call dll user32,"SendMessageA",hHwnd,WM_CAP_DLG_VIDEOCOMPRESSION,0,0
call dll user32,"SendMessageA",hHwnd,WM_CAP_SET_USER_DATA,0,hnd
call dll user32,"SendMessageA",hHwnd,1027,0,get ptr to function("status") // WM_CAP_SET_CALLBACK_STATUSA
call dll user32,"SendMessageA",hHwnd,1026,0,get ptr to function("error") // WM_CAP_SET_CALLBACK_ERROR
call dll user32,"SendMessageA",hHwnd,WM_CAP_SET_CALLBACK_YIELD,0,get ptr to function("sub")
if 0
print "==================== STREAM ====================" : sync
if call dll(user32,"SendMessageA",hHwnd,WM_CAP_SET_CALLBACK_VIDEOSTREAM,0,get ptr to function("stream_callback"))<>1 then errormessage "Vi fik ikke startet webcam'et"
if call dll(user32,"SendMessageA",hHwnd,WM_CAP_SEQUENCE_NOFILE,0,0)<>1 then errormessage "Fejl, vi fik ikke startet streamen korrekt!"
else
print "==================== FRAME ====================" : sync
if call dll(user32,"SendMessageA",hHwnd,WM_CAP_SET_PREVIEWRATE,33,0)<>1 then errormessage "Preview-rate kunne ikke sættes!"
if call dll(user32,"SendMessageA",hHwnd,WM_CAP_SET_CALLBACK_FRAME,0,get ptr to function("Preview_Frame"))<>1 then errormessage "Preview-rate kunne ikke sættes!"
endif
print "hHwnd 3 ",hHwnd
endfunction hHwnd
function status(hHwnd,status,tekst)
print "Status: "+str$(hHwnd)+" ; "+str$(status)+" ~ "+peek string(tekst) : sync
endfunction 1
function error(hHwnd,fejl,tekst)
print "Error: "+str$(hHwnd)+" ; "+str$(fejl)+" ~ "+peek string(tekst) : sync
endfunction
function Preview_Frame(HWND,LPVIDEOHDR)
pointer=peek dword(LPVIDEOHDR) // lpData
dwBufferLength=peek dword(LPVIDEOHDR+4) // dwBufferLength
dwBytesUsed=peek dword(LPVIDEOHDR+8) // dwBytesUsed
dwUser=peek dword(LPVIDEOHDR+12) // dwUser
dwFlags=peek dword(LPVIDEOHDR+16) // dwFlags
s=call dll(user32,"SendMessageA",HWND,WM_CAP_GET_VIDEOFORMAT,0,0) : format=alloc zeroed(s) : call dll user32,"SendMessageA",HWND,WM_CAP_GET_VIDEOFORMAT,s,format
width=peek dword(format+4) : height=peek dword(format+8) : style$=peek string(format+16) :
// message "Pallet size: "+str$(s-40)
free format
frame=frame+1
cls
print "Pointer ",pointer
print "Lenght: ",dwBufferLength
print "dwBytesUsed. ",dwBytesUsed
print "format: ",style$
print "Preview Frame ",timer()
hnd=call dll(user32,"SendMessageA",HWND,WM_CAP_GET_USER_DATA)
make bank 1,dwBufferLength
copy memory get bank ptr(1),pointer,dwBufferLength
if file exist("c:\image.YUY2") then delete file "c:\image.YUY2"
make file from bank "c:\image.YUY2",1
delete bank 1
ptr=0
for y=1 to height
for x=1 to width
dot x,100+y,peek_YUY2(pointer+ptr) // rgb(peek byte(pointer+ptr+2),peek byte(pointer+ptr+1),peek byte(pointer+ptr))
inc ptr,2
if ptr>=dwBufferLength-3 then sync : exitfunction
next x
next y
sync
endfunction
function peek_YUY2(ptr)
local farve as dword
// the YUY2 is located at ptr
luminance=peek byte(ptr)
farve=rgb(luminance,luminance,luminance)
col=peek byte(ptr+1)
endfunction farve
function stream_callback(HWND,LPVIDEOHDR)
print "Stream "+str$(timer())+" ~ "+str$(HWND)+" ; "+str$(peek byte(LPVIDEOHDR)) : sync
pointer=peek dword(LPVIDEOHDR)
print "lpData "+str$(peek dword(LPVIDEOHDR)) : inc LPVIDEOHDR,4
print "dwBufferLength "+str$(peek dword(LPVIDEOHDR)) : inc LPVIDEOHDR,4
print "dwBytesUsed "+str$(peek dword(LPVIDEOHDR)) : inc LPVIDEOHDR,4
print "dwTimeCaptured "+str$(peek dword(LPVIDEOHDR)) : inc LPVIDEOHDR,4
print "dwUser "+str$(peek dword(LPVIDEOHDR)) : inc LPVIDEOHDR,4
print "dwFlags "+str$(peek dword(LPVIDEOHDR)) : inc LPVIDEOHDR,4
print "dwReserved "+peek string(peek dword(LPVIDEOHDR),4)+" . "
sync
endfunction 1
function stop_cam(hHwnd)
call dll user32,"SendMessageA",hHwnd,WM_CAP_DRIVER_DISCONNECT,0,0
endfunction
initialize_video:
global avicap32 : avicap32=find free dll() : load dll "avicap32.dll",avicap32
global user32 : user32=find free dll() : load dll "user32.dll",user32
global gdi32 : gdi32=find free dll() : load dll "gdi32.dll",gdi32
#constant WM_CAP_SET_CALLBACK_ERROR=1024+2
#constant WM_CAP_SET_CALLBACK_YIELD=1024+4
#constant WM_CAP_SET_CALLBACK_FRAME=1024+5
#constant WM_CAP_SET_CALLBACK_VIDEOSTREAM=1024+6
#constant WM_CAP_GET_USER_DATA=1024+8
#constant WM_CAP_SET_USER_DATA=1024+9
#constant WM_CAP_DRIVER_CONNECT=1024+10
#constant WM_CAP_DRIVER_DISCONNECT=1024+11
#constant WM_CAP_SET_AUDIOFORMAT=1024+35
#constant WM_CAP_GET_AUDIOFORMAT=1024+36
#constant WM_CAP_DLG_VIDEOFORMAT=1024+41
#constant WM_CAP_DLG_VIDEOSOURCE=1024+42
#constant WM_CAP_DLG_VIDEODISPLAY=1024+43
#constant WM_CAP_GET_VIDEOFORMAT=1024+44
#constant WM_CAP_SET_VIDEOFORMAT=1024+45
#constant WM_CAP_DLG_VIDEOCOMPRESSION=1024+46
#constant WM_CAP_SET_PREVIEWRATE=1024+52
#constant WM_CAP_SEQUENCE_NOFILE=1024+63
#constant WM_CAP_SET_SEQUENCE_SETUP=1024+64
#constant WM_CAP_GET_SEQUENCE_SETUP=1024+65
#constant BI_RGB=0
#constant _RGB=0x32424752
return