In the course of displaying video on Nvidia cards using the Xvideo interface, I've come across two interesting quirks of how the Xvideo extension is implemented by Nvidia cards and drivers.
The first of these I discovered when I was trying to alternate between displaying video (using XvPutImage) and drawing other content (using normal Xlib calls) in the same window. This isn't such an outlandish thing to do - imagine an application that displays a menu of several videos you can choose from (using Xlib), then displays the chosen video in the same window. What I discovered was that if you go from using XvPutImage to normal Xlib calls (XFillRectangle, say), then back to XvPutImage, then the video no longer displays correctly - until you move or resize the window, that is.
Say we have the following scenario: We display a few video frames (in the whole window), then draw a black rectangle over the left half of the window using XFillRectangle, then display some more video frames. I'm not sure if my expectation is just wrong here, but what I would expect to happen is for the second bunch of XvPutImage calls to overwrite the rectangle that I drew using XFillRectangle. What actually happens is that the left half of the window stays black, and only the right half of the video gets displayed - until the window is moved or resized.
To explain what I think is going on here, I'll give a quick overview of how video output works on most graphics cards. What you might expect is that XvPutImage takes your YUV420 video frame, scales it, converts it to RGB and writes it into the frame buffer. On most video cards, including Nvidia, this is not what actually happens. Instead, video is displayed using a so-called overlay. What this means is that no actual video pixels are ever written into the frame buffer. Instead, the portion of the frame buffer where the video should be displayed is filled with a blue rectangle to indicate to the video scaler that these pixels should then be replaced with the scaled video image.
Of course, if you then go and draw something into the window using normal Xlib calls, those blue pixels get overwritten with whatever it is that you draw - which is what you want, because you don't want video to be displayed at those locations any more. However, the next time you call XvPutImage, what you would expect is for the corresponding region to be filled with blue pixels again - and apparently, that doesn't always happen. I believe Nvidia's implementation of XvPutImage contains an optimization that stops the blue rectangle from being painted if the video is being drawn in the same location as the last time around. Which is fine - so long as you haven't been drawing in the window in the meantime.
So, on Nvidia cards at least, the golden rule seems to be: Don't match Xvideo and normal Xlib calls in the same window. If you want to alternate between video and some other kind of display in the same location, you'll have to use two windows with the same position and dimensions and switch between the two.
The second little quirk of Xvideo on Nvidia has to do with what I said above about overlays. In fact, on Nvidia, you don't have to use overlays - you can also make XvPutImage write the video image directly to the frame buffer. Which of the two types of behaviour you get depends on which Xvideo adaptor you choose. XvQueryAdaptor returns three adaptors:
So if you use the first adaptor ("Video Overlay"), you get the overlay behaviour I described above (blue pixels written to the frame buffer, video display carried out using the video scaler), whereas with the second adaptor ("Video Blitter"), the video image is written directly to the frame buffer. (Don't ask me what the "Video Interface Port" is... maybe something to do with video input.).
Theoretically, the problem I described above (not being able to mix Xvideo and Xlib in the same window) should not occur if you restrict yourself to using the "Video Blitter" adaptor, but I haven't tested this. Note, though, that the "Video Blitter" adaptor might not be available on all Nvidia cards (I read something to the effect that it uses the 3D chip to do the scaling and YUV-to-RGB conversion).
Interestingly, the "Video Overlay" adaptor only has a single port - makes sense, because there's only one video scaler on the card. The "Video Blitter", on the other hand, has 32 ports - probably an arbitrary restriction since I suspect all of these "ports" just use the 3D chip to do their scaling. The upshot of this is that if you want to do simultaneous video output to several windows, you'll have to use the "Video Blitter" for the second and subsequent windows.
I haven't done any performance comparisons on the two adaptor types, but if you have, I'd be interested to hear. Also, if you have any other comments, please contact me at the address given at the top of this article. Standard disclaimer: I assume no liability for the correct functioning of the techniques presented in this article.