« codecs++; | Main | flickerbat ii »

January 12, 2007

flickerbat

this entry is long overdue. i will now describe in detail what i know about the so-called deflickering problem and present my attempts at solving it to date.

first, a brief introduction. there is a tendency of interlaced displays to "flicker" when showing rough edges or straight lines. some of you may have noticed this in ties or other articles of clothing with complex patterns worn by news anchors--the patterns will seem to move or jump about rapidly. this is a side effect of the psychological trick interlaced displays use to approximate full motion--what is not moving seems to be moving.

video games suffer from flickering more so than your average tv program because they contain more of the types of material that make flickering obvious, such as straight lines (usually in menus) and rough edges (usually in text). some early attempts at deflickering involved switching the hardware from d4 (half resolution) to d1 (full resolution) when navigating menus. one notable game to do this was metal gear solid. changing to full resolution allows the game console to display different information in each field. flickering is reduced as the jagged edges are reduced. for this reason, some people refer to deflickering as "antialiasing", quite similar in lineage to the methods used to hide "jaggies" from discerning gamers' eyes. (by the way, deflickering can be "experienced" firsthand by entering the super smash bros. melee options and enabling and disabling the option. what looks better on an interlaced scanning display looks worse when it comes to progressive scan.)

there is nothing wrong with games running in full resolution. the missing motion information can be accurately reconstructed with an advanced deinterlacing algorithm such as mvbob(). further, as previously mentioned, "hybrid" games like metal gear solid usually run at f2 (half framerate) outside of menus, so i can simply drop one of the fields to simultaneously deinterlace and de-deflicker in these cases (no mvbob() necessary!).

however, another type of deflickering has recently become much more common with the rise in console emulation (that is, running emulators on consoles). sonic mega collection and the mega man anniversary collection both deflicker their output. they accomplish this by blurring one field a quarter pixel up and the other a quarter pixel down. i have taken pictures of this in action:

the right image occurs one half-frame after the left. that is, each image represents one field. if you turn your attention to the top non-black line in the left picture, you will notice that it is different from the line immediately below it. it is exactly 50% white (or, if you prefer, 50% black!) because it has been blurred with the preceding (black) line. a similar situation can be verified in the second picture by looking at its last non-black line--the only difference is that this time, the picture was blurred down, not up.

material that was once d4 is now effectively d1. as you can imagine, playing back this video without any form of de-deflickering will present an unacceptable level of "bobbing", if you wish to call it that. after pondering this sad situation for many hours, i concluded (with the help of grenola) that the only solution is to blur the down-blurred field up and the up-blurred field down, canceling out the deflickering (thanks go to grenola for this particular method):

converttorgb32
field1=SelectEven.PointResize(640,480).addborders(0,0,0,1).bilinearresize(320,240)
field2=SelectOdd.PointResize(640,480).addborders(0,1,0,0).bilinearresize(320,240)
Interleave(field1,field2)

unfortunately, things are not so simple. upon performing this so-called "retard bob" (so dubbed after "smart bob"), one field will seem clearer when it comes to certain objects, while the other will seem clearer when it comes to other objects. the exact cause of this behavior is not yet known, but one theory involves the quite imperfect horizontal analog representations of luma and chroma changes. that is, different brightness levels and colors at the source will produce different levels of blur after deflickering. the problem now moves beyond my ability to correct.

having said that, "retard bob" has improved things significantly:

mega man's energy bar was used as a reference for attempting blur level equalization. however, rush and the cloud maker towers at the bottom of the frame are clearly more blurry in the left (blur compensated) picture than in the right one. this would seem to dictate less blur compensation. however, applying any less blur compensation results in mega man's energy bar coming out of "blur sync" and "flickering" in the final product. this "neo-flickering" (or, if you prefer, "bobbing") is considerably more noticeable at f3 (third framerate) than at f1 (full framerate) for obvious reasons. unfortunately, the divx medium and low quality as well as the h.264 low quality of all 2d runs are encoded at f3 in order to ensure playability on old hardware (can't be f1) as well as to avoid problems with 60 hz blinking in most games (can't be f2). the ability to encode at f2 would neatly solve this entire situation, as i mentioned earlier when discussing metal gear solid, and this is precisely what i did for the recent sonic 3 & knuckles and sonic 1 runs submitted by mike89 (old school sonic is very special in that it contains no salient 60 hz blinking effects).

using gaussresize() i have settled on a "not-so-happy medium" blur (p) of 40:

converttorgb32
notblurred=SelectEven.PointResize(640,480).addborders(0,0,0,1).gaussresize(320,240,p=40)
blurred=SelectOdd.PointResize(640,480).addborders(0,1,0,0).bilinearresize(320,240)
Interleave(notblurred,blurred)

("notblurred" refers to the field needing blur compensation based on mega man's energy bar.)

however, as shown and explained above, some "neo-flickering" or "bobbing" will be visible no matter the blur compensation. for this reason, i am recommending that emulation be completely avoided when recording speed runs. as previously discussed, there are exceptions, mario 64 and similar 3d games constituting one such class (because the games run at d4 f2, i can simply drop one of the fields to neatly solve the problem).

concluding, i wish to mention that all game boy advance games played using the game boy player suffer from deflickering. i have employed many solutions over the years, including old school "retard bob" in virtualdub (even field quarter scanline up, odd field quarter scanline down in the "field bob" filter) and even mvbob. however, because virtually all gba games run at f1, none of these solutions is optimal for the above explicated reasons. the jury is still out on deflickering.

Posted by njahnke at January 12, 2007 11:28 PM

Comments

Post a comment

Thanks for signing in, . Now you can comment. (sign out)

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)


Remember me?