Da YV12 a RGB - Cosa c'è di sbagliato nel mio algoritmo?


8

Sto tentando di convertire YV12 in RGB utilizzando il seguente shader di frammenti:

precision mediump float;
uniform sampler2D tex0, tex1, tex2;
varying vec2 v_texCoord;

void main(void) {
    float r, g, b, y, u, v;
    y = texture2D(tex0, v_texCoord).x;
    u = texture2D(tex1, v_texCoord).x;
    v = texture2D(tex2, v_texCoord).x;

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

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

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

Sotto è l'immagine originale seguita dall'immagine convertita. In base all'output, puoi determinare dove potrei cercare per determinare cosa sta causando la decodifica errata?

fonte Immagine decodificata


Come detto dai primi soccorritori, c'è sicuramente un problema con il numero di byte per riga. Mi chiedo un'altra cosa. YV12 ha sottocampionato i canali U e V. Come gestisci questo cambiamento di dimensione con il tuo shader? Quali sono le dimensioni delle tue trame? Lasci che OpenGL lo gestisca?
Stéphane Péchard,

Nel ciclo di disegno, i dati delle immagini mi vengono forniti in un array di 3 elementi in cui l'ordine è sempre YUV (indipendentemente da YV12 o YUV420p ecc.). Uso l'intera larghezza / altezza per l'elemento Y e sposto la larghezza / altezza a destra 1 (dividere per 2) per gli elementi UV. Queste trame sono quindi legate allo shader che gestisce il resto. Le dimensioni delle trame con cui ho lavorato sono in genere 1280x720.
Errore 454

Risposte:


5

L'immagine in uscita ha delle linee spostate l'una contro l'altra, il che è generalmente dovuto a una distanza errata [byte] tra le linee (falcata). Cioè, la matematica della conversione del colore è forse corretta, tuttavia stai prendendo il pixel di origine da una posizione errata e / o mettendo il pixel di output in una posizione errata.

Per motivi di prestazioni, le immagini YV12 potrebbero utilizzare passi estesi nell'hardware per facilitare le prestazioni. Ad esempio, l'immagine YV12 320x240 potrebbe avere un passo di 512 e ciò significa che il buffer di dati è uno spazio dati 512x240 (512x240 byte per Y, seguito da due array 256x120 per V e U) dove l'immagine del payload è a sinistra, e lì è un'imbottitura invisibile sulla destra.


Vedo che non sto spiegando il passo. Lo implementerò quando posso e aggiornerò la domanda una volta che posso verificare se questo è davvero il problema.
Errore 454

Alla fine, il passo fu la risposta. È stata l'unica cosa che ho cambiato e ora tutto funziona. Grande occhio!
Errore 454

1

Non so nulla sulla programmazione di shader di frammenti, ma a me sembra che la dimensione delle parole di input e output vari. E a me sembra che non presti attenzione al disimballaggio e al reimballaggio dei byte YV12 .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.