ich ffmpeg bin mit für mein Projekt, aber das Prinzip für das Rendern des YUV-Rahmens sollte für dich das gleiche sein.
Wenn ein Rahmen zum Beispiel 756 x 576 ist, wird der Y-Rahmen diese Größe haben. Der U- und V-Frame sind die Hälfte der Breite und Höhe des Y-Frames, daher müssen Sie sicherstellen, dass Sie die Größenunterschiede berücksichtigen.
Ich weiß nicht über die Kamera-API, aber die Frames, die ich von einer DVB-Quelle bekomme, haben eine Breite und auch jede Zeile hat einen Schritt. Extras Pixel am Ende jeder Zeile im Rahmen. Nur für den Fall, dass Ihr gleich ist, berücksichtigen Sie dies bei der Berechnung Ihrer Texturkoordinaten.
die Textur Einstellen Koordinaten für die Breite und Schritt (linesize) zu berücksichtigen:
float u = 1.0f/buffer->y_linesize * buffer->wid; // adjust texture coord for edge
Der Vertex-Shader ich verwendet habe, nimmt Bildschirm von 0,0 bis 1,0-Koordinaten, aber Sie können diese anpassen ändern. Es berücksichtigt auch die Texturkoordinaten und eine Farbeingabe. Ich habe die Farbeingabe verwendet, so dass I Fading hinzuzufügen, usw.
Vertex-Shader:
#ifdef GL_ES
precision mediump float;
const float c1 = 1.0;
const float c2 = 2.0;
#else
const float c1 = 1.0f;
const float c2 = 2.0f;
#endif
attribute vec4 a_vertex;
attribute vec2 a_texcoord;
attribute vec4 a_colorin;
varying vec2 v_texcoord;
varying vec4 v_colorout;
void main(void)
{
v_texcoord = a_texcoord;
v_colorout = a_colorin;
float x = a_vertex.x * c2 - c1;
float y = -(a_vertex.y * c2 - c1);
gl_Position = vec4(x, y, a_vertex.z, c1);
}
Die Fragment-Shader, die drei gleichförmige Texturen nimmt, eine für jeden Y, U und V und wandelt framges zu RGB. Dies vervielfacht auch durch die Farbe aus dem Vertex-Shader übergeben:
#ifdef GL_ES
precision mediump float;
#endif
uniform sampler2D u_texturey;
uniform sampler2D u_textureu;
uniform sampler2D u_texturev;
varying vec2 v_texcoord;
varying vec4 v_colorout;
void main(void)
{
float y = texture2D(u_texturey, v_texcoord).r;
float u = texture2D(u_textureu, v_texcoord).r - 0.5;
float v = texture2D(u_texturev, v_texcoord).r - 0.5;
vec4 rgb = vec4(y + 1.403 * v,
y - 0.344 * u - 0.714 * v,
y + 1.770 * u,
1.0);
gl_FragColor = rgb * v_colorout;
}
Die verwendeten Eckpunkte sind in:
float x, y, z; // coords
float s, t; // texture coords
uint8_t r, g, b, a; // colour and alpha
hoffe, das hilft!
EDIT:
Für NV12 Format, das Sie noch ein Fragment-Shader verwenden können, obwohl ich es selbst nicht ausprobiert habe. Es nimmt das verschachtelte UV als Luminanz-Alpha-Kanal oder ähnliches auf.
Sehen Sie hier, wie eine Person diese beantwortet hat: https://stackoverflow.com/a/22456885/2979092
Ich ging direkt auf der Strecke mit OpenGLES die YUV-Frames direkt von Rendering. Ich kann den Fragment-Shader und jede andere Quelle aus meinem Code veröffentlichen, wenn es hilft. – WLGfx
Wie Sie diese YUV-Frames gerendert haben, ist genau das, was ich wissen muss! Haben Sie diese Frames in Form eines Bytearrays empfangen, so wie ich bin? (Quellcode wäre hilfreich, danke!) –