我使用的ffmpeg的surfaceview/textureview我的項目,但渲染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);
}
片段着色器,其有三個均勻紋理,一個用於每個Y,U和V framges和轉換到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
希望這有助於!
編輯:
對於NV12格式,你仍然可以使用一個片段着色器,雖然我還沒有嘗試過自己。它將交錯紫外線作爲亮度α通道或類似物。
在這裏看到一個人是如何回答的:https://stackoverflow.com/a/22456885/2979092
我就直降直接與openGLES渲染YUV幀的路線。如果有幫助,我可以從我的代碼發佈片段着色器和其他任何源代碼。 – WLGfx
您如何設法呈現這些YUV幀正是我需要知道的!你是否像我一樣以字節數組的形式接收這些幀? (源代碼會很有幫助,謝謝!) –