Video Encoding/Decoding

Blitz3D Forums/Blitz3D Programming/Video Encoding/Decoding

ClayPigeon(Posted 2014) [#1]
Does anyone know if there is a way (I'm don't really mind if it's hacky) of extracting frames from a video in B3D, then feeding images from within B3D to a video encoder to turn it back into a video? I don't care if it only works with one file format; I just need a way to get a video into Blitz, then churn one out. (preferably NOT in the form of an image sequence). Is there a way I can feed B3D's native loaded images straight into some kind of external encoder dll like ffmpeg or DirectShow or something? Thanks!

P.S.: I'm thinking ffmpeg might be the answer; I managed to create an avi by using SaveImage to make an image sequence, then telling ffmpeg to convert those to a video. This is, of course, a poor solution because it takes much longer to make individual image files, it takes up lots of unnecessary space on the HDD, and it leaves a mess you need to clean up.


Kryzon(Posted 2014) [#2]
It will take a lot of patience and study.
You can use Libavcodec - the encoding and decoding library used by FFMPEG - directly with C.

You can then write a simple set of functions to be exported as a DLL that you use in your program as a userlib. You can use a free C compiler such as Code::Blocks.

The following is an example of encoding dummy frames to a video file. Of special interest are the functions "write_video_frame" and "fill_yuv_image:"
http://libav.org/doxygen/release/0.8/libavformat_2output-example_8c-example.html

You will need to refer to the userlib documentation of Blitz3D to know how to write the functions to generate the DLL.
http://blitzbasic.com/sdkspecs/sdkspecs/userlibs_specs.txt

Then you could use your DLL like so:

Const CODEC_THEORA% = 1

Const FRAME_WIDTH%	= 600
Const FRAME_HEIGHT%	= 400
Const FPS%		= 25

Local vHandle% = AV_CreateVideo( "video.ogv", CODEC_THEORA, FPS, FRAME_WIDTH, FRAME_HEIGHT ) ;Userlib function.

Local _recording% = True
Local frameData = CreateBank( 600 * 3 + 400 * 3 ) ;Or something to that effect.

While _recording

	;Draw on the Front or Back buffers.

	;You need to pass the frame data to the DLL.
	;After you put the pixel data in the bank, you would use:

	AV_AddFrame( vHandle, frameData ) ;Sending the address of the bank to your DLL.


	;...	

Wend

AV_CloseVideo( vHandle )



ClayPigeon(Posted 2014) [#3]
Thanks Kryzon! Interesting approach. I wouldn't have thought of that in a million years, mostly because I've never written a DLL before. I understand the concept and the execution, I've just never done it, so I can't be sure I'd do it right. It's worth a try, though. It looks like a much cleaner and more "correct" way of doing than I had expected, so thanks! Now. Time to go brutalize my poor mind trying to wrap it around this... :P