Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(127)

Side by Side Diff: media/base/simd/convert_yuv_to_rgb_c.cc

Issue 591313008: Add support for Rec709 color space videos in software YUV convert path. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add enum to mojom Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/base/simd/convert_yuv_to_rgb.h ('k') | media/base/simd/convert_yuv_to_rgb_sse.asm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "media/base/simd/convert_yuv_to_rgb.h" 5 #include "media/base/simd/convert_yuv_to_rgb.h"
6 #include "media/base/simd/yuv_to_rgb_table.h"
7 6
8 namespace media { 7 namespace media {
9 8
10 #define packuswb(x) ((x) < 0 ? 0 : ((x) > 255 ? 255 : (x))) 9 #define packuswb(x) ((x) < 0 ? 0 : ((x) > 255 ? 255 : (x)))
11 #define paddsw(x, y) (((x) + (y)) < -32768 ? -32768 : \ 10 #define paddsw(x, y) (((x) + (y)) < -32768 ? -32768 : \
12 (((x) + (y)) > 32767 ? 32767 : ((x) + (y)))) 11 (((x) + (y)) > 32767 ? 32767 : ((x) + (y))))
13 12
14 // On Android, pixel layout is RGBA (see skia/include/core/SkColorPriv.h); 13 // On Android, pixel layout is RGBA (see skia/include/core/SkColorPriv.h);
15 // however, other Chrome platforms use BGRA (see skia/config/SkUserConfig.h). 14 // however, other Chrome platforms use BGRA (see skia/config/SkUserConfig.h).
16 // Ideally, android should not use the functions here due to performance issue 15 // Ideally, android should not use the functions here due to performance issue
(...skipping 15 matching lines...) Expand all
32 #define B_INDEX 0 31 #define B_INDEX 0
33 #define G_INDEX 1 32 #define G_INDEX 1
34 #define R_INDEX 2 33 #define R_INDEX 2
35 #define A_INDEX 3 34 #define A_INDEX 3
36 #endif 35 #endif
37 36
38 static inline void ConvertYUVToRGB32_C(uint8 y, 37 static inline void ConvertYUVToRGB32_C(uint8 y,
39 uint8 u, 38 uint8 u,
40 uint8 v, 39 uint8 v,
41 uint8* rgb_buf, 40 uint8* rgb_buf,
42 const int16 convert_table[1024][4]) { 41 const int16* convert_table) {
43 int b = convert_table[256+u][B_INDEX]; 42 int b = convert_table[4 * (256 + u) + B_INDEX];
44 int g = convert_table[256+u][G_INDEX]; 43 int g = convert_table[4 * (256 + u) + G_INDEX];
45 int r = convert_table[256+u][R_INDEX]; 44 int r = convert_table[4 * (256 + u) + R_INDEX];
46 int a = convert_table[256+u][A_INDEX]; 45 int a = convert_table[4 * (256 + u) + A_INDEX];
47 46
48 b = paddsw(b, convert_table[512+v][B_INDEX]); 47 b = paddsw(b, convert_table[4 * (512 + v) + B_INDEX]);
49 g = paddsw(g, convert_table[512+v][G_INDEX]); 48 g = paddsw(g, convert_table[4 * (512 + v) + G_INDEX]);
50 r = paddsw(r, convert_table[512+v][R_INDEX]); 49 r = paddsw(r, convert_table[4 * (512 + v) + R_INDEX]);
51 a = paddsw(a, convert_table[512+v][A_INDEX]); 50 a = paddsw(a, convert_table[4 * (512 + v) + A_INDEX]);
52 51
53 b = paddsw(b, convert_table[y][B_INDEX]); 52 b = paddsw(b, convert_table[4 * y + B_INDEX]);
54 g = paddsw(g, convert_table[y][G_INDEX]); 53 g = paddsw(g, convert_table[4 * y + G_INDEX]);
55 r = paddsw(r, convert_table[y][R_INDEX]); 54 r = paddsw(r, convert_table[4 * y + R_INDEX]);
56 a = paddsw(a, convert_table[y][A_INDEX]); 55 a = paddsw(a, convert_table[4 * y + A_INDEX]);
57 56
58 b >>= 6; 57 b >>= 6;
59 g >>= 6; 58 g >>= 6;
60 r >>= 6; 59 r >>= 6;
61 a >>= 6; 60 a >>= 6;
62 61
63 *reinterpret_cast<uint32*>(rgb_buf) = (packuswb(b) << SK_B32_SHIFT) | 62 *reinterpret_cast<uint32*>(rgb_buf) = (packuswb(b) << SK_B32_SHIFT) |
64 (packuswb(g) << SK_G32_SHIFT) | 63 (packuswb(g) << SK_G32_SHIFT) |
65 (packuswb(r) << SK_R32_SHIFT) | 64 (packuswb(r) << SK_R32_SHIFT) |
66 (packuswb(a) << SK_A32_SHIFT); 65 (packuswb(a) << SK_A32_SHIFT);
67 } 66 }
68 67
69 static inline void ConvertYUVAToARGB_C(uint8 y, 68 static inline void ConvertYUVAToARGB_C(uint8 y,
70 uint8 u, 69 uint8 u,
71 uint8 v, 70 uint8 v,
72 uint8 a, 71 uint8 a,
73 uint8* rgb_buf, 72 uint8* rgb_buf,
74 const int16 convert_table[1024][4]) { 73 const int16* convert_table) {
75 int b = convert_table[256+u][0]; 74 int b = convert_table[4 * (256 + u) + 0];
76 int g = convert_table[256+u][1]; 75 int g = convert_table[4 * (256 + u) + 1];
77 int r = convert_table[256+u][2]; 76 int r = convert_table[4 * (256 + u) + 2];
78 77
79 b = paddsw(b, convert_table[512+v][0]); 78 b = paddsw(b, convert_table[4 * (512 + v) + 0]);
80 g = paddsw(g, convert_table[512+v][1]); 79 g = paddsw(g, convert_table[4 * (512 + v) + 1]);
81 r = paddsw(r, convert_table[512+v][2]); 80 r = paddsw(r, convert_table[4 * (512 + v) + 2]);
82 81
83 b = paddsw(b, convert_table[y][0]); 82 b = paddsw(b, convert_table[4 * y + 0]);
84 g = paddsw(g, convert_table[y][1]); 83 g = paddsw(g, convert_table[4 * y + 1]);
85 r = paddsw(r, convert_table[y][2]); 84 r = paddsw(r, convert_table[4 * y + 2]);
86 85
87 b >>= 6; 86 b >>= 6;
88 g >>= 6; 87 g >>= 6;
89 r >>= 6; 88 r >>= 6;
90 89
91 b = packuswb(b) * a >> 8; 90 b = packuswb(b) * a >> 8;
92 g = packuswb(g) * a >> 8; 91 g = packuswb(g) * a >> 8;
93 r = packuswb(r) * a >> 8; 92 r = packuswb(r) * a >> 8;
94 93
95 *reinterpret_cast<uint32*>(rgb_buf) = (b << SK_B32_SHIFT) | 94 *reinterpret_cast<uint32*>(rgb_buf) = (b << SK_B32_SHIFT) |
96 (g << SK_G32_SHIFT) | 95 (g << SK_G32_SHIFT) |
97 (r << SK_R32_SHIFT) | 96 (r << SK_R32_SHIFT) |
98 (a << SK_A32_SHIFT); 97 (a << SK_A32_SHIFT);
99 } 98 }
100 99
101 void ConvertYUVToRGB32Row_C(const uint8* y_buf, 100 void ConvertYUVToRGB32Row_C(const uint8* y_buf,
102 const uint8* u_buf, 101 const uint8* u_buf,
103 const uint8* v_buf, 102 const uint8* v_buf,
104 uint8* rgb_buf, 103 uint8* rgb_buf,
105 ptrdiff_t width, 104 ptrdiff_t width,
106 const int16 convert_table[1024][4]) { 105 const int16* convert_table) {
107 for (int x = 0; x < width; x += 2) { 106 for (int x = 0; x < width; x += 2) {
108 uint8 u = u_buf[x >> 1]; 107 uint8 u = u_buf[x >> 1];
109 uint8 v = v_buf[x >> 1]; 108 uint8 v = v_buf[x >> 1];
110 uint8 y0 = y_buf[x]; 109 uint8 y0 = y_buf[x];
111 ConvertYUVToRGB32_C(y0, u, v, rgb_buf, convert_table); 110 ConvertYUVToRGB32_C(y0, u, v, rgb_buf, convert_table);
112 if ((x + 1) < width) { 111 if ((x + 1) < width) {
113 uint8 y1 = y_buf[x + 1]; 112 uint8 y1 = y_buf[x + 1];
114 ConvertYUVToRGB32_C(y1, u, v, rgb_buf + 4, convert_table); 113 ConvertYUVToRGB32_C(y1, u, v, rgb_buf + 4, convert_table);
115 } 114 }
116 rgb_buf += 8; // Advance 2 pixels. 115 rgb_buf += 8; // Advance 2 pixels.
117 } 116 }
118 } 117 }
119 118
120 void ConvertYUVAToARGBRow_C(const uint8* y_buf, 119 void ConvertYUVAToARGBRow_C(const uint8* y_buf,
121 const uint8* u_buf, 120 const uint8* u_buf,
122 const uint8* v_buf, 121 const uint8* v_buf,
123 const uint8* a_buf, 122 const uint8* a_buf,
124 uint8* rgba_buf, 123 uint8* rgba_buf,
125 ptrdiff_t width, 124 ptrdiff_t width,
126 const int16 convert_table[1024][4]) { 125 const int16* convert_table) {
127 for (int x = 0; x < width; x += 2) { 126 for (int x = 0; x < width; x += 2) {
128 uint8 u = u_buf[x >> 1]; 127 uint8 u = u_buf[x >> 1];
129 uint8 v = v_buf[x >> 1]; 128 uint8 v = v_buf[x >> 1];
130 uint8 y0 = y_buf[x]; 129 uint8 y0 = y_buf[x];
131 uint8 a0 = a_buf[x]; 130 uint8 a0 = a_buf[x];
132 ConvertYUVAToARGB_C(y0, u, v, a0, rgba_buf, convert_table); 131 ConvertYUVAToARGB_C(y0, u, v, a0, rgba_buf, convert_table);
133 if ((x + 1) < width) { 132 if ((x + 1) < width) {
134 uint8 y1 = y_buf[x + 1]; 133 uint8 y1 = y_buf[x + 1];
135 uint8 a1 = a_buf[x + 1]; 134 uint8 a1 = a_buf[x + 1];
136 ConvertYUVAToARGB_C(y1, u, v, a1, rgba_buf + 4, convert_table); 135 ConvertYUVAToARGB_C(y1, u, v, a1, rgba_buf + 4, convert_table);
137 } 136 }
138 rgba_buf += 8; // Advance 2 pixels. 137 rgba_buf += 8; // Advance 2 pixels.
139 } 138 }
140 } 139 }
141 140
142 // 16.16 fixed point is used. A shift by 16 isolates the integer. 141 // 16.16 fixed point is used. A shift by 16 isolates the integer.
143 // A shift by 17 is used to further subsample the chrominence channels. 142 // A shift by 17 is used to further subsample the chrominence channels.
144 // & 0xffff isolates the fixed point fraction. >> 2 to get the upper 2 bits, 143 // & 0xffff isolates the fixed point fraction. >> 2 to get the upper 2 bits,
145 // for 1/65536 pixel accurate interpolation. 144 // for 1/65536 pixel accurate interpolation.
146 void ScaleYUVToRGB32Row_C(const uint8* y_buf, 145 void ScaleYUVToRGB32Row_C(const uint8* y_buf,
147 const uint8* u_buf, 146 const uint8* u_buf,
148 const uint8* v_buf, 147 const uint8* v_buf,
149 uint8* rgb_buf, 148 uint8* rgb_buf,
150 ptrdiff_t width, 149 ptrdiff_t width,
151 ptrdiff_t source_dx, 150 ptrdiff_t source_dx,
152 const int16 convert_table[1024][4]) { 151 const int16* convert_table) {
153 int x = 0; 152 int x = 0;
154 for (int i = 0; i < width; i += 2) { 153 for (int i = 0; i < width; i += 2) {
155 int y = y_buf[x >> 16]; 154 int y = y_buf[x >> 16];
156 int u = u_buf[(x >> 17)]; 155 int u = u_buf[(x >> 17)];
157 int v = v_buf[(x >> 17)]; 156 int v = v_buf[(x >> 17)];
158 ConvertYUVToRGB32_C(y, u, v, rgb_buf, convert_table); 157 ConvertYUVToRGB32_C(y, u, v, rgb_buf, convert_table);
159 x += source_dx; 158 x += source_dx;
160 if ((i + 1) < width) { 159 if ((i + 1) < width) {
161 y = y_buf[x >> 16]; 160 y = y_buf[x >> 16];
162 ConvertYUVToRGB32_C(y, u, v, rgb_buf+4, convert_table); 161 ConvertYUVToRGB32_C(y, u, v, rgb_buf+4, convert_table);
163 x += source_dx; 162 x += source_dx;
164 } 163 }
165 rgb_buf += 8; 164 rgb_buf += 8;
166 } 165 }
167 } 166 }
168 167
169 void LinearScaleYUVToRGB32Row_C(const uint8* y_buf, 168 void LinearScaleYUVToRGB32Row_C(const uint8* y_buf,
170 const uint8* u_buf, 169 const uint8* u_buf,
171 const uint8* v_buf, 170 const uint8* v_buf,
172 uint8* rgb_buf, 171 uint8* rgb_buf,
173 ptrdiff_t width, 172 ptrdiff_t width,
174 ptrdiff_t source_dx, 173 ptrdiff_t source_dx,
175 const int16 convert_table[1024][4]) { 174 const int16* convert_table) {
176 // Avoid point-sampling for down-scaling by > 2:1. 175 // Avoid point-sampling for down-scaling by > 2:1.
177 int source_x = 0; 176 int source_x = 0;
178 if (source_dx >= 0x20000) 177 if (source_dx >= 0x20000)
179 source_x += 0x8000; 178 source_x += 0x8000;
180 LinearScaleYUVToRGB32RowWithRange_C(y_buf, u_buf, v_buf, rgb_buf, width, 179 LinearScaleYUVToRGB32RowWithRange_C(y_buf, u_buf, v_buf, rgb_buf, width,
181 source_x, source_dx, convert_table); 180 source_x, source_dx, convert_table);
182 } 181 }
183 182
184 void LinearScaleYUVToRGB32RowWithRange_C(const uint8* y_buf, 183 void LinearScaleYUVToRGB32RowWithRange_C(const uint8* y_buf,
185 const uint8* u_buf, 184 const uint8* u_buf,
186 const uint8* v_buf, 185 const uint8* v_buf,
187 uint8* rgb_buf, 186 uint8* rgb_buf,
188 int dest_width, 187 int dest_width,
189 int x, 188 int x,
190 int source_dx, 189 int source_dx,
191 const int16 convert_table[1024][4]) { 190 const int16* convert_table) {
192 for (int i = 0; i < dest_width; i += 2) { 191 for (int i = 0; i < dest_width; i += 2) {
193 int y0 = y_buf[x >> 16]; 192 int y0 = y_buf[x >> 16];
194 int y1 = y_buf[(x >> 16) + 1]; 193 int y1 = y_buf[(x >> 16) + 1];
195 int u0 = u_buf[(x >> 17)]; 194 int u0 = u_buf[(x >> 17)];
196 int u1 = u_buf[(x >> 17) + 1]; 195 int u1 = u_buf[(x >> 17) + 1];
197 int v0 = v_buf[(x >> 17)]; 196 int v0 = v_buf[(x >> 17)];
198 int v1 = v_buf[(x >> 17) + 1]; 197 int v1 = v_buf[(x >> 17) + 1];
199 int y_frac = (x & 65535); 198 int y_frac = (x & 65535);
200 int uv_frac = ((x >> 1) & 65535); 199 int uv_frac = ((x >> 1) & 65535);
201 int y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16; 200 int y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16;
(...skipping 17 matching lines...) Expand all
219 const uint8* uplane, 218 const uint8* uplane,
220 const uint8* vplane, 219 const uint8* vplane,
221 uint8* rgbframe, 220 uint8* rgbframe,
222 int width, 221 int width,
223 int height, 222 int height,
224 int ystride, 223 int ystride,
225 int uvstride, 224 int uvstride,
226 int rgbstride, 225 int rgbstride,
227 YUVType yuv_type) { 226 YUVType yuv_type) {
228 unsigned int y_shift = GetVerticalShift(yuv_type); 227 unsigned int y_shift = GetVerticalShift(yuv_type);
228 const int16* lookup_table = GetLookupTable(yuv_type);
229 for (int y = 0; y < height; ++y) { 229 for (int y = 0; y < height; ++y) {
230 uint8* rgb_row = rgbframe + y * rgbstride; 230 uint8* rgb_row = rgbframe + y * rgbstride;
231 const uint8* y_ptr = yplane + y * ystride; 231 const uint8* y_ptr = yplane + y * ystride;
232 const uint8* u_ptr = uplane + (y >> y_shift) * uvstride; 232 const uint8* u_ptr = uplane + (y >> y_shift) * uvstride;
233 const uint8* v_ptr = vplane + (y >> y_shift) * uvstride; 233 const uint8* v_ptr = vplane + (y >> y_shift) * uvstride;
234 234
235 ConvertYUVToRGB32Row_C(y_ptr, 235 ConvertYUVToRGB32Row_C(y_ptr,
236 u_ptr, 236 u_ptr,
237 v_ptr, 237 v_ptr,
238 rgb_row, 238 rgb_row,
239 width, 239 width,
240 GetLookupTable(yuv_type)); 240 lookup_table);
241 } 241 }
242 } 242 }
243 243
244 void ConvertYUVAToARGB_C(const uint8* yplane, 244 void ConvertYUVAToARGB_C(const uint8* yplane,
245 const uint8* uplane, 245 const uint8* uplane,
246 const uint8* vplane, 246 const uint8* vplane,
247 const uint8* aplane, 247 const uint8* aplane,
248 uint8* rgbaframe, 248 uint8* rgbaframe,
249 int width, 249 int width,
250 int height, 250 int height,
251 int ystride, 251 int ystride,
252 int uvstride, 252 int uvstride,
253 int astride, 253 int astride,
254 int rgbastride, 254 int rgbastride,
255 YUVType yuv_type) { 255 YUVType yuv_type) {
256 unsigned int y_shift = yuv_type; 256 unsigned int y_shift = GetVerticalShift(yuv_type);
257 const int16* lookup_table = GetLookupTable(yuv_type);
257 for (int y = 0; y < height; y++) { 258 for (int y = 0; y < height; y++) {
258 uint8* rgba_row = rgbaframe + y * rgbastride; 259 uint8* rgba_row = rgbaframe + y * rgbastride;
259 const uint8* y_ptr = yplane + y * ystride; 260 const uint8* y_ptr = yplane + y * ystride;
260 const uint8* u_ptr = uplane + (y >> y_shift) * uvstride; 261 const uint8* u_ptr = uplane + (y >> y_shift) * uvstride;
261 const uint8* v_ptr = vplane + (y >> y_shift) * uvstride; 262 const uint8* v_ptr = vplane + (y >> y_shift) * uvstride;
262 const uint8* a_ptr = aplane + y * astride; 263 const uint8* a_ptr = aplane + y * astride;
263 264
264 ConvertYUVAToARGBRow_C(y_ptr, 265 ConvertYUVAToARGBRow_C(y_ptr,
265 u_ptr, 266 u_ptr,
266 v_ptr, 267 v_ptr,
267 a_ptr, 268 a_ptr,
268 rgba_row, 269 rgba_row,
269 width, 270 width,
270 GetLookupTable(yuv_type)); 271 lookup_table);
271 } 272 }
272 } 273 }
273 274
274 } // namespace media 275 } // namespace media
OLDNEW
« no previous file with comments | « media/base/simd/convert_yuv_to_rgb.h ('k') | media/base/simd/convert_yuv_to_rgb_sse.asm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698