[mythtv] YV12 problem

Jean-Yves Avenard jyavenard at gmail.com
Thu Dec 13 10:22:59 UTC 2018


On Thu, 13 Dec 2018 at 04:28, David Engel <david at istwok.net> wrote:

> I'm confused again.  I thought we were talking about yv12 but you're
> talking mostly about nv12.  I know there are a plethora of pixel
> formats but it's still mostly Greek alphabet soup to me until I get
> further up to speed.  If the hardware decoders generate nv12, how does
> yv12 fit in?  Is it a format that has to be converted to on the way to
> output or something else?

the only difference between NV12 and YUV420/YV12 is that U and V are
interleaved for NV12.

So YV12 is stored as:
YYYY
UUUU
VVVV

and NV12 is:
YYYY
UVUVUVUV

that's it.
information is identical just stored differently.

YV12 fits in because all FFmpeg decoder outputs that format.
If you have no hardware decoder you will get YV12 out
If you use a hardware decoder you get NV12 out (with the buffer
actually in GPU memory)


> I think that's kind of what I figured.  The pixel format is already
> known for the textures and handled appropriately, right?  The
> algorithm of which pixels from which lines/testures to mix with other
> pixels remains the same.

You do need to tell the GPU what textures you are you are feeding it.
So with OpenGL, for YV12 you pass 3 textures buffer
NV12 you pass 2 textures buffer.

To show the difference on what the shader would be to access the YV12 pixel:
float3 yuv = float3(
tY.Sample(sSampler, aTexCoords).r,
tCb.Sample(sSampler, aTexCoords).r,
tCr.Sample(sSampler, aTexCoords).r);
return CalculateYCbCrColor(yuv * vCoefficient);

That's for nv12
float y = tY.Sample(sSampler, aTexCoords).r;
float2 cbcr = tCb.Sample(sSampler, aTexCoords).rg;
return CalculateYCbCrColor(float3(y, cbcr) * vCoefficient);

That's a D3D11 shader for Firefox OpenGL compositor (everything gets
converted to RGB before being composited)

You can see that for YV12 you access the data for U/V separately, and
for NV12, together. that's it. 1 line change.

If you were to do that in C, it would be:
YV12
Yvalue = Y[x] + y * strideY;
Uvalue = U[x/2] + y * strideU;
Vvalue = V[x/2] + y * strideV;

With strideU=strideV=strideY/2

For NV12:
Yvalue = Y[x] + y * strideY;
Uvalue = UV[int(x/2)*2] + y * strideUV;
Vvalue = VV[int(x/2)*2+1] + y * strideUV;

with strideUV = strideY


More information about the mythtv-dev mailing list