viv

programmer & tinkerer with adhd

generalist software engineer at microsoft and author of https://twitter.com/dkpunchbot. check out @hell-labs for some other cool stuff

other places: @viv@snoot.tube, https://github.com/vivlim, https://twitter.com/vivviridian


Here's a draft I started writing soon after the initial rollout of Gif Plays GBC. I didn't finish it but... here you go!


fairly early on in the development of gif plays pkmn, i tried it out on my iphone and was dismayed to see two major issues

  1. tapping any button would show a modal dialog saying "do you want to download button.php?"
  2. safari would not would not consistently redraw and advance frames while a gif was being downloaded, only after it was complete.
    this could be worked around by resizing your browser, or on iOS, by continually pinch zooming the page

(gif of continuous pinch zooming omitted for extreme motion)

i tried several things to trick safari into redrawing the frame more often. one of the more successful ones was to draw this 1x1 gif which flashes between #000000 and #000001.

the 1x1 gif is a black dot above this text

this was... better in that the gif would play most(?) of the time without needing to wiggle the window, but there were still lots of pauses:

to work around these issues i implemented a streaming gif player in rust. i don't have the source posted anywhere but maybe one day that will change because i think it's pretty funny. here's the general idea:

gif plays gbc's video is implemented using an endless stream of animated gif data being streamed from a backend service. but we had a problem where iOS (and safari generally) really doesn't like to render gif files that aren't completely done downloading. so long story short I decide to implement an animated gif streamer in rust using wasm (click the popout link & 'stream gif using custom player' button to run that code)

i had pulled in a rust crate for decoding animated gif frames into a pixel buffer, which is challenging because frames can be small pieces that are overlaid on top of previous frames. the crate's implementation assumes that you can read the entire gif file at one time, and exhaustively reads gif data from the buffer i point it at, until it hits end of file.

but i don't want it to hit end of file, because then it will stop decoding and displaying new frames. so I come up with this scheme where I take whatever gif data I have on hand, put it into the read buffer, and then fill the rest with empty 0x0 frames that take 0ms to display. this works fine, until you end up with only part of a gif frame. if i write a partial gif frame into that read buffer, everything blows up. so I needed to change my scheme- instead of sending whatever gif data i have on hand, i send all the complete frames that I have, and hold on to incomplete ones, prefixing the next read with them (and hopefully giving me more complete frames)


You must log in to comment.