I was cursing the latest version of VLC player (3.0.16). Out of the box, on full-range videos, it was changing grays of 235-235-235 to 255-255-255, and changing 16-16-16 to 0-0-0.

After some poking around I found the cure:

Tools -> Preferences -> Video (icons at top of screen)
Output: Direct3D9 video output

I have a full-range test pattern consisting of four gray patches of 0, 16, 235 and 255. After applying the above fix I get correct levels on the test pattern.

I also get correct levels without adjustment on VirtualDub2. You can actually see separation between the 235 and 255 patches. This should be helpful if you are doing critical video work.