2011-12-09 11 views
9

Sto scrivendo framework per media player per Apple TV, utilizzando OpenGL ES e ffmpeg. La conversione in RGBA è richiesta per il rendering su OpenGL ES, la conversione soft tramite swscale è insopportabilmente lenta, quindi utilizzando le informazioni su Internet mi sono venute in mente due idee: usare il neon (come here) o usare fragment shaders e GL_LUMINANCE e GL_LUMINANCE_ALPHA.Da YUV a RGBA su Apple A4, dovrei usare shader o NEON?

Per quanto ne so quasi nulla di OpenGL, la seconda opzione non funziona ancora :)

potete darmi tutti i puntatori come procedere? Grazie in anticipo.

risposta

19

È sicuramente valide apprendimento OpenGL shaders ES2.0:

  1. È possibile bilanciare il carico tra la GPU e CPU (ad esempio decodifica video di fotogrammi successivi mentre GPU rende il frame corrente).
  2. I frame video devono comunque andare alla GPU: utilizzando YCbCr si risparmia il 25% di larghezza di banda del bus se il video ha una crominanza 4: 2: 0 campionata.
  3. Ottieni il campionamento in crominanza 4: 2: 0 gratuitamente, con l'interpolatore hardware GPU. (Lo shader deve essere configurato per utilizzare le coordinate stesso vertice sia Y e C{b,r} texture, in effetti si estende la trama crominanza affaccia sulla stessa area.)
  4. In iOS5 spingendo YCbCr texture per GPU é veloce (senza data-copy o swizzling) con la cache delle texture (vedere le funzioni API). Risparmierai a 1-2 copie di dati rispetto a NEON.

Sto usando queste tecniche con grande effetto in my super-fast iPhone camera app, SnappyCam.

Sei sulla strada giusta per l'attuazione: usare un GL_LUMINANCE texture per Y e GL_LUMINANCE_ALPHA se il vostro CbCr è interlacciata. In caso contrario, utilizzare tre trame GL_LUMINANCE se tutti i componenti di YCbCr non sono interlacciati.

Creazione di due texture per 4: 2: 0 bi-planare YCbCr (dove CbCr è interlacciata) è semplice:

glBindTexture(GL_TEXTURE_2D, texture_y); 
    glTexImage2D(
     GL_TEXTURE_2D, 
     0, 
     GL_LUMINANCE,  // Texture format (8bit) 
     width, 
     height, 
     0,     // No border 
     GL_LUMINANCE,  // Source format (8bit) 
     GL_UNSIGNED_BYTE, // Source data format 
     NULL 
    ); 
    glBindTexture(GL_TEXTURE_2D, texture_cbcr); 
    glTexImage2D(
     GL_TEXTURE_2D, 
     0, 
     GL_LUMINANCE_ALPHA, // Texture format (16-bit) 
     width/2, 
     height/2, 
     0,     // No border 
     GL_LUMINANCE_ALPHA, // Source format (16-bits) 
     GL_UNSIGNED_BYTE, // Source data format 
     NULL 
    ); 

dove si sarebbe quindi utilizzare glTexSubImage2D() o la cache tessitura iOS5 per aggiornare queste texture.

Si consiglia inoltre di utilizzare uno varying 2D che copre lo spazio delle coordinate di trama (x: [0,1], y: [0,1]) in modo da evitare letture di texture dipendenti nello shader di frammenti. Il risultato finale è super veloce e non carica affatto la GPU nella mia esperienza.

+0

Grazie mille, stavo davvero facendo tutto quello che hai descritto, ma non sapevo nulla delle nuove funzionalità in iOS 5. Proviamo. – pawlowski

+0

Grazie per la risposta. Dove posso ottenere ulteriori informazioni sul formato dei pixel di decodifica nativo su iOS (in risposta al tuo pt n. 2)? – fionbio

0

La conversione da YUV a RGB utilizzando NEON è molto lenta. Usa uno shader per scaricare sulla GPU.

Problemi correlati