12
votes

Afficher yuv dans OpenGL

Je vais avoir du mal à afficher un fichier vidéo YUV qu'il est au format NV12.

Je peux afficher une image sélectionnée, cependant, il est encore principalement en noir et blanc avec certaines nuances de rose et vert. P >

Voici comment mon apparence de sortie comme text alt p>

Enfin bref, voici comment mes travaux de programme. (Cela se fait dans le cacao / Objective-C, mais j'ai besoin de vos conseils d'experts sur l'algorithme de programme, et non pas sur la syntaxe.) P>

Avant l'exécution du programme, le fichier YUV est stocké dans un fichier binaire nommé « test .yuv ». Le fichier est au format NV12, ce qui signifie le plan Y est stocké en premier, puis le plan UV est entrelacée. Mon extraction de fichiers n'a pas de problème parce que je fait beaucoup testings dessus. P>

Au cours de l'initiation, je crée une table de recherche qui vous permet de convertir binaire / 8 piqûres / un octet / caractères en Y respecté, U, flotteur V valeurs p>

Pour le plan Y ceci est mon code p>

        float Y = (float) yBuffer [y*YUV_WIDTH + x] ;
        float U = (float) uvBuffer [ ((y / 2) * (YUV_WIDTH  / 2) + (x/2))   ] ; 
        float V = (float) uvBuffer [  ((y / 2) * (YUV_WIDTH  / 2) + (x/2))  + UOffset] ;

        float RFormula = (1.164*(Y-16) + (1.596* (V - 128) ));
        float GFormula = ((1.164 * (Y - 16)) - (0.813 * ((V) - 128)) - (0.391 * ((U) - 128)));
        float BFormula = ((1.164 * (Y - 16)) + (2.018 * ((U) - 128)));


        frameImage [frameImageCounter] = (unsigned char)( (int)[self clampValue:RFormula]);
        frameImageCounter ++;
        frameImage [frameImageCounter] =  (unsigned char)((int)[self clampValue:GFormula]);
        frameImageCounter++;
        frameImage [frameImageCounter] = (unsigned char)((int) [self clampValue:BFormula]);
        frameImageCounter++;



GLuint texture;

glGenTextures(1, &texture);
glEnable(GL_TEXTURE_2D);

glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, YUV_WIDTH, YUV_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, frameImage);

//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE_SGIS);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE_SGIS);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);

glRotatef( 180.0f, 1.0f, 0.0f, 0.0f );

glBegin( GL_QUADS );
glTexCoord2d(0.0,0.0); glVertex2d(-1.0,-1.0);
glTexCoord2d(1.0,0.0); glVertex2d(+1.0,-1.0);
glTexCoord2d(1.0,1.0); glVertex2d(+1.0,+1.0);
glTexCoord2d(0.0,1.0); glVertex2d(-1.0,+1.0);
glEnd();

NSLog(@"YUVFrameView: drawRect complete");
glFlush();


1 commentaires

Bonjour, est-il possible de partager un code exemplaire complet?


3 Réponses :


3
votes

Je pense que vous avez mal adressé les valeurs U et V. Plutôt que:

float U = lookupTableU [uvBuffer [ ((y / 2) * (YUV_WIDTH / 2) + (x/2)) * 2  ] ]; 
float V = lookupTableV [uvBuffer [  ((y / 2) * (YUV_WIDTH / 2) + (x/2)) * 2 + 1] ];


1 commentaires

Merci, j'ai raté cette erreur. Cependant, j'ai fait les modifications et le cadre affiché est toujours principalement en noir et blanc, avec des nuances roses et vertes ici et là.



0
votes

La photo semble être au format 4: 1: 1. Vous devriez changer vos lignes en xxx

peut-être que vous pouvez poster le résultat pour voir, quoi d'autre est faux. Je trouve qu'il est toujours difficile d'y penser. Il est beaucoup plus facile d'aborder cela itérativement.


0 commentaires

8
votes

Suivant essayer :) Je pense que votre tampon UV n'est pas entrelacé. On dirait que les valeurs U viennent d'abord, puis le tableau des valeurs V. Changer les lignes vers

unsigned int voffset = YUV_HEIGHT * YUV_WIDTH / 2;
float U = lookupTableU [uvBuffer [ y * (YUV_WIDTH / 2) + x/2] ]; 
float V = lookupTableV [uvBuffer [ voffset + y * (YUV_WIDTH / 2) + x/2] ];


3 commentaires

Wow, j'ai testé mon programme avec votre ajustement et cela a finalement travaillé. Merci beaucoup d'homme.Il s'avère que vous aviez raison, l'avion U & V n'est pas entrelacé car j'étais initialement raconté. Merci beaucoup Nschmidt. Je vous évalue


aucun problème :). Pour l'enregistrement, la première supposition sur le format étant 4: 1: 1 était en fait incorrecte. Vous avez le format 4: 2: 2. Le vrai problème était que vos données ne sont pas entrelées.


@ReachConnection: Pouvez-vous me dire ce que [auto ClampValue: la télécommande] Cette fonction fait? Je prévois d'utiliser votre code pour obtenir uiimage de yuv422.