-
-
Save crearo/0d50442145b63c6c288d1c1675909990 to your computer and use it in GitHub Desktop.
/** A fragment shader to convert NV12 to RGB. | |
* Input textures Y - is a block of size w*h. | |
* texture UV is of size w*h/2. | |
* Remember, both U and V are individually of size w/2*h/2, but they are interleaved. | |
* The layout looks like this : | |
* ---------- | |
* | | | |
* | Y | size = w*h | |
* | | | |
* |________| | |
* |UVUVUVUV|size = w/2*h/2 | |
* |UVUVUVUV|size = w/2*h/2 | |
* ---------- | |
*/ | |
precision highp float; | |
varying vec2 vTextureCoord; | |
uniform sampler2D sTextureY; | |
uniform sampler2D sTextureUV; | |
uniform float sBrightnessValue; | |
uniform float sContrastValue; | |
void main (void) { | |
float r, g, b, y, u, v; | |
// We had put the Y values of each pixel to the R,G,B components by GL_LUMINANCE, | |
// that's why we're pulling it from the R component, we could also use G or B | |
y = texture2D(sTextureY, vTextureCoord).r; | |
// We had put the U and V values of each pixel to the A and R,G,B components of the | |
// texture respectively using GL_LUMINANCE_ALPHA. Since U,V bytes are interspread | |
// in the texture, this is probably the fastest way to use them in the shader | |
u = texture2D(sTextureUV, vTextureCoord).r - 0.5; | |
v = texture2D(sTextureUV, vTextureCoord).a - 0.5; | |
// The numbers are just YUV to RGB conversion constants | |
r = y + 1.13983*v; | |
g = y - 0.39465*u - 0.58060*v; | |
b = y + 2.03211*u; | |
r = r * sContrastValue + sBrightnessValue; | |
g = g * sContrastValue + sBrightnessValue; | |
b = b * sContrastValue + sBrightnessValue; | |
// We finally set the RGB color of our pixel | |
gl_FragColor = vec4(r, g, b, 1.0); | |
} |
Checkout http://github.com/crearo/grafika. I haven't touched this code in a while so I'm not certain if you'll find it there.
In general though, if you're getting a green image, you're close. Swap U with V as an initial try.
Hi Crearo,
Thanks for your answer.
I'm using OPENGL ES on AOSP.
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, cameraTexY);
glUniform1i(locTexY, GL_ZERO);
glBindVertexArray(VAO);
glTexSubImage2D(GL_TEXTURE_2D, GL_ZERO, GL_ZERO, GL_ZERO, mVideoCapture.getWidth(),
mVideoCapture.getHeight(), GL_RED, GL_UNSIGNED_BYTE, mVideoCapture.getYBuffer()); //Y buffer size is 345600
glBufferSubData(GL_ARRAY_BUFFER, GL_ZERO, sizeof(vertices), vertices);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, cameraTexU);
glUniform1i(locTexU, GL_ZERO);
glBindVertexArray(VAO);
glTexSubImage2D(GL_TEXTURE_2D, GL_ZERO, GL_ZERO, GL_ZERO, mVideoCapture.getWidth() / 2,
mVideoCapture.getHeight() / 2, GL_RED, GL_UNSIGNED_BYTE, mVideoCapture.getUVBuffer()); //UV buffer size 172800
glBufferSubData(GL_ARRAY_BUFFER, GL_ZERO, sizeof(vertices), vertices);
When I swap I got blue image.. But still unable to decode colors :/
A little help would be appreciated.
Thanks a lot
Hello could you share the code that's using this shader. I get a weird result (green image)
Haha, I got red image at first try.
And seem like got some bropblem with image
NV12Render for anyone need example
@tqk2811 I have same problem, always display red image.
Have you solved this problem yet?
@tqk2811 I have same problem, always display red image. Have you solved this problem yet?
-Check width and linesize
-Check color order: ex rgba
and bgra
....
Hello could you share the code that's using this shader. I get a weird result (green image)