[mythtv] YV12 problem

David Engel david at istwok.net
Thu Dec 13 21:15:16 UTC 2018


On Thu, Dec 13, 2018 at 11:22:59AM +0100, Jean-Yves Avenard wrote:
> 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)

Thanks.  That is very helpful.

> > 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

Helpful again.  The C is quite understandable.  The shader code is
still quite foreign to me, though.

This will hopefully help me review the yv12 changes in question.

David
-- 
David Engel
david at istwok.net


More information about the mythtv-dev mailing list