Bug 551277. Merge from backout
authorChris Double <chris.double@double.co.nz>
Tue, 06 Apr 2010 18:09:28 +1200
changeset 40476 1d3fc492dfb2175ed61076375e732c135acfa678
parent 40474 f0ca1ffaa5b80cbb65abc2f86e4165b9e73c5790 (current diff)
parent 40475 56850227b2946ec32197a7cca78d2ea54156ee0b (diff)
child 40478 ac18decab3b314d30419c3095eea49213ef83c4a
push id12622
push usercdouble@mozilla.com
push dateTue, 06 Apr 2010 06:17:33 +0000
treeherdermozilla-central@ac18decab3b3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs551277
milestone1.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
Bug 551277. Merge from backout
gfx/ycbcr/README
gfx/ycbcr/update.sh
gfx/ycbcr/yuv_convert.h
gfx/ycbcr/yv24.patch
--- 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"
-