Я использую FFmpeg для мой проект, но основной для рендеринга кадра YUV должен быть одинаковым для вас.
Если кадр, например, равен 756 x 576, тогда кадр Y будет такого размера. Рамка U и V составляет половину ширины и высоты кадра Y, поэтому вам нужно будет убедиться, что вы учитываете различия в размерах.
Я не знаю об API-интерфейсе камеры, но кадры, которые я получаю от источника DVB, имеют ширину, а также каждая строка имеет шаг. Дополняет пиксели в конце каждой строки в кадре. На всякий случай, если у вас одинаковое, тогда учтите это при вычислении ваших координат текстуры.
Настройки координаты текстуры для учета ширины и шага (linesize):
float u = 1.0f/buffer->y_linesize * buffer->wid; // adjust texture coord for edge
вершинного шейдера Я использовал принимает координаты экрана от 0.0 до 1.0, но вы можете изменить их в соответствии с. Он также принимает текстурные координаты и цветной вход. Я использовал ввод цвета, так что можно добавить выцветанию и т.д.
вершинного шейдера:
#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);
}
фрагмент шейдера, который принимает три однородные текстуры, по одному для каждого framges и преобразует Y, U и V к RGB. Это также умножает цвет передается из вершинного шейдера:
#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;
}
Вершины, используемая в:
float x, y, z; // coords
float s, t; // texture coords
uint8_t r, g, b, a; // colour and alpha
Надеется, что это помогает!
EDIT:
Для формата NV12 вы можете использовать фрагмент шейдеров, хотя я не пробовал сам. Он принимает чередующийся УФ-излучение как канал яркости-альфа или аналогичный.
Смотрите здесь, как один человек ответил на это: https://stackoverflow.com/a/22456885/2979092
Я пошел прямо по пути оказания YUV кадры непосредственно с OpenGLES. Я могу опубликовать фрагментарный шейдер и любой другой источник из моего кода, если это поможет. – WLGfx
Как вам удалось отобразить эти кадры YUV именно то, что мне нужно знать! Получали ли вы эти кадры в виде байтового массива, как я? (Исходный код был бы полезен, спасибо!) –