 Chromium Code Reviews
 Chromium Code Reviews Issue 2122573003:
  media: replace LUMINANCE_F16 by RG_88 for 9/10-bit h264 videos 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master
    
  
    Issue 2122573003:
  media: replace LUMINANCE_F16 by RG_88 for 9/10-bit h264 videos 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master| OLD | NEW | 
|---|---|
| 1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 2011 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "cc/output/shader.h" | 5 #include "cc/output/shader.h" | 
| 6 | 6 | 
| 7 #include <stddef.h> | 7 #include <stddef.h> | 
| 8 | 8 | 
| 9 #include <algorithm> | 9 #include <algorithm> | 
| 10 | 10 | 
| (...skipping 2005 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2016 FragmentShaderYUVVideo::FragmentShaderYUVVideo() | 2016 FragmentShaderYUVVideo::FragmentShaderYUVVideo() | 
| 2017 : y_texture_location_(-1), | 2017 : y_texture_location_(-1), | 
| 2018 u_texture_location_(-1), | 2018 u_texture_location_(-1), | 
| 2019 v_texture_location_(-1), | 2019 v_texture_location_(-1), | 
| 2020 uv_texture_location_(-1), | 2020 uv_texture_location_(-1), | 
| 2021 a_texture_location_(-1), | 2021 a_texture_location_(-1), | 
| 2022 lut_texture_location_(-1), | 2022 lut_texture_location_(-1), | 
| 2023 alpha_location_(-1), | 2023 alpha_location_(-1), | 
| 2024 yuv_matrix_location_(-1), | 2024 yuv_matrix_location_(-1), | 
| 2025 yuv_adj_location_(-1), | 2025 yuv_adj_location_(-1), | 
| 2026 max_channel_value_location_(-1), | |
| 2027 ya_size_location_(-1), | |
| 2028 uv_size_location_(-1), | |
| 2026 ya_clamp_rect_location_(-1), | 2029 ya_clamp_rect_location_(-1), | 
| 2027 uv_clamp_rect_location_(-1), | 2030 uv_clamp_rect_location_(-1), | 
| 2028 resource_multiplier_location_(-1), | 2031 resource_multiplier_location_(-1), | 
| 2029 resource_offset_location_(-1) {} | 2032 resource_offset_location_(-1) {} | 
| 2030 | 2033 | 
| 2031 void FragmentShaderYUVVideo::SetFeatures(bool use_alpha_texture, | 2034 void FragmentShaderYUVVideo::SetFeatures(bool use_alpha_texture, | 
| 2032 bool use_nv12, | 2035 bool use_nv12, | 
| 2033 bool use_color_lut) { | 2036 bool use_color_lut, | 
| 2037 HighbitTexture highbit_texture) { | |
| 2034 use_alpha_texture_ = use_alpha_texture; | 2038 use_alpha_texture_ = use_alpha_texture; | 
| 2035 use_nv12_ = use_nv12; | 2039 use_nv12_ = use_nv12; | 
| 2036 use_color_lut_ = use_color_lut; | 2040 use_color_lut_ = use_color_lut; | 
| 2041 highbit_texture_ = highbit_texture; | |
| 2037 } | 2042 } | 
| 2038 | 2043 | 
| 2039 void FragmentShaderYUVVideo::Init(GLES2Interface* context, | 2044 void FragmentShaderYUVVideo::Init(GLES2Interface* context, | 
| 2040 unsigned program, | 2045 unsigned program, | 
| 2041 int* base_uniform_index) { | 2046 int* base_uniform_index) { | 
| 2042 static const char* uniforms[] = { | 2047 static const char* uniforms[] = { | 
| 2043 "y_texture", | 2048 "y_texture", | 
| 2044 "u_texture", | 2049 "u_texture", | 
| 2045 "v_texture", | 2050 "v_texture", | 
| 2046 "uv_texture", | 2051 "uv_texture", | 
| 2047 "a_texture", | 2052 "a_texture", | 
| 2048 "lut_texture", | 2053 "lut_texture", | 
| 2054 "yuv_matrix", | |
| 2055 "yuv_adj", | |
| 2049 "resource_multiplier", | 2056 "resource_multiplier", | 
| 2050 "resource_offset", | 2057 "resource_offset", | 
| 2051 "yuv_matrix", | 2058 "max_channel_value", | 
| 2052 "yuv_adj", | 2059 "ya_size", | 
| 2060 "uv_size", | |
| 2053 "alpha", | 2061 "alpha", | 
| 2054 "ya_clamp_rect", | 2062 "ya_clamp_rect", | 
| 2055 "uv_clamp_rect", | 2063 "uv_clamp_rect", | 
| 2056 }; | 2064 }; | 
| 2057 int locations[arraysize(uniforms)]; | 2065 int locations[arraysize(uniforms)]; | 
| 2058 | 2066 | 
| 2059 GetProgramUniformLocations(context, | 2067 GetProgramUniformLocations(context, | 
| 2060 program, | 2068 program, | 
| 2061 arraysize(uniforms), | 2069 arraysize(uniforms), | 
| 2062 uniforms, | 2070 uniforms, | 
| 2063 locations, | 2071 locations, | 
| 2064 base_uniform_index); | 2072 base_uniform_index); | 
| 2065 y_texture_location_ = locations[0]; | 2073 y_texture_location_ = locations[0]; | 
| 2066 if (!use_nv12_) { | 2074 if (!use_nv12_) { | 
| 2067 u_texture_location_ = locations[1]; | 2075 u_texture_location_ = locations[1]; | 
| 2068 v_texture_location_ = locations[2]; | 2076 v_texture_location_ = locations[2]; | 
| 2069 } else { | 2077 } else { | 
| 2070 uv_texture_location_ = locations[3]; | 2078 uv_texture_location_ = locations[3]; | 
| 2071 } | 2079 } | 
| 2072 if (use_alpha_texture_) { | 2080 if (use_alpha_texture_) { | 
| 2073 a_texture_location_ = locations[4]; | 2081 a_texture_location_ = locations[4]; | 
| 2074 } | 2082 } | 
| 2075 if (use_color_lut_) { | 2083 if (use_color_lut_) { | 
| 2076 lut_texture_location_ = locations[5]; | 2084 lut_texture_location_ = locations[5]; | 
| 2077 resource_multiplier_location_ = locations[6]; | |
| 2078 resource_offset_location_ = locations[7]; | |
| 2079 } else { | 2085 } else { | 
| 2080 yuv_matrix_location_ = locations[8]; | 2086 yuv_matrix_location_ = locations[6]; | 
| 2081 yuv_adj_location_ = locations[9]; | 2087 yuv_adj_location_ = locations[7]; | 
| 2082 } | 2088 } | 
| 2083 alpha_location_ = locations[10]; | 2089 if (highbit_texture_ == HIGHBIT_LUMINANCE_F16) { | 
| 2084 ya_clamp_rect_location_ = locations[11]; | 2090 resource_multiplier_location_ = locations[8]; | 
| 2085 uv_clamp_rect_location_ = locations[12]; | 2091 resource_offset_location_ = locations[9]; | 
| 2092 } else if (highbit_texture_ == HIGHBIT_RG88) { | |
| 2093 max_channel_value_location_ = locations[10]; | |
| 2094 ya_size_location_ = locations[11]; | |
| 2095 uv_size_location_ = locations[12]; | |
| 2096 } | |
| 2097 alpha_location_ = locations[13]; | |
| 2098 ya_clamp_rect_location_ = locations[14]; | |
| 2099 uv_clamp_rect_location_ = locations[15]; | |
| 2086 } | 2100 } | 
| 2087 | 2101 | 
| 2088 std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision, | 2102 std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision, | 
| 2089 SamplerType sampler) const { | 2103 SamplerType sampler) const { | 
| 2090 std::string head = SHADER0([]() { | 2104 std::string head = SHADER0([]() { | 
| 2091 precision mediump float; | 2105 precision mediump float; | 
| 2092 precision mediump int; | 2106 precision mediump int; | 
| 2093 varying TexCoordPrecision vec2 v_yaTexCoord; | 2107 varying TexCoordPrecision vec2 v_yaTexCoord; | 
| 2094 varying TexCoordPrecision vec2 v_uvTexCoord; | 2108 varying TexCoordPrecision vec2 v_uvTexCoord; | 
| 2095 uniform SamplerType y_texture; | 2109 uniform SamplerType y_texture; | 
| 2096 uniform float alpha; | 2110 uniform float alpha; | 
| 2097 uniform vec4 ya_clamp_rect; | 2111 uniform vec4 ya_clamp_rect; | 
| 2098 uniform vec4 uv_clamp_rect; | 2112 uniform vec4 uv_clamp_rect; | 
| 2099 }); | 2113 }); | 
| 2100 | 2114 | 
| 2101 std::string functions = ""; | 2115 std::string functions = ""; | 
| 2116 if (highbit_texture_ == HIGHBIT_RG88) { | |
| 
hubbe
2016/09/27 20:49:51
Can we make it so that the if and else branches pr
 
dshwang
2016/09/28 10:33:27
GetY() and GetUV() is kind of public function. Fol
 
hubbe
2016/09/28 17:57:44
Hmm, you're right. I was hoping to make this a bit
 | |
| 2117 head += " uniform int max_channel_value;\n"; | |
| 
hubbe
2016/09/28 17:57:44
How about reusing resource_multiplier?
The calling
 
dshwang
2016/09/29 18:52:28
It needs 2048 hardcode or interact code between vi
 | |
| 2118 head += " uniform vec2 ya_size;\n"; | |
| 2119 head += " uniform vec2 uv_size;\n"; | |
| 2120 functions += SHADER0([]() { | |
| 2121 float GetFloat(vec2 rg) { | |
| 2122 return ((rg.g * 65536.0) + (rg.r * 256.0)) / float(max_channel_value); | |
| 
hubbe
2016/09/28 17:57:44
should be (rg.g * 65280.0) + (rg.r * 255.0)
This
 
dshwang
2016/09/29 18:52:27
oh, you are right. I'm extending renderer_pixeltes
 | |
| 2123 } | |
| 2124 | |
| 2125 float RGTextureLookupBilinear(SamplerType sampler, vec2 tex_coord, | |
| 2126 vec4 clamp_rect, vec2 tex_size) { | |
| 2127 vec2 unit_texel = 1.0 / tex_size; | |
| 2128 vec2 tex_coord_clamped1 = | |
| 2129 max(clamp_rect.xy, min(clamp_rect.zw, tex_coord)); | |
| 2130 float s1 = GetFloat(TextureLookup(sampler, tex_coord_clamped1).xy); | |
| 2131 vec2 tex_coord_clamped2 = | |
| 2132 max(clamp_rect.xy, | |
| 2133 min(clamp_rect.zw, tex_coord + vec2(unit_texel.x, 0.))); | |
| 
hubbe
2016/09/28 17:57:44
This doesn't actually work, because there is no gu
 
dshwang
2016/09/29 18:52:28
Ok, I added snapping code inspired by http://http.
 
hubbe
2016/09/29 23:36:50
If snapping is not needed, I'd like to understand
 
dshwang
2016/10/05 15:13:39
I found snapping is needed when I made pixel test.
 | |
| 2134 float s2 = GetFloat(TextureLookup(sampler, tex_coord_clamped2).xy); | |
| 2135 vec2 tex_coord_clamped3 = | |
| 2136 max(clamp_rect.xy, | |
| 
hubbe
2016/09/28 17:57:44
Do we really need to do the clamping for every sub
 
dshwang
2016/09/29 18:52:27
make sense. it's not really needed.
 | |
| 2137 min(clamp_rect.zw, tex_coord + vec2(0., unit_texel.y))); | |
| 2138 float s3 = GetFloat(TextureLookup(sampler, tex_coord_clamped3).xy); | |
| 2139 vec2 tex_coord_clamped4 = | |
| 2140 max(clamp_rect.xy, min(clamp_rect.zw, tex_coord + unit_texel)); | |
| 2141 float s4 = GetFloat(TextureLookup(sampler, tex_coord_clamped4).xy); | |
| 2142 vec2 f = fract(tex_coord * tex_size); | |
| 2143 return mix(mix(s1, s2, f.x), mix(s3, s4, f.x), f.y); | |
| 2144 } | |
| 2145 | |
| 2146 float GetY() { | |
| 2147 return RGTextureLookupBilinear(y_texture, v_yaTexCoord, ya_clamp_rect, | |
| 2148 ya_size); | |
| 2149 } | |
| 2150 }); | |
| 2151 } else { | |
| 2152 functions += SHADER0([]() { | |
| 2153 float GetY() { | |
| 2154 vec2 ya_clamped = | |
| 2155 max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord)); | |
| 2156 return TextureLookup(y_texture, ya_clamped).x; | |
| 2157 } | |
| 2158 }); | |
| 2159 } | |
| 2160 | |
| 2102 if (use_nv12_) { | 2161 if (use_nv12_) { | 
| 2103 head += " uniform SamplerType uv_texture;\n"; | 2162 head += " uniform SamplerType uv_texture;\n"; | 
| 2104 functions += SHADER0([]() { | 2163 functions += SHADER0([]() { | 
| 2105 vec2 GetUV(vec2 uv_clamped) { | 2164 vec2 GetUV(vec2 uv_tex_coord) { | 
| 2165 vec2 uv_clamped = | |
| 2166 max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, uv_tex_coord)); | |
| 2106 return TextureLookup(uv_texture, uv_clamped).xy; | 2167 return TextureLookup(uv_texture, uv_clamped).xy; | 
| 2107 } | 2168 } | 
| 2108 }); | 2169 }); | 
| 2109 } else { | 2170 } else { | 
| 2110 head += " uniform SamplerType u_texture;\n"; | 2171 head += " uniform SamplerType u_texture;\n"; | 
| 2111 head += " uniform SamplerType v_texture;\n"; | 2172 head += " uniform SamplerType v_texture;\n"; | 
| 2112 functions += SHADER0([]() { | 2173 if (highbit_texture_ == HIGHBIT_RG88) { | 
| 2113 vec2 GetUV(vec2 uv_clamped) { | 2174 functions += SHADER0([]() { | 
| 2114 return vec2(TextureLookup(u_texture, uv_clamped).x, | 2175 vec2 GetUV(vec2 uv_tex_coord) { | 
| 
hubbe
2016/09/27 20:49:51
I think it would be more efficient if this was a a
 
dshwang
2016/09/28 10:33:27
That's good idea. 8888 texture could be fallback o
 
hubbe
2016/09/29 23:36:51
Almost everything supports RG88 I think.
 | |
| 2115 TextureLookup(v_texture, uv_clamped).x); | 2176 vec2 uv = vec2(RGTextureLookupBilinear(u_texture, uv_tex_coord, | 
| 2116 } | 2177 uv_clamp_rect, uv_size), | 
| 2117 }); | 2178 RGTextureLookupBilinear(v_texture, uv_tex_coord, | 
| 2179 uv_clamp_rect, uv_size)); | |
| 2180 return uv; | |
| 2181 } | |
| 2182 }); | |
| 2183 } else { | |
| 2184 functions += SHADER0([]() { | |
| 2185 vec2 GetUV(vec2 uv_tex_coord) { | |
| 2186 vec2 uv_clamped = | |
| 2187 max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, uv_tex_coord)); | |
| 2188 vec2 uv = vec2(TextureLookup(u_texture, uv_clamped).x, | |
| 2189 TextureLookup(v_texture, uv_clamped).x); | |
| 2190 return uv; | |
| 2191 } | |
| 2192 }); | |
| 2193 } | |
| 2118 } | 2194 } | 
| 2119 | 2195 | 
| 2120 if (use_alpha_texture_) { | 2196 if (use_alpha_texture_) { | 
| 2121 head += " uniform SamplerType a_texture;\n"; | 2197 head += " uniform SamplerType a_texture;\n"; | 
| 2122 functions += SHADER0([]() { | 2198 functions += SHADER0([]() { | 
| 2123 float GetAlpha(vec2 ya_clamped) { | 2199 float GetAlpha(vec2 ya_tex_coord) { | 
| 2200 vec2 ya_clamped = | |
| 2201 max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, ya_tex_coord)); | |
| 2124 return alpha * TextureLookup(a_texture, ya_clamped).x; | 2202 return alpha * TextureLookup(a_texture, ya_clamped).x; | 
| 2125 } | 2203 } | 
| 2126 }); | 2204 }); | 
| 2127 } else { | 2205 } else { | 
| 2128 functions += SHADER0([]() { | 2206 functions += SHADER0([]() { | 
| 2129 float GetAlpha(vec2 ya_clamped) { return alpha; } | 2207 float GetAlpha(vec2 ya_tex_coord) { return alpha; } | 
| 2130 }); | 2208 }); | 
| 2131 } | 2209 } | 
| 2132 | 2210 | 
| 2133 if (use_color_lut_) { | 2211 if (use_color_lut_) { | 
| 2134 head += " uniform sampler2D lut_texture;\n"; | 2212 head += " uniform sampler2D lut_texture;\n"; | 
| 2135 head += " uniform float resource_multiplier;\n"; | |
| 2136 head += " uniform float resource_offset;\n"; | |
| 2137 functions += SHADER0([]() { | 2213 functions += SHADER0([]() { | 
| 2138 vec4 LUT(sampler2D sampler, vec3 pos, float size) { | 2214 vec4 LUT(sampler2D sampler, vec3 pos, float size) { | 
| 2139 pos *= size - 1.0; | 2215 pos *= size - 1.0; | 
| 2140 // Select layer | 2216 // Select layer | 
| 2141 float layer = min(floor(pos.x), size - 2.0); | 2217 float layer = min(floor(pos.x), size - 2.0); | 
| 2142 // Compress the yz coordinates so they stay within | 2218 // Compress the yz coordinates so they stay within | 
| 2143 // [0.5 .. 31.5] / 32 (assuming a LUT size of 32^3) | 2219 // [0.5 .. 31.5] / 32 (assuming a LUT size of 32^3) | 
| 2144 pos.yz = (pos.yz + vec2(0.5)) / size; | 2220 pos.yz = (pos.yz + vec2(0.5)) / size; | 
| 2145 pos.z = (pos.z + layer) / size; | 2221 pos.z = (pos.z + layer) / size; | 
| 2146 return mix(texture2D(sampler, pos.yz), | 2222 return mix(texture2D(sampler, pos.yz), | 
| 2147 texture2D(sampler, pos.yz + vec2(0, 1.0 / size)), | 2223 texture2D(sampler, pos.yz + vec2(0, 1.0 / size)), | 
| 2148 pos.x - layer); | 2224 pos.x - layer); | 
| 2149 } | 2225 } | 
| 2150 | |
| 2151 vec3 yuv2rgb(vec3 yuv) { | |
| 2152 yuv = (yuv - vec3(resource_offset)) * resource_multiplier; | |
| 2153 return LUT(lut_texture, yuv, 32.0).xyz; | |
| 2154 } | |
| 2155 }); | 2226 }); | 
| 2227 if (highbit_texture_ == HIGHBIT_LUMINANCE_F16) { | |
| 2228 head += " uniform float resource_multiplier;\n"; | |
| 2229 head += " uniform float resource_offset;\n"; | |
| 2230 functions += SHADER0([]() { | |
| 2231 vec3 yuv2rgb(vec3 yuv) { | |
| 2232 yuv = (yuv - vec3(resource_offset)) * resource_multiplier; | |
| 2233 return LUT(lut_texture, yuv, 32.0).xyz; | |
| 2234 } | |
| 2235 }); | |
| 2236 } else { | |
| 2237 functions += SHADER0([]() { | |
| 2238 vec3 yuv2rgb(vec3 yuv) { return LUT(lut_texture, yuv, 32.0).xyz; } | |
| 2239 }); | |
| 2240 } | |
| 2156 } else { | 2241 } else { | 
| 2157 head += " uniform mat3 yuv_matrix;\n"; | 2242 head += " uniform mat3 yuv_matrix;\n"; | 
| 2158 head += " uniform vec3 yuv_adj;\n"; | 2243 head += " uniform vec3 yuv_adj;\n"; | 
| 2159 functions += SHADER0([]() { | 2244 functions += SHADER0([]() { | 
| 2160 vec3 yuv2rgb(vec3 yuv) { return yuv_matrix * (yuv + yuv_adj); } | 2245 vec3 yuv2rgb(vec3 yuv) { return yuv_matrix * (yuv + yuv_adj); } | 
| 2161 }); | 2246 }); | 
| 2162 } | 2247 } | 
| 2163 | 2248 | 
| 2164 functions += SHADER0([]() { | 2249 functions += SHADER0([]() { | 
| 2165 void main() { | 2250 void main() { | 
| 2166 vec2 ya_clamped = | 2251 float y_raw = GetY(); | 
| 
hubbe
2016/09/28 17:57:44
GetUV and GetAlpha takes a parameter, probably Get
 
dshwang
2016/09/29 18:52:28
to make consistent, let me change it to get |v_yaT
 | |
| 2167 max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord)); | 2252 vec3 yuv = vec3(y_raw, GetUV(v_uvTexCoord)); | 
| 2168 float y_raw = TextureLookup(y_texture, ya_clamped).x; | 2253 gl_FragColor = vec4(yuv2rgb(yuv), 1.0) * GetAlpha(v_yaTexCoord); | 
| 2169 vec2 uv_clamped = | |
| 2170 max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord)); | |
| 2171 vec3 yuv = vec3(y_raw, GetUV(uv_clamped)); | |
| 2172 gl_FragColor = vec4(yuv2rgb(yuv), 1.0) * GetAlpha(ya_clamped); | |
| 2173 } | 2254 } | 
| 2174 }); | 2255 }); | 
| 2175 | 2256 | 
| 2176 return FRAGMENT_SHADER(head, functions); | 2257 return FRAGMENT_SHADER(head, functions); | 
| 2177 } | 2258 } | 
| 2178 | 2259 | 
| 2179 FragmentShaderColor::FragmentShaderColor() : color_location_(-1) { | 2260 FragmentShaderColor::FragmentShaderColor() : color_location_(-1) { | 
| 2180 } | 2261 } | 
| 2181 | 2262 | 
| 2182 void FragmentShaderColor::Init(GLES2Interface* context, | 2263 void FragmentShaderColor::Init(GLES2Interface* context, | 
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2252 void main() { | 2333 void main() { | 
| 2253 vec4 d4 = min(edge_dist[0], edge_dist[1]); | 2334 vec4 d4 = min(edge_dist[0], edge_dist[1]); | 
| 2254 vec2 d2 = min(d4.xz, d4.yw); | 2335 vec2 d2 = min(d4.xz, d4.yw); | 
| 2255 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0); | 2336 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0); | 
| 2256 gl_FragColor = color * aa; | 2337 gl_FragColor = color * aa; | 
| 2257 } | 2338 } | 
| 2258 }); | 2339 }); | 
| 2259 } | 2340 } | 
| 2260 | 2341 | 
| 2261 } // namespace cc | 2342 } // namespace cc | 
| OLD | NEW |