[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