Domanda

Sto cercando di realizzare alcune ottimizzazioni in un lettore video privato per Linux che mira a migliorare le prestazioni perché Suonare i file MP4 sono pesanti sulla CPU, dal I frame video sono codificati in YV12 E OpenGL non fornisce un modo nativo per visualizzare questo formato. In questo momento c'è un codice che funziona sulla CPU per convertire YV12 in RGB prima che l'immagine venga inviata alla GPU per la visualizzazione e questo consuma il 100% dell'elaborazione della CPU.

Sto attualmente indagando Come decodificare i frame Yv12 senza dover scrivere uno shader Per fare la conversione Yv12 -> RGB. Per quanto ne capisco, un modo per farlo è attraverso il GL_MESA_YCBCR_TEXTURE, apparentemente supportato dal mio sistema (riportato da glxinfo).

In questa scatola Fedora ho un Dispositivo video ATI Technologies Inc RV610 [Radeon HD 2400 Pro, che è una scheda video decente. Quindi, ho scaricato il yuvrect testare e apportare alcune modifiche per la sostituzione GL_TEXTURE_RECTANGLE_NV Per una trama supportata da questa carta: GL_TEXTURE_RECTANGLE_ARB.

Tuttavia, quando eseguo questa applicazione modificata emette:

The MESA driver reports *unsupported texture format in setup_hardware_state*

Ho notato che questo errore viene visualizzato quando glPopMatrix(); viene eseguito da Display() richiama. Adesso, Questo non sembra un bug nella mia applicazione Perché ho eseguito lo stesso codice esatto su un'altra scatola Fedora (stesso sistema) che ha una scheda video diversa: Intel Corporation Sandy Bridge Integrated Graphics Controller (Rev 09) , e funziona in modo grave.

L'unica differenza visibile tra i 2 binari sono le librerie con cui sono collegate. Sulla (problematica) scheda ATI LDD rapporti:

linux-gate.so.1 =>  (0x00da3000)
libGL.so.1 => /usr/lib/libGL.so.1 (0x077bd000)
libGLU.so.1 => /usr/lib/libGLU.so.1 (0x0783b000)
libglut.so.3 => /usr/lib/libglut.so.3 (0x005a9000)
libGLEW.so.1.5 => /usr/lib/libGLEW.so.1.5 (0x00aa3000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x057e2000)
libm.so.6 => /lib/libm.so.6 (0x004e4000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x0053f000)
libc.so.6 => /lib/libc.so.6 (0x00358000)
libX11.so.6 => /usr/lib/libX11.so.6 (0x0071b000)
libXext.so.6 => /usr/lib/libXext.so.6 (0x009c5000)
libXdamage.so.1 => /usr/lib/libXdamage.so.1 (0x00af7000)
libXfixes.so.3 => /usr/lib/libXfixes.so.3 (0x00b76000)
libXxf86vm.so.1 => /usr/lib/libXxf86vm.so.1 (0x0014e000)
libdrm.so.2 => /usr/lib/libdrm.so.2 (0x00101000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00510000)
libdl.so.2 => /lib/libdl.so.2 (0x0052d000)
libXi.so.6 => /usr/lib/libXi.so.6 (0x00110000)
/lib/ld-linux.so.2 (0x00337000)
libxcb.so.1 => /usr/lib/libxcb.so.1 (0x00859000)
librt.so.1 => /lib/librt.so.1 (0x00534000)
libXau.so.6 => /usr/lib/libXau.so.6 (0x00854000)

Nel frattempo, sulla scheda Intel puoi vedere che si è collegato a libv4l e ad alcune altre librerie mentre l'ATI non l'ha fatto! Mi chiedo se questo abbia qualcosa a che fare con il problema che sto affrontando:

linux-gate.so.1 =>  (0x008d6000)
/usr/lib/libv4l/v4l1compat.so (0x00345000)
libGL.so.1 => /usr/lib/libGL.so.1 (0x4fb85000)
libGLU.so.1 => /usr/lib/libGLU.so.1 (0x4fc10000)
libglut.so.3 => /usr/lib/libglut.so.3 (0x005a9000)
libGLEW.so.1.5 => /usr/lib/libGLEW.so.1.5 (0x4fc82000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x42ca7000)
libm.so.6 => /lib/libm.so.6 (0x41fbc000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x42017000)
libc.so.6 => /lib/libc.so.6 (0x41e30000)
libv4l1.so.0 => /usr/lib/libv4l1.so.0 (0x00110000)
libX11.so.6 => /usr/lib/libX11.so.6 (0x421f8000)
libXext.so.6 => /usr/lib/libXext.so.6 (0x424c0000)
libXdamage.so.1 => /usr/lib/libXdamage.so.1 (0x42c0e000)
libXfixes.so.3 => /usr/lib/libXfixes.so.3 (0x42d98000)
libXxf86vm.so.1 => /usr/lib/libXxf86vm.so.1 (0x432a2000)
libdrm.so.2 => /usr/lib/libdrm.so.2 (0x4247b000)
libpthread.so.0 => /lib/libpthread.so.0 (0x41fe8000)
libdl.so.2 => /lib/libdl.so.2 (0x42005000)
libXi.so.6 => /usr/lib/libXi.so.6 (0x42748000)
/lib/ld-linux.so.2 (0x41e0f000)
libv4l2.so.0 => /usr/lib/libv4l2.so.0 (0x4217c000)
libxcb.so.1 => /usr/lib/libxcb.so.1 (0x42337000)
librt.so.1 => /lib/librt.so.1 (0x4200c000)
libv4lconvert.so.0 => /usr/lib/libv4lconvert.so.0 (0x42357000)
libXau.so.6 => /usr/lib/libXau.so.6 (0x421f3000)
libjpeg.so.62 => /usr/lib/libjpeg.so.62 (0x43317000)

Se vuoi eseguire l'esempio di seguito avrai bisogno readtex.c , readtex.h e girl.rgb, e compilalo con: g++ yuvrect.cpp -o yuvrect -lGL -lGLU -lglut -lGLEW

#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <GL/glew.h>
#include <GL/glut.h>

#include "readtex.c"   /* I know, this is a hack. */

#define TEXTURE_FILE "girl.rgb"

static GLfloat Xrot = 0, Yrot = 0, Zrot = 0;
static GLint ImgWidth, ImgHeight;
static GLushort *ImageYUV = NULL;


static void DrawObject(void)
{
   glBegin(GL_QUADS);

   glTexCoord2f(0, 0);
   glVertex2f(-1.0, -1.0);

   glTexCoord2f(ImgWidth, 0);
   glVertex2f(1.0, -1.0);

   glTexCoord2f(ImgWidth, ImgHeight);
   glVertex2f(1.0, 1.0);

   glTexCoord2f(0, ImgHeight);
   glVertex2f(-1.0, 1.0);

   glEnd();
}


static void Display( void )
{
   glClear( GL_COLOR_BUFFER_BIT );

   glPushMatrix();
      glRotatef(Xrot, 1.0, 0.0, 0.0);
      glRotatef(Yrot, 0.0, 1.0, 0.0);
      glRotatef(Zrot, 0.0, 0.0, 1.0);
      DrawObject();
   glPopMatrix(); // <--- error message comes from this call

   glutSwapBuffers();
}


static void Reshape( int width, int height )
{
   glViewport( 0, 0, width, height );
   glMatrixMode( GL_PROJECTION );
   glLoadIdentity();
   glFrustum( -1.0, 1.0, -1.0, 1.0, 10.0, 100.0 );
   glMatrixMode( GL_MODELVIEW );
   glLoadIdentity();
   glTranslatef( 0.0, 0.0, -15.0 );
}


static void Key( unsigned char key, int x, int y )
{
   (void) x;
   (void) y;
   switch (key) {
      case 27:
         exit(0);
         break;
   }
   glutPostRedisplay();
}


static void SpecialKey( int key, int x, int y )
{
   float step = 3.0;
   (void) x;
   (void) y;

   switch (key) {
      case GLUT_KEY_UP:
         Xrot += step;
         break;
      case GLUT_KEY_DOWN:
         Xrot -= step;
         break;
      case GLUT_KEY_LEFT:
         Yrot += step;
         break;
      case GLUT_KEY_RIGHT:
         Yrot -= step;
         break;
   }
   glutPostRedisplay();
}        

static void Init( int argc, char *argv[] )
{
   GLuint texObj = 100;
   const char *file;

   printf("Checking GL_ARB_texture_rectangle\n");
   if (!glutExtensionSupported("GL_ARB_texture_rectangle")) {
      printf("Sorry, GL_NV_texture_rectangle is required\n");
      exit(0);
   }

   printf("Checking GL_MESA_ycbcr_texture\n");
   if (!glutExtensionSupported("GL_MESA_ycbcr_texture")) {
      printf("Sorry, GL_MESA_ycbcr_texture is required\n");
      exit(0);
   }

   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

   glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texObj);
#ifdef LINEAR_FILTER
   /* linear filtering looks much nicer but is much slower for Mesa */
   glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
#else
   glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
#endif

   if (argc > 1)
      file = argv[1];
   else
      file = TEXTURE_FILE;

   ImageYUV = LoadYUVImage(file, &ImgWidth, &ImgHeight);
   if (!ImageYUV) {
      printf("Couldn't read %s\n", TEXTURE_FILE);
      exit(0);
   }

   printf("Image: %dx%d\n", ImgWidth, ImgHeight);

   printf("Calling glTexImage2D\n");
   glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0,
                GL_YCBCR_MESA, ImgWidth, ImgHeight, 0,
                GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, ImageYUV);
   printf("Called glTexImage2D\n");
   assert(glGetError() == GL_NO_ERROR);
   printf("* Assert #1\n");

   glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0,
                   0, 0, ImgWidth, ImgHeight,
                   GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, ImageYUV);

   assert(glGetError() == GL_NO_ERROR);
   printf("* Assert #2\n");

   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

   glEnable(GL_TEXTURE_RECTANGLE_ARB);

   glShadeModel(GL_FLAT);
   glClearColor(0.3, 0.3, 0.4, 1.0);

   if (argc > 1 && strcmp(argv[1], "-info")==0) {
      printf("GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER));
      printf("GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
      printf("GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
      printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
   }
}


int main( int argc, char *argv[] )
{
   glutInit( &argc, argv );
   glutInitWindowSize( 300, 300 );
   glutInitWindowPosition( 0, 0 );
   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
   glutCreateWindow(argv[0] );
   glewInit();

   Init( argc, argv );

   glutReshapeFunc( Reshape );
   glutKeyboardFunc( Key );
   glutSpecialFunc( SpecialKey );
   glutDisplayFunc( Display );

   glutMainLoop();
   return 0;
}

Qualche consiglio per risolvere questo problema, ragazzi?

Nessuna soluzione corretta

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top