here
. 和
here
这是我转换yuv文件的原始图像。
我使用以下内容创建了YUV文件:
ffmpeg -i color-test.jpg -pix_fmt yuvj420p -f rawvideo color-test.yuv
我明确使用
yuvj420p
yuv420p
获取全范围值(0-255)。因此,如果我在生产中使用此代码,我会添加一些制服以适应颜色范围。
attribute vec3 a_pos;
attribute vec2 a_uv;
uniform mat4 u_mvp;
varying vec2 v_uv;
void main () {
gl_Position = u_mvp * vec4(a_pos, 1.0);
v_uv = a_uv;
}
片段着色器
precision mediump float;
uniform sampler2D u_texY;
uniform sampler2D u_texU;
uniform sampler2D u_texV;
uniform vec4 u_diffuse;
varying vec2 v_uv;
// YUV to RGB coefficient matrix.
const mat3 coeff = mat3(
1.0, 1.0, 1.0,
0.0, -0.21482, 2.12798,
1.28033, -0.38059, 0.0
);
void main () {
vec3 yuv = vec3(texture2D(u_texY, v_uv).a, texture2D(u_texU, v_uv).a, texture2D(u_texV, v_uv).a) * 2.0 - 1.0;
vec3 colour = (coeff * yuv + 1.0) / 2.0;
gl_FragColor = u_diffuse * vec4(colour, 1.0);
}
系数矩阵为BT.709 rec的系数矩阵(
this wiki page
).
u_diffuse
通常是
vec4(1.0, 1.0, 1.0, 1.0)
除非你想用某种颜色扩散图片。
纹理上载
纹理上传如下(第233行):
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, tex.y);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.ALPHA, rp.yuv.meta.width, rp.yuv.meta.height, 0, gl.ALPHA, gl.UNSIGNED_BYTE, picture.y);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
CLAMP_TO_EDGE
用于处理图像的任何维度(即可被2整除的任何维度)。请注意,纹理在每次绘制回调时都会更新。这是有意的,因为通常情况下,每次从视频解码器移交图片时,我们都必须更新纹理。
最明显的问题是,渲染的图像明显不同于图像查看器应用程序(即web浏览器)的格式副本。这些程序可能通过CPU将图像从YUV扩展到RGB。我想这是最准确的转换方式。在我的程序中到底是什么导致了这种情况?我已经做了研究,但我不能得出一个明确的解释。浮点精度?
问题进一步扩大。不同设备的颜色不同。例如,这个女人在我的安卓手机上和在我的电脑上看起来有点不同。同样的事情在Linux和Windows浏览器上也会发生。当我测量右下角黑盒子的颜色时,我得到了平台/硬件上的“不同的黑色”。
-
Linux上的Chrome:060106
-
-
Android上的Chrome:060006
-
Windows上的Chrome/Firefox/Oprea:060106
有什么方法可以缓解这种情况吗?为什么我不能得到“真正的”黑色(#000000)?
我对此非常担心,因为有些人确实发现了这种差异。一天,当我在办公室工作时,一位客户坚持说我的视频播放器的颜色与另一家公司的程序不同。没有人知道为什么(没有其他程序的源代码)。但似乎另一个程序在RGB曲面上渲染,而我的程序在YUV DirectX曲面上渲染。如果是这样的话,他们必须从CPU进行转换。可能有很多原因导致它看起来有所不同。可能是颜色范围,一些吉米使用的坏系数。。。这个名单可能还会继续下去。