| OLD | NEW |
| (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 | |
| OLD | NEW |