2013-03-22 21 views
6

Ho un'app Android che decodifica il video nel formato yuv420p quindi esegue il rendering dei fotogrammi video utilizzando OpenGLES. Uso glTexSubImage2D() per caricare il buffer y/u/v in GPU, quindi eseguire una conversione YUV2RGB usando lo shader. Tutto il codice di setup/rendering EGL/OpenGL è nativo.Prestazioni lente glTexSubImage2D su Nexus 10/Android 4.2.2 (Samsung Exynos 5 con Mali-T604)

Ora non sto dicendo che non ci sono problemi con il mio codice, ma considerando che lo stesso codice sta funzionando perfettamente su iOS (iPad/iPhone), Nexus 7, Kindle HD 8.9, Samsung Note tablet (A31/RockChip 3188) con sistema operativo Android 4.0/4.1/4.2. Direi che è meno probabile che il mio codice sia sbagliato. Su quei dispositivi, glTexSubImage2D() utilizza meno di 16 ms per caricare una texture HD SD o 720P.

Tuttavia, su Nexus 10, glTexSubImage2D() sono necessari circa 50 ~ 90 ms per una trama HD SD o 720P che è troppo lenta per un video a 30 fps o 60 fps.

Vorrei sapere

1) se devo scegliere un formato di trama diversa (RGBA o BGRA). C'è un modo per scoprire qual è il miglior formato di texture usato da una GPU?

2) se è presente una funzione su "OFF" su tutti gli altri SOC ma su "ON" su Exynos 5. Ad esempio, l'opzione di generazione MIPMAP automatica. (L'ho spento, btw)

3) se questo è un problema noto di Samsung Exynos SOC - Non riesco a trovare un forum di supporto per CPU Exynos

4) C'è qualche possibilità che ho bisogno di impostare quando si configura la superficie EGL? come, trasparenza, formato della superficie, ecc.? (Non ho idea di cosa sto parlando)

5) Potrebbe significare che GPU sta eseguendo una conversione di formato implicita ma ho controllato che GL_LUMINANCE sia sempre utilizzato. Di nuovo funziona su tutte le altre piattaforme.

6) qualcos'altro?

mio EGL config:

const EGLint attribs[] = { 
    EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 
    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 
    EGL_BLUE_SIZE, 8, 
    EGL_GREEN_SIZE, 8, 
    EGL_RED_SIZE, 8, 
    EGL_NONE 
}; 

Impostazione iniziale:

glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, ctx->frameW, ctx->frameH, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); /* also for U/V */ 

successiva sostituzione parziale:

glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, ctx->frameW, ctx->frameH, GL_LUMINANCE, GL_UNSIGNED_BYTE, yBuffer); /*also for U/V */ 

Sto cercando di rendere il video a ~ 30fps o ~ 60FPS a SD o risoluzione 720P HD.

+0

Considerare il 'SurfaceTexture' per Android> 11: http://developer.android.com/reference/android/graphics/SurfaceTexture.html – Jave

+0

Grazie, ma mi piacerebbe ancora capire perché glTexSubImage2D() è lento poiché I non voglio mantenere più percorsi di codice - funziona per tutti eccetto Exynos –

+0

Abbiamo osservato lo stesso (o molto simile) problema e lo abbiamo segnalato su https://code.google.com/p/android/issues/detail?id = 53135, ma sembra essere una regressione tra 4.2.1 e 4.2.2 in base ai nostri test. – chuoling

risposta

6

Questo è un problema noto del driver che abbiamo segnalato a ARM. Un aggiornamento futuro dovrebbe risolverlo.

+0

è una regressione da 4.2 o 4.2.1? In tal caso, ripristinerò la versione del firmware e continuerò lo sviluppo ... –

+0

@ romain-guy - Avresti qualche idea di questo aggiornamento? La mia azienda ha lo stesso identico problema. – BlueVoodoo

+0

Il fix sarà in 4.2.3 o 5.0 –

1

EDIT aggiornamento di stato

Ora abbiamo riusciti a riprodurre le condizioni di caricamento lento per un percorso sul firmware pubblico, che si sta forse colpendo, e questo verrà risolto nella prossima release del driver.

Se si esegue il double-buffer degli ID di trama (ad es. Frame N = ID X, N + 1 = ID Y, N + 2 = ID X, N + 3 = ID Y, ecc.) Per le trame che si stanno caricando su di esso dovrebbe aiutare a evitare questo sul firmware corrente.

Grazie, Iso

+1

vedere la mia domanda modificata –

+0

Molto apprezzata. Quindi, per confermare che stai caricando una superficie YUV semiplanare come due trame di luminanza a 8 bit, una con Y a 8 bit e una con due valori U/V a 4 bit impacchettati in un canale a 8 bit. – solidpixel

+0

Hmm Non ho abbastanza punti rep per commentare la risposta di Romain, quindi la posterò qui. No, non si tratta di una regressione tra 4.2 e 4.2.1, quindi il rollback non aiuterà. – solidpixel

1

posso confermare questo è stato risolto in Android 4.3 - sto vedendo un aumento delle prestazioni di un fattore 2-3 con il formato RGBA e di un fattore di 10-50 con altri formati di texture su Android 4.2.2. Questi risultati si applicano sia a glTexImage2D che a glTexSubImage2D. (Non posso ancora aggiungere commenti quindi ho dovuto metterlo qui)

MODIFICA: Se sei bloccato con 4.2.2, potresti provare a utilizzare la trama RGBA invece, dovrebbe avere prestazioni migliori (3-10 volte circa con più grande potere di due dimensioni di trama).

+0

Apparentemente, non è ancora abbastanza veloce. La mia app ha iniziato a usare glTexSubImage2D con una trama RGBA, e da quella versione in poi si blocca su Nexus 10. Non si blocca su nessun altro Android là fuori! – HRJ