Started using BlitzMax an hour ago.. Help!

BlitzMax Forums/BlitzMax Beginners Area/Started using BlitzMax an hour ago.. Help!

Andy UK(Posted 2008) [#1]
Hi all, thought i'd take the leap and get in to BlizMax.. its very different to B+/B3d gonna take some time to get my head round this. Ok, im using the Escapi dll to grab video from a usb capture device. Using the example with the addition of "Delay 1" lets me grab video to the screen at 720 * 576 @ 25fps using just 20% CPU on my C2D 1.66 .. lovely but what i want is to capture at half this resolution and resize the image up to 720 * 576. I have some how found my way and managed to get it working but it seems resizing a Pixmap is REALLY slow. Can someone help me speed this up? Learning curve is a bit steep! Code below is what i have so far. Thanks, hope someone can help. Oh, and its leaking memory like a tea bag. Cant find how you free a Pixmap.. is that what you even do??

' Thanks to Freak from the PureBasic forums for assistance!

Type SimpleCapParams
	Field mTargetBuf:Byte Ptr ' Must be at least mWidth * mHeight * SizeOf(Int) of size! 
	Field mWidth
	Field mHeight
End Type

Global InitCOM () "C"
Global CountCaptureDevices () "C"
Global OpenCaptureDevice (device, scp:Byte Ptr) "C"
Global CloseCaptureDevice (device) "C"
Global GetCapture (device) "C"
Global CaptureDone (device) "C"
Global CaptureDeviceName (device, name:Byte Ptr, namelen) "C"
Global ESCAPIDLLVersion () "C"

Function SetupESCAPI ()

	esc = LoadLibraryA ("escapi.dll")
	
	If esc
	
		InitCOM				= GetProcAddress (esc, "initCOM")
		CountCaptureDevices		= GetProcAddress (esc, "countCaptureDevices")
		OpenCaptureDevice 		= GetProcAddress (esc, "initCapture")
		CloseCaptureDevice		= GetProcAddress (esc, "deinitCapture")
		GetCapture				= GetProcAddress (esc, "doCapture")
		CaptureDone				= GetProcAddress (esc, "isCaptureDone")
		CaptureDeviceName			= GetProcAddress (esc, "getCaptureDeviceName")
		ESCAPIDLLVersion			= GetProcAddress (esc, "ESCAPIDLLVersion")

		If InitCOM = Null Or CountCaptureDevices = Null Or OpenCaptureDevice = Null Or..
			CloseCaptureDevice = Null Or GetCapture = Null Or CaptureDone = Null Or..
				CaptureDeviceName = Null Or ESCAPIDLLVersion = Null
					DebugLog "Function missing!"
					Return 0
		EndIf

		InitCOM ()
		
		If ESCAPIDLLVersion () < $200
			DebugLog "Old DLL (needs version 2.0+)"
			Return 0
		EndIf
		
	Else
		DebugLog "Failed to open DLL"
		Return 0
	EndIf

	Return 1
	
End Function

Function CaptureDevice$ (device)
	Local cam:Byte [1024]
	CaptureDeviceName (device, cam, 1024)
	Return String.FromCString (cam)
End Function

If SetupESCAPI () = 0
	Notify "Error! Make sure escapi.dll is in same folder and capture device plugged in!"
	End
EndIf

For num = 0 Until CountCaptureDevices ()
	Print "Capture device [" + num + "] name: " + CaptureDevice (num)
Next

device = 0

' To list/select devices...

	'Repeat
	'	device = Int (Input ("Enter capture device number: "))
	'Until device > -1 And device < CountCaptureDevices ()

' Preferred target width/height (ESCAPI scales capture data to this)...

width = 360
height = 288

AppTitle = "Using " + CaptureDevice (device) + "..."

Graphics width * 2, height * 2', 32

' Data structure...

Local scp:SimpleCapParams = New SimpleCapParams

' A PixMap for captured data...

pix:TPixmap = CreatePixmap (width, height, PF_BGRA8888)

' Stick pixmap memory pointer into data structure...

scp.mTargetBuf	= PixmapPixelPtr (pix)
scp.mWidth		= width
scp.mHeight		= height

' Start capture process...

If OpenCaptureDevice (device, scp) = 0
	Print "Failed to initialise capture device!"
	End
EndIf

Repeat

	Cls

	GetCapture (device)
	
	Repeat
	Delay 1
		If KeyHit (KEY_ESCAPE) Then quit = True
	Until CaptureDone (device)
	pix2:TPixmap = ResizePixmap(pix, 720, 576)
	DrawPixmap(pix2, 0, 0)

	Flip

Until quit = True

' Stop capture process...
	
CloseCaptureDevice (device)

End



Andy UK(Posted 2008) [#2]
Just changed "Flip" to "Flip 1" to get rid of the tearing in the video and the cpu usage has gone up by nearly 10%. Surely if the refresh rate is lower, the usage should be lower? Does "Flip 1" halt exercution or does it slam the cpu during the pause before the vertical blank? Strange.


verfum(Posted 2008) [#3]
I don't know how to fix your problem, it looks very tailored to what your doing, in other words your more than likely going to find your problem than us, the only advise I can give you regarding your code is bin B3D style of programming, it's very bad practice, put SuperStrict at the top of your code and fix your none defined variables, this alone is dangerous programming!

Best of luck with Bmax, it's the way forward, trust me.


skidracer(Posted 2008) [#4]
I would change

pix2:TPixmap = ResizePixmap(pix, 720, 576)
DrawPixmap(pix2, 0, 0)

to

SetScale 0.5,0.5
DrawPixmap pix, 0, 0

or look into telling the capture driver to lower it's resolution


plash(Posted 2008) [#5]
Aye, SetScale will be much faster than resizing the pixmap, but you're still handling/loading the same data.

You should try capturing in a lower resolution to see if the whole image is still visible, or if it cut out a section of the video.


Andy UK(Posted 2008) [#6]
I done what skidracer said but it does nothing to the image.. no error just a 360 * 288 video in the top left of a 720 * 576 window


Andy UK(Posted 2008) [#7]
ok i fixed it by putting this codein.

image= LoadImage(pix)
	SetScale 2,2
	DrawImage(image, 0, 0)
	Flip 1
	Release image


the release command seems to fix the memory leak but looking at the task manager while the application is running, the usage climbs from 20mb to 70mb and back down then it fluctuates between them.. is this normal for an app like this?? This program in purebasic uses no more than 11mb and its pretty stable.


ziggy(Posted 2008) [#8]
Windows will give more ram that the one needed by the application if it detects that the application is reading a writting to ram very frequently. TaksManager won't give you any accurate information about what's you app ram usage. Specially on a managed language. I wouldn't worry much about this. If you're concerned, try adding a GCCollect() in your main loop, and see if it helps, but I wouldn't waste time on this.