viel GRÜNE Farbe, an YUV420p --> RGB in OpenGL 2.0 Shader auf iOS

Ich will ein movie-player für iOS mit ffmpeg und OpenGL ES 2.0
aber ich habe einige Probleme. Ausgang RGB-Bild hat eine Menge von GRÜNER Farbe.
Dies ist der code und Bilder

  • 480x320 Breite & height:
  • 512x512 Textur-Breite & height

Bekam ich einen YUV420p Zeile Daten von ffmpeg AVFrame.

    for (int i = 0, nDataLen = 0; i < 3; i++) {
        int nShift = (i == 0) ? 0 : 1;
        uint8_t *pYUVData = (uint8_t *)_frame->data[i];
        for (int j = 0; j < (mHeight >> nShift); j++) {
            memcpy(&pData->pOutBuffer[nDataLen], pYUVData, (mWidth >> nShift));
            pYUVData += _frame->linesize[i];
            nDataLen += (mWidth >> nShift);
        }
    }

vorzubereiten und textur für Y, U & V-Kanal.

//: U Texture
    if (sampler1Texture) glDeleteTextures(1, &sampler1Texture);

    glActiveTexture(GL_TEXTURE1);
    glGenTextures(1, &sampler1Texture);
    glBindTexture(GL_TEXTURE_2D, sampler1Texture);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    //This is necessary for non-power-of-two textures
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glEnable(GL_TEXTURE_2D);

    glTexImage2D(GL_TEXTURE_2D, 
                 0, 
                 GL_LUMINANCE, 
                 texW / 2, 
                 texH / 2, 
                 0, 
                 GL_LUMINANCE, 
                 GL_UNSIGNED_BYTE,
                 NULL);

    //: V Texture
    if (sampler2Texture) glDeleteTextures(1, &sampler2Texture);

    glActiveTexture(GL_TEXTURE2);
    glGenTextures(1, &sampler2Texture);
    glBindTexture(GL_TEXTURE_2D, sampler2Texture);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    //This is necessary for non-power-of-two textures
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glEnable(GL_TEXTURE_2D);

    glTexImage2D(GL_TEXTURE_2D, 
                 0, 
                 GL_LUMINANCE, 
                 texW / 2, 
                 texH / 2, 
                 0, 
                 GL_LUMINANCE,
                 GL_UNSIGNED_BYTE,
                 NULL);

    //: Y Texture
    if (sampler0Texture) glDeleteTextures(1, &sampler0Texture);

    glActiveTexture(GL_TEXTURE0);
    glGenTextures(1, &sampler0Texture);
    glBindTexture(GL_TEXTURE_2D, sampler0Texture);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    //This is necessary for non-power-of-two textures
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glEnable(GL_TEXTURE_2D);

    glTexImage2D(GL_TEXTURE_2D, 
                 0, 
                 GL_LUMINANCE, 
                 texW, 
                 texH, 
                 0, 
                 GL_LUMINANCE,
                 GL_UNSIGNED_BYTE, 
                 NULL);

Rendering-Teil ist unten.

int _idxU = mFrameW * mFrameH;
int _idxV = _idxU + (_idxU / 4);

//U data
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, sampler1Texture);
glUniform1i(sampler1Uniform, 1);

glTexSubImage2D(
                GL_TEXTURE_2D, 
                0, 
                0, 
                0, 
                mFrameW / 2,            //source width
                mFrameH / 2,            //source height
                GL_LUMINANCE,
                GL_UNSIGNED_BYTE, 
                &_frameData[_idxU]);

//V data
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, sampler2Texture);
glUniform1i(sampler2Texture, 2);

glTexSubImage2D(
                GL_TEXTURE_2D, 
                0, 
                0, 
                0, 
                mFrameW / 2,            //source width
                mFrameH / 2,            //source height
                GL_LUMINANCE,
                GL_UNSIGNED_BYTE,
                &_frameData[_idxV]);

//Y data
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, sampler0Texture);
glUniform1i(sampler0Uniform, 0);

glTexSubImage2D(
                GL_TEXTURE_2D, 
                0, 
                0, 
                0, 
                mFrameW,            //source width
                mFrameH,            //source height
                GL_LUMINANCE,
                GL_UNSIGNED_BYTE,
                _frameData);

Vertex-Shader & Fragment Shader ist unten.

attribute vec4 Position;
attribute vec2 TexCoordIn;

varying vec2 TexCoordOut;
varying vec2 TexCoordOut_UV;

uniform mat4 Projection;
uniform mat4 Modelview;

void main()
{
    gl_Position = Projection * Modelview * Position;
    TexCoordOut = TexCoordIn;
}



uniform sampler2D sampler0; //Y Texture Sampler
uniform sampler2D sampler1; //U Texture Sampler
uniform sampler2D sampler2; //V Texture Sampler

varying highp vec2 TexCoordOut;

void main()
{
    highp float y = texture2D(sampler0, TexCoordOut).r;
    highp float u = texture2D(sampler2, TexCoordOut).r - 0.5;
    highp float v = texture2D(sampler1, TexCoordOut).r - 0.5;

    //y = 0.0;
    //u = 0.0;
    //v = 0.0;

    highp float r = y + 1.13983 * v;
    highp float g = y - 0.39465 * u - 0.58060 * v;
    highp float b = y + 2.03211 * u;

    gl_FragColor = vec4(r, g, b, 1.0);
}

Y-Textur (Graustufen) ist korrekt, aber U & V hat viel von der Grünen Farbe.
So Finale RGB-Bild (Y+U+V) hat eine Menge von GRÜNER Farbe.
Was ist das problem?

Bitte helfen.
danke.

  • Was meinst du - "u & v eine Menge der grünen Farbe"? U und V nicht die Farbe. Sie sind U und V. Grüne Farbe im letzten Bild kommt von Ihrem "float g" - Berechnung. Haben Sie überprüft, Formeln in der CPU? Versuchen Sie die Konvertierung Ihrer YUV-Daten in RGB um, um zu sehen, wenn die Formel korrekt ist. Auch - warum Lesen Sie schweben u von sampler2, aber v von sampler1 ? Kommentare nach sampler definition sagt sampler1 ist u und sampler2 ist v.
  • Ich weiß, dass U & V hat nicht die Farbe grün. aber wenn ich Tat, dass y = 0.0; & v = 0.0; dann Ausgang Bildschirm hat eine Menge von grüner Farbe. und ich habe Fehler, den Sie sagte. sampler1 ist u, sampler2 ist v. aber das Ergebnis ist dasselbe. hmm. Ich habe versucht, zu konvertieren YUV zu RGB über sws_scale in ffmpeg-Funktion. Ergebnis ist gut.aber das problem ist die Geschwindigkeit(oder die Leistung).
  • Hallo, hast du eine Lösung für das problem? Ich versuche zu tun, die genau die gleiche Sache, aber mit kein Glück...
InformationsquelleAutor | 2012-06-23
Schreibe einen Kommentar