Vive Media Decoder repair and formula derivation

Ice yesterday to repair the problem resolved Vive Media Decoder mp4 image color wrong, and wrote a blog.

https://gameoldboy.com/488/

 

Read a bit, there are a few additional explanation, because I like to be numbered again to determine its validity.

 

The main contents in these formulas

The ycbcr remapped to the full range of 0- 255 : 
Y = ( 255 / ( 235 - 16 )) * (Y- 16 ) 
CB = ( 255 / ( 240 - 16 )) * (CB- 16 ) 
Cr = ( 255 / ( 240 - 16 )) * (CR- 16 ) 

according to u and v range will be mapped to ycbcr YUV (integer): 
Y = Y 
u = 0.872 * (CB- 128 ) 
v = 1.230 * (CR- 128 ) 

application of matrix cross product expand: 
R & lt = Y +1.28033 * V 
G = Y- .21482 * U- 0.38059 * V 
B = Y + 2.12798 * U 

integration formula: 
R & lt = ( 255 / ( 235 - 16 )) * (Y- 16 ) + ( 255 / ( 240 - 16 )) * 1.28033 * ( 1.230 * (CB- 128 )) 
G = ( 255 / ( 235 - 16 )) * (Y- 16 ) - ( 255 / ( 240 - 16 )) *0.21482*(0.872*(cr-128))-(255/(240-16))*0.38059*(1.230*(cb-128))
b=(255/(235-16))*(y-16)+(255/(240-16))*2.12798*(0.872*(cr-128))

Corresponding to these formulas are RGB888 format, wherein

y=y
u=0.872*(cb-128)
v=1.230*(cr-128)

The origin of this factor is here

https://en.wikipedia.org/wiki/YUV#Numerical_approximations

 

 

That is

umax = 0.436
vmax = 0.615
y = [0, 1]
u = [-umax, umax]
v = [-vmax, vmax]
rangeY = 1 - 0 = 1
rangeU = umax - (-umax) = 2 * umax = 0.872
rangeV = vmax - (-vmax) = 2 * vmax = 1.230

 

YUV turn RGB, application BT.709 matrix

Application of matrix cross product Expand: 
R & lt = Y + 1.28033 * V 
G = Y- 0.21482 * U- 0.38059 * V 
B = Y + 2.12798 * U

 

 

r = 1 * y + 0 * u + 1.28033 * v
g = 1 * y - 0.21482 * u - 0.38059 * v
b = 1 * y + 2.12798 * u + 0 * v

 

Then is a simple arithmetic expansion and consolidation

r=(255/(235-16))*(y-16)+(255/(240-16))*1.28033*(1.230*(cb-128))
g=(255/(235-16))*(y-16)-(255/(240-16))*0.21482*(0.872*(cr-128))-(255/(240-16))*0.38059*(1.230*(cb-128))
b=(255/(235-16))*(y-16)+(255/(240-16))*2.12798*(0.872*(cr-128))

定义个变量简化一下

float facY = (255/(235-16)) = 1.1643835616438356164383561643836
float facCBCR = (255/(240-16)) = 1.1383928571428571428571428571429

于是上式可以写为

r = facY * (y-16) + facCBCR * 1.28033 * (1.230*(cb-128))
g = facY * (y-16) - facCBCR * 0.21482 * (0.872*(cr-128)) - facCBCR * 0.38059 * (1.230*(cb-128))
b = facY * (y-16) + facCBCR*  2.12798 * (0.872*(cr-128))

 

因为目前是RGB888,范围是[0-255],变成Shader范围是[0,1],所以

y-16要变成y-0.0627451

cb-128要变成cb-0.5019608

因为

16/255 = 0.062745098039215686274509803921569 约 0.0627451
128/255 = 0.50196078431372549019607843137255 约 0.5019608
 

接着替换

r = facY * (y-0.0627451) + facCBCR * 1.28033 * (1.230*(cb-0.5019608))
g = facY * (y-0.0627451) - facCBCR * 0.21482 * (0.872*(cr-0.5019608)) - facCBCR * 0.38059 * (1.230*(cb-0.5019608))
b = facY * (y-0.0627451) + facCBCR * 2.12798 * (0.872*(cr-0.5019608))

合并常量

facCBCR * 1.28033 * 1.230 = 1.792748
facCBCR * 0.21482 * 0.872 = 0.2132472
facCBCR * 0.38059 * 1.230 = 0.5329109
facCBCR*  2.12798 * 0.872 = 2.1124

 

最后rgb结果近似为

r = 1.164384 * (y-0.0627451) + 1.792748 * (cb-0.5019608)
g = 1.164384 * (y-0.0627451) - 0.2132472 * (cr-0.5019608) - 0.5329109 * (cb-0.5019608)
b = 1.164384 * (y-0.0627451) + 2.1124 * (cr-0.5019608)

 

Guess you like

Origin www.cnblogs.com/kileyi/p/10991897.html