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

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

Issue 242643011: Add correct support for videos with YUVJ420P color format, in the software conversion path. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@yuvnopic
Patch Set: YUVJ browsertest now passes, update expectation Created 6 years, 7 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_mmx.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" 6 #include "media/base/simd/yuv_to_rgb_table.h"
7 7
8 namespace media { 8 namespace media {
9 9
10 #define packuswb(x) ((x) < 0 ? 0 : ((x) > 255 ? 255 : (x))) 10 #define packuswb(x) ((x) < 0 ? 0 : ((x) > 255 ? 255 : (x)))
(...skipping 20 matching lines...) Expand all
31 #define SK_A32_SHIFT 24 31 #define SK_A32_SHIFT 24
32 #define B_INDEX 0 32 #define B_INDEX 0
33 #define G_INDEX 1 33 #define G_INDEX 1
34 #define R_INDEX 2 34 #define R_INDEX 2
35 #define A_INDEX 3 35 #define A_INDEX 3
36 #endif 36 #endif
37 37
38 static inline void ConvertYUVToRGB32_C(uint8 y, 38 static inline void ConvertYUVToRGB32_C(uint8 y,
39 uint8 u, 39 uint8 u,
40 uint8 v, 40 uint8 v,
41 uint8* rgb_buf) { 41 uint8* rgb_buf,
42 int b = kCoefficientsRgbY[256+u][B_INDEX]; 42 const int16 convert_table[1024][4]) {
43 int g = kCoefficientsRgbY[256+u][G_INDEX]; 43 int b = convert_table[256+u][B_INDEX];
44 int r = kCoefficientsRgbY[256+u][R_INDEX]; 44 int g = convert_table[256+u][G_INDEX];
45 int a = kCoefficientsRgbY[256+u][A_INDEX]; 45 int r = convert_table[256+u][R_INDEX];
46 int a = convert_table[256+u][A_INDEX];
46 47
47 b = paddsw(b, kCoefficientsRgbY[512+v][B_INDEX]); 48 b = paddsw(b, convert_table[512+v][B_INDEX]);
48 g = paddsw(g, kCoefficientsRgbY[512+v][G_INDEX]); 49 g = paddsw(g, convert_table[512+v][G_INDEX]);
49 r = paddsw(r, kCoefficientsRgbY[512+v][R_INDEX]); 50 r = paddsw(r, convert_table[512+v][R_INDEX]);
50 a = paddsw(a, kCoefficientsRgbY[512+v][A_INDEX]); 51 a = paddsw(a, convert_table[512+v][A_INDEX]);
51 52
52 b = paddsw(b, kCoefficientsRgbY[y][B_INDEX]); 53 b = paddsw(b, convert_table[y][B_INDEX]);
53 g = paddsw(g, kCoefficientsRgbY[y][G_INDEX]); 54 g = paddsw(g, convert_table[y][G_INDEX]);
54 r = paddsw(r, kCoefficientsRgbY[y][R_INDEX]); 55 r = paddsw(r, convert_table[y][R_INDEX]);
55 a = paddsw(a, kCoefficientsRgbY[y][A_INDEX]); 56 a = paddsw(a, convert_table[y][A_INDEX]);
56 57
57 b >>= 6; 58 b >>= 6;
58 g >>= 6; 59 g >>= 6;
59 r >>= 6; 60 r >>= 6;
60 a >>= 6; 61 a >>= 6;
61 62
62 *reinterpret_cast<uint32*>(rgb_buf) = (packuswb(b) << SK_B32_SHIFT) | 63 *reinterpret_cast<uint32*>(rgb_buf) = (packuswb(b) << SK_B32_SHIFT) |
63 (packuswb(g) << SK_G32_SHIFT) | 64 (packuswb(g) << SK_G32_SHIFT) |
64 (packuswb(r) << SK_R32_SHIFT) | 65 (packuswb(r) << SK_R32_SHIFT) |
65 (packuswb(a) << SK_A32_SHIFT); 66 (packuswb(a) << SK_A32_SHIFT);
66 } 67 }
67 68
68 static inline void ConvertYUVAToARGB_C(uint8 y, 69 static inline void ConvertYUVAToARGB_C(uint8 y,
69 uint8 u, 70 uint8 u,
70 uint8 v, 71 uint8 v,
71 uint8 a, 72 uint8 a,
72 uint8* rgb_buf) { 73 uint8* rgb_buf,
73 int b = kCoefficientsRgbY[256+u][0]; 74 const int16 convert_table[1024][4]) {
74 int g = kCoefficientsRgbY[256+u][1]; 75 int b = convert_table[256+u][0];
75 int r = kCoefficientsRgbY[256+u][2]; 76 int g = convert_table[256+u][1];
77 int r = convert_table[256+u][2];
76 78
77 b = paddsw(b, kCoefficientsRgbY[512+v][0]); 79 b = paddsw(b, convert_table[512+v][0]);
78 g = paddsw(g, kCoefficientsRgbY[512+v][1]); 80 g = paddsw(g, convert_table[512+v][1]);
79 r = paddsw(r, kCoefficientsRgbY[512+v][2]); 81 r = paddsw(r, convert_table[512+v][2]);
80 82
81 b = paddsw(b, kCoefficientsRgbY[y][0]); 83 b = paddsw(b, convert_table[y][0]);
82 g = paddsw(g, kCoefficientsRgbY[y][1]); 84 g = paddsw(g, convert_table[y][1]);
83 r = paddsw(r, kCoefficientsRgbY[y][2]); 85 r = paddsw(r, convert_table[y][2]);
84 86
85 b >>= 6; 87 b >>= 6;
86 g >>= 6; 88 g >>= 6;
87 r >>= 6; 89 r >>= 6;
88 90
89 b = packuswb(b) * a >> 8; 91 b = packuswb(b) * a >> 8;
90 g = packuswb(g) * a >> 8; 92 g = packuswb(g) * a >> 8;
91 r = packuswb(r) * a >> 8; 93 r = packuswb(r) * a >> 8;
92 94
93 *reinterpret_cast<uint32*>(rgb_buf) = (b << SK_B32_SHIFT) | 95 *reinterpret_cast<uint32*>(rgb_buf) = (b << SK_B32_SHIFT) |
94 (g << SK_G32_SHIFT) | 96 (g << SK_G32_SHIFT) |
95 (r << SK_R32_SHIFT) | 97 (r << SK_R32_SHIFT) |
96 (a << SK_A32_SHIFT); 98 (a << SK_A32_SHIFT);
97 } 99 }
98 100
99 void ConvertYUVToRGB32Row_C(const uint8* y_buf, 101 void ConvertYUVToRGB32Row_C(const uint8* y_buf,
100 const uint8* u_buf, 102 const uint8* u_buf,
101 const uint8* v_buf, 103 const uint8* v_buf,
102 uint8* rgb_buf, 104 uint8* rgb_buf,
103 ptrdiff_t width) { 105 ptrdiff_t width,
106 const int16 convert_table[1024][4]) {
104 for (int x = 0; x < width; x += 2) { 107 for (int x = 0; x < width; x += 2) {
105 uint8 u = u_buf[x >> 1]; 108 uint8 u = u_buf[x >> 1];
106 uint8 v = v_buf[x >> 1]; 109 uint8 v = v_buf[x >> 1];
107 uint8 y0 = y_buf[x]; 110 uint8 y0 = y_buf[x];
108 ConvertYUVToRGB32_C(y0, u, v, rgb_buf); 111 ConvertYUVToRGB32_C(y0, u, v, rgb_buf, convert_table);
109 if ((x + 1) < width) { 112 if ((x + 1) < width) {
110 uint8 y1 = y_buf[x + 1]; 113 uint8 y1 = y_buf[x + 1];
111 ConvertYUVToRGB32_C(y1, u, v, rgb_buf + 4); 114 ConvertYUVToRGB32_C(y1, u, v, rgb_buf + 4, convert_table);
112 } 115 }
113 rgb_buf += 8; // Advance 2 pixels. 116 rgb_buf += 8; // Advance 2 pixels.
114 } 117 }
115 } 118 }
116 119
117 void ConvertYUVAToARGBRow_C(const uint8* y_buf, 120 void ConvertYUVAToARGBRow_C(const uint8* y_buf,
118 const uint8* u_buf, 121 const uint8* u_buf,
119 const uint8* v_buf, 122 const uint8* v_buf,
120 const uint8* a_buf, 123 const uint8* a_buf,
121 uint8* rgba_buf, 124 uint8* rgba_buf,
122 ptrdiff_t width) { 125 ptrdiff_t width,
126 const int16 convert_table[1024][4]) {
123 for (int x = 0; x < width; x += 2) { 127 for (int x = 0; x < width; x += 2) {
124 uint8 u = u_buf[x >> 1]; 128 uint8 u = u_buf[x >> 1];
125 uint8 v = v_buf[x >> 1]; 129 uint8 v = v_buf[x >> 1];
126 uint8 y0 = y_buf[x]; 130 uint8 y0 = y_buf[x];
127 uint8 a0 = a_buf[x]; 131 uint8 a0 = a_buf[x];
128 ConvertYUVAToARGB_C(y0, u, v, a0, rgba_buf); 132 ConvertYUVAToARGB_C(y0, u, v, a0, rgba_buf, convert_table);
129 if ((x + 1) < width) { 133 if ((x + 1) < width) {
130 uint8 y1 = y_buf[x + 1]; 134 uint8 y1 = y_buf[x + 1];
131 uint8 a1 = a_buf[x + 1]; 135 uint8 a1 = a_buf[x + 1];
132 ConvertYUVAToARGB_C(y1, u, v, a1, rgba_buf + 4); 136 ConvertYUVAToARGB_C(y1, u, v, a1, rgba_buf + 4, convert_table);
133 } 137 }
134 rgba_buf += 8; // Advance 2 pixels. 138 rgba_buf += 8; // Advance 2 pixels.
135 } 139 }
136 } 140 }
137 141
138 // 16.16 fixed point is used. A shift by 16 isolates the integer. 142 // 16.16 fixed point is used. A shift by 16 isolates the integer.
139 // A shift by 17 is used to further subsample the chrominence channels. 143 // A shift by 17 is used to further subsample the chrominence channels.
140 // & 0xffff isolates the fixed point fraction. >> 2 to get the upper 2 bits, 144 // & 0xffff isolates the fixed point fraction. >> 2 to get the upper 2 bits,
141 // for 1/65536 pixel accurate interpolation. 145 // for 1/65536 pixel accurate interpolation.
142 void ScaleYUVToRGB32Row_C(const uint8* y_buf, 146 void ScaleYUVToRGB32Row_C(const uint8* y_buf,
143 const uint8* u_buf, 147 const uint8* u_buf,
144 const uint8* v_buf, 148 const uint8* v_buf,
145 uint8* rgb_buf, 149 uint8* rgb_buf,
146 ptrdiff_t width, 150 ptrdiff_t width,
147 ptrdiff_t source_dx) { 151 ptrdiff_t source_dx,
152 const int16 convert_table[1024][4]) {
148 int x = 0; 153 int x = 0;
149 for (int i = 0; i < width; i += 2) { 154 for (int i = 0; i < width; i += 2) {
150 int y = y_buf[x >> 16]; 155 int y = y_buf[x >> 16];
151 int u = u_buf[(x >> 17)]; 156 int u = u_buf[(x >> 17)];
152 int v = v_buf[(x >> 17)]; 157 int v = v_buf[(x >> 17)];
153 ConvertYUVToRGB32_C(y, u, v, rgb_buf); 158 ConvertYUVToRGB32_C(y, u, v, rgb_buf, convert_table);
154 x += source_dx; 159 x += source_dx;
155 if ((i + 1) < width) { 160 if ((i + 1) < width) {
156 y = y_buf[x >> 16]; 161 y = y_buf[x >> 16];
157 ConvertYUVToRGB32_C(y, u, v, rgb_buf+4); 162 ConvertYUVToRGB32_C(y, u, v, rgb_buf+4, convert_table);
158 x += source_dx; 163 x += source_dx;
159 } 164 }
160 rgb_buf += 8; 165 rgb_buf += 8;
161 } 166 }
162 } 167 }
163 168
164 void LinearScaleYUVToRGB32Row_C(const uint8* y_buf, 169 void LinearScaleYUVToRGB32Row_C(const uint8* y_buf,
165 const uint8* u_buf, 170 const uint8* u_buf,
166 const uint8* v_buf, 171 const uint8* v_buf,
167 uint8* rgb_buf, 172 uint8* rgb_buf,
168 ptrdiff_t width, 173 ptrdiff_t width,
169 ptrdiff_t source_dx) { 174 ptrdiff_t source_dx,
175 const int16 convert_table[1024][4]) {
170 // Avoid point-sampling for down-scaling by > 2:1. 176 // Avoid point-sampling for down-scaling by > 2:1.
171 int source_x = 0; 177 int source_x = 0;
172 if (source_dx >= 0x20000) 178 if (source_dx >= 0x20000)
173 source_x += 0x8000; 179 source_x += 0x8000;
174 LinearScaleYUVToRGB32RowWithRange_C(y_buf, u_buf, v_buf, rgb_buf, width, 180 LinearScaleYUVToRGB32RowWithRange_C(y_buf, u_buf, v_buf, rgb_buf, width,
175 source_x, source_dx); 181 source_x, source_dx, convert_table);
176 } 182 }
177 183
178 void LinearScaleYUVToRGB32RowWithRange_C(const uint8* y_buf, 184 void LinearScaleYUVToRGB32RowWithRange_C(const uint8* y_buf,
179 const uint8* u_buf, 185 const uint8* u_buf,
180 const uint8* v_buf, 186 const uint8* v_buf,
181 uint8* rgb_buf, 187 uint8* rgb_buf,
182 int dest_width, 188 int dest_width,
183 int x, 189 int x,
184 int source_dx) { 190 int source_dx,
191 const int16 convert_table[1024][4]) {
185 for (int i = 0; i < dest_width; i += 2) { 192 for (int i = 0; i < dest_width; i += 2) {
186 int y0 = y_buf[x >> 16]; 193 int y0 = y_buf[x >> 16];
187 int y1 = y_buf[(x >> 16) + 1]; 194 int y1 = y_buf[(x >> 16) + 1];
188 int u0 = u_buf[(x >> 17)]; 195 int u0 = u_buf[(x >> 17)];
189 int u1 = u_buf[(x >> 17) + 1]; 196 int u1 = u_buf[(x >> 17) + 1];
190 int v0 = v_buf[(x >> 17)]; 197 int v0 = v_buf[(x >> 17)];
191 int v1 = v_buf[(x >> 17) + 1]; 198 int v1 = v_buf[(x >> 17) + 1];
192 int y_frac = (x & 65535); 199 int y_frac = (x & 65535);
193 int uv_frac = ((x >> 1) & 65535); 200 int uv_frac = ((x >> 1) & 65535);
194 int y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16; 201 int y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16;
195 int u = (uv_frac * u1 + (uv_frac ^ 65535) * u0) >> 16; 202 int u = (uv_frac * u1 + (uv_frac ^ 65535) * u0) >> 16;
196 int v = (uv_frac * v1 + (uv_frac ^ 65535) * v0) >> 16; 203 int v = (uv_frac * v1 + (uv_frac ^ 65535) * v0) >> 16;
197 ConvertYUVToRGB32_C(y, u, v, rgb_buf); 204 ConvertYUVToRGB32_C(y, u, v, rgb_buf, convert_table);
198 x += source_dx; 205 x += source_dx;
199 if ((i + 1) < dest_width) { 206 if ((i + 1) < dest_width) {
200 y0 = y_buf[x >> 16]; 207 y0 = y_buf[x >> 16];
201 y1 = y_buf[(x >> 16) + 1]; 208 y1 = y_buf[(x >> 16) + 1];
202 y_frac = (x & 65535); 209 y_frac = (x & 65535);
203 y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16; 210 y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16;
204 ConvertYUVToRGB32_C(y, u, v, rgb_buf+4); 211 ConvertYUVToRGB32_C(y, u, v, rgb_buf+4, convert_table);
205 x += source_dx; 212 x += source_dx;
206 } 213 }
207 rgb_buf += 8; 214 rgb_buf += 8;
208 } 215 }
209 } 216 }
210 217
211 void ConvertYUVToRGB32_C(const uint8* yplane, 218 void ConvertYUVToRGB32_C(const uint8* yplane,
212 const uint8* uplane, 219 const uint8* uplane,
213 const uint8* vplane, 220 const uint8* vplane,
214 uint8* rgbframe, 221 uint8* rgbframe,
215 int width, 222 int width,
216 int height, 223 int height,
217 int ystride, 224 int ystride,
218 int uvstride, 225 int uvstride,
219 int rgbstride, 226 int rgbstride,
220 YUVType yuv_type) { 227 YUVType yuv_type) {
221 unsigned int y_shift = yuv_type; 228 unsigned int y_shift = GetVerticalShift(yuv_type);
222 for (int y = 0; y < height; ++y) { 229 for (int y = 0; y < height; ++y) {
223 uint8* rgb_row = rgbframe + y * rgbstride; 230 uint8* rgb_row = rgbframe + y * rgbstride;
224 const uint8* y_ptr = yplane + y * ystride; 231 const uint8* y_ptr = yplane + y * ystride;
225 const uint8* u_ptr = uplane + (y >> y_shift) * uvstride; 232 const uint8* u_ptr = uplane + (y >> y_shift) * uvstride;
226 const uint8* v_ptr = vplane + (y >> y_shift) * uvstride; 233 const uint8* v_ptr = vplane + (y >> y_shift) * uvstride;
227 234
228 ConvertYUVToRGB32Row_C(y_ptr, 235 ConvertYUVToRGB32Row_C(y_ptr,
229 u_ptr, 236 u_ptr,
230 v_ptr, 237 v_ptr,
231 rgb_row, 238 rgb_row,
232 width); 239 width,
240 GetLookupTable(yuv_type));
233 } 241 }
234 } 242 }
235 243
236 void ConvertYUVAToARGB_C(const uint8* yplane, 244 void ConvertYUVAToARGB_C(const uint8* yplane,
237 const uint8* uplane, 245 const uint8* uplane,
238 const uint8* vplane, 246 const uint8* vplane,
239 const uint8* aplane, 247 const uint8* aplane,
240 uint8* rgbaframe, 248 uint8* rgbaframe,
241 int width, 249 int width,
242 int height, 250 int height,
243 int ystride, 251 int ystride,
244 int uvstride, 252 int uvstride,
245 int astride, 253 int astride,
246 int rgbastride, 254 int rgbastride,
247 YUVType yuv_type) { 255 YUVType yuv_type) {
248 unsigned int y_shift = yuv_type; 256 unsigned int y_shift = yuv_type;
249 for (int y = 0; y < height; y++) { 257 for (int y = 0; y < height; y++) {
250 uint8* rgba_row = rgbaframe + y * rgbastride; 258 uint8* rgba_row = rgbaframe + y * rgbastride;
251 const uint8* y_ptr = yplane + y * ystride; 259 const uint8* y_ptr = yplane + y * ystride;
252 const uint8* u_ptr = uplane + (y >> y_shift) * uvstride; 260 const uint8* u_ptr = uplane + (y >> y_shift) * uvstride;
253 const uint8* v_ptr = vplane + (y >> y_shift) * uvstride; 261 const uint8* v_ptr = vplane + (y >> y_shift) * uvstride;
254 const uint8* a_ptr = aplane + y * astride; 262 const uint8* a_ptr = aplane + y * astride;
255 263
256 ConvertYUVAToARGBRow_C(y_ptr, 264 ConvertYUVAToARGBRow_C(y_ptr,
257 u_ptr, 265 u_ptr,
258 v_ptr, 266 v_ptr,
259 a_ptr, 267 a_ptr,
260 rgba_row, 268 rgba_row,
261 width); 269 width,
270 GetLookupTable(yuv_type));
262 } 271 }
263 } 272 }
264 273
265 } // namespace media 274 } // namespace media
OLDNEW
« no previous file with comments | « media/base/simd/convert_yuv_to_rgb.h ('k') | media/base/simd/convert_yuv_to_rgb_mmx.asm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698