[MPlayer-dev-eng] nvidia_vid YV12 - some progress

Joachim Breuer jmbreuer at gmx.net
Sun Jan 4 15:16:07 CET 2004


Allright, I poked around a bit using mplayer -vo directx under '98 and
a modified version of Sascha's test to read out the card registers
while mplayer was running. Specific values in the following refer to
the playback of an 320x240 MPEG1 test stream.

I now have a rough idea how YV12 on my GeForce4 Ti4200 works, that is,
at least the Y plane seems to be displayed OK. YV12 register settings
differ from YUY2 as follows:

NV_PVIDEO_FORMAT (0x958):
  YUY2: 0x00110280
  YV12: 0x00110201
  YV12: 0x00110301 (640x384 stream)

Apparently, bit0 turns on YV12 mode, b8-11 correspond to bits 8-11 of
some kind of line buffer, i.e. if the video width is <0x100 it should
be set to 0x.....101, if 0x100 <= video width < 0x200 it should be set
to 0x.....201, and so on.

NV_PVIDEO_OFFSET (0x920, 0x924)
  YUY2: 0x03f2f800, 0x03f2f800
  YV12: 0x03f06400, 0x03eac400

The interesting thing is that in YV12 mode OFFSET1 differs from OFFSET
by 0x5a000, which happens to be 0x200 ('line buffer' size) * 3 * height.
Also, interestingly, OFFSET1 < OFFSET, whether this is because directx
has the YV12 planes ordered with Y last I don't know.

Anyway, OFFSET seems to point to the start of the Y plane, with the
following parameters the Y channel displays correctly:

  info->pitch = info->width + (info->width >> 1);

  vinfo->dest.pitch.y = info->pitch;
  vinfo->dest.pitch.u = info->pitch/2;
  vinfo->dest.pitch.v = info->pitch/2;

  vinfo->offset.y = 0;
  vinfo->offset.u = 0x200 * info->height;
  vinfo->offset.v = 0x200 * info->height * 2;

  vinfo->frame_size = 0x200 * info->height * 3;

The 0x200 should really be sth like ((info->width>>8)+1)<<8) (I know
that's wrong for the border cases), but I'm too lazy right
now. U/V is not displayed correctly anyway.

It looks as if some random portion of memory (if only I know that
address) is displayed in the U and V channels, whereas whatever is
written into the above locations for U and V is ignored.

I've had a look at reordering the planes as suggested by the DirectX
parameters, by setting OFFSET to the start of the Y plane again, which
now has an offset.y of 0x200*info->height*3, adjusting offset.u and
offset.v accordingly, and setting OFFSET1 to the start of the UV
planes. (I've tried both ways around, too.) No change, Y is displayed
OK; random, but static, garbage in UV.

Does anybody happen to know of a tool to dump the GeForces complete
memory? Then I could hunt around for where and how the color planes
are stored.

Next I'll try and see whether YV12's Y channel displays correctly
using the above settings after switching off the machine, it might
still be that some necessary registers are not initialized at all by
nvidia_vid.c at the moment - I've soft-booted from '98 into linux for
the current test. Wish me luck.


So long,
   Joe

-- 
"I use emacs, which might be thought of as a thermonuclear
 word processor."
-- Neal Stephenson, "In the beginning... was the command line"




More information about the MPlayer-dev-eng mailing list