Index: media/base/yuv_convert.cc |
=================================================================== |
--- media/base/yuv_convert.cc (revision 19949) |
+++ media/base/yuv_convert.cc (working copy) |
@@ -6,92 +6,34 @@ |
// http://www.fourcc.org/yuv.php |
// The actual conversion is best described here |
// http://en.wikipedia.org/wiki/YUV |
-// excerpt from wiki: |
-// These formulae are based on the NTSC standard; |
-// Y' = 0.299 x R + 0.587 x G + 0.114 x B |
-// U = -0.147 x R - 0.289 x G + 0.436 x B |
-// V = 0.615 x R - 0.515 x G - 0.100 x B |
-// On older, non-SIMD architectures, floating point arithmetic is much |
-// slower than using fixed-point arithmetic, so an alternative formulation |
-// is: |
-// c = Y' - 16 |
-// d = U - 128 |
-// e = V - 128 |
-// Using the previous coefficients and noting that clip() denotes clipping a |
-// value to the range of 0 to 255, the following formulae provide the |
-// conversion from Y'UV to RGB (NTSC version): |
-// R = clip((298 x c + 409 x e + 128) >> 8) |
-// G = clip((298 x c - 100 x d - 208 x e + 128) >> 8) |
-// B = clip((298 x c + 516 x d + 128) >> 8) |
-// |
// An article on optimizing YUV conversion using tables instead of multiplies |
-// http://lestourtereaux.free.fr/papers/data/yuvrgb.pdf |
+// 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 output, which on little endian is stored as BGRA. |
-// The alpha is filled in, allowing the application to use RGBA or RGB32. |
-// |
-// The Visual C assembler is considered the source. |
-// The GCC asm was created by compiling with Visual C and disassembling |
-// with GNU objdump. |
-// cl /c /Ox yuv_convert.cc |
-// objdump -d yuv_convert.o |
-// The code almost copy/pasted in, except the table lookups, which produced |
-// movq 0x800(,%eax,8),%mm0 |
-// and needed to be changed to cdecl style table names |
-// "movq _coefficients_RGB_U(,%eax,8),%mm0\n" |
-// extern "C" was used to avoid name mangling. |
-// |
-// Once compiled with both MinGW GCC and Visual C on PC, performance should |
-// be identical. A small difference will occur in the C++ calling code, |
-// depending on the frame size. |
-// To confirm the same code is being generated |
-// g++ -O3 -c yuv_convert.cc |
-// dumpbin -disasm yuv_convert.o >gcc.txt |
-// cl /Ox /c yuv_convert.cc |
-// dumpbin -disasm yuv_convert.obj >vc.txt |
-// and compare the files. |
-// |
-// The GCC function label is inside the assembler to avoid a stack frame |
-// push ebp, that may vary depending on compile options. |
+// ARGB pixel format is output, which on little endian is stored as BGRA. |
+// The alpha is set to 255, allowing the application to use RGBA or RGB32. |
#include "media/base/yuv_convert.h" |
-#ifdef _OPENMP |
-#include <omp.h> |
-#endif |
- |
-#ifdef _DEBUG |
-#include "base/logging.h" |
-#else |
-#define DCHECK(a) |
-#endif |
- |
// Header for low level row functions. |
#include "media/base/yuv_row.h" |
namespace media { |
+ |
// Convert a frame of YUV to 32 bit ARGB. |
void ConvertYUVToRGB32(const uint8* y_buf, |
- const uint8* u_buf, |
- const uint8* v_buf, |
- uint8* rgb_buf, |
- int width, |
- int height, |
- int y_pitch, |
- int uv_pitch, |
- int rgb_pitch, |
- YUVType yuv_type) { |
+ const uint8* u_buf, |
+ const uint8* v_buf, |
+ uint8* rgb_buf, |
+ int width, |
+ int height, |
+ int y_pitch, |
+ int uv_pitch, |
+ int rgb_pitch, |
+ YUVType yuv_type) { |
unsigned int y_shift = yuv_type; |
-#ifdef _OPENMP |
-#pragma omp parallel for |
-#endif |
for (int y = 0; y < height; ++y) { |
uint8* rgb_row = rgb_buf + y * rgb_pitch; |
const uint8* y_ptr = y_buf + y * y_pitch; |
@@ -104,23 +46,25 @@ |
rgb_row, |
width); |
} |
+ |
+ // MMX used for FastConvertYUVToRGB32Row requires emms instruction. |
EMMS(); |
} |
// Scale a frame of YUV to 32 bit ARGB. |
void ScaleYUVToRGB32(const uint8* y_buf, |
- const uint8* u_buf, |
- const uint8* v_buf, |
- uint8* rgb_buf, |
- int width, |
- int height, |
- int scaled_width, |
- int scaled_height, |
- int y_pitch, |
- int uv_pitch, |
- int rgb_pitch, |
- YUVType yuv_type, |
- Rotate view_rotate) { |
+ const uint8* u_buf, |
+ const uint8* v_buf, |
+ uint8* rgb_buf, |
+ int width, |
+ int height, |
+ int scaled_width, |
+ int scaled_height, |
+ int y_pitch, |
+ int uv_pitch, |
+ int rgb_pitch, |
+ YUVType yuv_type, |
+ Rotate view_rotate) { |
unsigned int y_shift = yuv_type; |
// Diagram showing origin and direction of source sampling. |
// ->0 4<- |
@@ -180,9 +124,6 @@ |
} |
} |
-#ifdef _OPENMP |
-#pragma omp parallel for |
-#endif |
for (int y = 0; y < scaled_height; ++y) { |
uint8* dest_pixel = rgb_buf + y * rgb_pitch; |
int scaled_y = (y * height / scaled_height); |
@@ -218,6 +159,8 @@ |
dest_pixel, scaled_width, scaled_dx); |
} |
} |
+ |
+ // MMX used for FastConvertYUVToRGB32Row requires emms instruction. |
EMMS(); |
} |