The essential problem of trying to play a video stream correctly on TV in a tear-free and jump-free way is to synchronize the delivery of new frames with the vertical retrace period; the time around the vertical sync pulse when the monitor is moving the beam from the bottom back to the top of the screen.
So far my attempt at achieving this has been to hack my video card’s X11 XVideo driver to sit in a polling loop until the bit in the video controller registers indicates that retrace is in progress. While this works, it sucks up a lot of CPU time in a busy-waiting loop; time that could have been better spent decoding video and audio streams.
What’s needed is to take advantage of the video controller’s ability to interrupt on vertical retrace. That way other processes can use the time profitably. Possible ways to do this are:
Have the Xv driver’s PutImage routine sleep on an event until woken by an interrupt handler. The driver could then move its data into the video overlay’s memory area, or swap a controller register to point to a new memory area. This approach only allows threads other than the caller to use the time for decoding, etc.
Have the Xv PutImage routine set stuff up so that the everything was ready to be swapped at the next interrupt, then return to the caller immediately. The interrupt handler could then do the actual swapping. This has the advantage that the calling thread can be the one using the time profitably. But probably breaks the semantics of the PutImage routine, by returning before the work is truly done.
Bypass X11 completely, and write a driver (for mplayer or VideoLAN) that just does Trident YUV overlay stuff, natively.