FastPointer library use case: play movies

Blitz3D Forums/Blitz3D Userlibs/FastPointer library use case: play movies

alain(Posted 2009) [#1]
Hi there,

As everybody knows, movie playing in Blitz3D is, well, limited (to say the least).

One annoying thing in Blitz3D is the fact that when you are playing a movie, the framerate is limited to the framerate of the movie.

For instance if you are running a 10FPS movie in front of a 3D background, the 3D background animation will also play at 10FPS, and will look sluggish and jerky.

I was toying this morning with the FastPointer library (Available here: http://fastlibs.com/libraries.php ) and using multithread we can enhance this fact.. check the following code, you can set the variable "use_thread" to true or false to show the difference between standard and multi-thread.

There is still some graphical glitches (probably due to the fact that I am using SetBuffer() in the thread) and it seems it is not possible to call OpenMovie from inside the worker thread (for instance to loop the movie seamlessly) but I think this use case is really interesting.

By the way, if somebody knows about a DLL that handle movies better than Blitz3D do (not an experimental thing, but somethings that works) I am interested!

Global use_thread = True
Global movie = 0
Global tex = 0
Global movie_name$ = "SD0075.wmv"

; function for thread (with single integer param - it is obligatory)
; don't load meshes in thread, if you use RenderWorld function in main loop
Function ThreadFunction ( StartValue% = 0 )
	Repeat
		draw_movie()
	Forever
End Function


; get pointer to thread function
ThreadFunctionPointer = FunctionPointer()
	Goto skip
	ThreadFunction()		; <<< get pointer from this function
	.skip


; create scene objects
Graphics3D 800,600,0,2
Camera = CreateCamera()  :  PositionEntity Camera, 0, 0, -3.5
Light = CreateLight()
Cube = CreateCube()
movie=OpenMovie(movie_name)

tex = CreateTexture(256,256,256)
EntityTexture(cube,tex)

; create thread
If(use_thread=True)
	Thread = CreateThread (ThreadFunctionPointer, 100)
EndIf

; main loop
While Not KeyHit(1)
	If(use_thread=False)	
		draw_movie() 
	EndIf
	
	SetBuffer(BackBuffer())	
	TurnEntity Cube, 0.0, 0.1, 0.0
	RenderWorld
	Flip False
;	If(Not MoviePlaying(movie))
;		CloseMovie(movie)
;		movie=OpenMovie(movie_name)
;	EndIf
Wend

If(use_thread=True)
	; free thread
	If IsThread(Thread) Then FreeThread(Thread)
EndIf

CloseMovie(movie)
End

Function draw_movie()
	SetBuffer(TextureBuffer(tex))
	DrawMovie movie,0,0,255,255 
	SetBuffer(BackBuffer())
End Function



_33(Posted 2009) [#2]
Nice research going on in here. Thanks for the share.


xMicky(Posted 2009) [#3]
One problem of a use of SetBuffer() within an application with more then one thread seems to be, that it has a global effect =means, the newly setted buffer is valid for ALL currently running threads (and the main program).

So you can never be sure, even if you write the lines of: setting buffer, read/write to it, resetting the buffer - in source code directly under each other, that a buffer set in one thread will not be just switched to another buffer in another thread (or the main programm) or that the set buffer in the thread function will be used unintended in parallel running other threads or main loop.

So under the current circumstances I assume that one never would get a stabile application with using SetBuffer() in parallel threads.