Search code examples
opengl-esglslyuvv4l2

yuyv 4:2:2 parse buffer


I'm getting one buffer in YUYV 4:2:2 format from v4l. I would like to separate Y & UV from this buffer to get 2 buffers: buffer Y & buffer UV to be able to pass it to OpenGL and display the image in C++.

The buffer length is 1280 * 720 * 2 = 1843200 bytes

Is it possible, what is the algorithm?

V4L is sending one buffer 4:2:2 YUV but my shader is waiting 2 buffers

const char gFragmentNV12ToRGB[] =
    "#version 320 es\n"
    "precision highp float;\n"
    "in vec2 TexCoords;\n"
    "out vec4 color;\n"
    "uniform sampler2D text;\n"
    "layout(binding = 0) uniform sampler2D textureY;\n"
    "layout(binding = 1) uniform sampler2D textureUV;\n"
    "void main() {\n"
    "   float r, g, b, y, u, v;\n"
    "   y = texture(textureY, TexCoords).r;\n"
    "   u = texture(textureUV, TexCoords).r - 0.5;\n"
    "   v = texture(textureUV, TexCoords).a - 0.5;\n"
    "   r = y + 1.13983 * v;\n"
    "   g = y - 0.39465 * u - 0.58060 * v;\n"
    "   b = y + 2.03211 * u;\n"
    "   color = vec4(r, g, b, 1.0);\n"
    "}\n";

So I need to split my buffer first, but don't know how to proceed as I don't know the structure of the YUYV buffer...

The best would be to be able to send one buffer to GPU and he does the job...


Solution

  • I finally found how to render YUV 4:2:2 from one sampler only using OpenGL ES 3.0 ... To bad there are no examples on net ...

    Here is the final shader

    const char gFragment4:2:2ToRGB[] =
        "#version 320 es\n"
        "precision highp float;\n"
        "in vec2 TexCoords;\n"
        "out vec4 color;\n"
        "layout(binding = 0) uniform sampler2D textureYUV;\n"
        "void main() {\n"
        "   float r, g, b, y, u, v;\n"
        "   y = texture(textureYUV, TexCoords).r;\n"
        "   u = texture(textureYUV, TexCoords).g - 0.5;\n"
        "   v = texture(textureYUV, TexCoords).a - 0.5;\n"
        "   r = y + 1.13983 * v;\n"
        "   g = y - 0.39465 * u - 0.58060 * v;\n"
        "   b = y + 2.03211 * u;\n"
        "   color = vec4(r, g, b, 1.0);\n"
        "}\n";