| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 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 #ifndef NDEBUG | |
| 8 #include "base/logging.h" | |
| 9 #else | |
| 10 #define DCHECK(a) | |
| 11 #endif | |
| 12 | |
| 13 extern "C" { | |
| 14 | |
| 15 #if USE_SSE2 && defined(ARCH_CPU_X86_64) | |
| 16 | |
| 17 // AMD64 ABI uses register paremters. | |
| 18 void FastConvertYUVToRGB32Row(const uint8* y_buf, // rdi | |
| 19 const uint8* u_buf, // rsi | |
| 20 const uint8* v_buf, // rdx | |
| 21 uint8* rgb_buf, // rcx | |
| 22 int width) { // r8 | |
| 23 asm( | |
| 24 "jmp convertend\n" | |
| 25 "convertloop:" | |
| 26 "movzb (%1),%%r10\n" | |
| 27 "add $0x1,%1\n" | |
| 28 "movzb (%2),%%r11\n" | |
| 29 "add $0x1,%2\n" | |
| 30 "movq 2048(%5,%%r10,8),%%xmm0\n" | |
| 31 "movzb (%0),%%r10\n" | |
| 32 "movq 4096(%5,%%r11,8),%%xmm1\n" | |
| 33 "movzb 0x1(%0),%%r11\n" | |
| 34 "paddsw %%xmm1,%%xmm0\n" | |
| 35 "movq (%5,%%r10,8),%%xmm2\n" | |
| 36 "add $0x2,%0\n" | |
| 37 "movq (%5,%%r11,8),%%xmm3\n" | |
| 38 "paddsw %%xmm0,%%xmm2\n" | |
| 39 "paddsw %%xmm0,%%xmm3\n" | |
| 40 "shufps $0x44,%%xmm3,%%xmm2\n" | |
| 41 "psraw $0x6,%%xmm2\n" | |
| 42 "packuswb %%xmm2,%%xmm2\n" | |
| 43 "movq %%xmm2,0x0(%3)\n" | |
| 44 "add $0x8,%3\n" | |
| 45 "convertend:" | |
| 46 "sub $0x2,%4\n" | |
| 47 "jns convertloop\n" | |
| 48 | |
| 49 "convertnext:" | |
| 50 "add $0x1,%4\n" | |
| 51 "js convertdone\n" | |
| 52 | |
| 53 "movzb (%1),%%r10\n" | |
| 54 "movq 2048(%5,%%r10,8),%%xmm0\n" | |
| 55 "movzb (%2),%%r10\n" | |
| 56 "movq 4096(%5,%%r10,8),%%xmm1\n" | |
| 57 "paddsw %%xmm1,%%xmm0\n" | |
| 58 "movzb (%0),%%r10\n" | |
| 59 "movq (%5,%%r10,8),%%xmm1\n" | |
| 60 "paddsw %%xmm0,%%xmm1\n" | |
| 61 "psraw $0x6,%%xmm1\n" | |
| 62 "packuswb %%xmm1,%%xmm1\n" | |
| 63 "movd %%xmm1,0x0(%3)\n" | |
| 64 "convertdone:" | |
| 65 : | |
| 66 : "r"(y_buf), // %0 | |
| 67 "r"(u_buf), // %1 | |
| 68 "r"(v_buf), // %2 | |
| 69 "r"(rgb_buf), // %3 | |
| 70 "r"(width), // %4 | |
| 71 "r" (kCoefficientsRgbY) // %5 | |
| 72 : "memory", "r10", "r11", "xmm0", "xmm1", "xmm2", "xmm3" | |
| 73 ); | |
| 74 } | |
| 75 | |
| 76 void ScaleYUVToRGB32Row(const uint8* y_buf, // rdi | |
| 77 const uint8* u_buf, // rsi | |
| 78 const uint8* v_buf, // rdx | |
| 79 uint8* rgb_buf, // rcx | |
| 80 int width, // r8 | |
| 81 int source_dx) { // r9 | |
| 82 asm( | |
| 83 "xor %%r11,%%r11\n" | |
| 84 "sub $0x2,%4\n" | |
| 85 "js scalenext\n" | |
| 86 | |
| 87 "scaleloop:" | |
| 88 "mov %%r11,%%r10\n" | |
| 89 "sar $0x11,%%r10\n" | |
| 90 "movzb (%1,%%r10,1),%%rax\n" | |
| 91 "movq 2048(%5,%%rax,8),%%xmm0\n" | |
| 92 "movzb (%2,%%r10,1),%%rax\n" | |
| 93 "movq 4096(%5,%%rax,8),%%xmm1\n" | |
| 94 "lea (%%r11,%6),%%r10\n" | |
| 95 "sar $0x10,%%r11\n" | |
| 96 "movzb (%0,%%r11,1),%%rax\n" | |
| 97 "paddsw %%xmm1,%%xmm0\n" | |
| 98 "movq (%5,%%rax,8),%%xmm1\n" | |
| 99 "lea (%%r10,%6),%%r11\n" | |
| 100 "sar $0x10,%%r10\n" | |
| 101 "movzb (%0,%%r10,1),%%rax\n" | |
| 102 "movq (%5,%%rax,8),%%xmm2\n" | |
| 103 "paddsw %%xmm0,%%xmm1\n" | |
| 104 "paddsw %%xmm0,%%xmm2\n" | |
| 105 "shufps $0x44,%%xmm2,%%xmm1\n" | |
| 106 "psraw $0x6,%%xmm1\n" | |
| 107 "packuswb %%xmm1,%%xmm1\n" | |
| 108 "movq %%xmm1,0x0(%3)\n" | |
| 109 "add $0x8,%3\n" | |
| 110 "sub $0x2,%4\n" | |
| 111 "jns scaleloop\n" | |
| 112 | |
| 113 "scalenext:" | |
| 114 "add $0x1,%4\n" | |
| 115 "js scaledone\n" | |
| 116 | |
| 117 "mov %%r11,%%r10\n" | |
| 118 "sar $0x11,%%r10\n" | |
| 119 "movzb (%1,%%r10,1),%%rax\n" | |
| 120 "movq 2048(%5,%%rax,8),%%xmm0\n" | |
| 121 "movzb (%2,%%r10,1),%%rax\n" | |
| 122 "movq 4096(%5,%%rax,8),%%xmm1\n" | |
| 123 "paddsw %%xmm1,%%xmm0\n" | |
| 124 "sar $0x10,%%r11\n" | |
| 125 "movzb (%0,%%r11,1),%%rax\n" | |
| 126 "movq (%5,%%rax,8),%%xmm1\n" | |
| 127 "paddsw %%xmm0,%%xmm1\n" | |
| 128 "psraw $0x6,%%xmm1\n" | |
| 129 "packuswb %%xmm1,%%xmm1\n" | |
| 130 "movd %%xmm1,0x0(%3)\n" | |
| 131 | |
| 132 "scaledone:" | |
| 133 : | |
| 134 : "r"(y_buf), // %0 | |
| 135 "r"(u_buf), // %1 | |
| 136 "r"(v_buf), // %2 | |
| 137 "r"(rgb_buf), // %3 | |
| 138 "r"(width), // %4 | |
| 139 "r" (kCoefficientsRgbY), // %5 | |
| 140 "r"(static_cast<long>(source_dx)) // %6 | |
| 141 : "memory", "r10", "r11", "rax", "xmm0", "xmm1", "xmm2" | |
| 142 ); | |
| 143 } | |
| 144 | |
| 145 void LinearScaleYUVToRGB32Row(const uint8* y_buf, | |
| 146 const uint8* u_buf, | |
| 147 const uint8* v_buf, | |
| 148 uint8* rgb_buf, | |
| 149 int width, | |
| 150 int source_dx) { | |
| 151 asm( | |
| 152 "xor %%r11,%%r11\n" // x = 0 | |
| 153 "sub $0x2,%4\n" | |
| 154 "js .lscalenext\n" | |
| 155 "cmp $0x20000,%6\n" // if source_dx >= 2.0 | |
| 156 "jl .lscalehalf\n" | |
| 157 "mov $0x8000,%%r11\n" // x = 0.5 for 1/2 or less | |
| 158 ".lscalehalf:" | |
| 159 | |
| 160 ".lscaleloop:" | |
| 161 "mov %%r11,%%r10\n" | |
| 162 "sar $0x11,%%r10\n" | |
| 163 | |
| 164 "movzb (%1, %%r10, 1), %%r13 \n" | |
| 165 "movzb 1(%1, %%r10, 1), %%r14 \n" | |
| 166 "mov %%r11, %%rax \n" | |
| 167 "and $0x1fffe, %%rax \n" | |
| 168 "imul %%rax, %%r14 \n" | |
| 169 "xor $0x1fffe, %%rax \n" | |
| 170 "imul %%rax, %%r13 \n" | |
| 171 "add %%r14, %%r13 \n" | |
| 172 "shr $17, %%r13 \n" | |
| 173 "movq 2048(%5,%%r13,8), %%xmm0\n" | |
| 174 | |
| 175 "movzb (%2, %%r10, 1), %%r13 \n" | |
| 176 "movzb 1(%2, %%r10, 1), %%r14 \n" | |
| 177 "mov %%r11, %%rax \n" | |
| 178 "and $0x1fffe, %%rax \n" | |
| 179 "imul %%rax, %%r14 \n" | |
| 180 "xor $0x1fffe, %%rax \n" | |
| 181 "imul %%rax, %%r13 \n" | |
| 182 "add %%r14, %%r13 \n" | |
| 183 "shr $17, %%r13 \n" | |
| 184 "movq 4096(%5,%%r13,8), %%xmm1\n" | |
| 185 | |
| 186 "mov %%r11, %%rax \n" | |
| 187 "lea (%%r11,%6),%%r10\n" | |
| 188 "sar $0x10,%%r11\n" | |
| 189 "paddsw %%xmm1,%%xmm0\n" | |
| 190 | |
| 191 "movzb (%0, %%r11, 1), %%r13 \n" | |
| 192 "movzb 1(%0, %%r11, 1), %%r14 \n" | |
| 193 "and $0xffff, %%rax \n" | |
| 194 "imul %%rax, %%r14 \n" | |
| 195 "xor $0xffff, %%rax \n" | |
| 196 "imul %%rax, %%r13 \n" | |
| 197 "add %%r14, %%r13 \n" | |
| 198 "shr $16, %%r13 \n" | |
| 199 "movq (%5,%%r13,8),%%xmm1\n" | |
| 200 | |
| 201 "mov %%r10, %%rax \n" | |
| 202 "lea (%%r10,%6),%%r11\n" | |
| 203 "sar $0x10,%%r10\n" | |
| 204 | |
| 205 "movzb (%0,%%r10,1), %%r13 \n" | |
| 206 "movzb 1(%0,%%r10,1), %%r14 \n" | |
| 207 "and $0xffff, %%rax \n" | |
| 208 "imul %%rax, %%r14 \n" | |
| 209 "xor $0xffff, %%rax \n" | |
| 210 "imul %%rax, %%r13 \n" | |
| 211 "add %%r14, %%r13 \n" | |
| 212 "shr $16, %%r13 \n" | |
| 213 "movq (%5,%%r13,8),%%xmm2\n" | |
| 214 | |
| 215 "paddsw %%xmm0,%%xmm1\n" | |
| 216 "paddsw %%xmm0,%%xmm2\n" | |
| 217 "shufps $0x44,%%xmm2,%%xmm1\n" | |
| 218 "psraw $0x6,%%xmm1\n" | |
| 219 "packuswb %%xmm1,%%xmm1\n" | |
| 220 "movq %%xmm1,0x0(%3)\n" | |
| 221 "add $0x8,%3\n" | |
| 222 "sub $0x2,%4\n" | |
| 223 "jns .lscaleloop\n" | |
| 224 | |
| 225 ".lscalenext:" | |
| 226 "add $0x1,%4\n" | |
| 227 "js .lscaledone\n" | |
| 228 | |
| 229 "mov %%r11,%%r10\n" | |
| 230 "sar $0x11,%%r10\n" | |
| 231 | |
| 232 "movzb (%1,%%r10,1), %%r13 \n" | |
| 233 "movq 2048(%5,%%r13,8),%%xmm0\n" | |
| 234 | |
| 235 "movzb (%2,%%r10,1), %%r13 \n" | |
| 236 "movq 4096(%5,%%r13,8),%%xmm1\n" | |
| 237 | |
| 238 "paddsw %%xmm1,%%xmm0\n" | |
| 239 "sar $0x10,%%r11\n" | |
| 240 | |
| 241 "movzb (%0,%%r11,1), %%r13 \n" | |
| 242 "movq (%5,%%r13,8),%%xmm1\n" | |
| 243 | |
| 244 "paddsw %%xmm0,%%xmm1\n" | |
| 245 "psraw $0x6,%%xmm1\n" | |
| 246 "packuswb %%xmm1,%%xmm1\n" | |
| 247 "movd %%xmm1,0x0(%3)\n" | |
| 248 | |
| 249 ".lscaledone:" | |
| 250 : | |
| 251 : "r"(y_buf), // %0 | |
| 252 "r"(u_buf), // %1 | |
| 253 "r"(v_buf), // %2 | |
| 254 "r"(rgb_buf), // %3 | |
| 255 "r"(width), // %4 | |
| 256 "r" (kCoefficientsRgbY), // %5 | |
| 257 "r"(static_cast<long>(source_dx)) // %6 | |
| 258 : "memory", "r10", "r11", "r13", "r14", "rax", "xmm0", "xmm1", "xmm2" | |
| 259 ); | |
| 260 } | |
| 261 | |
| 262 #elif USE_MMX && !defined(ARCH_CPU_X86_64) && !defined(__PIC__) | |
| 263 | |
| 264 // PIC version is slower because less registers are available, so | |
| 265 // non-PIC is used on platforms where it is possible. | |
| 266 | |
| 267 void FastConvertYUVToRGB32Row(const uint8* y_buf, | |
| 268 const uint8* u_buf, | |
| 269 const uint8* v_buf, | |
| 270 uint8* rgb_buf, | |
| 271 int width); | |
| 272 asm( | |
| 273 ".text\n" | |
| 274 ".global FastConvertYUVToRGB32Row\n" | |
| 275 "FastConvertYUVToRGB32Row:\n" | |
| 276 "pusha\n" | |
| 277 "mov 0x24(%esp),%edx\n" | |
| 278 "mov 0x28(%esp),%edi\n" | |
| 279 "mov 0x2c(%esp),%esi\n" | |
| 280 "mov 0x30(%esp),%ebp\n" | |
| 281 "mov 0x34(%esp),%ecx\n" | |
| 282 "jmp convertend\n" | |
| 283 | |
| 284 "convertloop:" | |
| 285 "movzbl (%edi),%eax\n" | |
| 286 "add $0x1,%edi\n" | |
| 287 "movzbl (%esi),%ebx\n" | |
| 288 "add $0x1,%esi\n" | |
| 289 "movq kCoefficientsRgbY+2048(,%eax,8),%mm0\n" | |
| 290 "movzbl (%edx),%eax\n" | |
| 291 "paddsw kCoefficientsRgbY+4096(,%ebx,8),%mm0\n" | |
| 292 "movzbl 0x1(%edx),%ebx\n" | |
| 293 "movq kCoefficientsRgbY(,%eax,8),%mm1\n" | |
| 294 "add $0x2,%edx\n" | |
| 295 "movq kCoefficientsRgbY(,%ebx,8),%mm2\n" | |
| 296 "paddsw %mm0,%mm1\n" | |
| 297 "paddsw %mm0,%mm2\n" | |
| 298 "psraw $0x6,%mm1\n" | |
| 299 "psraw $0x6,%mm2\n" | |
| 300 "packuswb %mm2,%mm1\n" | |
| 301 "movntq %mm1,0x0(%ebp)\n" | |
| 302 "add $0x8,%ebp\n" | |
| 303 "convertend:" | |
| 304 "sub $0x2,%ecx\n" | |
| 305 "jns convertloop\n" | |
| 306 | |
| 307 "and $0x1,%ecx\n" | |
| 308 "je convertdone\n" | |
| 309 | |
| 310 "movzbl (%edi),%eax\n" | |
| 311 "movq kCoefficientsRgbY+2048(,%eax,8),%mm0\n" | |
| 312 "movzbl (%esi),%eax\n" | |
| 313 "paddsw kCoefficientsRgbY+4096(,%eax,8),%mm0\n" | |
| 314 "movzbl (%edx),%eax\n" | |
| 315 "movq kCoefficientsRgbY(,%eax,8),%mm1\n" | |
| 316 "paddsw %mm0,%mm1\n" | |
| 317 "psraw $0x6,%mm1\n" | |
| 318 "packuswb %mm1,%mm1\n" | |
| 319 "movd %mm1,0x0(%ebp)\n" | |
| 320 "convertdone:" | |
| 321 "popa\n" | |
| 322 "ret\n" | |
| 323 ); | |
| 324 | |
| 325 | |
| 326 void ScaleYUVToRGB32Row(const uint8* y_buf, | |
| 327 const uint8* u_buf, | |
| 328 const uint8* v_buf, | |
| 329 uint8* rgb_buf, | |
| 330 int width, | |
| 331 int source_dx); | |
| 332 asm( | |
| 333 ".text\n" | |
| 334 ".global ScaleYUVToRGB32Row\n" | |
| 335 "ScaleYUVToRGB32Row:\n" | |
| 336 "pusha\n" | |
| 337 "mov 0x24(%esp),%edx\n" | |
| 338 "mov 0x28(%esp),%edi\n" | |
| 339 "mov 0x2c(%esp),%esi\n" | |
| 340 "mov 0x30(%esp),%ebp\n" | |
| 341 "mov 0x34(%esp),%ecx\n" | |
| 342 "xor %ebx,%ebx\n" | |
| 343 "jmp scaleend\n" | |
| 344 | |
| 345 "scaleloop:" | |
| 346 "mov %ebx,%eax\n" | |
| 347 "sar $0x11,%eax\n" | |
| 348 "movzbl (%edi,%eax,1),%eax\n" | |
| 349 "movq kCoefficientsRgbY+2048(,%eax,8),%mm0\n" | |
| 350 "mov %ebx,%eax\n" | |
| 351 "sar $0x11,%eax\n" | |
| 352 "movzbl (%esi,%eax,1),%eax\n" | |
| 353 "paddsw kCoefficientsRgbY+4096(,%eax,8),%mm0\n" | |
| 354 "mov %ebx,%eax\n" | |
| 355 "add 0x38(%esp),%ebx\n" | |
| 356 "sar $0x10,%eax\n" | |
| 357 "movzbl (%edx,%eax,1),%eax\n" | |
| 358 "movq kCoefficientsRgbY(,%eax,8),%mm1\n" | |
| 359 "mov %ebx,%eax\n" | |
| 360 "add 0x38(%esp),%ebx\n" | |
| 361 "sar $0x10,%eax\n" | |
| 362 "movzbl (%edx,%eax,1),%eax\n" | |
| 363 "movq kCoefficientsRgbY(,%eax,8),%mm2\n" | |
| 364 "paddsw %mm0,%mm1\n" | |
| 365 "paddsw %mm0,%mm2\n" | |
| 366 "psraw $0x6,%mm1\n" | |
| 367 "psraw $0x6,%mm2\n" | |
| 368 "packuswb %mm2,%mm1\n" | |
| 369 "movntq %mm1,0x0(%ebp)\n" | |
| 370 "add $0x8,%ebp\n" | |
| 371 "scaleend:" | |
| 372 "sub $0x2,%ecx\n" | |
| 373 "jns scaleloop\n" | |
| 374 | |
| 375 "and $0x1,%ecx\n" | |
| 376 "je scaledone\n" | |
| 377 | |
| 378 "mov %ebx,%eax\n" | |
| 379 "sar $0x11,%eax\n" | |
| 380 "movzbl (%edi,%eax,1),%eax\n" | |
| 381 "movq kCoefficientsRgbY+2048(,%eax,8),%mm0\n" | |
| 382 "mov %ebx,%eax\n" | |
| 383 "sar $0x11,%eax\n" | |
| 384 "movzbl (%esi,%eax,1),%eax\n" | |
| 385 "paddsw kCoefficientsRgbY+4096(,%eax,8),%mm0\n" | |
| 386 "mov %ebx,%eax\n" | |
| 387 "sar $0x10,%eax\n" | |
| 388 "movzbl (%edx,%eax,1),%eax\n" | |
| 389 "movq kCoefficientsRgbY(,%eax,8),%mm1\n" | |
| 390 "paddsw %mm0,%mm1\n" | |
| 391 "psraw $0x6,%mm1\n" | |
| 392 "packuswb %mm1,%mm1\n" | |
| 393 "movd %mm1,0x0(%ebp)\n" | |
| 394 | |
| 395 "scaledone:" | |
| 396 "popa\n" | |
| 397 "ret\n" | |
| 398 ); | |
| 399 | |
| 400 void LinearScaleYUVToRGB32Row(const uint8* y_buf, | |
| 401 const uint8* u_buf, | |
| 402 const uint8* v_buf, | |
| 403 uint8* rgb_buf, | |
| 404 int width, | |
| 405 int source_dx); | |
| 406 asm( | |
| 407 ".text\n" | |
| 408 ".global LinearScaleYUVToRGB32Row\n" | |
| 409 "LinearScaleYUVToRGB32Row:\n" | |
| 410 "pusha\n" | |
| 411 "mov 0x24(%esp),%edx\n" | |
| 412 "mov 0x28(%esp),%edi\n" | |
| 413 "mov 0x30(%esp),%ebp\n" | |
| 414 | |
| 415 // source_width = width * source_dx + ebx | |
| 416 "mov 0x34(%esp), %ecx\n" | |
| 417 "imull 0x38(%esp), %ecx\n" | |
| 418 "mov %ecx, 0x34(%esp)\n" | |
| 419 | |
| 420 "mov 0x38(%esp), %ecx\n" | |
| 421 "xor %ebx,%ebx\n" // x = 0 | |
| 422 "cmp $0x20000,%ecx\n" // if source_dx >= 2.0 | |
| 423 "jl .lscaleend\n" | |
| 424 "mov $0x8000,%ebx\n" // x = 0.5 for 1/2 or less | |
| 425 "jmp .lscaleend\n" | |
| 426 | |
| 427 ".lscaleloop:" | |
| 428 "mov %ebx,%eax\n" | |
| 429 "sar $0x11,%eax\n" | |
| 430 | |
| 431 "movzbl (%edi,%eax,1),%ecx\n" | |
| 432 "movzbl 1(%edi,%eax,1),%esi\n" | |
| 433 "mov %ebx,%eax\n" | |
| 434 "andl $0x1fffe, %eax \n" | |
| 435 "imul %eax, %esi \n" | |
| 436 "xorl $0x1fffe, %eax \n" | |
| 437 "imul %eax, %ecx \n" | |
| 438 "addl %esi, %ecx \n" | |
| 439 "shrl $17, %ecx \n" | |
| 440 "movq kCoefficientsRgbY+2048(,%ecx,8),%mm0\n" | |
| 441 | |
| 442 "mov 0x2c(%esp),%esi\n" | |
| 443 "mov %ebx,%eax\n" | |
| 444 "sar $0x11,%eax\n" | |
| 445 | |
| 446 "movzbl (%esi,%eax,1),%ecx\n" | |
| 447 "movzbl 1(%esi,%eax,1),%esi\n" | |
| 448 "mov %ebx,%eax\n" | |
| 449 "andl $0x1fffe, %eax \n" | |
| 450 "imul %eax, %esi \n" | |
| 451 "xorl $0x1fffe, %eax \n" | |
| 452 "imul %eax, %ecx \n" | |
| 453 "addl %esi, %ecx \n" | |
| 454 "shrl $17, %ecx \n" | |
| 455 "paddsw kCoefficientsRgbY+4096(,%ecx,8),%mm0\n" | |
| 456 | |
| 457 "mov %ebx,%eax\n" | |
| 458 "sar $0x10,%eax\n" | |
| 459 "movzbl (%edx,%eax,1),%ecx\n" | |
| 460 "movzbl 1(%edx,%eax,1),%esi\n" | |
| 461 "mov %ebx,%eax\n" | |
| 462 "add 0x38(%esp),%ebx\n" | |
| 463 "andl $0xffff, %eax \n" | |
| 464 "imul %eax, %esi \n" | |
| 465 "xorl $0xffff, %eax \n" | |
| 466 "imul %eax, %ecx \n" | |
| 467 "addl %esi, %ecx \n" | |
| 468 "shrl $16, %ecx \n" | |
| 469 "movq kCoefficientsRgbY(,%ecx,8),%mm1\n" | |
| 470 | |
| 471 "cmp 0x34(%esp), %ebx\n" | |
| 472 "jge .lscalelastpixel\n" | |
| 473 | |
| 474 "mov %ebx,%eax\n" | |
| 475 "sar $0x10,%eax\n" | |
| 476 "movzbl (%edx,%eax,1),%ecx\n" | |
| 477 "movzbl 1(%edx,%eax,1),%esi\n" | |
| 478 "mov %ebx,%eax\n" | |
| 479 "add 0x38(%esp),%ebx\n" | |
| 480 "andl $0xffff, %eax \n" | |
| 481 "imul %eax, %esi \n" | |
| 482 "xorl $0xffff, %eax \n" | |
| 483 "imul %eax, %ecx \n" | |
| 484 "addl %esi, %ecx \n" | |
| 485 "shrl $16, %ecx \n" | |
| 486 "movq kCoefficientsRgbY(,%ecx,8),%mm2\n" | |
| 487 | |
| 488 "paddsw %mm0,%mm1\n" | |
| 489 "paddsw %mm0,%mm2\n" | |
| 490 "psraw $0x6,%mm1\n" | |
| 491 "psraw $0x6,%mm2\n" | |
| 492 "packuswb %mm2,%mm1\n" | |
| 493 "movntq %mm1,0x0(%ebp)\n" | |
| 494 "add $0x8,%ebp\n" | |
| 495 | |
| 496 ".lscaleend:" | |
| 497 "cmp 0x34(%esp), %ebx\n" | |
| 498 "jl .lscaleloop\n" | |
| 499 "popa\n" | |
| 500 "ret\n" | |
| 501 | |
| 502 ".lscalelastpixel:" | |
| 503 "paddsw %mm0, %mm1\n" | |
| 504 "psraw $6, %mm1\n" | |
| 505 "packuswb %mm1, %mm1\n" | |
| 506 "movd %mm1, (%ebp)\n" | |
| 507 "popa\n" | |
| 508 "ret\n" | |
| 509 ); | |
| 510 | |
| 511 #elif USE_MMX && !defined(ARCH_CPU_X86_64) && defined(__PIC__) | |
| 512 | |
| 513 extern void PICConvertYUVToRGB32Row(const uint8* y_buf, | |
| 514 const uint8* u_buf, | |
| 515 const uint8* v_buf, | |
| 516 uint8* rgb_buf, | |
| 517 int width, | |
| 518 int16 *kCoefficientsRgbY); | |
| 519 asm( | |
| 520 ".text\n" | |
| 521 #if defined(OS_MACOSX) | |
| 522 "_PICConvertYUVToRGB32Row:\n" | |
| 523 #else | |
| 524 "PICConvertYUVToRGB32Row:\n" | |
| 525 #endif | |
| 526 "pusha\n" | |
| 527 "mov 0x24(%esp),%edx\n" | |
| 528 "mov 0x28(%esp),%edi\n" | |
| 529 "mov 0x2c(%esp),%esi\n" | |
| 530 "mov 0x30(%esp),%ebp\n" | |
| 531 "mov 0x38(%esp),%ecx\n" | |
| 532 | |
| 533 "jmp .Lconvertend\n" | |
| 534 | |
| 535 ".Lconvertloop:" | |
| 536 "movzbl (%edi),%eax\n" | |
| 537 "add $0x1,%edi\n" | |
| 538 "movzbl (%esi),%ebx\n" | |
| 539 "add $0x1,%esi\n" | |
| 540 "movq 2048(%ecx,%eax,8),%mm0\n" | |
| 541 "movzbl (%edx),%eax\n" | |
| 542 "paddsw 4096(%ecx,%ebx,8),%mm0\n" | |
| 543 "movzbl 0x1(%edx),%ebx\n" | |
| 544 "movq 0(%ecx,%eax,8),%mm1\n" | |
| 545 "add $0x2,%edx\n" | |
| 546 "movq 0(%ecx,%ebx,8),%mm2\n" | |
| 547 "paddsw %mm0,%mm1\n" | |
| 548 "paddsw %mm0,%mm2\n" | |
| 549 "psraw $0x6,%mm1\n" | |
| 550 "psraw $0x6,%mm2\n" | |
| 551 "packuswb %mm2,%mm1\n" | |
| 552 "movntq %mm1,0x0(%ebp)\n" | |
| 553 "add $0x8,%ebp\n" | |
| 554 ".Lconvertend:" | |
| 555 "subl $0x2,0x34(%esp)\n" | |
| 556 "jns .Lconvertloop\n" | |
| 557 | |
| 558 "andl $0x1,0x34(%esp)\n" | |
| 559 "je .Lconvertdone\n" | |
| 560 | |
| 561 "movzbl (%edi),%eax\n" | |
| 562 "movq 2048(%ecx,%eax,8),%mm0\n" | |
| 563 "movzbl (%esi),%eax\n" | |
| 564 "paddsw 4096(%ecx,%eax,8),%mm0\n" | |
| 565 "movzbl (%edx),%eax\n" | |
| 566 "movq 0(%ecx,%eax,8),%mm1\n" | |
| 567 "paddsw %mm0,%mm1\n" | |
| 568 "psraw $0x6,%mm1\n" | |
| 569 "packuswb %mm1,%mm1\n" | |
| 570 "movd %mm1,0x0(%ebp)\n" | |
| 571 ".Lconvertdone:\n" | |
| 572 "popa\n" | |
| 573 "ret\n" | |
| 574 ); | |
| 575 | |
| 576 void FastConvertYUVToRGB32Row(const uint8* y_buf, | |
| 577 const uint8* u_buf, | |
| 578 const uint8* v_buf, | |
| 579 uint8* rgb_buf, | |
| 580 int width) { | |
| 581 PICConvertYUVToRGB32Row(y_buf, u_buf, v_buf, rgb_buf, width, | |
| 582 &kCoefficientsRgbY[0][0]); | |
| 583 } | |
| 584 | |
| 585 extern void PICScaleYUVToRGB32Row(const uint8* y_buf, | |
| 586 const uint8* u_buf, | |
| 587 const uint8* v_buf, | |
| 588 uint8* rgb_buf, | |
| 589 int width, | |
| 590 int source_dx, | |
| 591 int16 *kCoefficientsRgbY); | |
| 592 | |
| 593 asm( | |
| 594 ".text\n" | |
| 595 #if defined(OS_MACOSX) | |
| 596 "_PICScaleYUVToRGB32Row:\n" | |
| 597 #else | |
| 598 "PICScaleYUVToRGB32Row:\n" | |
| 599 #endif | |
| 600 "pusha\n" | |
| 601 "mov 0x24(%esp),%edx\n" | |
| 602 "mov 0x28(%esp),%edi\n" | |
| 603 "mov 0x2c(%esp),%esi\n" | |
| 604 "mov 0x30(%esp),%ebp\n" | |
| 605 "mov 0x3c(%esp),%ecx\n" | |
| 606 "xor %ebx,%ebx\n" | |
| 607 "jmp Lscaleend\n" | |
| 608 | |
| 609 "Lscaleloop:" | |
| 610 "mov %ebx,%eax\n" | |
| 611 "sar $0x11,%eax\n" | |
| 612 "movzbl (%edi,%eax,1),%eax\n" | |
| 613 "movq 2048(%ecx,%eax,8),%mm0\n" | |
| 614 "mov %ebx,%eax\n" | |
| 615 "sar $0x11,%eax\n" | |
| 616 "movzbl (%esi,%eax,1),%eax\n" | |
| 617 "paddsw 4096(%ecx,%eax,8),%mm0\n" | |
| 618 "mov %ebx,%eax\n" | |
| 619 "add 0x38(%esp),%ebx\n" | |
| 620 "sar $0x10,%eax\n" | |
| 621 "movzbl (%edx,%eax,1),%eax\n" | |
| 622 "movq 0(%ecx,%eax,8),%mm1\n" | |
| 623 "mov %ebx,%eax\n" | |
| 624 "add 0x38(%esp),%ebx\n" | |
| 625 "sar $0x10,%eax\n" | |
| 626 "movzbl (%edx,%eax,1),%eax\n" | |
| 627 "movq 0(%ecx,%eax,8),%mm2\n" | |
| 628 "paddsw %mm0,%mm1\n" | |
| 629 "paddsw %mm0,%mm2\n" | |
| 630 "psraw $0x6,%mm1\n" | |
| 631 "psraw $0x6,%mm2\n" | |
| 632 "packuswb %mm2,%mm1\n" | |
| 633 "movntq %mm1,0x0(%ebp)\n" | |
| 634 "add $0x8,%ebp\n" | |
| 635 "Lscaleend:" | |
| 636 "subl $0x2,0x34(%esp)\n" | |
| 637 "jns Lscaleloop\n" | |
| 638 | |
| 639 "andl $0x1,0x34(%esp)\n" | |
| 640 "je Lscaledone\n" | |
| 641 | |
| 642 "mov %ebx,%eax\n" | |
| 643 "sar $0x11,%eax\n" | |
| 644 "movzbl (%edi,%eax,1),%eax\n" | |
| 645 "movq 2048(%ecx,%eax,8),%mm0\n" | |
| 646 "mov %ebx,%eax\n" | |
| 647 "sar $0x11,%eax\n" | |
| 648 "movzbl (%esi,%eax,1),%eax\n" | |
| 649 "paddsw 4096(%ecx,%eax,8),%mm0\n" | |
| 650 "mov %ebx,%eax\n" | |
| 651 "sar $0x10,%eax\n" | |
| 652 "movzbl (%edx,%eax,1),%eax\n" | |
| 653 "movq 0(%ecx,%eax,8),%mm1\n" | |
| 654 "paddsw %mm0,%mm1\n" | |
| 655 "psraw $0x6,%mm1\n" | |
| 656 "packuswb %mm1,%mm1\n" | |
| 657 "movd %mm1,0x0(%ebp)\n" | |
| 658 | |
| 659 "Lscaledone:" | |
| 660 "popa\n" | |
| 661 "ret\n" | |
| 662 ); | |
| 663 | |
| 664 | |
| 665 void ScaleYUVToRGB32Row(const uint8* y_buf, | |
| 666 const uint8* u_buf, | |
| 667 const uint8* v_buf, | |
| 668 uint8* rgb_buf, | |
| 669 int width, | |
| 670 int source_dx) { | |
| 671 PICScaleYUVToRGB32Row(y_buf, u_buf, v_buf, rgb_buf, width, source_dx, | |
| 672 &kCoefficientsRgbY[0][0]); | |
| 673 } | |
| 674 | |
| 675 void PICLinearScaleYUVToRGB32Row(const uint8* y_buf, | |
| 676 const uint8* u_buf, | |
| 677 const uint8* v_buf, | |
| 678 uint8* rgb_buf, | |
| 679 int width, | |
| 680 int source_dx, | |
| 681 int16 *kCoefficientsRgbY); | |
| 682 asm( | |
| 683 ".text\n" | |
| 684 #if defined(OS_MACOSX) | |
| 685 "_PICLinearScaleYUVToRGB32Row:\n" | |
| 686 #else | |
| 687 "PICLinearScaleYUVToRGB32Row:\n" | |
| 688 #endif | |
| 689 "pusha\n" | |
| 690 "mov 0x24(%esp),%edx\n" | |
| 691 "mov 0x30(%esp),%ebp\n" | |
| 692 "mov 0x34(%esp),%ecx\n" | |
| 693 "mov 0x3c(%esp),%edi\n" | |
| 694 "xor %ebx,%ebx\n" | |
| 695 | |
| 696 // source_width = width * source_dx + ebx | |
| 697 "mov 0x34(%esp), %ecx\n" | |
| 698 "imull 0x38(%esp), %ecx\n" | |
| 699 "mov %ecx, 0x34(%esp)\n" | |
| 700 | |
| 701 "mov 0x38(%esp), %ecx\n" | |
| 702 "xor %ebx,%ebx\n" // x = 0 | |
| 703 "cmp $0x20000,%ecx\n" // if source_dx >= 2.0 | |
| 704 "jl .lscaleend\n" | |
| 705 "mov $0x8000,%ebx\n" // x = 0.5 for 1/2 or less | |
| 706 "jmp .lscaleend\n" | |
| 707 | |
| 708 ".lscaleloop:" | |
| 709 "mov 0x28(%esp),%esi\n" | |
| 710 "mov %ebx,%eax\n" | |
| 711 "sar $0x11,%eax\n" | |
| 712 | |
| 713 "movzbl (%esi,%eax,1),%ecx\n" | |
| 714 "movzbl 1(%esi,%eax,1),%esi\n" | |
| 715 "mov %ebx,%eax\n" | |
| 716 "andl $0x1fffe, %eax \n" | |
| 717 "imul %eax, %esi \n" | |
| 718 "xorl $0x1fffe, %eax \n" | |
| 719 "imul %eax, %ecx \n" | |
| 720 "addl %esi, %ecx \n" | |
| 721 "shrl $17, %ecx \n" | |
| 722 "movq 2048(%edi,%ecx,8),%mm0\n" | |
| 723 | |
| 724 "mov 0x2c(%esp),%esi\n" | |
| 725 "mov %ebx,%eax\n" | |
| 726 "sar $0x11,%eax\n" | |
| 727 | |
| 728 "movzbl (%esi,%eax,1),%ecx\n" | |
| 729 "movzbl 1(%esi,%eax,1),%esi\n" | |
| 730 "mov %ebx,%eax\n" | |
| 731 "andl $0x1fffe, %eax \n" | |
| 732 "imul %eax, %esi \n" | |
| 733 "xorl $0x1fffe, %eax \n" | |
| 734 "imul %eax, %ecx \n" | |
| 735 "addl %esi, %ecx \n" | |
| 736 "shrl $17, %ecx \n" | |
| 737 "paddsw 4096(%edi,%ecx,8),%mm0\n" | |
| 738 | |
| 739 "mov %ebx,%eax\n" | |
| 740 "sar $0x10,%eax\n" | |
| 741 "movzbl (%edx,%eax,1),%ecx\n" | |
| 742 "movzbl 1(%edx,%eax,1),%esi\n" | |
| 743 "mov %ebx,%eax\n" | |
| 744 "add 0x38(%esp),%ebx\n" | |
| 745 "andl $0xffff, %eax \n" | |
| 746 "imul %eax, %esi \n" | |
| 747 "xorl $0xffff, %eax \n" | |
| 748 "imul %eax, %ecx \n" | |
| 749 "addl %esi, %ecx \n" | |
| 750 "shrl $16, %ecx \n" | |
| 751 "movq (%edi,%ecx,8),%mm1\n" | |
| 752 | |
| 753 "cmp 0x34(%esp), %ebx\n" | |
| 754 "jge .lscalelastpixel\n" | |
| 755 | |
| 756 "mov %ebx,%eax\n" | |
| 757 "sar $0x10,%eax\n" | |
| 758 "movzbl (%edx,%eax,1),%ecx\n" | |
| 759 "movzbl 1(%edx,%eax,1),%esi\n" | |
| 760 "mov %ebx,%eax\n" | |
| 761 "add 0x38(%esp),%ebx\n" | |
| 762 "andl $0xffff, %eax \n" | |
| 763 "imul %eax, %esi \n" | |
| 764 "xorl $0xffff, %eax \n" | |
| 765 "imul %eax, %ecx \n" | |
| 766 "addl %esi, %ecx \n" | |
| 767 "shrl $16, %ecx \n" | |
| 768 "movq (%edi,%ecx,8),%mm2\n" | |
| 769 | |
| 770 "paddsw %mm0,%mm1\n" | |
| 771 "paddsw %mm0,%mm2\n" | |
| 772 "psraw $0x6,%mm1\n" | |
| 773 "psraw $0x6,%mm2\n" | |
| 774 "packuswb %mm2,%mm1\n" | |
| 775 "movntq %mm1,0x0(%ebp)\n" | |
| 776 "add $0x8,%ebp\n" | |
| 777 | |
| 778 ".lscaleend:" | |
| 779 "cmp %ebx, 0x34(%esp)\n" | |
| 780 "jg .lscaleloop\n" | |
| 781 "popa\n" | |
| 782 "ret\n" | |
| 783 | |
| 784 ".lscalelastpixel:" | |
| 785 "paddsw %mm0, %mm1\n" | |
| 786 "psraw $6, %mm1\n" | |
| 787 "packuswb %mm1, %mm1\n" | |
| 788 "movd %mm1, (%ebp)\n" | |
| 789 "popa\n" | |
| 790 "ret\n" | |
| 791 ); | |
| 792 | |
| 793 void LinearScaleYUVToRGB32Row(const uint8* y_buf, | |
| 794 const uint8* u_buf, | |
| 795 const uint8* v_buf, | |
| 796 uint8* rgb_buf, | |
| 797 int width, | |
| 798 int source_dx) { | |
| 799 PICLinearScaleYUVToRGB32Row(y_buf, u_buf, v_buf, rgb_buf, width, source_dx, | |
| 800 &kCoefficientsRgbY[0][0]); | |
| 801 } | |
| 802 | |
| 803 #else // USE_MMX | |
| 804 | |
| 805 // C reference code that mimic the YUV assembly. | |
| 806 #define packuswb(x) ((x) < 0 ? 0 : ((x) > 255 ? 255 : (x))) | |
| 807 #define paddsw(x, y) (((x) + (y)) < -32768 ? -32768 : \ | |
| 808 (((x) + (y)) > 32767 ? 32767 : ((x) + (y)))) | |
| 809 | |
| 810 static inline void YuvPixel(uint8 y, | |
| 811 uint8 u, | |
| 812 uint8 v, | |
| 813 uint8* rgb_buf) { | |
| 814 | |
| 815 int b = kCoefficientsRgbY[256+u][0]; | |
| 816 int g = kCoefficientsRgbY[256+u][1]; | |
| 817 int r = kCoefficientsRgbY[256+u][2]; | |
| 818 int a = kCoefficientsRgbY[256+u][3]; | |
| 819 | |
| 820 b = paddsw(b, kCoefficientsRgbY[512+v][0]); | |
| 821 g = paddsw(g, kCoefficientsRgbY[512+v][1]); | |
| 822 r = paddsw(r, kCoefficientsRgbY[512+v][2]); | |
| 823 a = paddsw(a, kCoefficientsRgbY[512+v][3]); | |
| 824 | |
| 825 b = paddsw(b, kCoefficientsRgbY[y][0]); | |
| 826 g = paddsw(g, kCoefficientsRgbY[y][1]); | |
| 827 r = paddsw(r, kCoefficientsRgbY[y][2]); | |
| 828 a = paddsw(a, kCoefficientsRgbY[y][3]); | |
| 829 | |
| 830 b >>= 6; | |
| 831 g >>= 6; | |
| 832 r >>= 6; | |
| 833 a >>= 6; | |
| 834 | |
| 835 *reinterpret_cast<uint32*>(rgb_buf) = (packuswb(b)) | | |
| 836 (packuswb(g) << 8) | | |
| 837 (packuswb(r) << 16) | | |
| 838 (packuswb(a) << 24); | |
| 839 } | |
| 840 | |
| 841 void FastConvertYUVToRGB32Row(const uint8* y_buf, | |
| 842 const uint8* u_buf, | |
| 843 const uint8* v_buf, | |
| 844 uint8* rgb_buf, | |
| 845 int width) { | |
| 846 for (int x = 0; x < width; x += 2) { | |
| 847 uint8 u = u_buf[x >> 1]; | |
| 848 uint8 v = v_buf[x >> 1]; | |
| 849 uint8 y0 = y_buf[x]; | |
| 850 YuvPixel(y0, u, v, rgb_buf); | |
| 851 if ((x + 1) < width) { | |
| 852 uint8 y1 = y_buf[x + 1]; | |
| 853 YuvPixel(y1, u, v, rgb_buf + 4); | |
| 854 } | |
| 855 rgb_buf += 8; // Advance 2 pixels. | |
| 856 } | |
| 857 } | |
| 858 | |
| 859 // 16.16 fixed point is used. A shift by 16 isolates the integer. | |
| 860 // A shift by 17 is used to further subsample the chrominence channels. | |
| 861 // & 0xffff isolates the fixed point fraction. >> 2 to get the upper 2 bits, | |
| 862 // for 1/65536 pixel accurate interpolation. | |
| 863 void ScaleYUVToRGB32Row(const uint8* y_buf, | |
| 864 const uint8* u_buf, | |
| 865 const uint8* v_buf, | |
| 866 uint8* rgb_buf, | |
| 867 int width, | |
| 868 int source_dx) { | |
| 869 int x = 0; | |
| 870 for (int i = 0; i < width; i += 2) { | |
| 871 int y = y_buf[x >> 16]; | |
| 872 int u = u_buf[(x >> 17)]; | |
| 873 int v = v_buf[(x >> 17)]; | |
| 874 YuvPixel(y, u, v, rgb_buf); | |
| 875 x += source_dx; | |
| 876 if ((i + 1) < width) { | |
| 877 y = y_buf[x >> 16]; | |
| 878 YuvPixel(y, u, v, rgb_buf+4); | |
| 879 x += source_dx; | |
| 880 } | |
| 881 rgb_buf += 8; | |
| 882 } | |
| 883 } | |
| 884 | |
| 885 void LinearScaleYUVToRGB32Row(const uint8* y_buf, | |
| 886 const uint8* u_buf, | |
| 887 const uint8* v_buf, | |
| 888 uint8* rgb_buf, | |
| 889 int width, | |
| 890 int source_dx) { | |
| 891 int x = 0; | |
| 892 if (source_dx >= 0x20000) { | |
| 893 x = 32768; | |
| 894 } | |
| 895 for (int i = 0; i < width; i += 2) { | |
| 896 int y0 = y_buf[x >> 16]; | |
| 897 int y1 = y_buf[(x >> 16) + 1]; | |
| 898 int u0 = u_buf[(x >> 17)]; | |
| 899 int u1 = u_buf[(x >> 17) + 1]; | |
| 900 int v0 = v_buf[(x >> 17)]; | |
| 901 int v1 = v_buf[(x >> 17) + 1]; | |
| 902 int y_frac = (x & 65535); | |
| 903 int uv_frac = ((x >> 1) & 65535); | |
| 904 int y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16; | |
| 905 int u = (uv_frac * u1 + (uv_frac ^ 65535) * u0) >> 16; | |
| 906 int v = (uv_frac * v1 + (uv_frac ^ 65535) * v0) >> 16; | |
| 907 YuvPixel(y, u, v, rgb_buf); | |
| 908 x += source_dx; | |
| 909 if ((i + 1) < width) { | |
| 910 y0 = y_buf[x >> 16]; | |
| 911 y1 = y_buf[(x >> 16) + 1]; | |
| 912 y_frac = (x & 65535); | |
| 913 y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16; | |
| 914 YuvPixel(y, u, v, rgb_buf+4); | |
| 915 x += source_dx; | |
| 916 } | |
| 917 rgb_buf += 8; | |
| 918 } | |
| 919 } | |
| 920 | |
| 921 #endif // USE_MMX | |
| 922 } // extern "C" | |
| OLD | NEW |