2012-05-12 2 views
0

В настоящее время я разрабатываю видеоплеер с использованием FFMPEG. Я пытаюсь преобразовать YUV420P в RGB Shader, чтобы уменьшить удар производительности, и я мог видеть, что он работает нормально. Проблема возникает, когда я пытаюсь изменить размер изображения.YUV to RGB Shader на iPhone

Корпус 1. YUV to RGB идеально подходит. но изображение точно не соответствует рамкам текстуры. Например, если я воспроизвожу видео 640x360, часть справа (640-512) обрезается, а нижняя (512-360) заполняется прямоугольником зеленого цвета.

FRAME_X=512; //This is texture size 
FRAME_Y=512; 

    avpicture_fill((AVPicture *) f, [currentVideoBuffer.data mutableBytes], 
       enc->pix_fmt, 
       FRAME_X, FRAME_Y); 

    av_picture_copy((AVPicture *) f, (AVPicture *) avFrame, 
       enc->pix_fmt, 
       enc->width, enc->height); 

....

int yuvWidth= FRAME_X ; 
int yuvHeight= FRAME_Y; 
glBindTexture (GL_TEXTURE_2D, textureIdY); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 
yuvWidth, yuvHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, y_channel); 


glBindTexture (GL_TEXTURE_2D, textureIdU); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 
yuvWidth/2, yuvHeight/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, u_channel); 

glBindTexture (GL_TEXTURE_2D, textureIdV); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 
yuvWidth/2, yuvHeight/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, v_channel); 

Случай 2. Если я установить фактический размер изображения до размера текстуры, то изображение точно приспособленное к текстуре, но цвет изображения немного странно. Он имеет слишком много зеленого цвета.

Кто-нибудь дает мне некоторые подсказки для этого? Спасибо заранее.

ответ

3

Во-первых, вам нужно установить надлежащий режим обертывания для не-власти двух текстур.

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 

затем попытайтесь установить режим фильтрации для GL_LINEAR

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 

и шейдеры.

  1. вершинный шейдер

    attribute vec4 position; 
    attribute vec2 texcoord; 
    uniform mat4 modelViewProjectionMatrix; 
    varying vec2 v_texcoord; 
    
    void main() 
    { 
        gl_Position = modelViewProjectionMatrix * position; 
        v_texcoord = texcoord.xy; 
    } 
    
  2. набор вершин

    vertices[0] = -1.0f; // x0 
    vertices[1] = -1.0f; // y0 
    vertices[2] = 1.0f; // .. 
    vertices[3] = -1.0f; 
    vertices[4] = -1.0f; 
    vertices[5] = 1.0f; 
    vertices[6] = 1.0f; // x3 
    vertices[7] = 1.0f; // y3 
    
  3. нагрузки правильная матрица viewProj для 2d изображений (спрайтов), лучше использовать орто-проекции.

    GLfloat modelviewProj[16]; 
    mat4f_LoadOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, modelviewProj); 
    glUniformMatrix4fv(_uniformMatrix, 1, GL_FALSE, modelviewProj); 
    
  4. дальше, убедитесь, что вы используете правильную текст коорд, как этот

    GLfloat texCoords[] = { 
        0.0f, 1.0f, 
        1.0f, 1.0f, 
        0.0f, 0.0f, 
        1.0f, 0.0f, 
    }; 
    
  5. наконец, фрагмент шейдера, как это:

    varying highp vec2 v_texcoord; 
    uniform sampler2D s_texture_y; 
    uniform sampler2D s_texture_u; 
    uniform sampler2D s_texture_v; 
    
    void main() 
    { 
        highp float y = texture2D(s_texture_y, v_texcoord).r; 
        highp float u = texture2D(s_texture_u, v_texcoord).r - 0.5; 
        highp float v = texture2D(s_texture_v, v_texcoord).r - 0.5; 
        highp float r = y +    1.402 * v; 
        highp float g = y - 0.344 * u - 0.714 * v; 
        highp float b = y + 1.772 * u;  
        gl_FragColor = vec4(r,g,b,1.0); 
    } 
    

Вы можете посмотреть на мой код в качестве примера использования FFmpeg и OpenGLES на iOS: https://github.com/kolyvan/kxmovie.

+0

О, еще слишком поздно сказать спасибо. Я видел ваш ответ прямо перед этим. Спасибо. – user1333656

Смежные вопросы