2013-06-14 9 views
7

को YUV कन्वर्ट करने के लिए मैं सिर्फ एक नमूना है जो YUV डेटा होता है के साथ OpenGL ES शेडर में आरजीबी के लिए YUV परिवर्तित करना चाहते हैं। मेरे कोड के नीचे है:OpenGL का उपयोग तों शेडर आरजीबी

GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE, 
      mData.w, mData.h * 3/2, 0, GLES20.GL_LUMINANCE, 
      GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(mData.yuv)); 

2) मेरे शिखर शेडर:

attribute vec4 position; 
attribute vec2 inputTextureCoordinate; 
attribute mediump float width; 

varying vec2 v_texCoord; 
varying mediump vec2 v_vuTexCoord; 
varying mediump float x_coord; 

void main() 
{ 
    gl_Position = position; 
    v_texCoord = vec2(inputTextureCoordinate.x, inputTextureCoordinate.y * 0.6666667); 
    v_vuTexCoord = vec2(inputTextureCoordinate.x, inputTextureCoordinate.y * 0.333333 + 0.6666667); 
    x_coord = floor(inputTextureCoordinate.x * width); 
} 

3) मेरे टुकड़ा शेडर:

uniform sampler2D inputImageTexture; 
varying mediump vec2 v_texCoord; 
varying mediump vec2 v_vuTexCoord; 
varying mediump float x_coord; 
uniform mediump float u_one_over_tex_size; 

void main() 
{ 
    mediump vec3 yuv; 
    mediump vec3 rgb; 
    mediump float valx = mod(x_coord , 2.0); 
    if(valx < 1.0) 
    { 
     yuv.y = texture2D(inputImageTexture, v_vuTexCoord + vec2(u_one_over_tex_size, 0)).r - 0.5; 
     yuv.z = texture2D(inputImageTexture, v_vuTexCoord).r - 0.5; 
    } 
    else { 
     yuv.y = texture2D(inputImageTexture, v_vuTexCoord).r - 0.5; 
     yuv.z = texture2D(inputImageTexture, v_vuTexCoord + vec2(u_one_over_tex_size, 0)).r - 0.5; 
    } 
    yuv.x = texture2D(inputImageTexture, v_texCoord).r; 
    rgb = mat3( 1,  1,  1, 
        0, -.34413, 1.772, 
       1.402, -.71414,  0) * yuv; 
    gl_FragColor = vec4(rgb, 1); 
} 

1) मैं बनावट को YUV डेटा भेजने

लेकिन परिणाम ऐसा नहीं है जैसा मैंने सोचा था। यदि मैं yuv डेटा को y और uv नमूने में विभाजित करता हूं और वर्टेक्स और खंड शेडर बदलता हूं, और मेरे पास सही परिणाम हो सकता है। लेकिन यह कैसे मैं केवल एक नमूना सिर्फ
ऊपर की तरह भेज सकता है?

+0

मुझे इस वेबसाइट में कुछ रोचक जानकारी मिली है https://code.google.com/p/o3d/source/browse/trunk/samples_webgl/shaders/yuv2rgb-glsl.shader?r=219 –

उत्तर

4

कोड यहाँ पर एक नज़र डालें: http://www.fourcc.org/source/YUV420P-OpenGL-GLSLang.c

/* 
* Very simple example of how to perform YUV->RGB (YCrCb->RGB) 
* conversion with an OpenGL fragmen shader. The data (not included) 
* is presumed to be three files with Y, U and V samples for a 720x576 
* pixels large image. 
* 
* Note! The example uses NVidia extensions for rectangular textures 
* to make it simpler to read (non-normalised coordinates). 
* Rewriting it without the extensions is quite simple, but left as an 
* exercise to the reader. (The trick is that the shader must know the 
* image dimensions instead) 
* 
* The program also does not check to see if the shader extensions are 
* available - this is after all just a simple example. 
* 
* This code is released under a BSD style license. Do what you want, but 
* do not blame me. 
* 
* Peter Bengtsson, Dec 2004. 
*/ 

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <GL/gl.h> 
#include <GL/glext.h> 
#include <SDL/SDL.h> 

int Quit=0; 

static int B_WIDTH=640; 
static int B_HEIGHT=480; 

int main(int cnt,char *arg[]) 
{ 
SDL_Surface *Win=NULL; 
GLubyte *Ytex,*Utex,*Vtex; 
SDL_Event evt; 
int i; 
GLhandleARB FSHandle,PHandle; 
char *s; 
FILE *fp; 

char *FProgram= 
    "uniform sampler2DRect Ytex;\n" 
    "uniform sampler2DRect Utex,Vtex;\n" 
    "void main(void) {\n" 
    " float nx,ny,r,g,b,y,u,v;\n" 
    " vec4 txl,ux,vx;" 
    " nx=gl_TexCoord[0].x;\n" 
    " ny=576.0-gl_TexCoord[0].y;\n" 
    " y=texture2DRect(Ytex,vec2(nx,ny)).r;\n" 
    " u=texture2DRect(Utex,vec2(nx/2.0,ny/2.0)).r;\n" 
    " v=texture2DRect(Vtex,vec2(nx/2.0,ny/2.0)).r;\n" 

    " y=1.1643*(y-0.0625);\n" 
    " u=u-0.5;\n" 
    " v=v-0.5;\n" 

    " r=y+1.5958*v;\n" 
    " g=y-0.39173*u-0.81290*v;\n" 
    " b=y+2.017*u;\n" 

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


if(!SDL_Init(SDL_INIT_VIDEO)) { 

    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1); 

    Win=SDL_SetVideoMode(B_WIDTH,B_HEIGHT,32,SDL_HWSURFACE|SDL_ANYFORMAT|SDL_OPENGL); 

    if(Win) { 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glOrtho(0,B_WIDTH,0,B_HEIGHT,-1,1); 
    glViewport(0,0,B_WIDTH,B_HEIGHT); 
    glClearColor(0,0,0,0); 
    glColor3f(1.0,0.84,0.0); 
    glHint(GL_POLYGON_SMOOTH_HINT,GL_NICEST); 

    /* Set up program objects. */ 
    PHandle=glCreateProgramObjectARB(); 
    FSHandle=glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB); 

    /* Compile the shader. */ 
    glShaderSourceARB(FSHandle,1,&FProgram,NULL); 
    glCompileShaderARB(FSHandle); 

    /* Print the compilation log. */ 
    glGetObjectParameterivARB(FSHandle,GL_OBJECT_COMPILE_STATUS_ARB,&i); 
    s=malloc(32768); 
    glGetInfoLogARB(FSHandle,32768,NULL,s); 
    printf("Compile Log: %s\n", s); 
    free(s); 

    /* Create a complete program object. */ 
    glAttachObjectARB(PHandle,FSHandle); 
    glLinkProgramARB(PHandle); 

    /* And print the link log. */ 
    s=malloc(32768); 
    glGetInfoLogARB(PHandle,32768,NULL,s); 
    printf("Link Log: %s\n", s); 
    free(s); 

    /* Finally, use the program. */ 
    glUseProgramObjectARB(PHandle); 

    /* Load the textures. */ 
    Ytex=malloc(414720); 
    Utex=malloc(103680); 
    Vtex=malloc(103680); 

    fp=fopen("Image.Y","rb"); 
    fread(Ytex,414720,1,fp); 
    fclose(fp); 
    fp=fopen("Image.U","rb"); 
    fread(Utex,103680,1,fp); 
    fclose(fp); 
    fp=fopen("Image.V","rb"); 
    fread(Vtex,103680,1,fp); 
    fclose(fp); 

    /* This might not be required, but should not hurt. */ 
    glEnable(GL_TEXTURE_2D); 

    /* Select texture unit 1 as the active unit and bind the U texture. */ 
    glActiveTexture(GL_TEXTURE1); 
    i=glGetUniformLocationARB(PHandle,"Utex"); 
    glUniform1iARB(i,1); /* Bind Utex to texture unit 1 */ 
    glBindTexture(GL_TEXTURE_RECTANGLE_NV,1); 

    glTexParameteri(GL_TEXTURE_RECTANGLE_NV,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_RECTANGLE_NV,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
    glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL); 
    glTexImage2D(GL_TEXTURE_RECTANGLE_NV,0,GL_LUMINANCE,376,288,0,GL_LUMINANCE,GL_UNSIGNED_BYTE,Utex); 

    /* Select texture unit 2 as the active unit and bind the V texture. */ 
    glActiveTexture(GL_TEXTURE2); 
    i=glGetUniformLocationARB(PHandle,"Vtex"); 
    glBindTexture(GL_TEXTURE_RECTANGLE_NV,2); 
    glUniform1iARB(i,2); /* Bind Vtext to texture unit 2 */ 

    glTexParameteri(GL_TEXTURE_RECTANGLE_NV,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_RECTANGLE_NV,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
    glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL); 
    glTexImage2D(GL_TEXTURE_RECTANGLE_NV,0,GL_LUMINANCE,376,288,0,GL_LUMINANCE,GL_UNSIGNED_BYTE,Vtex); 

    /* Select texture unit 0 as the active unit and bind the Y texture. */ 
    glActiveTexture(GL_TEXTURE0); 
    i=glGetUniformLocationARB(PHandle,"Ytex"); 
    glUniform1iARB(i,0); /* Bind Ytex to texture unit 0 */ 
    glBindTexture(GL_TEXTURE_RECTANGLE_NV,3); 

    glTexParameteri(GL_TEXTURE_RECTANGLE_NV,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_RECTANGLE_NV,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
    glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL); 
    glTexImage2D(GL_TEXTURE_RECTANGLE_NV,0,GL_LUMINANCE,752,576,0,GL_LUMINANCE,GL_UNSIGNED_BYTE,Ytex); 

    /* Simple loop, just draws the image and waits for quit. */ 
    while(!Quit) { 
     if(SDL_PollEvent(&evt)) { 
     switch(evt.type) { 
     case SDL_KEYDOWN: 
     case SDL_QUIT: 
      Quit=1; 
     break; 
     } 
     } 

     glClear(GL_COLOR_BUFFER_BIT); 

     /* Draw image (again and again). */ 

     glBegin(GL_QUADS); 
     glTexCoord2i(0,0); 
     glVertex2i(0,0); 
     glTexCoord2i(720,0); 
     glVertex2i(B_WIDTH,0); 
     glTexCoord2i(720,576); 
     glVertex2i(B_WIDTH,B_HEIGHT); 
     glTexCoord2i(0,576); 
     glVertex2i(0,B_HEIGHT); 
     glEnd(); 

     /* Flip buffers. */ 

     glFlush(); 
     SDL_GL_SwapBuffers(); 

     sleep(1); 
    } /* while(!Quit) */ 

    /* Clean up before exit. */ 

    glUseProgramObjectARB(0); 
    glDeleteObjectARB(sprog); 

    free(Ytex); 
    free(Utex); 
    free(Vtex); 

    } else { 
    fprintf(stderr,"Unable to create primary surface. \"%s\".\n",SDL_GetError()); 
    } 
    SDL_Quit(); 
} else { 
    fprintf(stderr,"Initialisation failed. \"%s\".\n",SDL_GetError()); 
} 

return(0); 
} 
+1

यह अभी भी ऐसा लगता है वाई और यूवी विमानों को विभाजित करना और उन्हें अलग-अलग बनावट के रूप में सबमिट करना, जो पूछताछ करने वाले पहले से ही काम कर रहे हैं। वे आरजीबी में कनवर्ट करने के लिए एक एकल यूयूवी फ्रेम और पार्स लेने का तरीका ढूंढने की कोशिश कर रहे हैं। –

+0

तो यह करता है। मेरा बुरा, मैं हटा दूंगा। –

0

हो सकता है कि बाहर के विषयों है, लेकिन here मैं एक YUV 4 लागू किया: 2: 2 V210 10 बिट विकोडक GLSL में।