YV12 zu RGB - Was ist mit meinem Algorithmus falsch?


8

Ich versuche, YV12 mit dem folgenden Fragment-Shader in RGB zu konvertieren:

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);
}

Unten sehen Sie das Originalbild, gefolgt vom konvertierten Bild. Können Sie anhand der Ausgabe feststellen, wo ich möglicherweise nachschaue, um festzustellen, was die fehlerhafte Dekodierung verursacht?

Quelle Dekodiertes Bild


Wie von Ersthelfern gesagt, gibt es definitiv ein Problem mit der Anzahl der Bytes pro Zeile. Ich frage mich noch etwas. YV12 hat U- und V-Kanäle unterabgetastet. Wie verwalten Sie diese Dimensionsänderung mit Ihrem Shader? Wie groß sind deine Texturen? Lassen Sie OpenGL damit umgehen?
Stéphane Péchard

In der Zeichenschleife werden mir Bilddaten in einem 3-Element-Array gegeben, in dem die Reihenfolge immer YUV ist (unabhängig von YV12 oder YUV420p usw.). Ich verwende die volle Breite / Höhe für das Y-Element und verschiebe die Breite / Höhe für die UV-Elemente nach rechts 1 (geteilt durch 2). Diese Texturen werden dann an den Shader gebunden, der den Rest erledigt. Texturgrößen, mit denen ich gearbeitet habe, sind normalerweise 1280 x 720.
Fehler 454

Antworten:


5

Das Ausgabebild weist Linien auf, die gegeneinander verschoben sind, was typischerweise auf einen falschen [Byte] Abstand zwischen den Linien (Schritt) zurückzuführen ist. Das heißt, die Farbkonvertierungsmathematik ist möglicherweise korrekt, Sie nehmen jedoch entweder das Quellpixel von der falschen Position und / oder platzieren das Ausgabepixel an der falschen Stelle.

Aus Leistungsgründen verwenden YV12-Images möglicherweise erweiterte Schritte in der Hardware, um die Leistung zu verbessern. Beispielsweise kann ein 320x240-YV12-Bild einen Schritt von 512 haben, und dies bedeutet, dass der Datenpuffer ein 512x240-Datenraum (512x240 Bytes für Y, gefolgt von zwei 256x120-Arrays für V und U) ist, in dem sich das Nutzdatenbild links und dort befindet ist unsichtbare Polsterung auf der rechten Seite.


Ich sehe, dass ich keinen Schritt mache. Ich werde dies implementieren, wenn ich kann, und die Frage aktualisieren, sobald ich überprüfen kann, ob dies tatsächlich das Problem ist.
Fehler 454

Am Ende war Schritt die Antwort. Es war das einzige, was ich geändert habe und jetzt funktioniert alles. Tolles Auge!
Fehler 454

1

Ich weiß nichts über Fragment-Shader-Programmierung, aber für mich sieht es so aus, als ob die Wortgröße der Eingabe und Ausgabe variiert. Und für mich sieht es so aus, als würden Sie die YV12- Bytes nicht auspacken und neu verpacken .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.