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

Side by Side Diff: media/base/yuv_row_win.cc

Issue 7888012: Reorganize YUV scalers (Continued) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 3 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/base/yuv_row.h"
6
7 #define kCoefficientsRgbU kCoefficientsRgbY + 2048
8 #define kCoefficientsRgbV kCoefficientsRgbY + 4096
9
10 extern "C" {
11
12 #if USE_MMX
13 __declspec(naked)
14 void FastConvertYUVToRGB32Row(const uint8* y_buf,
15 const uint8* u_buf,
16 const uint8* v_buf,
17 uint8* rgb_buf,
18 int width) {
19 __asm {
20 pushad
21 mov edx, [esp + 32 + 4] // Y
22 mov edi, [esp + 32 + 8] // U
23 mov esi, [esp + 32 + 12] // V
24 mov ebp, [esp + 32 + 16] // rgb
25 mov ecx, [esp + 32 + 20] // width
26 jmp convertend
27
28 convertloop :
29 movzx eax, byte ptr [edi]
30 add edi, 1
31 movzx ebx, byte ptr [esi]
32 add esi, 1
33 movq mm0, [kCoefficientsRgbU + 8 * eax]
34 movzx eax, byte ptr [edx]
35 paddsw mm0, [kCoefficientsRgbV + 8 * ebx]
36 movzx ebx, byte ptr [edx + 1]
37 movq mm1, [kCoefficientsRgbY + 8 * eax]
38 add edx, 2
39 movq mm2, [kCoefficientsRgbY + 8 * ebx]
40 paddsw mm1, mm0
41 paddsw mm2, mm0
42 psraw mm1, 6
43 psraw mm2, 6
44 packuswb mm1, mm2
45 movntq [ebp], mm1
46 add ebp, 8
47 convertend :
48 sub ecx, 2
49 jns convertloop
50
51 and ecx, 1 // odd number of pixels?
52 jz convertdone
53
54 movzx eax, byte ptr [edi]
55 movq mm0, [kCoefficientsRgbU + 8 * eax]
56 movzx eax, byte ptr [esi]
57 paddsw mm0, [kCoefficientsRgbV + 8 * eax]
58 movzx eax, byte ptr [edx]
59 movq mm1, [kCoefficientsRgbY + 8 * eax]
60 paddsw mm1, mm0
61 psraw mm1, 6
62 packuswb mm1, mm1
63 movd [ebp], mm1
64 convertdone :
65
66 popad
67 ret
68 }
69 }
70
71 __declspec(naked)
72 void ConvertYUVToRGB32Row(const uint8* y_buf,
73 const uint8* u_buf,
74 const uint8* v_buf,
75 uint8* rgb_buf,
76 int width,
77 int step) {
78 __asm {
79 pushad
80 mov edx, [esp + 32 + 4] // Y
81 mov edi, [esp + 32 + 8] // U
82 mov esi, [esp + 32 + 12] // V
83 mov ebp, [esp + 32 + 16] // rgb
84 mov ecx, [esp + 32 + 20] // width
85 mov ebx, [esp + 32 + 24] // step
86 jmp wend
87
88 wloop :
89 movzx eax, byte ptr [edi]
90 add edi, ebx
91 movq mm0, [kCoefficientsRgbU + 8 * eax]
92 movzx eax, byte ptr [esi]
93 add esi, ebx
94 paddsw mm0, [kCoefficientsRgbV + 8 * eax]
95 movzx eax, byte ptr [edx]
96 add edx, ebx
97 movq mm1, [kCoefficientsRgbY + 8 * eax]
98 movzx eax, byte ptr [edx]
99 add edx, ebx
100 movq mm2, [kCoefficientsRgbY + 8 * eax]
101 paddsw mm1, mm0
102 paddsw mm2, mm0
103 psraw mm1, 6
104 psraw mm2, 6
105 packuswb mm1, mm2
106 movntq [ebp], mm1
107 add ebp, 8
108 wend :
109 sub ecx, 2
110 jns wloop
111
112 and ecx, 1 // odd number of pixels?
113 jz wdone
114
115 movzx eax, byte ptr [edi]
116 movq mm0, [kCoefficientsRgbU + 8 * eax]
117 movzx eax, byte ptr [esi]
118 paddsw mm0, [kCoefficientsRgbV + 8 * eax]
119 movzx eax, byte ptr [edx]
120 movq mm1, [kCoefficientsRgbY + 8 * eax]
121 paddsw mm1, mm0
122 psraw mm1, 6
123 packuswb mm1, mm1
124 movd [ebp], mm1
125 wdone :
126
127 popad
128 ret
129 }
130 }
131
132 __declspec(naked)
133 void RotateConvertYUVToRGB32Row(const uint8* y_buf,
134 const uint8* u_buf,
135 const uint8* v_buf,
136 uint8* rgb_buf,
137 int width,
138 int ystep,
139 int uvstep) {
140 __asm {
141 pushad
142 mov edx, [esp + 32 + 4] // Y
143 mov edi, [esp + 32 + 8] // U
144 mov esi, [esp + 32 + 12] // V
145 mov ebp, [esp + 32 + 16] // rgb
146 mov ecx, [esp + 32 + 20] // width
147 jmp wend
148
149 wloop :
150 movzx eax, byte ptr [edi]
151 mov ebx, [esp + 32 + 28] // uvstep
152 add edi, ebx
153 movq mm0, [kCoefficientsRgbU + 8 * eax]
154 movzx eax, byte ptr [esi]
155 add esi, ebx
156 paddsw mm0, [kCoefficientsRgbV + 8 * eax]
157 movzx eax, byte ptr [edx]
158 mov ebx, [esp + 32 + 24] // ystep
159 add edx, ebx
160 movq mm1, [kCoefficientsRgbY + 8 * eax]
161 movzx eax, byte ptr [edx]
162 add edx, ebx
163 movq mm2, [kCoefficientsRgbY + 8 * eax]
164 paddsw mm1, mm0
165 paddsw mm2, mm0
166 psraw mm1, 6
167 psraw mm2, 6
168 packuswb mm1, mm2
169 movntq [ebp], mm1
170 add ebp, 8
171 wend :
172 sub ecx, 2
173 jns wloop
174
175 and ecx, 1 // odd number of pixels?
176 jz wdone
177
178 movzx eax, byte ptr [edi]
179 movq mm0, [kCoefficientsRgbU + 8 * eax]
180 movzx eax, byte ptr [esi]
181 paddsw mm0, [kCoefficientsRgbV + 8 * eax]
182 movzx eax, byte ptr [edx]
183 movq mm1, [kCoefficientsRgbY + 8 * eax]
184 paddsw mm1, mm0
185 psraw mm1, 6
186 packuswb mm1, mm1
187 movd [ebp], mm1
188 wdone :
189
190 popad
191 ret
192 }
193 }
194
195 __declspec(naked)
196 void DoubleYUVToRGB32Row(const uint8* y_buf,
197 const uint8* u_buf,
198 const uint8* v_buf,
199 uint8* rgb_buf,
200 int width) {
201 __asm {
202 pushad
203 mov edx, [esp + 32 + 4] // Y
204 mov edi, [esp + 32 + 8] // U
205 mov esi, [esp + 32 + 12] // V
206 mov ebp, [esp + 32 + 16] // rgb
207 mov ecx, [esp + 32 + 20] // width
208 jmp wend
209
210 wloop :
211 movzx eax, byte ptr [edi]
212 add edi, 1
213 movzx ebx, byte ptr [esi]
214 add esi, 1
215 movq mm0, [kCoefficientsRgbU + 8 * eax]
216 movzx eax, byte ptr [edx]
217 paddsw mm0, [kCoefficientsRgbV + 8 * ebx]
218 movq mm1, [kCoefficientsRgbY + 8 * eax]
219 paddsw mm1, mm0
220 psraw mm1, 6
221 packuswb mm1, mm1
222 punpckldq mm1, mm1
223 movntq [ebp], mm1
224
225 movzx ebx, byte ptr [edx + 1]
226 add edx, 2
227 paddsw mm0, [kCoefficientsRgbY + 8 * ebx]
228 psraw mm0, 6
229 packuswb mm0, mm0
230 punpckldq mm0, mm0
231 movntq [ebp+8], mm0
232 add ebp, 16
233 wend :
234 sub ecx, 4
235 jns wloop
236
237 add ecx, 4
238 jz wdone
239
240 movzx eax, byte ptr [edi]
241 movq mm0, [kCoefficientsRgbU + 8 * eax]
242 movzx eax, byte ptr [esi]
243 paddsw mm0, [kCoefficientsRgbV + 8 * eax]
244 movzx eax, byte ptr [edx]
245 movq mm1, [kCoefficientsRgbY + 8 * eax]
246 paddsw mm1, mm0
247 psraw mm1, 6
248 packuswb mm1, mm1
249 jmp wend1
250
251 wloop1 :
252 movd [ebp], mm1
253 add ebp, 4
254 wend1 :
255 sub ecx, 1
256 jns wloop1
257 wdone :
258 popad
259 ret
260 }
261 }
262
263 // This version does general purpose scaling by any amount, up or down.
264 // The only thing it can not do it rotation by 90 or 270.
265 // For performance the chroma is under sampled, reducing cost of a 3x
266 // 1080p scale from 8.4 ms to 5.4 ms.
267 __declspec(naked)
268 void ScaleYUVToRGB32Row(const uint8* y_buf,
269 const uint8* u_buf,
270 const uint8* v_buf,
271 uint8* rgb_buf,
272 int width,
273 int source_dx) {
274 __asm {
275 pushad
276 mov edx, [esp + 32 + 4] // Y
277 mov edi, [esp + 32 + 8] // U
278 mov esi, [esp + 32 + 12] // V
279 mov ebp, [esp + 32 + 16] // rgb
280 mov ecx, [esp + 32 + 20] // width
281 xor ebx, ebx // x
282 jmp scaleend
283
284 scaleloop :
285 mov eax, ebx
286 sar eax, 17
287 movzx eax, byte ptr [edi + eax]
288 movq mm0, [kCoefficientsRgbU + 8 * eax]
289 mov eax, ebx
290 sar eax, 17
291 movzx eax, byte ptr [esi + eax]
292 paddsw mm0, [kCoefficientsRgbV + 8 * eax]
293 mov eax, ebx
294 add ebx, [esp + 32 + 24] // x += source_dx
295 sar eax, 16
296 movzx eax, byte ptr [edx + eax]
297 movq mm1, [kCoefficientsRgbY + 8 * eax]
298 mov eax, ebx
299 add ebx, [esp + 32 + 24] // x += source_dx
300 sar eax, 16
301 movzx eax, byte ptr [edx + eax]
302 movq mm2, [kCoefficientsRgbY + 8 * eax]
303 paddsw mm1, mm0
304 paddsw mm2, mm0
305 psraw mm1, 6
306 psraw mm2, 6
307 packuswb mm1, mm2
308 movntq [ebp], mm1
309 add ebp, 8
310 scaleend :
311 sub ecx, 2
312 jns scaleloop
313
314 and ecx, 1 // odd number of pixels?
315 jz scaledone
316
317 mov eax, ebx
318 sar eax, 17
319 movzx eax, byte ptr [edi + eax]
320 movq mm0, [kCoefficientsRgbU + 8 * eax]
321 mov eax, ebx
322 sar eax, 17
323 movzx eax, byte ptr [esi + eax]
324 paddsw mm0, [kCoefficientsRgbV + 8 * eax]
325 mov eax, ebx
326 sar eax, 16
327 movzx eax, byte ptr [edx + eax]
328 movq mm1, [kCoefficientsRgbY + 8 * eax]
329 paddsw mm1, mm0
330 psraw mm1, 6
331 packuswb mm1, mm1
332 movd [ebp], mm1
333
334 scaledone :
335 popad
336 ret
337 }
338 }
339
340 __declspec(naked)
341 void LinearScaleYUVToRGB32Row(const uint8* y_buf,
342 const uint8* u_buf,
343 const uint8* v_buf,
344 uint8* rgb_buf,
345 int width,
346 int source_dx) {
347 __asm {
348 pushad
349 mov edx, [esp + 32 + 4] // Y
350 mov edi, [esp + 32 + 8] // U
351 // [esp + 32 + 12] // V
352 mov ebp, [esp + 32 + 16] // rgb
353 mov ecx, [esp + 32 + 20] // width
354 imul ecx, [esp + 32 + 24] // source_dx
355 mov [esp + 32 + 20], ecx // source_width = width * source_dx
356 mov ecx, [esp + 32 + 24] // source_dx
357 xor ebx, ebx // x = 0
358 cmp ecx, 0x20000
359 jl lscaleend
360 mov ebx, 0x8000 // x = 0.5 for 1/2 or less
361 jmp lscaleend
362 lscaleloop:
363 mov eax, ebx
364 sar eax, 0x11
365
366 movzx ecx, byte ptr [edi + eax]
367 movzx esi, byte ptr [edi + eax + 1]
368 mov eax, ebx
369 and eax, 0x1fffe
370 imul esi, eax
371 xor eax, 0x1fffe
372 imul ecx, eax
373 add ecx, esi
374 shr ecx, 17
375 movq mm0, [kCoefficientsRgbU + 8 * ecx]
376
377 mov esi, [esp + 32 + 12]
378 mov eax, ebx
379 sar eax, 0x11
380
381 movzx ecx, byte ptr [esi + eax]
382 movzx esi, byte ptr [esi + eax + 1]
383 mov eax, ebx
384 and eax, 0x1fffe
385 imul esi, eax
386 xor eax, 0x1fffe
387 imul ecx, eax
388 add ecx, esi
389 shr ecx, 17
390 paddsw mm0, [kCoefficientsRgbV + 8 * ecx]
391
392 mov eax, ebx
393 sar eax, 0x10
394 movzx ecx, byte ptr [edx + eax]
395 movzx esi, byte ptr [1 + edx + eax]
396 mov eax, ebx
397 add ebx, [esp + 32 + 24]
398 and eax, 0xffff
399 imul esi, eax
400 xor eax, 0xffff
401 imul ecx, eax
402 add ecx, esi
403 shr ecx, 16
404 movq mm1, [kCoefficientsRgbY + 8 * ecx]
405
406 cmp ebx, [esp + 32 + 20]
407 jge lscalelastpixel
408
409 mov eax, ebx
410 sar eax, 0x10
411 movzx ecx, byte ptr [edx + eax]
412 movzx esi, byte ptr [edx + eax + 1]
413 mov eax, ebx
414 add ebx, [esp + 32 + 24]
415 and eax, 0xffff
416 imul esi, eax
417 xor eax, 0xffff
418 imul ecx, eax
419 add ecx, esi
420 shr ecx, 16
421 movq mm2, [kCoefficientsRgbY + 8 * ecx]
422
423 paddsw mm1, mm0
424 paddsw mm2, mm0
425 psraw mm1, 0x6
426 psraw mm2, 0x6
427 packuswb mm1, mm2
428 movntq [ebp], mm1
429 add ebp, 0x8
430
431 lscaleend:
432 cmp ebx, [esp + 32 + 20]
433 jl lscaleloop
434 popad
435 ret
436
437 lscalelastpixel:
438 paddsw mm1, mm0
439 psraw mm1, 6
440 packuswb mm1, mm1
441 movd [ebp], mm1
442 popad
443 ret
444 };
445 }
446 #else // USE_MMX
447
448 // C reference code that mimic the YUV assembly.
449 #define packuswb(x) ((x) < 0 ? 0 : ((x) > 255 ? 255 : (x)))
450 #define paddsw(x, y) (((x) + (y)) < -32768 ? -32768 : \
451 (((x) + (y)) > 32767 ? 32767 : ((x) + (y))))
452
453 static inline void YuvPixel(uint8 y,
454 uint8 u,
455 uint8 v,
456 uint8* rgb_buf) {
457
458 int b = kCoefficientsRgbY[256+u][0];
459 int g = kCoefficientsRgbY[256+u][1];
460 int r = kCoefficientsRgbY[256+u][2];
461 int a = kCoefficientsRgbY[256+u][3];
462
463 b = paddsw(b, kCoefficientsRgbY[512+v][0]);
464 g = paddsw(g, kCoefficientsRgbY[512+v][1]);
465 r = paddsw(r, kCoefficientsRgbY[512+v][2]);
466 a = paddsw(a, kCoefficientsRgbY[512+v][3]);
467
468 b = paddsw(b, kCoefficientsRgbY[y][0]);
469 g = paddsw(g, kCoefficientsRgbY[y][1]);
470 r = paddsw(r, kCoefficientsRgbY[y][2]);
471 a = paddsw(a, kCoefficientsRgbY[y][3]);
472
473 b >>= 6;
474 g >>= 6;
475 r >>= 6;
476 a >>= 6;
477
478 *reinterpret_cast<uint32*>(rgb_buf) = (packuswb(b)) |
479 (packuswb(g) << 8) |
480 (packuswb(r) << 16) |
481 (packuswb(a) << 24);
482 }
483
484 #if TEST_MMX_YUV
485 static inline void YuvPixel(uint8 y,
486 uint8 u,
487 uint8 v,
488 uint8* rgb_buf) {
489
490 __asm {
491 movzx eax, u
492 movq mm0, [kCoefficientsRgbY+2048 + 8 * eax]
493 movzx eax, v
494 paddsw mm0, [kCoefficientsRgbY+4096 + 8 * eax]
495 movzx eax, y
496 movq mm1, [kCoefficientsRgbY + 8 * eax]
497 paddsw mm1, mm0
498 psraw mm1, 6
499 packuswb mm1, mm1
500 mov eax, rgb_buf
501 movd [eax], mm1
502 emms
503 }
504 }
505 #endif
506
507 void FastConvertYUVToRGB32Row(const uint8* y_buf,
508 const uint8* u_buf,
509 const uint8* v_buf,
510 uint8* rgb_buf,
511 int width) {
512 for (int x = 0; x < width; x += 2) {
513 uint8 u = u_buf[x >> 1];
514 uint8 v = v_buf[x >> 1];
515 uint8 y0 = y_buf[x];
516 YuvPixel(y0, u, v, rgb_buf);
517 if ((x + 1) < width) {
518 uint8 y1 = y_buf[x + 1];
519 YuvPixel(y1, u, v, rgb_buf + 4);
520 }
521 rgb_buf += 8; // Advance 2 pixels.
522 }
523 }
524
525 // 16.16 fixed point is used. A shift by 16 isolates the integer.
526 // A shift by 17 is used to further subsample the chrominence channels.
527 // & 0xffff isolates the fixed point fraction. >> 2 to get the upper 2 bits,
528 // for 1/65536 pixel accurate interpolation.
529 void ScaleYUVToRGB32Row(const uint8* y_buf,
530 const uint8* u_buf,
531 const uint8* v_buf,
532 uint8* rgb_buf,
533 int width,
534 int source_dx) {
535 int x = 0;
536 for (int i = 0; i < width; i += 2) {
537 int y = y_buf[x >> 16];
538 int u = u_buf[(x >> 17)];
539 int v = v_buf[(x >> 17)];
540 YuvPixel(y, u, v, rgb_buf);
541 x += source_dx;
542 if ((i + 1) < width) {
543 y = y_buf[x >> 16];
544 YuvPixel(y, u, v, rgb_buf+4);
545 x += source_dx;
546 }
547 rgb_buf += 8;
548 }
549 }
550
551 void LinearScaleYUVToRGB32Row(const uint8* y_buf,
552 const uint8* u_buf,
553 const uint8* v_buf,
554 uint8* rgb_buf,
555 int width,
556 int source_dx) {
557 int x = 0;
558 if (source_dx >= 0x20000) {
559 x = 32768;
560 }
561 for (int i = 0; i < width; i += 2) {
562 int y0 = y_buf[x >> 16];
563 int y1 = y_buf[(x >> 16) + 1];
564 int u0 = u_buf[(x >> 17)];
565 int u1 = u_buf[(x >> 17) + 1];
566 int v0 = v_buf[(x >> 17)];
567 int v1 = v_buf[(x >> 17) + 1];
568 int y_frac = (x & 65535);
569 int uv_frac = ((x >> 1) & 65535);
570 int y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16;
571 int u = (uv_frac * u1 + (uv_frac ^ 65535) * u0) >> 16;
572 int v = (uv_frac * v1 + (uv_frac ^ 65535) * v0) >> 16;
573 YuvPixel(y, u, v, rgb_buf);
574 x += source_dx;
575 if ((i + 1) < width) {
576 y0 = y_buf[x >> 16];
577 y1 = y_buf[(x >> 16) + 1];
578 y_frac = (x & 65535);
579 y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16;
580 YuvPixel(y, u, v, rgb_buf+4);
581 x += source_dx;
582 }
583 rgb_buf += 8;
584 }
585 }
586
587 #endif // USE_MMX
588 } // extern "C"
589
OLDNEW
« no previous file with comments | « media/base/yuv_row_table.cc ('k') | media/media.gyp » ('j') | media/media.gyp » ('J')

Powered by Google App Engine
This is Rietveld 408576698