author | Chris Double <chris.double@double.co.nz> |
Tue, 06 Apr 2010 18:09:18 +1200 | |
changeset 40475 | 56850227b2946ec32197a7cca78d2ea54156ee0b |
parent 40463 | 67f4c546d40329f52d64b4290779008c670fbdfa |
child 40476 | 1d3fc492dfb2175ed61076375e732c135acfa678 |
push id | unknown |
push user | unknown |
push date | unknown |
bugs | 551277 |
milestone | 1.9.3a4pre |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
|
gfx/layers/ImageLayers.h | file | annotate | diff | comparison | revisions | |
gfx/layers/basic/BasicImages.cpp | file | annotate | diff | comparison | revisions | |
gfx/ycbcr/README | file | annotate | diff | comparison | revisions | |
gfx/ycbcr/update.sh | file | annotate | diff | comparison | revisions | |
gfx/ycbcr/yuv_convert.cpp | file | annotate | diff | comparison | revisions | |
gfx/ycbcr/yuv_convert.h | file | annotate | diff | comparison | revisions | |
gfx/ycbcr/yuv_row.h | file | annotate | diff | comparison | revisions | |
gfx/ycbcr/yuv_row_c.cpp | file | annotate | diff | comparison | revisions | |
gfx/ycbcr/yv24.patch | file | annotate | diff | comparison | revisions |
--- a/gfx/layers/ImageLayers.h +++ b/gfx/layers/ImageLayers.h @@ -214,16 +214,19 @@ protected: * 4:2:0 - CbCr width and height is half that of Y. * * The color format is detected based on the height/width ratios * defined above. * * The Image that is rendered is the picture region defined by * mPicX, mPicY and mPicSize. The size of the rendered image is * mPicSize, not mYSize or mCbCrSize. + * + * Note: The color-conversion code does not currently support 4:4:4 + * and an error is raised in this case. See bug 551378. */ class THEBES_API PlanarYCbCrImage : public Image { public: struct Data { // Luminance buffer PRUint8* mYChannel; PRInt32 mYStride; gfxIntSize mYSize;
--- a/gfx/layers/basic/BasicImages.cpp +++ b/gfx/layers/basic/BasicImages.cpp @@ -130,17 +130,17 @@ BasicPlanarYCbCrImage::SetData(const Dat if (!mBuffer) { // out of memory return; } gfx::YUVType type = gfx::YV12; if (aData.mYSize.width == aData.mCbCrSize.width && aData.mYSize.height == aData.mCbCrSize.height) { - type = gfx::YV24; + NS_ERROR("YCbCr 4:4:4 format not supported"); } else if (aData.mYSize.width / 2 == aData.mCbCrSize.width && aData.mYSize.height == aData.mCbCrSize.height) { type = gfx::YV16; } else if (aData.mYSize.width / 2 == aData.mCbCrSize.width && aData.mYSize.height / 2 == aData.mCbCrSize.height ) { type = gfx::YV12;
--- a/gfx/ycbcr/README +++ b/gfx/ycbcr/README @@ -10,10 +10,8 @@ convert.patch: Change Chromium code to b Add runtime CPU detection for MMX Move default C implementation to work on all platforms. picture_region.patch: Change Chromium code to allow a picture region. The YUV conversion will convert within this picture region only. remove_scale.patch: Removes Chromium scaling code. - -yv24.patch: Adds YCbCr 4:4:4 support
--- a/gfx/ycbcr/update.sh +++ b/gfx/ycbcr/update.sh @@ -4,9 +4,8 @@ cp $1/media/base/yuv_convert.cc yuv_conv cp $1/media/base/yuv_row.h . cp $1/media/base/yuv_row_linux.cc yuv_row_linux.cpp cp $1/media/base/yuv_row_mac.cc yuv_row_mac.cpp cp $1/media/base/yuv_row_win.cc yuv_row_win.cpp cp $1/media/base/yuv_row_linux.cc yuv_row_c.cpp patch -p3 <convert.patch patch -p3 <picture_region.patch patch -p3 <remove_scale.patch -patch -p3 <yv24.patch
--- a/gfx/ycbcr/yuv_convert.cpp +++ b/gfx/ycbcr/yuv_convert.cpp @@ -6,17 +6,16 @@ // http://www.fourcc.org/yuv.php // The actual conversion is best described here // http://en.wikipedia.org/wiki/YUV // 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 -// YV24 is a full plane of Y and a full height, full width chroma planes // // 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 "yuv_convert.h" // Header for low level row functions. #include "yuv_row.h" @@ -34,55 +33,50 @@ void ConvertYCbCrToRGB32(const uint8* y_ int pic_x, int pic_y, int pic_width, int pic_height, int y_pitch, int uv_pitch, int rgb_pitch, YUVType yuv_type) { - unsigned int y_shift = yuv_type == YV12 ? 1 : 0; - unsigned int x_shift = yuv_type == YV24 ? 0 : 1; - // There is no optimized YV24 MMX routine so we check for this and - // fall back to the C code. - bool has_mmx = supports_mmx() && yuv_type != YV24; - bool odd_pic_x = yuv_type != YV24 && pic_x % 2 != 0; + unsigned int y_shift = yuv_type; + bool has_mmx = supports_mmx(); + bool odd_pic_x = pic_x % 2 != 0; int x_width = odd_pic_x ? pic_width - 1 : pic_width; for (int y = pic_y; y < pic_height + pic_y; ++y) { uint8* rgb_row = rgb_buf + (y - pic_y) * rgb_pitch; const uint8* y_ptr = y_buf + y * y_pitch + pic_x; - const uint8* u_ptr = u_buf + (y >> y_shift) * uv_pitch + (pic_x >> x_shift); - const uint8* v_ptr = v_buf + (y >> y_shift) * uv_pitch + (pic_x >> x_shift); + const uint8* u_ptr = u_buf + (y >> y_shift) * uv_pitch + (pic_x >> 1); + const uint8* v_ptr = v_buf + (y >> y_shift) * uv_pitch + (pic_x >> 1); if (odd_pic_x) { // Handle the single odd pixel manually and use the // fast routines for the remaining. FastConvertYUVToRGB32Row_C(y_ptr++, u_ptr++, v_ptr++, rgb_row, - 1, - x_shift); + 1); rgb_row += 4; } if (has_mmx) FastConvertYUVToRGB32Row(y_ptr, u_ptr, v_ptr, rgb_row, x_width); else FastConvertYUVToRGB32Row_C(y_ptr, u_ptr, v_ptr, rgb_row, - x_width, - x_shift); + x_width); } // MMX used for FastConvertYUVToRGB32Row requires emms instruction. if (has_mmx) EMMS(); } } // namespace gfx
--- a/gfx/ycbcr/yuv_convert.h +++ b/gfx/ycbcr/yuv_convert.h @@ -9,19 +9,18 @@ namespace mozilla { namespace gfx { // Type of YUV surface. // The value of these enums matter as they are used to shift vertical indices. enum YUVType { - YV12 = 0, // YV12 is half width and half height chroma channels. - YV16 = 1, // YV16 is half width and full height chroma channels. - YV24 = 2 // YV24 is full width and full height chroma channels. + YV16 = 0, // YV16 is half width and full height chroma channels. + YV12 = 1 // YV12 is half width and half height chroma channels. }; // Convert a frame of YUV to 32 bit ARGB. // Pass in YV16/YV12 depending on source format void ConvertYCbCrToRGB32(const uint8* yplane, const uint8* uplane, const uint8* vplane, uint8* rgbframe,
--- a/gfx/ycbcr/yuv_row.h +++ b/gfx/ycbcr/yuv_row.h @@ -20,18 +20,17 @@ void FastConvertYUVToRGB32Row(const uint const uint8* v_buf, uint8* rgb_buf, int width); void FastConvertYUVToRGB32Row_C(const uint8* y_buf, const uint8* u_buf, const uint8* v_buf, uint8* rgb_buf, - int width, - unsigned int x_shift); + int width); } // extern "C" // x64 uses MMX2 (SSE) so emms is not required. #if !defined(ARCH_CPU_X86_64) && !defined(ARCH_CPU_PPC) #if defined(_MSC_VER) #define EMMS() __asm emms
--- a/gfx/ycbcr/yuv_row_c.cpp +++ b/gfx/ycbcr/yuv_row_c.cpp @@ -153,29 +153,24 @@ static inline void YuvPixel(uint8 y, (clip(C298a + cr) << 16) | (0xff000000); } void FastConvertYUVToRGB32Row_C(const uint8* y_buf, const uint8* u_buf, const uint8* v_buf, uint8* rgb_buf, - int width, - unsigned int x_shift) { + int width) { for (int x = 0; x < width; x += 2) { - uint8 u = u_buf[x >> x_shift]; - uint8 v = v_buf[x >> x_shift]; + uint8 u = u_buf[x >> 1]; + uint8 v = v_buf[x >> 1]; uint8 y0 = y_buf[x]; YuvPixel(y0, u, v, rgb_buf); if ((x + 1) < width) { uint8 y1 = y_buf[x + 1]; - if (x_shift == 0) { - u = u_buf[x + 1]; - v = v_buf[x + 1]; - } YuvPixel(y1, u, v, rgb_buf + 4); } rgb_buf += 8; // Advance 2 pixels. } } } // extern "C"
deleted file mode 100644 --- a/gfx/ycbcr/yv24.patch +++ /dev/null @@ -1,172 +0,0 @@ -diff --git a/gfx/ycbcr/yuv_convert.cpp b/gfx/ycbcr/yuv_convert.cpp -index b22e778..cdbb040 100644 ---- a/gfx/ycbcr/yuv_convert.cpp -+++ b/gfx/ycbcr/yuv_convert.cpp -@@ -6,16 +6,17 @@ - // http://www.fourcc.org/yuv.php - // The actual conversion is best described here - // http://en.wikipedia.org/wiki/YUV - // 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 -+// YV24 is a full plane of Y and a full height, full width chroma planes - // - // 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 "yuv_convert.h" - - // Header for low level row functions. - #include "yuv_row.h" -@@ -33,50 +34,55 @@ void ConvertYCbCrToRGB32(const uint8* y_buf, - int pic_x, - int pic_y, - int pic_width, - int pic_height, - int y_pitch, - int uv_pitch, - int rgb_pitch, - YUVType yuv_type) { -- unsigned int y_shift = yuv_type; -- bool has_mmx = supports_mmx(); -- bool odd_pic_x = pic_x % 2 != 0; -+ unsigned int y_shift = yuv_type == YV12 ? 1 : 0; -+ unsigned int x_shift = yuv_type == YV24 ? 0 : 1; -+ // There is no optimized YV24 MMX routine so we check for this and -+ // fall back to the C code. -+ bool has_mmx = supports_mmx() && yuv_type != YV24; -+ bool odd_pic_x = yuv_type != YV24 && pic_x % 2 != 0; - int x_width = odd_pic_x ? pic_width - 1 : pic_width; - - for (int y = pic_y; y < pic_height + pic_y; ++y) { - uint8* rgb_row = rgb_buf + (y - pic_y) * rgb_pitch; - const uint8* y_ptr = y_buf + y * y_pitch + pic_x; -- const uint8* u_ptr = u_buf + (y >> y_shift) * uv_pitch + (pic_x >> 1); -- const uint8* v_ptr = v_buf + (y >> y_shift) * uv_pitch + (pic_x >> 1); -+ const uint8* u_ptr = u_buf + (y >> y_shift) * uv_pitch + (pic_x >> x_shift); -+ const uint8* v_ptr = v_buf + (y >> y_shift) * uv_pitch + (pic_x >> x_shift); - - if (odd_pic_x) { - // Handle the single odd pixel manually and use the - // fast routines for the remaining. - FastConvertYUVToRGB32Row_C(y_ptr++, - u_ptr++, - v_ptr++, - rgb_row, -- 1); -+ 1, -+ x_shift); - rgb_row += 4; - } - - if (has_mmx) - FastConvertYUVToRGB32Row(y_ptr, - u_ptr, - v_ptr, - rgb_row, - x_width); - else - FastConvertYUVToRGB32Row_C(y_ptr, - u_ptr, - v_ptr, - rgb_row, -- x_width); -+ x_width, -+ x_shift); - } - - // MMX used for FastConvertYUVToRGB32Row requires emms instruction. - if (has_mmx) - EMMS(); - } - - } // namespace gfx -diff --git a/gfx/ycbcr/yuv_convert.h b/gfx/ycbcr/yuv_convert.h -index 6735b77..15fe381 100644 ---- a/gfx/ycbcr/yuv_convert.h -+++ b/gfx/ycbcr/yuv_convert.h -@@ -9,18 +9,19 @@ - - namespace mozilla { - - namespace gfx { - - // Type of YUV surface. - // The value of these enums matter as they are used to shift vertical indices. - enum YUVType { -- YV16 = 0, // YV16 is half width and full height chroma channels. -- YV12 = 1 // YV12 is half width and half height chroma channels. -+ YV12 = 0, // YV12 is half width and half height chroma channels. -+ YV16 = 1, // YV16 is half width and full height chroma channels. -+ YV24 = 2 // YV24 is full width and full height chroma channels. - }; - - // Convert a frame of YUV to 32 bit ARGB. - // Pass in YV16/YV12 depending on source format - void ConvertYCbCrToRGB32(const uint8* yplane, - const uint8* uplane, - const uint8* vplane, - uint8* rgbframe, -diff --git a/gfx/ycbcr/yuv_row.h b/gfx/ycbcr/yuv_row.h -index 2a82972..d776dac 100644 ---- a/gfx/ycbcr/yuv_row.h -+++ b/gfx/ycbcr/yuv_row.h -@@ -20,17 +20,18 @@ void FastConvertYUVToRGB32Row(const uint8* y_buf, - const uint8* v_buf, - uint8* rgb_buf, - int width); - - void FastConvertYUVToRGB32Row_C(const uint8* y_buf, - const uint8* u_buf, - const uint8* v_buf, - uint8* rgb_buf, -- int width); -+ int width, -+ unsigned int x_shift); - - - } // extern "C" - - // x64 uses MMX2 (SSE) so emms is not required. - #if !defined(ARCH_CPU_X86_64) && !defined(ARCH_CPU_PPC) - #if defined(_MSC_VER) - #define EMMS() __asm emms -diff --git a/gfx/ycbcr/yuv_row_c.cpp b/gfx/ycbcr/yuv_row_c.cpp -index d3bdab4..36d9bda 100644 ---- a/gfx/ycbcr/yuv_row_c.cpp -+++ b/gfx/ycbcr/yuv_row_c.cpp -@@ -153,24 +153,29 @@ static inline void YuvPixel(uint8 y, - (clip(C298a + cr) << 16) | - (0xff000000); - } - - void FastConvertYUVToRGB32Row_C(const uint8* y_buf, - const uint8* u_buf, - const uint8* v_buf, - uint8* rgb_buf, -- int width) { -+ int width, -+ unsigned int x_shift) { - for (int x = 0; x < width; x += 2) { -- uint8 u = u_buf[x >> 1]; -- uint8 v = v_buf[x >> 1]; -+ uint8 u = u_buf[x >> x_shift]; -+ uint8 v = v_buf[x >> x_shift]; - uint8 y0 = y_buf[x]; - YuvPixel(y0, u, v, rgb_buf); - if ((x + 1) < width) { - uint8 y1 = y_buf[x + 1]; -+ if (x_shift == 0) { -+ u = u_buf[x + 1]; -+ v = v_buf[x + 1]; -+ } - YuvPixel(y1, u, v, rgb_buf + 4); - } - rgb_buf += 8; // Advance 2 pixels. - } - } - - } // extern "C" -