I’ve had a go at squeezing the Bad Apple!! video down onto the arduboy. Unlike other consoles the video has been ported to, the issue is not speed, but storage. The arduboy has a fixed 32kb of program
memory, no way of expanding with cartridges. I’ve aimed for 11x8 resolution and 8 frames per second, which when uncompressed sits at ~27KB of memory, but the overhead of the libraries and arduino gunk pushes that up to about 40KB combined.
My compression method pads the video to 16x8 resolution, 2 bytes per line. The left hand byte stores 5 data bits and 3 image bits, while the right hand byte stores 8 image bits. If the right byte can be matched to anything from the previous 31 bytes in the chain, it is discarded, and the distance to the matching byte is stored in the data bits. This compresses the source video down to 62%-ish, making room for other things like more frames or music, maybe. There is the odd bit of video corruption, but I think that’s down to my encoding tool, not the method used.
If anyone has a good idea on how to store the music alongside the video, I’m open to suggestions.
Yeah, out of context it doesn’t mean much, just wanted to get the Arduboy on the list of consoles with a port.
I have a few other ideas for compressing, but not any that would be effective enough to keep the video legible, sadly.
If you are doing this with the hope of using it as a basis for game cutscenes… you might take a tip from how they did things on the NES and animate sprites while moving them around. Could potentially allow for a much more pleasing approximation. I believe there is a function that will let one scale and rotate sprites on the fly.
I held off on buying one specifically because I heard they were making a better Arduboy with an SD card slot. That was around christmas time I think :P, I’ve been ‘borrowing’ my friend’s kickstarter unit since before then.
A modified version of gif might just compress a video small enough to fit some quality seconds. Dividing down the rez would allow for more time, and if you don’t do it quite as much the video might be discernible. gif format would have to be redesigned to take advantage of the framebuffer order. I think gif patent ran out and there is likely example source out there either way. I believe the gif animations are mostly diffs so only a fraction of the frame is being compressed along with vectors. One could likely compress the 1 bit frames in an ordinary gif and find out how much space it should take.
The header block wastes 6 bytes, the logical screen descriptor is 7 bytes and uses 16-bit numbers (when realistically the Arduboy would only need 8 bits describing the image width and height), then it has an optimal global table which requires at least one byte to indicate that it’s been disabled, et cetera et cetera.
Long story short, it would be more efficient and probably easier to just use an entirely custom-made format that takes all the Arduboy’s limitations into account. All it would need to be is a series of (compressed) frames with a list of timings indicating which frame is to be displayed next and for how long.
I think a modified version of the format might work. Since the payload should be modified so should the headers. One could even go so far as to assume we are dealing with arduboy and forgo the traditional header. Use an index into constant array to define header details. Decoding builds string tables which are likely going to be where one sees memory concerns.
I was thinking one could get better results replacing the string table compression with Huffman coding. I don’t see any reason why the table couldn’t be stored in PROGMEM so that would lower processing overhead Not that we are suffering from a lack of processor power. It would avoid cluttering ram. Actually thinking about it making use of ram would be better for compression tables as well as generating them on the fly from data like gif does.
I think the most important part of any video format for the Arduboy is storing/compressing diffs avoiding whole frames as much as possible. There is going to be a threshold where storing diffs will approach the size of a full frame so those might as well be full frames.
It’s a bit of a Thesseus’s Ship paradox though.
Once you scrap the headers, the unnecessary 16-bit stuff, the colour table etc can you really say it’s based on gif anymore? At some point when you’ve removed enough features its effectively an entirely different format that doesn’t resemble gif anymore, at which point it might as well have been its own thing in the first place.
If you start from scratch and pluck the best bits of several different image formats you’ll end up with a better format overall. For example, PNG’s deflate algorithm (which is combination of huffman coding and LZ77) is typically much better than GIF’s LZW.
Without running tests though it’s impossible to say which method will work best. It might be the case that RLE works better than any of the fancier compression methods.
I experimented with some frames we used to make the video for our game jam submission. I was able to get 207 frames down to about 24k with gif. And for lolz I 7ziped it. I think we might be able to come up with some worthwhile video compression if the 7zip source isn’t insanely huge. I know it is processor intensive, but we have way more processor than available space so…
The 7z format supports LZMA, LZMA2, Bzip2, PPMd and DEFLATE as well as AES-256 encryption, unicode file names, various preprocessing features et cetera et cetera. There are 99 files alone for the different compression methods.