簡體   English   中英

Android使用着色器將YUV轉換為RGB轉換

[英]Android opengl es YUV to RGB conversion using shaders

我正在研究Android設備的視頻播放器,其中我使用ffmpeg進行解碼,並使用opengl進行渲染。 我被困在一個地方,我正在使用opengl es着色器進行YUV到RGB的轉換。 應用程序能夠顯示圖像但不顯示正確的顏色。 從YUV到RGB后,圖像僅顯示綠色和粉紅色。 我在谷歌搜索過,但沒有找到解決方案。 任何人都可以幫我解決這個話題嗎?

我從ffmpeg得到三個不同的緩沖區(y,u,v),然后我將這些緩沖區傳遞給3個紋理。

這是我正在使用的着色器。

static const char kVertexShader[] =
"attribute vec4 vPosition;      \n"
  "attribute vec2 vTexCoord;        \n"
  "varying vec2 v_vTexCoord;        \n"
"void main() {                        \n"
    "gl_Position = vPosition;       \n"
    "v_vTexCoord = vTexCoord;       \n"
"}                                          \n";

static const char kFragmentShader[] =
    "precision mediump float;               \n"
    "varying vec2 v_vTexCoord;          \n"
    "uniform sampler2D yTexture;        \n"
    "uniform sampler2D uTexture;        \n"
    "uniform sampler2D vTexture;        \n"
    "void main() {                      \n"
        "float y=texture2D(yTexture, v_vTexCoord).r;\n"
        "float u=texture2D(uTexture, v_vTexCoord).r - 0.5;\n"
        "float v=texture2D(vTexture, v_vTexCoord).r - 0.5;\n"
        "float r=y + 1.13983 * v;\n"
        "float g=y - 0.39465 * u - 0.58060 * v;\n"
        "float b=y + 2.03211 * u;\n"
        "gl_FragColor = vec4(r, g, b, 1.0);\n"
    "}\n";

    static const GLfloat kVertexInformation[] =
    {
         -1.0f, 1.0f,           // TexCoord 0 top left
         -1.0f,-1.0f,           // TexCoord 1 bottom left
          1.0f,-1.0f,           // TexCoord 2 bottom right
          1.0f, 1.0f            // TexCoord 3 top right
    };
    static const GLshort kTextureCoordinateInformation[] =
    {
         0, 0,         // TexCoord 0 top left
         0, 1,         // TexCoord 1 bottom left
         1, 1,         // TexCoord 2 bottom right
         1, 0          // TexCoord 3 top right
    };
    static const GLuint kStride = 0;//COORDS_PER_VERTEX * 4;
    static const GLshort kIndicesInformation[] =
    {
         0, 1, 2, 
         0, 2, 3
    };

這是另一個提出相同問題的人: 使用GL着色器語言對相框進行rgb轉換

謝謝。

更新

ClayMontgomery的着色器。

const char* VERTEX_SHADER = "\
attribute vec4 a_position;\
attribute vec2 a_texCoord;\
varying   vec2 gsvTexCoord;\
varying   vec2 gsvTexCoordLuma;\
varying   vec2 gsvTexCoordChroma;\
\
void main()\
{\
    gl_Position = a_position;\
    gsvTexCoord = a_texCoord;\
    gsvTexCoordLuma.s = a_texCoord.s / 2.0;\
    gsvTexCoordLuma.t = a_texCoord.t / 2.0;\
    gsvTexCoordChroma.s = a_texCoord.s / 4.0;\
    gsvTexCoordChroma.t = a_texCoord.t / 4.0;\
}";


const char* YUV_FRAGMENT_SHADER = "\
precision highp float;\
uniform sampler2D y_texture;\
uniform sampler2D u_texture;\
uniform sampler2D v_texture;\
varying   vec2 gsvTexCoord;\
varying vec2 gsvTexCoordLuma;\
varying vec2 gsvTexCoordChroma;\
\
void main()\
{\
    float y = texture2D(y_texture, gsvTexCoordLuma).r;\
    float u = texture2D(u_texture, gsvTexCoordChroma).r;\
    float v = texture2D(v_texture, gsvTexCoordChroma).r;\
    u = u - 0.5;\
    v = v - 0.5;\
    vec3 rgb;\
    rgb.r = y + (1.403 * v);\
    rgb.g = y - (0.344 * u) - (0.714 * v);\
    rgb.b = y + (1.770 * u);\
    gl_FragColor = vec4(rgb, 1.0);\
}";

這是輸出:

在此輸入圖像描述

粉紅色和綠色表示在CSC矩陣計算和某些常量看起來錯誤之前,您的輸入亮度和色度值未正確歸一化。 此外,您可能應該縮放色度的紋理坐標,因為它通常相對於亮度進行子采樣。 這里有一個很好的指南:

http://fourcc.org/fccyvrgb.php

這是我在飛思卡爾i.MX53上編碼和測試的GLSL實現。 我建議你試試這個代碼。

const char* pVertexShaderSource = "\
    uniform   mat4 gsuMatModelView;\
    uniform   mat4 gsuMatProj;\
    attribute vec4 gsaVertex;\
    attribute vec2 gsaTexCoord;\
    varying   vec2 gsvTexCoord;\
    varying   vec2 gsvTexCoordLuma;\
    varying   vec2 gsvTexCoordChroma;\
    \
    void main()\
    {\
        vec4 vPosition = gsuMatModelView * gsaVertex;\
        gl_Position = gsuMatProj * vPosition;\
        gsvTexCoord = gsaTexCoord;\
        gsvTexCoordLuma.s = gsaTexCoord.s / 2.0;\
        gsvTexCoordLuma.t = gsaTexCoord.t / 2.0;\
        gsvTexCoordChroma.s = gsaTexCoord.s / 4.0;\
        gsvTexCoordChroma.t = gsaTexCoord.t / 4.0;\
    }";


const char* pFragmentShaderSource = "\
    precision highp float;\
    uniform sampler2D gsuTexture0;\
    uniform sampler2D gsuTexture1;\
    uniform sampler2D gsuTexture2;\
    varying vec2 gsvTexCoordLuma;\
    varying vec2 gsvTexCoordChroma;\
    \
    void main()\
    {\
        float y = texture2D(gsuTexture0, gsvTexCoordLuma).r;\
        float u = texture2D(gsuTexture1, gsvTexCoordChroma).r;\
        float v = texture2D(gsuTexture2, gsvTexCoordChroma).r;\
        u = u - 0.5;\
        v = v - 0.5;\
        vec3 rgb;\
        rgb.r = y + (1.403 * v);\
        rgb.g = y - (0.344 * u) - (0.714 * v);\
        rgb.b = y + (1.770 * u);\
        gl_FragColor = vec4(rgb, 1.0);\
    }";

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM