| Index: media/base/yuv_convert.cc
|
| ===================================================================
|
| --- media/base/yuv_convert.cc (revision 13092)
|
| +++ media/base/yuv_convert.cc (working copy)
|
| @@ -27,14 +27,15 @@
|
| // An article on optimizing YUV conversion using tables instead of multiplies
|
| // http://lestourtereaux.free.fr/papers/data/yuvrgb.pdf
|
| //
|
| +// YV12 is a full plane of Y and a half height, half width chroma planes
|
| +// YV16 is a full plane of Y and a full height, half width chroma planes
|
| +//
|
| // Implimentation notes
|
| // This version uses MMX for Visual C and GCC, which should cover all
|
| // current platforms. C++ is included for reference and future platforms.
|
| //
|
| -// ARGB pixel format is assumed, which on little endian is stored as BGRA.
|
| +// ARGB pixel format is output, which on little endian is stored as BGRA.
|
| // The alpha is filled in, allowing the application to use RGBA or RGB32.
|
| -// The row based conversion allows for a future YV16 version, and simplifies
|
| -// the platform specific portion of the code.
|
| //
|
| // The Visual C assembler is considered the source.
|
| // The GCC asm was created by compiling with Visual C and disassembling
|
| @@ -383,14 +384,14 @@
|
| "mov 0x34(%esp),%ecx\n"
|
| "shr %ecx\n"
|
| "1:\n"
|
| - "movzbl (%edi),%eax\n"
|
| + "movzb (%edi),%eax\n"
|
| "add $0x1,%edi\n"
|
| - "movzbl (%esi),%ebx\n"
|
| + "movzb (%esi),%ebx\n"
|
| "add $0x1,%esi\n"
|
| "movq coefficients_RGB_U(,%eax,8),%mm0\n"
|
| - "movzbl (%edx),%eax\n"
|
| + "movzb (%edx),%eax\n"
|
| "paddsw coefficients_RGB_V(,%ebx,8),%mm0\n"
|
| - "movzbl 0x1(%edx),%ebx\n"
|
| + "movzb 0x1(%edx),%ebx\n"
|
| "movq coefficients_RGB_Y(,%eax,8),%mm1\n"
|
| "add $0x2,%edx\n"
|
| "movq coefficients_RGB_Y(,%ebx,8),%mm2\n"
|
| @@ -428,14 +429,14 @@
|
| "xor %eax,%eax\n"
|
| "xor %ebx,%ebx\n"
|
| "1:\n"
|
| - "movzbl (%edi),%eax\n"
|
| + "movzb (%edi),%eax\n"
|
| "add $0x1,%edi\n"
|
| - "movzbl (%esi),%ebx\n"
|
| + "movzb (%esi),%ebx\n"
|
| "add $0x1,%esi\n"
|
| "movq _coefficients_RGB_U(,%eax,8),%mm0\n"
|
| - "movzbl (%edx),%eax\n"
|
| + "movzb (%edx),%eax\n"
|
| "paddsw _coefficients_RGB_V(,%ebx,8),%mm0\n"
|
| - "movzbl 0x1(%edx),%ebx\n"
|
| + "movzb 0x1(%edx),%ebx\n"
|
| "movq _coefficients_RGB_Y(,%eax,8),%mm1\n"
|
| "add $0x2,%edx\n"
|
| "movq _coefficients_RGB_Y(,%ebx,8),%mm2\n"
|
| @@ -464,7 +465,7 @@
|
| size_t width);
|
| #endif
|
|
|
| -// Convert a frame of YUV to 32 bit ARGB.
|
| +// Convert a frame of YV12 (aka YUV420) to 32 bit ARGB.
|
| void ConvertYV12ToRGB32(const uint8* y_buf,
|
| const uint8* u_buf,
|
| const uint8* v_buf,
|
| @@ -503,6 +504,45 @@
|
| #endif
|
| }
|
|
|
| +// Convert a frame of YV16 (aka YUV422) to 32 bit ARGB.
|
| +void ConvertYV16ToRGB32(const uint8* y_buf,
|
| + const uint8* u_buf,
|
| + const uint8* v_buf,
|
| + uint8* rgb_buf,
|
| + size_t width,
|
| + size_t height,
|
| + int y_pitch,
|
| + int uv_pitch,
|
| + int rgb_pitch) {
|
| + // Image must be multiple of 2 in width.
|
| + DCHECK((width & 1) == 0);
|
| + // Check alignment. Use memalign to allocate the buffer if you hit this
|
| + // check:
|
| + DCHECK((reinterpret_cast<uintptr_t>(rgb_buf) & 7) == 0);
|
| +#ifdef _OPENMP
|
| +#pragma omp parallel for
|
| +#endif
|
| + for (int y = 0; y < static_cast<int>(height); ++y) {
|
| + uint8* d1 = rgb_buf + y * rgb_pitch;
|
| + const uint8* y_ptr = y_buf + y * y_pitch;
|
| + const uint8* u_ptr = u_buf + y * uv_pitch;
|
| + const uint8* v_ptr = v_buf + y * uv_pitch;
|
| +
|
| + ConvertYV12ToRGB32Row(y_ptr,
|
| + u_ptr,
|
| + v_ptr,
|
| + d1,
|
| + width);
|
| + }
|
| +#if USE_MMX
|
| +#if defined(_MSC_VER)
|
| + __asm emms;
|
| +#else
|
| + asm("emms");
|
| +#endif
|
| +#endif
|
| +}
|
| +
|
| //------------------------------------------------------------------------------
|
| // This is pure C code
|
|
|
|
|