Bug 551277 - Implement software YCbCr conversion in layers, replacing liboggplay color conversion code - r=roc
authorChris Double <chris.double@double.co.nz>
Tue, 06 Apr 2010 12:07:39 +1200
changeset 40462 f9a11b9b2b9fd4d081708217fac56e29ec23e8db
parent 40461 ac526bc2af65da8548f66dab57b15787ce8c2a02
child 40463 67f4c546d40329f52d64b4290779008c670fbdfa
child 40477 83e18ba3893d9cf1315e4de44f36bc98cb2f4b79
push idunknown
push userunknown
push dateunknown
reviewersroc
bugs551277
milestone1.9.3a4pre
Bug 551277 - Implement software YCbCr conversion in layers, replacing liboggplay color conversion code - r=roc
content/media/ogg/nsOggPlayStateMachine.cpp
gfx/Makefile.in
gfx/layers/ImageLayers.h
gfx/layers/basic/BasicImages.cpp
gfx/ycbcr/LICENSE
gfx/ycbcr/Makefile.in
gfx/ycbcr/README
gfx/ycbcr/chromium_types.h
gfx/ycbcr/convert.patch
gfx/ycbcr/picture_region.patch
gfx/ycbcr/remove_scale.patch
gfx/ycbcr/update.sh
gfx/ycbcr/yuv_convert.cpp
gfx/ycbcr/yuv_convert.h
gfx/ycbcr/yuv_row.h
gfx/ycbcr/yuv_row_c.cpp
gfx/ycbcr/yuv_row_linux.cpp
gfx/ycbcr/yuv_row_mac.cpp
gfx/ycbcr/yuv_row_win.cpp
layout/build/Makefile.in
toolkit/content/license.html
toolkit/library/libxul-config.mk
toolkit/toolkit-makefiles.sh
--- a/content/media/ogg/nsOggPlayStateMachine.cpp
+++ b/content/media/ogg/nsOggPlayStateMachine.cpp
@@ -964,165 +964,95 @@ nsresult nsOggPlayStateMachine::Run()
       }
       break;
     }
   }
 
   return NS_OK;
 }
 
-static void ToARGBHook(const PlanarYCbCrImage::Data& aData, PRUint8* aOutput)
-{
-  OggPlayYUVChannels yuv;
-  NS_ASSERTION(aData.mYStride == aData.mYSize.width,
-               "Stride not supported");
-  NS_ASSERTION(aData.mCbCrStride == aData.mCbCrSize.width,
-               "Stride not supported");
-  yuv.ptry = aData.mYChannel;
-  yuv.ptru = aData.mCbChannel;
-  yuv.ptrv = aData.mCrChannel;
-  yuv.uv_width = aData.mCbCrSize.width;
-  yuv.uv_height = aData.mCbCrSize.height;
-  yuv.y_width = aData.mYSize.width;
-  yuv.y_height = aData.mYSize.height;
-
-  OggPlayRGBChannels rgb;
-  rgb.ptro = aOutput;
-  rgb.rgb_width = aData.mYSize.width;
-  rgb.rgb_height = aData.mYSize.height;
-
-  oggplay_yuv2bgra(&yuv, &rgb);  
-}
-
 void nsOggPlayStateMachine::RenderVideoFrame(VideoData* aData)
 {
   NS_ASSERTION(IsThread(mDecoder->mStateMachineThread), "Should be on state machine thread.");
 
   if (aData->mDuplicate) {
     return;
   }
 
-  unsigned xSubsample = (aData->mBuffer[1].width != 0) ?
-    (aData->mBuffer[0].width / aData->mBuffer[1].width) : 0;
-
-  unsigned ySubsample = (aData->mBuffer[1].height != 0) ?
-    (aData->mBuffer[0].height / aData->mBuffer[1].height) : 0;
-
-  if (xSubsample == 0 || ySubsample == 0) {
-    // We can't perform yCbCr to RGB, so we can't render the frame...
-    return;
-  }
   NS_ASSERTION(mInfo.mPicture.width != 0 && mInfo.mPicture.height != 0,
                "We can only render non-zero-sized video");
-
-  unsigned cbCrStride = mInfo.mPicture.width / xSubsample;
-  unsigned cbCrHeight = mInfo.mPicture.height / ySubsample;
+  NS_ASSERTION(aData->mBuffer[0].stride >= 0 && aData->mBuffer[0].height >= 0 &&
+               aData->mBuffer[1].stride >= 0 && aData->mBuffer[1].height >= 0 &&
+               aData->mBuffer[2].stride >= 0 && aData->mBuffer[2].height >= 0,
+               "YCbCr stride and height must be non-negative");
 
   // Ensure the picture size specified in the headers can be extracted out of
   // the frame we've been supplied without indexing out of bounds.
   PRUint32 picXLimit;
   PRUint32 picYLimit;
   if (!AddOverflow(mInfo.mPicture.x, mInfo.mPicture.width, picXLimit) ||
       picXLimit > PRUint32(PR_ABS(aData->mBuffer[0].stride)) ||
       !AddOverflow(mInfo.mPicture.y, mInfo.mPicture.height, picYLimit) ||
       picYLimit > PRUint32(PR_ABS(aData->mBuffer[0].height)))
   {
     // The specified picture dimensions can't be contained inside the video
     // frame, we'll stomp memory if we try to copy it. Fail.
     return;
   }
 
-  unsigned cbCrSize = PR_ABS(aData->mBuffer[0].stride * aData->mBuffer[0].height) +
-                      PR_ABS(aData->mBuffer[1].stride * aData->mBuffer[1].height) * 2;
+  unsigned ySize = aData->mBuffer[0].stride * aData->mBuffer[0].height;
+  unsigned cbSize = aData->mBuffer[1].stride * aData->mBuffer[1].height;
+  unsigned crSize = aData->mBuffer[2].stride * aData->mBuffer[2].height;
+  unsigned cbCrSize = ySize + cbSize + crSize;
+
   if (cbCrSize != mCbCrSize) {
     mCbCrSize = cbCrSize;
     mCbCrBuffer = static_cast<unsigned char*>(moz_xmalloc(cbCrSize));
     if (!mCbCrBuffer) {
       // Malloc failed...
       NS_WARNING("Malloc failure allocating YCbCr->RGB buffer");
       return;
     }
   }
 
   unsigned char* data = mCbCrBuffer.get();
 
   unsigned char* y = data;
-  unsigned char* cb = y + (mInfo.mPicture.width * PR_ABS(aData->mBuffer[0].height));
-  unsigned char* cr = cb + (cbCrStride * PR_ABS(aData->mBuffer[1].height));
-
-  unsigned char* p = y;
-  unsigned char* q = aData->mBuffer[0].data + mInfo.mPicture.x +
-                     aData->mBuffer[0].stride * mInfo.mPicture.y;
-  for(PRInt32 i=0; i < mInfo.mPicture.height; ++i) {
-    NS_ASSERTION(q + mInfo.mPicture.width <
-                 aData->mBuffer[0].data + aData->mBuffer[0].stride * aData->mBuffer[0].height,
-                 "Y read must be in bounds");
-    NS_ASSERTION(p + mInfo.mPicture.width < data + mCbCrSize,
-                 "Memory copy 1 will stomp");
-    memcpy(p, q, mInfo.mPicture.width);
-    p += mInfo.mPicture.width;
-    q += aData->mBuffer[0].stride;
-  }
-
-  unsigned xo = xSubsample ? (mInfo.mPicture.x / xSubsample) : 0;
-  unsigned yo = ySubsample ? aData->mBuffer[1].stride * (mInfo.mPicture.y / ySubsample) : 0;
-
-  unsigned cbCrOffset = xo+yo;
-  p = cb;
-  q = aData->mBuffer[1].data + cbCrOffset;
-  unsigned char* p2 = cr;
-  unsigned char* q2 = aData->mBuffer[2].data + cbCrOffset;
-#ifdef DEBUG
-  unsigned char* buffer1Limit =
-    aData->mBuffer[1].data + aData->mBuffer[1].stride * aData->mBuffer[1].height;
-  unsigned char* buffer2Limit =
-    aData->mBuffer[2].data + aData->mBuffer[2].stride * aData->mBuffer[2].height;
-#endif
-  for(unsigned i=0; i < cbCrHeight; ++i) {
-    NS_ASSERTION(q + cbCrStride <= buffer1Limit,
-                 "Cb source read must be within bounds");
-    NS_ASSERTION(q2 + cbCrStride <= buffer2Limit,
-                 "Cr source read must be within bounds");
-    NS_ASSERTION(p + cbCrStride < data + mCbCrSize,
-                 "Cb write destination must be within bounds");
-    NS_ASSERTION(p2 + cbCrStride < data + mCbCrSize,
-                 "Cr write destination must be within bounds");
-    memcpy(p, q, cbCrStride);
-    memcpy(p2, q2, cbCrStride);
-    p += cbCrStride;
-    p2 += cbCrStride;
-    q += aData->mBuffer[1].stride;
-    q2 += aData->mBuffer[2].stride;
-  }
-
+  unsigned char* cb = y + ySize;
+  unsigned char* cr = cb + cbSize;
+  
+  memcpy(y, aData->mBuffer[0].data, ySize);
+  memcpy(cb, aData->mBuffer[1].data, cbSize);
+  memcpy(cr, aData->mBuffer[2].data, crSize);
+ 
   ImageContainer* container = mDecoder->GetImageContainer();
   // Currently our Ogg decoder only knows how to output to PLANAR_YCBCR
   // format.
   Image::Format format = Image::PLANAR_YCBCR;
   nsRefPtr<Image> image;
   if (container) {
     image = container->CreateImage(&format, 1);
   }
   if (image) {
     NS_ASSERTION(image->GetFormat() == Image::PLANAR_YCBCR,
                  "Wrong format?");
     PlanarYCbCrImage* videoImage = static_cast<PlanarYCbCrImage*>(image.get());
-    // XXX this is only temporary until we get YCbCr code in the layer
-    // system.
-    videoImage->SetRGBConverter(ToARGBHook);
     PlanarYCbCrImage::Data data;
     data.mYChannel = y;
-    data.mYSize = gfxIntSize(mInfo.mPicture.width, mInfo.mPicture.height);
-    data.mYStride = mInfo.mPicture.width;
+    data.mYSize = gfxIntSize(mInfo.mFrame.width, mInfo.mFrame.height);
+    data.mYStride = aData->mBuffer[0].stride;
     data.mCbChannel = cb;
     data.mCrChannel = cr;
-    data.mCbCrSize = gfxIntSize(cbCrStride, cbCrHeight);
-    data.mCbCrStride = cbCrStride;
+    data.mCbCrSize = gfxIntSize(aData->mBuffer[1].width, aData->mBuffer[1].height);
+    data.mCbCrStride = aData->mBuffer[1].stride;
+    data.mPicX = mInfo.mPicture.x;
+    data.mPicY = mInfo.mPicture.y;
+    data.mPicSize = gfxIntSize(mInfo.mPicture.width, mInfo.mPicture.height);
     videoImage->SetData(data);
-    mDecoder->SetVideoData(data.mYSize, mInfo.mAspectRatio, image);
+    mDecoder->SetVideoData(data.mPicSize, mInfo.mAspectRatio, image);
   }
 }
 
 PRInt64
 nsOggPlayStateMachine::GetAudioClock()
 {
   NS_ASSERTION(IsThread(mDecoder->mStateMachineThread), "Should be on state machine thread.");
   if (!mAudioStream || !HasAudio())
--- a/gfx/Makefile.in
+++ b/gfx/Makefile.in
@@ -43,17 +43,17 @@ VPATH		= @srcdir@
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= gfx
 
 ifdef MOZ_TREE_CAIRO
 DIRS		= cairo
 endif
 
-DIRS		+= thebes public idl src qcms layers
+DIRS		+= thebes public idl src qcms ycbcr layers
 
 ifdef MOZ_IPC
 DIRS		+= ipc
 endif
 
 ifdef ENABLE_TESTS
 ifndef MOZ_ENABLE_LIBXUL
 TOOL_DIRS	+= tests
--- a/gfx/layers/ImageLayers.h
+++ b/gfx/layers/ImageLayers.h
@@ -201,40 +201,51 @@ protected:
   gfxPattern::GraphicsFilter mFilter;
 };
 
 /****** Image subtypes for the different formats ******/
 
 /**
  * We assume that the image data is in the REC 470M color space (see
  * Theora specification, section 4.3.1).
- * XXX Eventually we should some color space parameter(s) here.
+ *
+ * The YCbCr format can be:
+ *
+ * 4:4:4 - CbCr width/height are the same as Y.
+ * 4:2:2 - CbCr width is half that of Y. Height is the same.
+ * 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;
     // Chroma buffers
     PRUint8* mCbChannel;
     PRUint8* mCrChannel;
     PRInt32 mCbCrStride;
     gfxIntSize mCbCrSize;
+    // Picture region
+    PRUint32 mPicX;
+    PRUint32 mPicY;
+    gfxIntSize mPicSize;
   };
 
-  typedef void (* ToARGBHook)(const Data& aData, PRUint8* aOutput);
-  /**
-   * XXX this is just a hack until we can get YCbCr conversion code into
-   * gfx
-   * This must be called before SetData().
-   */
-  virtual void SetRGBConverter(ToARGBHook aHook) {}
-
   /**
    * This makes a copy of the data buffers.
    * XXX Eventually we will change this to not make a copy of the data,
    * but we can't do that until we have tighter control of nsOggDecoder's
    * buffer management (i.e. not going through liboggplay). Right now
    * it doesn't matter because the BasicLayer implementation does YCbCr
    * conversion here anyway.
    */
--- a/gfx/layers/basic/BasicImages.cpp
+++ b/gfx/layers/basic/BasicImages.cpp
@@ -42,16 +42,18 @@
 #include "gfxImageSurface.h"
 
 #ifdef XP_MACOSX
 #include "gfxQuartzImageSurface.h"
 #endif
 
 #include "cairo.h"
 
+#include "yuv_convert.h"
+
 using mozilla::Monitor;
 
 namespace mozilla {
 namespace layers {
 
 /**
  * All our images can yield up a cairo surface and their size.
  */
@@ -98,49 +100,74 @@ protected:
 /**
  * We handle YCbCr by converting to RGB when the image is initialized
  * (which should be done off the main thread). The RGB results are stored
  * in a memory buffer and converted to a cairo surface lazily.
  */
 class BasicPlanarYCbCrImage : public PlanarYCbCrImage, public BasicImageImplData {
 public:
   BasicPlanarYCbCrImage() :
-    PlanarYCbCrImage(static_cast<BasicImageImplData*>(this)),
-    mToARGB(nsnull)
+    PlanarYCbCrImage(static_cast<BasicImageImplData*>(this))
     {}
 
-  virtual void SetRGBConverter(ToARGBHook aHook) { mToARGB = aHook; }
   virtual void SetData(const Data& aData);
 
   virtual already_AddRefed<gfxASurface> GetAsSurface();
 
 protected:
-  ToARGBHook                           mToARGB;
   nsAutoArrayPtr<PRUint8>              mBuffer;
   nsCountedRef<nsMainThreadSurfaceRef> mSurface;
 };
 
 void
 BasicPlanarYCbCrImage::SetData(const Data& aData)
 {
   // Do some sanity checks to prevent integer overflow
   if (aData.mYSize.width > 16384 || aData.mYSize.height > 16384) {
     NS_ERROR("Illegal width or height");
     return;
   }
-  size_t size = aData.mYSize.width*aData.mYSize.height*4;
+  size_t size = aData.mPicSize.width*aData.mPicSize.height*4;
   mBuffer = new PRUint8[size];
   if (!mBuffer) {
     // out of memory
     return;
   }
 
+  gfx::YUVType type = gfx::YV12;
+  if (aData.mYSize.width == aData.mCbCrSize.width &&
+      aData.mYSize.height == aData.mCbCrSize.height) {
+    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;
+  }
+  else {
+    NS_ERROR("YCbCr format not supported");
+  }
+ 
   // Convert from YCbCr to RGB now
-  mToARGB(aData, mBuffer);
-  mSize = aData.mYSize;
+  gfx::ConvertYCbCrToRGB32(aData.mYChannel,
+                           aData.mCbChannel,
+                           aData.mCrChannel,
+                           mBuffer,
+                           aData.mPicX,
+                           aData.mPicY,
+                           aData.mPicSize.width,
+                           aData.mPicSize.height,
+                           aData.mYStride,
+                           aData.mCbCrStride,
+                           aData.mPicSize.width*4,
+                           type);                                                          
+  mSize = aData.mPicSize;
 }
 
 static cairo_user_data_key_t imageSurfaceDataKey;
 
 static void
 DestroyBuffer(void* aBuffer)
 {
   delete[] static_cast<PRUint8*>(aBuffer);
new file mode 100644
--- /dev/null
+++ b/gfx/ycbcr/LICENSE
@@ -0,0 +1,27 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//    * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//    * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//    * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
new file mode 100644
--- /dev/null
+++ b/gfx/ycbcr/Makefile.in
@@ -0,0 +1,39 @@
+DEPTH		= ../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE       = ycbcr
+LIBRARY_NAME = ycbcr
+LIBXUL_LIBRARY = 1
+EXPORT_LIBRARY = 1
+
+EXPORTS      = chromium_types.h \
+               yuv_convert.h \
+               yuv_row.h \
+               $(NULL)
+
+CPPSRCS = yuv_convert.cpp \
+          yuv_row_c.cpp \
+          $(NULL)
+
+ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
+CPPSRCS += yuv_row_win.cpp \
+           $(NULL)
+endif
+
+ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
+CPPSRCS += yuv_row_linux.cpp \
+           $(NULL)
+endif
+
+ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
+CPPSRCS += yuv_row_mac.cpp \
+           $(NULL)
+endif
+
+FORCE_STATIC_LIB = 1
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/gfx/ycbcr/README
@@ -0,0 +1,17 @@
+This color conversion code is from the Chromium open source project available here:
+
+http://code.google.com/chromium/
+
+The code comes from svn revision 40876.
+
+The code was copied from a Chromium svn checkout using the 'update.sh' script which then applies patches for our build and to add dynamic CPU detection.
+
+convert.patch: Change Chromium code to build using Mozilla build system.
+               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.
new file mode 100644
--- /dev/null
+++ b/gfx/ycbcr/chromium_types.h
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Chris Double <chris.double@double.co.nz>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#ifndef GFX_CHROMIUMTYPES_H
+#define GFX_CHROMIUMTYPES_H
+
+#include "prtypes.h"
+
+typedef PRUint8 uint8;
+typedef PRInt8 int8;
+typedef PRInt16 int16;
+
+// From Chromium build_config.h:
+// Processor architecture detection.  For more info on what's defined, see:
+//   http://msdn.microsoft.com/en-us/library/b0084kay.aspx
+//   http://www.agner.org/optimize/calling_conventions.pdf
+//   or with gcc, run: "echo | gcc -E -dM -"
+#if defined(_M_X64) || defined(__x86_64__)
+#define ARCH_CPU_X86_FAMILY 1
+#define ARCH_CPU_X86_64 1
+#define ARCH_CPU_64_BITS 1
+#elif defined(_M_IX86) || defined(__i386__)
+#define ARCH_CPU_X86_FAMILY 1
+#define ARCH_CPU_X86 1
+#define ARCH_CPU_32_BITS 1
+#elif defined(__ARMEL__)
+#define ARCH_CPU_ARM_FAMILY 1
+#define ARCH_CPU_ARMEL 1
+#define ARCH_CPU_32_BITS 1
+#elif defined(__ppc__)
+#define ARCH_CPU_PPC_FAMILY 1
+#define ARCH_CPU_PPC 1
+#define ARCH_CPU_32_BITS 1
+#else
+#error Please add support for your architecture in chromium_types.h
+#endif
+
+#endif // GFX_CHROMIUMTYPES_H
new file mode 100644
--- /dev/null
+++ b/gfx/ycbcr/convert.patch
@@ -0,0 +1,1239 @@
+diff --git b/gfx/ycbcr/yuv_convert.cpp a/gfx/ycbcr/yuv_convert.cpp
+index c73dfe4..c291d5c 100644
+--- b/gfx/ycbcr/yuv_convert.cpp
++++ a/gfx/ycbcr/yuv_convert.cpp
+@@ -10,67 +10,80 @@
+ // 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
+ //
+ // 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"
++#include "yuv_convert.h"
+ 
+ // Header for low level row functions.
+-#include "media/base/yuv_row.h"
++#include "yuv_row.h"
++#include "mozilla/SSE.h"
+ 
+-namespace media {
++namespace mozilla {
++
++namespace gfx {
+ 
+ // 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) {
++void ConvertYCbCrToRGB32(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) {
+   unsigned int y_shift = yuv_type;
++  bool has_mmx = supports_mmx();
+   for (int y = 0; y < height; ++y) {
+     uint8* rgb_row = rgb_buf + y * rgb_pitch;
+     const uint8* y_ptr = y_buf + y * y_pitch;
+     const uint8* u_ptr = u_buf + (y >> y_shift) * uv_pitch;
+     const uint8* v_ptr = v_buf + (y >> y_shift) * uv_pitch;
+ 
+-    FastConvertYUVToRGB32Row(y_ptr,
+-                             u_ptr,
+-                             v_ptr,
+-                             rgb_row,
+-                             width);
++    if (has_mmx)
++      FastConvertYUVToRGB32Row(y_ptr,
++                               u_ptr,
++                               v_ptr,
++                               rgb_row,
++                               width);
++    else
++      FastConvertYUVToRGB32Row_C(y_ptr,
++                                 u_ptr,
++                                 v_ptr,
++                                 rgb_row,
++                                 width);
+   }
+ 
+   // MMX used for FastConvertYUVToRGB32Row requires emms instruction.
+-  EMMS();
++  if (has_mmx)
++    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) {
++void ScaleYCbCrToRGB32(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) {
+   unsigned int y_shift = yuv_type;
++  bool has_mmx = supports_mmx();
+   // Diagram showing origin and direction of source sampling.
+   // ->0   4<-
+   // 7       3
+   //
+   // 6       5
+   // ->1   2<-
+   // Rotations that start at right side of image.
+   if ((view_rotate == ROTATE_180) ||
+@@ -126,42 +139,57 @@ void ScaleYUVToRGB32(const uint8* y_buf,
+ 
+   for (int y = 0; y < scaled_height; ++y) {
+     uint8* dest_pixel = rgb_buf + y * rgb_pitch;
+     int scaled_y = (y * height / scaled_height);
+     const uint8* y_ptr = y_buf + scaled_y * y_pitch;
+     const uint8* u_ptr = u_buf + (scaled_y >> y_shift) * uv_pitch;
+     const uint8* v_ptr = v_buf + (scaled_y >> y_shift) * uv_pitch;
+ 
+-#if USE_MMX && defined(_MSC_VER)
++#if defined(_MSC_VER)
+     if (scaled_width == (width * 2)) {
+       DoubleYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
+                           dest_pixel, scaled_width);
+     } else if ((scaled_dx & 15) == 0) {  // Scaling by integer scale factor.
+       if (scaled_dx_uv == scaled_dx) {   // Not rotated.
+         if (scaled_dx == 16) {           // Not scaled
+-          FastConvertYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
+-                                   dest_pixel, scaled_width);
++          if (has_mmx)
++            FastConvertYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
++                                     dest_pixel, scaled_width);
++          else
++            FastConvertYUVToRGB32Row_C(y_ptr, u_ptr, v_ptr,
++                                      dest_pixel, scaled_width);
+         } else {  // Simple scale down. ie half
+           ConvertYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
+                                dest_pixel, scaled_width, scaled_dx >> 4);
+         }
+       } else {
+         RotateConvertYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
+                                    dest_pixel, scaled_width,
+                                    scaled_dx >> 4, scaled_dx_uv >> 4);
+       }
+ #else
+     if (scaled_dx == 16) {           // Not scaled
+-      FastConvertYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
+-                               dest_pixel, scaled_width);
++      if (has_mmx) 
++        FastConvertYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
++                                 dest_pixel, scaled_width);
++      else
++        FastConvertYUVToRGB32Row_C(y_ptr, u_ptr, v_ptr,
++                                   dest_pixel, scaled_width);
+ #endif
+     } else {
+-      ScaleYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
+-                         dest_pixel, scaled_width, scaled_dx);
+-    }
++      if (has_mmx) 
++        ScaleYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
++                           dest_pixel, scaled_width, scaled_dx);
++      else
++        ScaleYUVToRGB32Row_C(y_ptr, u_ptr, v_ptr,
++                             dest_pixel, scaled_width, scaled_dx);
++
++    }  
+   }
+ 
+   // MMX used for FastConvertYUVToRGB32Row requires emms instruction.
+-  EMMS();
++  if (has_mmx)
++    EMMS();
+ }
+ 
+-}  // namespace media
++}  // namespace gfx
++}  // namespace mozilla
+diff --git b/gfx/ycbcr/yuv_convert.h a/gfx/ycbcr/yuv_convert.h
+index a757070..9d148a6 100644
+--- b/gfx/ycbcr/yuv_convert.h
++++ a/gfx/ycbcr/yuv_convert.h
+@@ -1,63 +1,66 @@
+ // Copyright (c) 2009 The Chromium Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style license that can be
+ // found in the LICENSE file.
+ 
+ #ifndef MEDIA_BASE_YUV_CONVERT_H_
+ #define MEDIA_BASE_YUV_CONVERT_H_
+ 
+-#include "base/basictypes.h"
++#include "chromium_types.h"
+ 
+-namespace media {
++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 = 1            // YV12 is half width and half height chroma channels.
+ };
+ 
+ // Mirror means flip the image horizontally, as in looking in a mirror.
+ // Rotate happens after mirroring.
+ enum Rotate {
+   ROTATE_0,           // Rotation off.
+   ROTATE_90,          // Rotate clockwise.
+   ROTATE_180,         // Rotate upside down.
+   ROTATE_270,         // Rotate counter clockwise.
+   MIRROR_ROTATE_0,    // Mirror horizontally.
+   MIRROR_ROTATE_90,   // Mirror then Rotate clockwise.
+   MIRROR_ROTATE_180,  // Mirror vertically.
+-  MIRROR_ROTATE_270,  // Transpose.
++  MIRROR_ROTATE_270   // Transpose.
+ };
+ 
+ // Convert a frame of YUV to 32 bit ARGB.
+ // Pass in YV16/YV12 depending on source format
+-void ConvertYUVToRGB32(const uint8* yplane,
++void ConvertYCbCrToRGB32(const uint8* yplane,
++                         const uint8* uplane,
++                         const uint8* vplane,
++                         uint8* rgbframe,
++                         int frame_width,
++                         int frame_height,
++                         int ystride,
++                         int uvstride,
++                         int rgbstride,
++                         YUVType yuv_type);
++
++// Scale a frame of YUV to 32 bit ARGB.
++// Supports rotation and mirroring.
++void ScaleYCbCrToRGB32(const uint8* yplane,
+                        const uint8* uplane,
+                        const uint8* vplane,
+                        uint8* rgbframe,
+                        int frame_width,
+                        int frame_height,
++                       int scaled_width,
++                       int scaled_height,
+                        int ystride,
+                        int uvstride,
+                        int rgbstride,
+-                       YUVType yuv_type);
++                       YUVType yuv_type,
++                       Rotate view_rotate);
+ 
+-// Scale a frame of YUV to 32 bit ARGB.
+-// Supports rotation and mirroring.
+-void ScaleYUVToRGB32(const uint8* yplane,
+-                     const uint8* uplane,
+-                     const uint8* vplane,
+-                     uint8* rgbframe,
+-                     int frame_width,
+-                     int frame_height,
+-                     int scaled_width,
+-                     int scaled_height,
+-                     int ystride,
+-                     int uvstride,
+-                     int rgbstride,
+-                     YUVType yuv_type,
+-                     Rotate view_rotate);
+-
+-}  // namespace media
++}  // namespace gfx
++}  // namespace mozilla
+ 
+ #endif  // MEDIA_BASE_YUV_CONVERT_H_
+diff --git b/gfx/ycbcr/yuv_row.h a/gfx/ycbcr/yuv_row.h
+index ac5c6fd..98efca6 100644
+--- b/gfx/ycbcr/yuv_row.h
++++ a/gfx/ycbcr/yuv_row.h
+@@ -5,27 +5,34 @@
+ // yuv_row internal functions to handle YUV conversion and scaling to RGB.
+ // These functions are used from both yuv_convert.cc and yuv_scale.cc.
+ 
+ // TODO(fbarchard): Write function that can handle rotation and scaling.
+ 
+ #ifndef MEDIA_BASE_YUV_ROW_H_
+ #define MEDIA_BASE_YUV_ROW_H_
+ 
+-#include "base/basictypes.h"
++#include "chromium_types.h"
+ 
+ extern "C" {
+ // Can only do 1x.
+ // This is the second fastest of the scalers.
+ void FastConvertYUVToRGB32Row(const uint8* y_buf,
+                               const uint8* u_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);
++
++
+ // Can do 1x, half size or any scale down by an integer amount.
+ // Step can be negative (mirroring, rotate 180).
+ // This is the third fastest of the scalers.
+ void ConvertYUVToRGB32Row(const uint8* y_buf,
+                           const uint8* u_buf,
+                           const uint8* v_buf,
+                           uint8* rgb_buf,
+                           int width,
+@@ -55,29 +62,28 @@ void DoubleYUVToRGB32Row(const uint8* y_buf,
+ // Chroma is under sampled every 2 pixels for performance.
+ // This is the slowest of the scalers.
+ void ScaleYUVToRGB32Row(const uint8* y_buf,
+                         const uint8* u_buf,
+                         const uint8* v_buf,
+                         uint8* rgb_buf,
+                         int width,
+                         int scaled_dx);
+-}  // extern "C"
+ 
+-#if !defined(USE_MMX)
+-// Windows, Mac and Linux use MMX
+-#if defined(ARCH_CPU_X86) || (defined(ARCH_CPU_X86_64) && defined(OS_LINUX))
+-#define USE_MMX 1
+-#else
+-#define USE_MMX 0
+-#endif
+-#endif
++void ScaleYUVToRGB32Row_C(const uint8* y_buf,
++                          const uint8* u_buf,
++                          const uint8* v_buf,
++                          uint8* rgb_buf,
++                          int width,
++                          int scaled_dx);
++
++}  // extern "C"
+ 
+ // x64 uses MMX2 (SSE) so emms is not required.
+-#if USE_MMX && !defined(ARCH_CPU_X86_64)
++#if !defined(ARCH_CPU_X86_64)
+ #if defined(_MSC_VER)
+ #define EMMS() __asm emms
+ #else
+ #define EMMS() asm("emms")
+ #endif
+ #else
+ #define EMMS()
+ #endif
+diff --git b/gfx/ycbcr/yuv_row_c.cpp a/gfx/ycbcr/yuv_row_c.cpp
+index 4a20777..a81416c 100644
+--- b/gfx/ycbcr/yuv_row_c.cpp
++++ a/gfx/ycbcr/yuv_row_c.cpp
+@@ -1,522 +1,20 @@
+ // Copyright (c) 2009 The Chromium Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style license that can be
+ // found in the LICENSE file.
+ 
+-#include "media/base/yuv_row.h"
++#include "yuv_row.h"
+ 
+-#ifdef _DEBUG
+-#include "base/logging.h"
+-#else
+ #define DCHECK(a)
+-#endif
+ 
+ // TODO(fbarchard): Move this to yuv_row_posix.cc to share with Mac.
+ // TODO(fbarchard): Do 64 bit version.
+ 
+ extern "C" {
+-#if USE_MMX
+-
+-#define RGBY(i) { \
+-  static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
+-  static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
+-  static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
+-  0 \
+-}
+-
+-#define RGBU(i) { \
+-  static_cast<int16>(2.018 * 64 * (i - 128) + 0.5), \
+-  static_cast<int16>(-0.391 * 64 * (i - 128) + 0.5), \
+-  0, \
+-  static_cast<int16>(256 * 64 - 1) \
+-}
+-
+-#define RGBV(i) { \
+-  0, \
+-  static_cast<int16>(-0.813 * 64 * (i - 128) + 0.5), \
+-  static_cast<int16>(1.596 * 64 * (i - 128) + 0.5), \
+-  0 \
+-}
+-
+-#define MMX_ALIGNED(var) var __attribute__((aligned(16)))
+-
+-
+-MMX_ALIGNED(int16 kCoefficientsRgbY[768][4]) = {
+-  RGBY(0x00), RGBY(0x01), RGBY(0x02), RGBY(0x03),
+-  RGBY(0x04), RGBY(0x05), RGBY(0x06), RGBY(0x07),
+-  RGBY(0x08), RGBY(0x09), RGBY(0x0A), RGBY(0x0B),
+-  RGBY(0x0C), RGBY(0x0D), RGBY(0x0E), RGBY(0x0F),
+-  RGBY(0x10), RGBY(0x11), RGBY(0x12), RGBY(0x13),
+-  RGBY(0x14), RGBY(0x15), RGBY(0x16), RGBY(0x17),
+-  RGBY(0x18), RGBY(0x19), RGBY(0x1A), RGBY(0x1B),
+-  RGBY(0x1C), RGBY(0x1D), RGBY(0x1E), RGBY(0x1F),
+-  RGBY(0x20), RGBY(0x21), RGBY(0x22), RGBY(0x23),
+-  RGBY(0x24), RGBY(0x25), RGBY(0x26), RGBY(0x27),
+-  RGBY(0x28), RGBY(0x29), RGBY(0x2A), RGBY(0x2B),
+-  RGBY(0x2C), RGBY(0x2D), RGBY(0x2E), RGBY(0x2F),
+-  RGBY(0x30), RGBY(0x31), RGBY(0x32), RGBY(0x33),
+-  RGBY(0x34), RGBY(0x35), RGBY(0x36), RGBY(0x37),
+-  RGBY(0x38), RGBY(0x39), RGBY(0x3A), RGBY(0x3B),
+-  RGBY(0x3C), RGBY(0x3D), RGBY(0x3E), RGBY(0x3F),
+-  RGBY(0x40), RGBY(0x41), RGBY(0x42), RGBY(0x43),
+-  RGBY(0x44), RGBY(0x45), RGBY(0x46), RGBY(0x47),
+-  RGBY(0x48), RGBY(0x49), RGBY(0x4A), RGBY(0x4B),
+-  RGBY(0x4C), RGBY(0x4D), RGBY(0x4E), RGBY(0x4F),
+-  RGBY(0x50), RGBY(0x51), RGBY(0x52), RGBY(0x53),
+-  RGBY(0x54), RGBY(0x55), RGBY(0x56), RGBY(0x57),
+-  RGBY(0x58), RGBY(0x59), RGBY(0x5A), RGBY(0x5B),
+-  RGBY(0x5C), RGBY(0x5D), RGBY(0x5E), RGBY(0x5F),
+-  RGBY(0x60), RGBY(0x61), RGBY(0x62), RGBY(0x63),
+-  RGBY(0x64), RGBY(0x65), RGBY(0x66), RGBY(0x67),
+-  RGBY(0x68), RGBY(0x69), RGBY(0x6A), RGBY(0x6B),
+-  RGBY(0x6C), RGBY(0x6D), RGBY(0x6E), RGBY(0x6F),
+-  RGBY(0x70), RGBY(0x71), RGBY(0x72), RGBY(0x73),
+-  RGBY(0x74), RGBY(0x75), RGBY(0x76), RGBY(0x77),
+-  RGBY(0x78), RGBY(0x79), RGBY(0x7A), RGBY(0x7B),
+-  RGBY(0x7C), RGBY(0x7D), RGBY(0x7E), RGBY(0x7F),
+-  RGBY(0x80), RGBY(0x81), RGBY(0x82), RGBY(0x83),
+-  RGBY(0x84), RGBY(0x85), RGBY(0x86), RGBY(0x87),
+-  RGBY(0x88), RGBY(0x89), RGBY(0x8A), RGBY(0x8B),
+-  RGBY(0x8C), RGBY(0x8D), RGBY(0x8E), RGBY(0x8F),
+-  RGBY(0x90), RGBY(0x91), RGBY(0x92), RGBY(0x93),
+-  RGBY(0x94), RGBY(0x95), RGBY(0x96), RGBY(0x97),
+-  RGBY(0x98), RGBY(0x99), RGBY(0x9A), RGBY(0x9B),
+-  RGBY(0x9C), RGBY(0x9D), RGBY(0x9E), RGBY(0x9F),
+-  RGBY(0xA0), RGBY(0xA1), RGBY(0xA2), RGBY(0xA3),
+-  RGBY(0xA4), RGBY(0xA5), RGBY(0xA6), RGBY(0xA7),
+-  RGBY(0xA8), RGBY(0xA9), RGBY(0xAA), RGBY(0xAB),
+-  RGBY(0xAC), RGBY(0xAD), RGBY(0xAE), RGBY(0xAF),
+-  RGBY(0xB0), RGBY(0xB1), RGBY(0xB2), RGBY(0xB3),
+-  RGBY(0xB4), RGBY(0xB5), RGBY(0xB6), RGBY(0xB7),
+-  RGBY(0xB8), RGBY(0xB9), RGBY(0xBA), RGBY(0xBB),
+-  RGBY(0xBC), RGBY(0xBD), RGBY(0xBE), RGBY(0xBF),
+-  RGBY(0xC0), RGBY(0xC1), RGBY(0xC2), RGBY(0xC3),
+-  RGBY(0xC4), RGBY(0xC5), RGBY(0xC6), RGBY(0xC7),
+-  RGBY(0xC8), RGBY(0xC9), RGBY(0xCA), RGBY(0xCB),
+-  RGBY(0xCC), RGBY(0xCD), RGBY(0xCE), RGBY(0xCF),
+-  RGBY(0xD0), RGBY(0xD1), RGBY(0xD2), RGBY(0xD3),
+-  RGBY(0xD4), RGBY(0xD5), RGBY(0xD6), RGBY(0xD7),
+-  RGBY(0xD8), RGBY(0xD9), RGBY(0xDA), RGBY(0xDB),
+-  RGBY(0xDC), RGBY(0xDD), RGBY(0xDE), RGBY(0xDF),
+-  RGBY(0xE0), RGBY(0xE1), RGBY(0xE2), RGBY(0xE3),
+-  RGBY(0xE4), RGBY(0xE5), RGBY(0xE6), RGBY(0xE7),
+-  RGBY(0xE8), RGBY(0xE9), RGBY(0xEA), RGBY(0xEB),
+-  RGBY(0xEC), RGBY(0xED), RGBY(0xEE), RGBY(0xEF),
+-  RGBY(0xF0), RGBY(0xF1), RGBY(0xF2), RGBY(0xF3),
+-  RGBY(0xF4), RGBY(0xF5), RGBY(0xF6), RGBY(0xF7),
+-  RGBY(0xF8), RGBY(0xF9), RGBY(0xFA), RGBY(0xFB),
+-  RGBY(0xFC), RGBY(0xFD), RGBY(0xFE), RGBY(0xFF),
+-
+-  // Chroma U table.
+-  RGBU(0x00), RGBU(0x01), RGBU(0x02), RGBU(0x03),
+-  RGBU(0x04), RGBU(0x05), RGBU(0x06), RGBU(0x07),
+-  RGBU(0x08), RGBU(0x09), RGBU(0x0A), RGBU(0x0B),
+-  RGBU(0x0C), RGBU(0x0D), RGBU(0x0E), RGBU(0x0F),
+-  RGBU(0x10), RGBU(0x11), RGBU(0x12), RGBU(0x13),
+-  RGBU(0x14), RGBU(0x15), RGBU(0x16), RGBU(0x17),
+-  RGBU(0x18), RGBU(0x19), RGBU(0x1A), RGBU(0x1B),
+-  RGBU(0x1C), RGBU(0x1D), RGBU(0x1E), RGBU(0x1F),
+-  RGBU(0x20), RGBU(0x21), RGBU(0x22), RGBU(0x23),
+-  RGBU(0x24), RGBU(0x25), RGBU(0x26), RGBU(0x27),
+-  RGBU(0x28), RGBU(0x29), RGBU(0x2A), RGBU(0x2B),
+-  RGBU(0x2C), RGBU(0x2D), RGBU(0x2E), RGBU(0x2F),
+-  RGBU(0x30), RGBU(0x31), RGBU(0x32), RGBU(0x33),
+-  RGBU(0x34), RGBU(0x35), RGBU(0x36), RGBU(0x37),
+-  RGBU(0x38), RGBU(0x39), RGBU(0x3A), RGBU(0x3B),
+-  RGBU(0x3C), RGBU(0x3D), RGBU(0x3E), RGBU(0x3F),
+-  RGBU(0x40), RGBU(0x41), RGBU(0x42), RGBU(0x43),
+-  RGBU(0x44), RGBU(0x45), RGBU(0x46), RGBU(0x47),
+-  RGBU(0x48), RGBU(0x49), RGBU(0x4A), RGBU(0x4B),
+-  RGBU(0x4C), RGBU(0x4D), RGBU(0x4E), RGBU(0x4F),
+-  RGBU(0x50), RGBU(0x51), RGBU(0x52), RGBU(0x53),
+-  RGBU(0x54), RGBU(0x55), RGBU(0x56), RGBU(0x57),
+-  RGBU(0x58), RGBU(0x59), RGBU(0x5A), RGBU(0x5B),
+-  RGBU(0x5C), RGBU(0x5D), RGBU(0x5E), RGBU(0x5F),
+-  RGBU(0x60), RGBU(0x61), RGBU(0x62), RGBU(0x63),
+-  RGBU(0x64), RGBU(0x65), RGBU(0x66), RGBU(0x67),
+-  RGBU(0x68), RGBU(0x69), RGBU(0x6A), RGBU(0x6B),
+-  RGBU(0x6C), RGBU(0x6D), RGBU(0x6E), RGBU(0x6F),
+-  RGBU(0x70), RGBU(0x71), RGBU(0x72), RGBU(0x73),
+-  RGBU(0x74), RGBU(0x75), RGBU(0x76), RGBU(0x77),
+-  RGBU(0x78), RGBU(0x79), RGBU(0x7A), RGBU(0x7B),
+-  RGBU(0x7C), RGBU(0x7D), RGBU(0x7E), RGBU(0x7F),
+-  RGBU(0x80), RGBU(0x81), RGBU(0x82), RGBU(0x83),
+-  RGBU(0x84), RGBU(0x85), RGBU(0x86), RGBU(0x87),
+-  RGBU(0x88), RGBU(0x89), RGBU(0x8A), RGBU(0x8B),
+-  RGBU(0x8C), RGBU(0x8D), RGBU(0x8E), RGBU(0x8F),
+-  RGBU(0x90), RGBU(0x91), RGBU(0x92), RGBU(0x93),
+-  RGBU(0x94), RGBU(0x95), RGBU(0x96), RGBU(0x97),
+-  RGBU(0x98), RGBU(0x99), RGBU(0x9A), RGBU(0x9B),
+-  RGBU(0x9C), RGBU(0x9D), RGBU(0x9E), RGBU(0x9F),
+-  RGBU(0xA0), RGBU(0xA1), RGBU(0xA2), RGBU(0xA3),
+-  RGBU(0xA4), RGBU(0xA5), RGBU(0xA6), RGBU(0xA7),
+-  RGBU(0xA8), RGBU(0xA9), RGBU(0xAA), RGBU(0xAB),
+-  RGBU(0xAC), RGBU(0xAD), RGBU(0xAE), RGBU(0xAF),
+-  RGBU(0xB0), RGBU(0xB1), RGBU(0xB2), RGBU(0xB3),
+-  RGBU(0xB4), RGBU(0xB5), RGBU(0xB6), RGBU(0xB7),
+-  RGBU(0xB8), RGBU(0xB9), RGBU(0xBA), RGBU(0xBB),
+-  RGBU(0xBC), RGBU(0xBD), RGBU(0xBE), RGBU(0xBF),
+-  RGBU(0xC0), RGBU(0xC1), RGBU(0xC2), RGBU(0xC3),
+-  RGBU(0xC4), RGBU(0xC5), RGBU(0xC6), RGBU(0xC7),
+-  RGBU(0xC8), RGBU(0xC9), RGBU(0xCA), RGBU(0xCB),
+-  RGBU(0xCC), RGBU(0xCD), RGBU(0xCE), RGBU(0xCF),
+-  RGBU(0xD0), RGBU(0xD1), RGBU(0xD2), RGBU(0xD3),
+-  RGBU(0xD4), RGBU(0xD5), RGBU(0xD6), RGBU(0xD7),
+-  RGBU(0xD8), RGBU(0xD9), RGBU(0xDA), RGBU(0xDB),
+-  RGBU(0xDC), RGBU(0xDD), RGBU(0xDE), RGBU(0xDF),
+-  RGBU(0xE0), RGBU(0xE1), RGBU(0xE2), RGBU(0xE3),
+-  RGBU(0xE4), RGBU(0xE5), RGBU(0xE6), RGBU(0xE7),
+-  RGBU(0xE8), RGBU(0xE9), RGBU(0xEA), RGBU(0xEB),
+-  RGBU(0xEC), RGBU(0xED), RGBU(0xEE), RGBU(0xEF),
+-  RGBU(0xF0), RGBU(0xF1), RGBU(0xF2), RGBU(0xF3),
+-  RGBU(0xF4), RGBU(0xF5), RGBU(0xF6), RGBU(0xF7),
+-  RGBU(0xF8), RGBU(0xF9), RGBU(0xFA), RGBU(0xFB),
+-  RGBU(0xFC), RGBU(0xFD), RGBU(0xFE), RGBU(0xFF),
+-
+-  // Chroma V table.
+-  RGBV(0x00), RGBV(0x01), RGBV(0x02), RGBV(0x03),
+-  RGBV(0x04), RGBV(0x05), RGBV(0x06), RGBV(0x07),
+-  RGBV(0x08), RGBV(0x09), RGBV(0x0A), RGBV(0x0B),
+-  RGBV(0x0C), RGBV(0x0D), RGBV(0x0E), RGBV(0x0F),
+-  RGBV(0x10), RGBV(0x11), RGBV(0x12), RGBV(0x13),
+-  RGBV(0x14), RGBV(0x15), RGBV(0x16), RGBV(0x17),
+-  RGBV(0x18), RGBV(0x19), RGBV(0x1A), RGBV(0x1B),
+-  RGBV(0x1C), RGBV(0x1D), RGBV(0x1E), RGBV(0x1F),
+-  RGBV(0x20), RGBV(0x21), RGBV(0x22), RGBV(0x23),
+-  RGBV(0x24), RGBV(0x25), RGBV(0x26), RGBV(0x27),
+-  RGBV(0x28), RGBV(0x29), RGBV(0x2A), RGBV(0x2B),
+-  RGBV(0x2C), RGBV(0x2D), RGBV(0x2E), RGBV(0x2F),
+-  RGBV(0x30), RGBV(0x31), RGBV(0x32), RGBV(0x33),
+-  RGBV(0x34), RGBV(0x35), RGBV(0x36), RGBV(0x37),
+-  RGBV(0x38), RGBV(0x39), RGBV(0x3A), RGBV(0x3B),
+-  RGBV(0x3C), RGBV(0x3D), RGBV(0x3E), RGBV(0x3F),
+-  RGBV(0x40), RGBV(0x41), RGBV(0x42), RGBV(0x43),
+-  RGBV(0x44), RGBV(0x45), RGBV(0x46), RGBV(0x47),
+-  RGBV(0x48), RGBV(0x49), RGBV(0x4A), RGBV(0x4B),
+-  RGBV(0x4C), RGBV(0x4D), RGBV(0x4E), RGBV(0x4F),
+-  RGBV(0x50), RGBV(0x51), RGBV(0x52), RGBV(0x53),
+-  RGBV(0x54), RGBV(0x55), RGBV(0x56), RGBV(0x57),
+-  RGBV(0x58), RGBV(0x59), RGBV(0x5A), RGBV(0x5B),
+-  RGBV(0x5C), RGBV(0x5D), RGBV(0x5E), RGBV(0x5F),
+-  RGBV(0x60), RGBV(0x61), RGBV(0x62), RGBV(0x63),
+-  RGBV(0x64), RGBV(0x65), RGBV(0x66), RGBV(0x67),
+-  RGBV(0x68), RGBV(0x69), RGBV(0x6A), RGBV(0x6B),
+-  RGBV(0x6C), RGBV(0x6D), RGBV(0x6E), RGBV(0x6F),
+-  RGBV(0x70), RGBV(0x71), RGBV(0x72), RGBV(0x73),
+-  RGBV(0x74), RGBV(0x75), RGBV(0x76), RGBV(0x77),
+-  RGBV(0x78), RGBV(0x79), RGBV(0x7A), RGBV(0x7B),
+-  RGBV(0x7C), RGBV(0x7D), RGBV(0x7E), RGBV(0x7F),
+-  RGBV(0x80), RGBV(0x81), RGBV(0x82), RGBV(0x83),
+-  RGBV(0x84), RGBV(0x85), RGBV(0x86), RGBV(0x87),
+-  RGBV(0x88), RGBV(0x89), RGBV(0x8A), RGBV(0x8B),
+-  RGBV(0x8C), RGBV(0x8D), RGBV(0x8E), RGBV(0x8F),
+-  RGBV(0x90), RGBV(0x91), RGBV(0x92), RGBV(0x93),
+-  RGBV(0x94), RGBV(0x95), RGBV(0x96), RGBV(0x97),
+-  RGBV(0x98), RGBV(0x99), RGBV(0x9A), RGBV(0x9B),
+-  RGBV(0x9C), RGBV(0x9D), RGBV(0x9E), RGBV(0x9F),
+-  RGBV(0xA0), RGBV(0xA1), RGBV(0xA2), RGBV(0xA3),
+-  RGBV(0xA4), RGBV(0xA5), RGBV(0xA6), RGBV(0xA7),
+-  RGBV(0xA8), RGBV(0xA9), RGBV(0xAA), RGBV(0xAB),
+-  RGBV(0xAC), RGBV(0xAD), RGBV(0xAE), RGBV(0xAF),
+-  RGBV(0xB0), RGBV(0xB1), RGBV(0xB2), RGBV(0xB3),
+-  RGBV(0xB4), RGBV(0xB5), RGBV(0xB6), RGBV(0xB7),
+-  RGBV(0xB8), RGBV(0xB9), RGBV(0xBA), RGBV(0xBB),
+-  RGBV(0xBC), RGBV(0xBD), RGBV(0xBE), RGBV(0xBF),
+-  RGBV(0xC0), RGBV(0xC1), RGBV(0xC2), RGBV(0xC3),
+-  RGBV(0xC4), RGBV(0xC5), RGBV(0xC6), RGBV(0xC7),
+-  RGBV(0xC8), RGBV(0xC9), RGBV(0xCA), RGBV(0xCB),
+-  RGBV(0xCC), RGBV(0xCD), RGBV(0xCE), RGBV(0xCF),
+-  RGBV(0xD0), RGBV(0xD1), RGBV(0xD2), RGBV(0xD3),
+-  RGBV(0xD4), RGBV(0xD5), RGBV(0xD6), RGBV(0xD7),
+-  RGBV(0xD8), RGBV(0xD9), RGBV(0xDA), RGBV(0xDB),
+-  RGBV(0xDC), RGBV(0xDD), RGBV(0xDE), RGBV(0xDF),
+-  RGBV(0xE0), RGBV(0xE1), RGBV(0xE2), RGBV(0xE3),
+-  RGBV(0xE4), RGBV(0xE5), RGBV(0xE6), RGBV(0xE7),
+-  RGBV(0xE8), RGBV(0xE9), RGBV(0xEA), RGBV(0xEB),
+-  RGBV(0xEC), RGBV(0xED), RGBV(0xEE), RGBV(0xEF),
+-  RGBV(0xF0), RGBV(0xF1), RGBV(0xF2), RGBV(0xF3),
+-  RGBV(0xF4), RGBV(0xF5), RGBV(0xF6), RGBV(0xF7),
+-  RGBV(0xF8), RGBV(0xF9), RGBV(0xFA), RGBV(0xFB),
+-  RGBV(0xFC), RGBV(0xFD), RGBV(0xFE), RGBV(0xFF),
+-};
+-
+-#undef RGBY
+-#undef RGBU
+-#undef RGBV
+-#undef MMX_ALIGNED
+-
+-#if defined(ARCH_CPU_X86_64)
+-
+-// AMD64 ABI uses register paremters.
+-void FastConvertYUVToRGB32Row(const uint8* y_buf,  // rdi
+-                              const uint8* u_buf,  // rsi
+-                              const uint8* v_buf,  // rdx
+-                              uint8* rgb_buf,      // rcx
+-                              int width) {         // r8
+-  asm(
+-  "jmp    convertend\n"
+-"convertloop:"
+-  "movzb  (%1),%%r10\n"
+-  "add    $0x1,%1\n"
+-  "movzb  (%2),%%r11\n"
+-  "add    $0x1,%2\n"
+-  "movq   2048(%5,%%r10,8),%%xmm0\n"
+-  "movzb  (%0),%%r10\n"
+-  "movq   4096(%5,%%r11,8),%%xmm1\n"
+-  "movzb  0x1(%0),%%r11\n"
+-  "paddsw %%xmm1,%%xmm0\n"
+-  "movq   (%5,%%r10,8),%%xmm2\n"
+-  "add    $0x2,%0\n"
+-  "movq   (%5,%%r11,8),%%xmm3\n"
+-  "paddsw %%xmm0,%%xmm2\n"
+-  "paddsw %%xmm0,%%xmm3\n"
+-  "shufps $0x44,%%xmm3,%%xmm2\n"
+-  "psraw  $0x6,%%xmm2\n"
+-  "packuswb %%xmm2,%%xmm2\n"
+-  "movq   %%xmm2,0x0(%3)\n"
+-  "add    $0x8,%3\n"
+-"convertend:"
+-  "sub    $0x2,%4\n"
+-  "jns    convertloop\n"
+-
+-"convertnext:"
+-  "add    $0x1,%4\n"
+-  "js     convertdone\n"
+-
+-  "movzb  (%1),%%r10\n"
+-  "movq   2048(%5,%%r10,8),%%xmm0\n"
+-  "movzb  (%2),%%r10\n"
+-  "movq   4096(%5,%%r10,8),%%xmm1\n"
+-  "paddsw %%xmm1,%%xmm0\n"
+-  "movzb  (%0),%%r10\n"
+-  "movq   (%5,%%r10,8),%%xmm1\n"
+-  "paddsw %%xmm0,%%xmm1\n"
+-  "psraw  $0x6,%%xmm1\n"
+-  "packuswb %%xmm1,%%xmm1\n"
+-  "movd   %%xmm1,0x0(%3)\n"
+-"convertdone:"
+-  :
+-  : "r"(y_buf),  // %0
+-    "r"(u_buf),  // %1
+-    "r"(v_buf),  // %2
+-    "r"(rgb_buf),  // %3
+-    "r"(width),  // %4
+-    "r" (kCoefficientsRgbY)  // %5
+-  : "memory", "r10", "r11", "xmm0", "xmm1", "xmm2", "xmm3"
+-);
+-}
+-
+-void ScaleYUVToRGB32Row(const uint8* y_buf,  // rdi
+-                        const uint8* u_buf,  // rsi
+-                        const uint8* v_buf,  // rdx
+-                        uint8* rgb_buf,      // rcx
+-                        int width,           // r8
+-                        int scaled_dx) {     // r9
+-  asm(
+-  "xor    %%r11,%%r11\n"
+-  "sub    $0x2,%4\n"
+-  "js     scalenext\n"
+-
+-"scaleloop:"
+-  "mov    %%r11,%%r10\n"
+-  "sar    $0x5,%%r10\n"
+-  "movzb  (%1,%%r10,1),%%rax\n"
+-  "movq   2048(%5,%%rax,8),%%xmm0\n"
+-  "movzb  (%2,%%r10,1),%%rax\n"
+-  "movq   4096(%5,%%rax,8),%%xmm1\n"
+-  "lea    (%%r11,%6),%%r10\n"
+-  "sar    $0x4,%%r11\n"
+-  "movzb  (%0,%%r11,1),%%rax\n"
+-  "paddsw %%xmm1,%%xmm0\n"
+-  "movq   (%5,%%rax,8),%%xmm1\n"
+-  "lea    (%%r10,%6),%%r11\n"
+-  "sar    $0x4,%%r10\n"
+-  "movzb  (%0,%%r10,1),%%rax\n"
+-  "movq   (%5,%%rax,8),%%xmm2\n"
+-  "paddsw %%xmm0,%%xmm1\n"
+-  "paddsw %%xmm0,%%xmm2\n"
+-  "shufps $0x44,%%xmm2,%%xmm1\n"
+-  "psraw  $0x6,%%xmm1\n"
+-  "packuswb %%xmm1,%%xmm1\n"
+-  "movq   %%xmm1,0x0(%3)\n"
+-  "add    $0x8,%3\n"
+-  "sub    $0x2,%4\n"
+-  "jns    scaleloop\n"
+-
+-"scalenext:"
+-  "add    $0x1,%4\n"
+-  "js     scaledone\n"
+-
+-  "mov    %%r11,%%r10\n"
+-  "sar    $0x5,%%r10\n"
+-  "movzb  (%1,%%r10,1),%%rax\n"
+-  "movq   2048(%5,%%rax,8),%%xmm0\n"
+-  "movzb  (%2,%%r10,1),%%rax\n"
+-  "movq   4096(%5,%%rax,8),%%xmm1\n"
+-  "paddsw %%xmm1,%%xmm0\n"
+-  "sar    $0x4,%%r11\n"
+-  "movzb  (%0,%%r11,1),%%rax\n"
+-  "movq   (%5,%%rax,8),%%xmm1\n"
+-  "paddsw %%xmm0,%%xmm1\n"
+-  "psraw  $0x6,%%xmm1\n"
+-  "packuswb %%xmm1,%%xmm1\n"
+-  "movd   %%xmm1,0x0(%3)\n"
+-
+-"scaledone:"
+-  :
+-  : "r"(y_buf),  // %0
+-    "r"(u_buf),  // %1
+-    "r"(v_buf),  // %2
+-    "r"(rgb_buf),  // %3
+-    "r"(width),  // %4
+-    "r" (kCoefficientsRgbY),  // %5
+-    "r"(static_cast<long>(scaled_dx))  // %6
+-  : "memory", "r10", "r11", "rax", "xmm0", "xmm1", "xmm2"
+-);
+-}
+-
+-#else
+-
+-void FastConvertYUVToRGB32Row(const uint8* y_buf,
+-                              const uint8* u_buf,
+-                              const uint8* v_buf,
+-                              uint8* rgb_buf,
+-                              int width);
+-
+-  asm(
+-  ".global FastConvertYUVToRGB32Row\n"
+-"FastConvertYUVToRGB32Row:\n"
+-  "pusha\n"
+-  "mov    0x24(%esp),%edx\n"
+-  "mov    0x28(%esp),%edi\n"
+-  "mov    0x2c(%esp),%esi\n"
+-  "mov    0x30(%esp),%ebp\n"
+-  "mov    0x34(%esp),%ecx\n"
+-  "jmp    convertend\n"
+-
+-"convertloop:"
+-  "movzbl (%edi),%eax\n"
+-  "add    $0x1,%edi\n"
+-  "movzbl (%esi),%ebx\n"
+-  "add    $0x1,%esi\n"
+-  "movq   kCoefficientsRgbY+2048(,%eax,8),%mm0\n"
+-  "movzbl (%edx),%eax\n"
+-  "paddsw kCoefficientsRgbY+4096(,%ebx,8),%mm0\n"
+-  "movzbl 0x1(%edx),%ebx\n"
+-  "movq   kCoefficientsRgbY(,%eax,8),%mm1\n"
+-  "add    $0x2,%edx\n"
+-  "movq   kCoefficientsRgbY(,%ebx,8),%mm2\n"
+-  "paddsw %mm0,%mm1\n"
+-  "paddsw %mm0,%mm2\n"
+-  "psraw  $0x6,%mm1\n"
+-  "psraw  $0x6,%mm2\n"
+-  "packuswb %mm2,%mm1\n"
+-  "movntq %mm1,0x0(%ebp)\n"
+-  "add    $0x8,%ebp\n"
+-"convertend:"
+-  "sub    $0x2,%ecx\n"
+-  "jns    convertloop\n"
+-
+-  "and    $0x1,%ecx\n"
+-  "je     convertdone\n"
+-
+-  "movzbl (%edi),%eax\n"
+-  "movq   kCoefficientsRgbY+2048(,%eax,8),%mm0\n"
+-  "movzbl (%esi),%eax\n"
+-  "paddsw kCoefficientsRgbY+4096(,%eax,8),%mm0\n"
+-  "movzbl (%edx),%eax\n"
+-  "movq   kCoefficientsRgbY(,%eax,8),%mm1\n"
+-  "paddsw %mm0,%mm1\n"
+-  "psraw  $0x6,%mm1\n"
+-  "packuswb %mm1,%mm1\n"
+-  "movd   %mm1,0x0(%ebp)\n"
+-"convertdone:"
+-  "popa\n"
+-  "ret\n"
+-);
+-
+-
+-void ScaleYUVToRGB32Row(const uint8* y_buf,
+-                        const uint8* u_buf,
+-                        const uint8* v_buf,
+-                        uint8* rgb_buf,
+-                        int width,
+-                        int scaled_dx);
+-
+-  asm(
+-  ".global ScaleYUVToRGB32Row\n"
+-"ScaleYUVToRGB32Row:\n"
+-  "pusha\n"
+-  "mov    0x24(%esp),%edx\n"
+-  "mov    0x28(%esp),%edi\n"
+-  "mov    0x2c(%esp),%esi\n"
+-  "mov    0x30(%esp),%ebp\n"
+-  "mov    0x34(%esp),%ecx\n"
+-  "xor    %ebx,%ebx\n"
+-  "jmp    scaleend\n"
+-
+-"scaleloop:"
+-  "mov    %ebx,%eax\n"
+-  "sar    $0x5,%eax\n"
+-  "movzbl (%edi,%eax,1),%eax\n"
+-  "movq   kCoefficientsRgbY+2048(,%eax,8),%mm0\n"
+-  "mov    %ebx,%eax\n"
+-  "sar    $0x5,%eax\n"
+-  "movzbl (%esi,%eax,1),%eax\n"
+-  "paddsw kCoefficientsRgbY+4096(,%eax,8),%mm0\n"
+-  "mov    %ebx,%eax\n"
+-  "add    0x38(%esp),%ebx\n"
+-  "sar    $0x4,%eax\n"
+-  "movzbl (%edx,%eax,1),%eax\n"
+-  "movq   kCoefficientsRgbY(,%eax,8),%mm1\n"
+-  "mov    %ebx,%eax\n"
+-  "add    0x38(%esp),%ebx\n"
+-  "sar    $0x4,%eax\n"
+-  "movzbl (%edx,%eax,1),%eax\n"
+-  "movq   kCoefficientsRgbY(,%eax,8),%mm2\n"
+-  "paddsw %mm0,%mm1\n"
+-  "paddsw %mm0,%mm2\n"
+-  "psraw  $0x6,%mm1\n"
+-  "psraw  $0x6,%mm2\n"
+-  "packuswb %mm2,%mm1\n"
+-  "movntq %mm1,0x0(%ebp)\n"
+-  "add    $0x8,%ebp\n"
+-"scaleend:"
+-  "sub    $0x2,%ecx\n"
+-  "jns    scaleloop\n"
+-
+-  "and    $0x1,%ecx\n"
+-  "je     scaledone\n"
+-
+-  "mov    %ebx,%eax\n"
+-  "sar    $0x5,%eax\n"
+-  "movzbl (%edi,%eax,1),%eax\n"
+-  "movq   kCoefficientsRgbY+2048(,%eax,8),%mm0\n"
+-  "mov    %ebx,%eax\n"
+-  "sar    $0x5,%eax\n"
+-  "movzbl (%esi,%eax,1),%eax\n"
+-  "paddsw kCoefficientsRgbY+4096(,%eax,8),%mm0\n"
+-  "mov    %ebx,%eax\n"
+-  "sar    $0x4,%eax\n"
+-  "movzbl (%edx,%eax,1),%eax\n"
+-  "movq   kCoefficientsRgbY(,%eax,8),%mm1\n"
+-  "paddsw %mm0,%mm1\n"
+-  "psraw  $0x6,%mm1\n"
+-  "packuswb %mm1,%mm1\n"
+-  "movd   %mm1,0x0(%ebp)\n"
+-
+-"scaledone:"
+-  "popa\n"
+-  "ret\n"
+-);
+-
+-#endif
+-
+-#else  // USE_MMX
+ 
+ // Reference version of YUV converter.
+ static const int kClipTableSize = 256;
+ static const int kClipOverflow = 288;  // Cb max is 535.
+ 
+ static uint8 kRgbClipTable[kClipOverflow +
+                            kClipTableSize +
+                            kClipOverflow] = {
+@@ -651,17 +149,17 @@ static inline void YuvPixel(uint8 y,
+ 
+   int32 C298a = ((static_cast<int32>(y) - 16) * 298 + 128);
+   *reinterpret_cast<uint32*>(rgb_buf) = (clip(C298a + cb)) |
+                                         (clip(C298a + cg) << 8) |
+                                         (clip(C298a + cr) << 16) |
+                                         (0xff000000);
+ }
+ 
+-void FastConvertYUVToRGB32Row(const uint8* y_buf,
++void FastConvertYUVToRGB32Row_C(const uint8* y_buf,
+                               const uint8* u_buf,
+                               const uint8* v_buf,
+                               uint8* rgb_buf,
+                               int width) {
+   for (int x = 0; x < width; x += 2) {
+     uint8 u = u_buf[x >> 1];
+     uint8 v = v_buf[x >> 1];
+     uint8 y0 = y_buf[x];
+@@ -673,27 +171,26 @@ void FastConvertYUVToRGB32Row(const uint8* y_buf,
+     rgb_buf += 8;  // Advance 2 pixels.
+   }
+ }
+ 
+ // 28.4 fixed point is used.  A shift by 4 isolates the integer.
+ // A shift by 5 is used to further subsample the chrominence channels.
+ // & 15 isolates the fixed point fraction.  >> 2 to get the upper 2 bits,
+ // for 1/4 pixel accurate interpolation.
+-void ScaleYUVToRGB32Row(const uint8* y_buf,
++void ScaleYUVToRGB32Row_C(const uint8* y_buf,
+                         const uint8* u_buf,
+                         const uint8* v_buf,
+                         uint8* rgb_buf,
+                         int width,
+                         int scaled_dx) {
+   int scaled_x = 0;
+   for (int x = 0; x < width; ++x) {
+     uint8 u = u_buf[scaled_x >> 5];
+     uint8 v = v_buf[scaled_x >> 5];
+     uint8 y0 = y_buf[scaled_x >> 4];
+     YuvPixel(y0, u, v, rgb_buf);
+     rgb_buf += 4;
+     scaled_x += scaled_dx;
+   }
+ }
+-#endif  // USE_MMX
+ }  // extern "C"
+ 
+diff --git b/gfx/ycbcr/yuv_row_linux.cpp a/gfx/ycbcr/yuv_row_linux.cpp
+index 4a20777..eeb78f6 100644
+--- b/gfx/ycbcr/yuv_row_linux.cpp
++++ a/gfx/ycbcr/yuv_row_linux.cpp
+@@ -1,25 +1,20 @@
+ // Copyright (c) 2009 The Chromium Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style license that can be
+ // found in the LICENSE file.
+ 
+-#include "media/base/yuv_row.h"
++#include "yuv_row.h"
+ 
+-#ifdef _DEBUG
+-#include "base/logging.h"
+-#else
+ #define DCHECK(a)
+-#endif
+ 
+ // TODO(fbarchard): Move this to yuv_row_posix.cc to share with Mac.
+ // TODO(fbarchard): Do 64 bit version.
+ 
+ extern "C" {
+-#if USE_MMX
+ 
+ #define RGBY(i) { \
+   static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
+   static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
+   static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
+   0 \
+ }
+ 
+@@ -234,21 +229,16 @@ MMX_ALIGNED(int16 kCoefficientsRgbY[768][4]) = {
+   RGBV(0xE8), RGBV(0xE9), RGBV(0xEA), RGBV(0xEB),
+   RGBV(0xEC), RGBV(0xED), RGBV(0xEE), RGBV(0xEF),
+   RGBV(0xF0), RGBV(0xF1), RGBV(0xF2), RGBV(0xF3),
+   RGBV(0xF4), RGBV(0xF5), RGBV(0xF6), RGBV(0xF7),
+   RGBV(0xF8), RGBV(0xF9), RGBV(0xFA), RGBV(0xFB),
+   RGBV(0xFC), RGBV(0xFD), RGBV(0xFE), RGBV(0xFF),
+ };
+ 
+-#undef RGBY
+-#undef RGBU
+-#undef RGBV
+-#undef MMX_ALIGNED
+-
+ #if defined(ARCH_CPU_X86_64)
+ 
+ // AMD64 ABI uses register paremters.
+ void FastConvertYUVToRGB32Row(const uint8* y_buf,  // rdi
+                               const uint8* u_buf,  // rsi
+                               const uint8* v_buf,  // rdx
+                               uint8* rgb_buf,      // rcx
+                               int width) {         // r8
+@@ -376,17 +366,16 @@ void ScaleYUVToRGB32Row(const uint8* y_buf,  // rdi
+ 
+ #else
+ 
+ void FastConvertYUVToRGB32Row(const uint8* y_buf,
+                               const uint8* u_buf,
+                               const uint8* v_buf,
+                               uint8* rgb_buf,
+                               int width);
+-
+   asm(
+   ".global FastConvertYUVToRGB32Row\n"
+ "FastConvertYUVToRGB32Row:\n"
+   "pusha\n"
+   "mov    0x24(%esp),%edx\n"
+   "mov    0x28(%esp),%edi\n"
+   "mov    0x2c(%esp),%esi\n"
+   "mov    0x30(%esp),%ebp\n"
+@@ -505,195 +494,10 @@ void ScaleYUVToRGB32Row(const uint8* y_buf,
+   "movd   %mm1,0x0(%ebp)\n"
+ 
+ "scaledone:"
+   "popa\n"
+   "ret\n"
+ );
+ 
+ #endif
+-
+-#else  // USE_MMX
+-
+-// Reference version of YUV converter.
+-static const int kClipTableSize = 256;
+-static const int kClipOverflow = 288;  // Cb max is 535.
+-
+-static uint8 kRgbClipTable[kClipOverflow +
+-                           kClipTableSize +
+-                           kClipOverflow] = {
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 288 underflow values
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // clipped to 0.
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,  // Unclipped values.
+-  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+-  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+-  0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+-  0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+-  0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
+-  0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+-  0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
+-  0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+-  0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+-  0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+-  0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
+-  0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+-  0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
+-  0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+-  0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
+-  0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+-  0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
+-  0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+-  0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
+-  0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
+-  0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
+-  0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
+-  0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
+-  0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+-  0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
+-  0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
+-  0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
+-  0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
+-  0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
+-  0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+-  0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  // 288 overflow values
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  // clipped to 255.
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+-};
+-
+-// Clip an rgb channel value to 0..255 range.
+-// Source is signed fixed point 8.8.
+-// Table allows for values to underflow or overflow by 128.
+-// Therefore source range is -128 to 384.
+-// Output clips to unsigned 0 to 255.
+-static inline uint32 clip(int32 value) {
+-  DCHECK(((value >> 8) + kClipOverflow) >= 0);
+-  DCHECK(((value >> 8) + kClipOverflow) <
+-         (kClipOverflow + kClipTableSize + kClipOverflow));
+-  return static_cast<uint32>(kRgbClipTable[((value) >> 8) + kClipOverflow]);
+-}
+-
+-static inline void YuvPixel(uint8 y,
+-                            uint8 u,
+-                            uint8 v,
+-                            uint8* rgb_buf) {
+-  int32 d = static_cast<int32>(u) - 128;
+-  int32 e = static_cast<int32>(v) - 128;
+-
+-  int32 cb =   (516 * d + 128);
+-  int32 cg = (- 100 * d - 208 * e + 128);
+-  int32 cr =             (409 * e + 128);
+-
+-  int32 C298a = ((static_cast<int32>(y) - 16) * 298 + 128);
+-  *reinterpret_cast<uint32*>(rgb_buf) = (clip(C298a + cb)) |
+-                                        (clip(C298a + cg) << 8) |
+-                                        (clip(C298a + cr) << 16) |
+-                                        (0xff000000);
+-}
+-
+-void FastConvertYUVToRGB32Row(const uint8* y_buf,
+-                              const uint8* u_buf,
+-                              const uint8* v_buf,
+-                              uint8* rgb_buf,
+-                              int width) {
+-  for (int x = 0; x < width; x += 2) {
+-    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];
+-      YuvPixel(y1, u, v, rgb_buf + 4);
+-    }
+-    rgb_buf += 8;  // Advance 2 pixels.
+-  }
+-}
+-
+-// 28.4 fixed point is used.  A shift by 4 isolates the integer.
+-// A shift by 5 is used to further subsample the chrominence channels.
+-// & 15 isolates the fixed point fraction.  >> 2 to get the upper 2 bits,
+-// for 1/4 pixel accurate interpolation.
+-void ScaleYUVToRGB32Row(const uint8* y_buf,
+-                        const uint8* u_buf,
+-                        const uint8* v_buf,
+-                        uint8* rgb_buf,
+-                        int width,
+-                        int scaled_dx) {
+-  int scaled_x = 0;
+-  for (int x = 0; x < width; ++x) {
+-    uint8 u = u_buf[scaled_x >> 5];
+-    uint8 v = v_buf[scaled_x >> 5];
+-    uint8 y0 = y_buf[scaled_x >> 4];
+-    YuvPixel(y0, u, v, rgb_buf);
+-    rgb_buf += 4;
+-    scaled_x += scaled_dx;
+-  }
+-}
+-#endif  // USE_MMX
+ }  // extern "C"
+ 
+diff --git b/gfx/ycbcr/yuv_row_mac.cpp a/gfx/ycbcr/yuv_row_mac.cpp
+index 39c252d..aa40aac 100644
+--- b/gfx/ycbcr/yuv_row_mac.cpp
++++ a/gfx/ycbcr/yuv_row_mac.cpp
+@@ -1,13 +1,13 @@
+ // Copyright (c) 2009 The Chromium Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style license that can be
+ // found in the LICENSE file.
+ 
+-#include "media/base/yuv_row.h"
++#include "yuv_row.h"
+ 
+ // TODO(fbarchard): Do 64 bit version.
+ 
+ extern "C" {
+ 
+ #define RGBY(i) { \
+   static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
+   static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
+diff --git b/gfx/ycbcr/yuv_row_win.cpp a/gfx/ycbcr/yuv_row_win.cpp
+index 1e11d94..a77a16f 100644
+--- b/gfx/ycbcr/yuv_row_win.cpp
++++ a/gfx/ycbcr/yuv_row_win.cpp
+@@ -1,13 +1,13 @@
+ // Copyright (c) 2009 The Chromium Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style license that can be
+ // found in the LICENSE file.
+ 
+-#include "media/base/yuv_row.h"
++#include "yuv_row.h"
+ 
+ extern "C" {
+ #define RGBY(i) { \
+   static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
+   static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
+   static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
+   0 \
+ }
new file mode 100644
--- /dev/null
+++ b/gfx/ycbcr/picture_region.patch
@@ -0,0 +1,99 @@
+diff --git a/gfx/ycbcr/yuv_convert.cpp b/gfx/ycbcr/yuv_convert.cpp
+index c291d5c..ff7267e 100644
+--- a/gfx/ycbcr/yuv_convert.cpp
++++ b/gfx/ycbcr/yuv_convert.cpp
+@@ -25,42 +25,58 @@ namespace mozilla {
+ 
+ namespace gfx {
+ 
+ // Convert a frame of YUV to 32 bit ARGB.
+ void ConvertYCbCrToRGB32(const uint8* y_buf,
+                          const uint8* u_buf,
+                          const uint8* v_buf,
+                          uint8* rgb_buf,
+-                         int width,
+-                         int height,
++                         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();
+-  for (int y = 0; y < height; ++y) {
+-    uint8* rgb_row = rgb_buf + y * rgb_pitch;
+-    const uint8* y_ptr = y_buf + y * y_pitch;
+-    const uint8* u_ptr = u_buf + (y >> y_shift) * uv_pitch;
+-    const uint8* v_ptr = v_buf + (y >> y_shift) * uv_pitch;
++  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 >> 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);
++      rgb_row += 4;
++    }
+ 
+     if (has_mmx)
+       FastConvertYUVToRGB32Row(y_ptr,
+                                u_ptr,
+                                v_ptr,
+                                rgb_row,
+-                               width);
++                               x_width);
+     else
+       FastConvertYUVToRGB32Row_C(y_ptr,
+                                  u_ptr,
+                                  v_ptr,
+                                  rgb_row,
+-                                 width);
++                                 x_width);
+   }
+ 
+   // MMX used for FastConvertYUVToRGB32Row requires emms instruction.
+   if (has_mmx)
+     EMMS();
+ }
+ 
+ // Scale a frame of YUV to 32 bit ARGB.
+diff --git a/gfx/ycbcr/yuv_convert.h b/gfx/ycbcr/yuv_convert.h
+index 9d148a6..77ca8e6 100644
+--- a/gfx/ycbcr/yuv_convert.h
++++ b/gfx/ycbcr/yuv_convert.h
+@@ -32,18 +32,20 @@ enum Rotate {
+ };
+ 
+ // 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,
+-                         int frame_width,
+-                         int frame_height,
++                         int pic_x,
++                         int pic_y,
++                         int pic_width,
++                         int pic_height,
+                          int ystride,
+                          int uvstride,
+                          int rgbstride,
+                          YUVType yuv_type);
+ 
+ // Scale a frame of YUV to 32 bit ARGB.
+ // Supports rotation and mirroring.
+ void ScaleYCbCrToRGB32(const uint8* yplane,
new file mode 100644
--- /dev/null
+++ b/gfx/ycbcr/remove_scale.patch
@@ -0,0 +1,839 @@
+diff --git a/gfx/ycbcr/yuv_convert.cpp b/gfx/ycbcr/yuv_convert.cpp
+index eec578d..de91f79 100644
+--- a/gfx/ycbcr/yuv_convert.cpp
++++ b/gfx/ycbcr/yuv_convert.cpp
+@@ -81,133 +81,5 @@ void ConvertYCbCrToRGB32(const uint8* y_buf,
+     EMMS();
+ }
+ 
+-// Scale a frame of YUV to 32 bit ARGB.
+-void ScaleYCbCrToRGB32(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) {
+-  unsigned int y_shift = yuv_type;
+-  bool has_mmx = supports_mmx();
+-  // Diagram showing origin and direction of source sampling.
+-  // ->0   4<-
+-  // 7       3
+-  //
+-  // 6       5
+-  // ->1   2<-
+-  // Rotations that start at right side of image.
+-  if ((view_rotate == ROTATE_180) ||
+-      (view_rotate == ROTATE_270) ||
+-      (view_rotate == MIRROR_ROTATE_0) ||
+-      (view_rotate == MIRROR_ROTATE_90)) {
+-    y_buf += width - 1;
+-    u_buf += width / 2 - 1;
+-    v_buf += width / 2 - 1;
+-    width = -width;
+-  }
+-  // Rotations that start at bottom of image.
+-  if ((view_rotate == ROTATE_90) ||
+-      (view_rotate == ROTATE_180) ||
+-      (view_rotate == MIRROR_ROTATE_90) ||
+-      (view_rotate == MIRROR_ROTATE_180)) {
+-    y_buf += (height - 1) * y_pitch;
+-    u_buf += ((height >> y_shift) - 1) * uv_pitch;
+-    v_buf += ((height >> y_shift) - 1) * uv_pitch;
+-    height = -height;
+-  }
+-
+-  // Handle zero sized destination.
+-  if (scaled_width == 0 || scaled_height == 0)
+-    return;
+-  int scaled_dx = width * 16 / scaled_width;
+-  int scaled_dy = height * 16 / scaled_height;
+-
+-  int scaled_dx_uv = scaled_dx;
+-
+-  if ((view_rotate == ROTATE_90) ||
+-      (view_rotate == ROTATE_270)) {
+-    int tmp = scaled_height;
+-    scaled_height = scaled_width;
+-    scaled_width = tmp;
+-    tmp = height;
+-    height = width;
+-    width = tmp;
+-    int original_dx = scaled_dx;
+-    int original_dy = scaled_dy;
+-    scaled_dx = ((original_dy >> 4) * y_pitch) << 4;
+-    scaled_dx_uv = ((original_dy >> 4) * uv_pitch) << 4;
+-    scaled_dy = original_dx;
+-    if (view_rotate == ROTATE_90) {
+-      y_pitch = -1;
+-      uv_pitch = -1;
+-      height = -height;
+-    } else {
+-      y_pitch = 1;
+-      uv_pitch = 1;
+-    }
+-  }
+-
+-  for (int y = 0; y < scaled_height; ++y) {
+-    uint8* dest_pixel = rgb_buf + y * rgb_pitch;
+-    int scaled_y = (y * height / scaled_height);
+-    const uint8* y_ptr = y_buf + scaled_y * y_pitch;
+-    const uint8* u_ptr = u_buf + (scaled_y >> y_shift) * uv_pitch;
+-    const uint8* v_ptr = v_buf + (scaled_y >> y_shift) * uv_pitch;
+-
+-#if defined(_MSC_VER)
+-    if (scaled_width == (width * 2)) {
+-      DoubleYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
+-                          dest_pixel, scaled_width);
+-    } else if ((scaled_dx & 15) == 0) {  // Scaling by integer scale factor.
+-      if (scaled_dx_uv == scaled_dx) {   // Not rotated.
+-        if (scaled_dx == 16) {           // Not scaled
+-          if (has_mmx)
+-            FastConvertYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
+-                                     dest_pixel, scaled_width);
+-          else
+-            FastConvertYUVToRGB32Row_C(y_ptr, u_ptr, v_ptr,
+-                                      dest_pixel, scaled_width);
+-        } else {  // Simple scale down. ie half
+-          ConvertYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
+-                               dest_pixel, scaled_width, scaled_dx >> 4);
+-        }
+-      } else {
+-        RotateConvertYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
+-                                   dest_pixel, scaled_width,
+-                                   scaled_dx >> 4, scaled_dx_uv >> 4);
+-      }
+-#else
+-    if (scaled_dx == 16) {           // Not scaled
+-      if (has_mmx) 
+-        FastConvertYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
+-                                 dest_pixel, scaled_width);
+-      else
+-        FastConvertYUVToRGB32Row_C(y_ptr, u_ptr, v_ptr,
+-                                   dest_pixel, scaled_width);
+-#endif
+-    } else {
+-      if (has_mmx) 
+-        ScaleYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
+-                           dest_pixel, scaled_width, scaled_dx);
+-      else
+-        ScaleYUVToRGB32Row_C(y_ptr, u_ptr, v_ptr,
+-                             dest_pixel, scaled_width, scaled_dx);
+-
+-    }  
+-  }
+-
+-  // MMX used for FastConvertYUVToRGB32Row requires emms instruction.
+-  if (has_mmx)
+-    EMMS();
+-}
+-
+ }  // namespace gfx
+ }  // namespace mozilla
+diff --git a/gfx/ycbcr/yuv_convert.h b/gfx/ycbcr/yuv_convert.h
+index 7962af7..c9bf7e0 100644
+--- a/gfx/ycbcr/yuv_convert.h
++++ b/gfx/ycbcr/yuv_convert.h
+@@ -18,19 +18,6 @@ enum YUVType {
+   YV12 = 1            // YV12 is half width and half height chroma channels.
+ };
+ 
+-// Mirror means flip the image horizontally, as in looking in a mirror.
+-// Rotate happens after mirroring.
+-enum Rotate {
+-  ROTATE_0,           // Rotation off.
+-  ROTATE_90,          // Rotate clockwise.
+-  ROTATE_180,         // Rotate upside down.
+-  ROTATE_270,         // Rotate counter clockwise.
+-  MIRROR_ROTATE_0,    // Mirror horizontally.
+-  MIRROR_ROTATE_90,   // Mirror then Rotate clockwise.
+-  MIRROR_ROTATE_180,  // Mirror vertically.
+-  MIRROR_ROTATE_270   // Transpose.
+-};
+-
+ // Convert a frame of YUV to 32 bit ARGB.
+ // Pass in YV16/YV12 depending on source format
+ void ConvertYCbCrToRGB32(const uint8* yplane,
+@@ -48,22 +35,6 @@ void ConvertYCbCrToRGB32(const uint8* yplane,
+                          int rgbstride,
+                          YUVType yuv_type);
+ 
+-// Scale a frame of YUV to 32 bit ARGB.
+-// Supports rotation and mirroring.
+-void ScaleYCbCrToRGB32(const uint8* yplane,
+-                       const uint8* uplane,
+-                       const uint8* vplane,
+-                       uint8* rgbframe,
+-                       int frame_width,
+-                       int frame_height,
+-                       int scaled_width,
+-                       int scaled_height,
+-                       int ystride,
+-                       int uvstride,
+-                       int rgbstride,
+-                       YUVType yuv_type,
+-                       Rotate view_rotate);
+-
+ }  // namespace gfx
+ }  // namespace mozilla
+ 
+diff --git a/gfx/ycbcr/yuv_row.h b/gfx/ycbcr/yuv_row.h
+index c43f713..2a82972 100644
+--- a/gfx/ycbcr/yuv_row.h
++++ b/gfx/ycbcr/yuv_row.h
+@@ -28,53 +28,6 @@ void FastConvertYUVToRGB32Row_C(const uint8* y_buf,
+                                 int width);
+ 
+ 
+-// Can do 1x, half size or any scale down by an integer amount.
+-// Step can be negative (mirroring, rotate 180).
+-// This is the third fastest of the scalers.
+-void ConvertYUVToRGB32Row(const uint8* y_buf,
+-                          const uint8* u_buf,
+-                          const uint8* v_buf,
+-                          uint8* rgb_buf,
+-                          int width,
+-                          int step);
+-
+-// Rotate is like Convert, but applies different step to Y versus U and V.
+-// This allows rotation by 90 or 270, by stepping by stride.
+-// This is the forth fastest of the scalers.
+-void RotateConvertYUVToRGB32Row(const uint8* y_buf,
+-                                const uint8* u_buf,
+-                                const uint8* v_buf,
+-                                uint8* rgb_buf,
+-                                int width,
+-                                int ystep,
+-                                int uvstep);
+-
+-// Doubler does 4 pixels at a time.  Each pixel is replicated.
+-// This is the fastest of the scalers.
+-void DoubleYUVToRGB32Row(const uint8* y_buf,
+-                         const uint8* u_buf,
+-                         const uint8* v_buf,
+-                         uint8* rgb_buf,
+-                         int width);
+-
+-// Handles arbitrary scaling up or down.
+-// Mirroring is supported, but not 90 or 270 degree rotation.
+-// Chroma is under sampled every 2 pixels for performance.
+-// This is the slowest of the scalers.
+-void ScaleYUVToRGB32Row(const uint8* y_buf,
+-                        const uint8* u_buf,
+-                        const uint8* v_buf,
+-                        uint8* rgb_buf,
+-                        int width,
+-                        int scaled_dx);
+-
+-void ScaleYUVToRGB32Row_C(const uint8* y_buf,
+-                          const uint8* u_buf,
+-                          const uint8* v_buf,
+-                          uint8* rgb_buf,
+-                          int width,
+-                          int scaled_dx);
+-
+ }  // extern "C"
+ 
+ // x64 uses MMX2 (SSE) so emms is not required.
+diff --git a/gfx/ycbcr/yuv_row_c.cpp b/gfx/ycbcr/yuv_row_c.cpp
+index a81416c..d3bdab4 100644
+--- a/gfx/ycbcr/yuv_row_c.cpp
++++ b/gfx/ycbcr/yuv_row_c.cpp
+@@ -172,25 +172,5 @@ void FastConvertYUVToRGB32Row_C(const uint8* y_buf,
+   }
+ }
+ 
+-// 28.4 fixed point is used.  A shift by 4 isolates the integer.
+-// A shift by 5 is used to further subsample the chrominence channels.
+-// & 15 isolates the fixed point fraction.  >> 2 to get the upper 2 bits,
+-// for 1/4 pixel accurate interpolation.
+-void ScaleYUVToRGB32Row_C(const uint8* y_buf,
+-                        const uint8* u_buf,
+-                        const uint8* v_buf,
+-                        uint8* rgb_buf,
+-                        int width,
+-                        int scaled_dx) {
+-  int scaled_x = 0;
+-  for (int x = 0; x < width; ++x) {
+-    uint8 u = u_buf[scaled_x >> 5];
+-    uint8 v = v_buf[scaled_x >> 5];
+-    uint8 y0 = y_buf[scaled_x >> 4];
+-    YuvPixel(y0, u, v, rgb_buf);
+-    rgb_buf += 4;
+-    scaled_x += scaled_dx;
+-  }
+-}
+ }  // extern "C"
+ 
+diff --git a/gfx/ycbcr/yuv_row_linux.cpp b/gfx/ycbcr/yuv_row_linux.cpp
+index 5fb2bc4..ce5ee89 100644
+--- a/gfx/ycbcr/yuv_row_linux.cpp
++++ b/gfx/ycbcr/yuv_row_linux.cpp
+@@ -21,14 +21,6 @@ void FastConvertYUVToRGB32Row(const uint8* y_buf,
+   FastConvertYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, width);
+ }
+  
+-void ScaleYUVToRGB32Row(const uint8* y_buf,
+-                        const uint8* u_buf,
+-                        const uint8* v_buf,
+-                        uint8* rgb_buf,
+-                        int width,
+-                        int scaled_dx) {
+-  ScaleYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, width, scaled_dx);
+-}
+ #else
+ 
+ #define RGBY(i) { \
+@@ -315,75 +307,6 @@ void FastConvertYUVToRGB32Row(const uint8* y_buf,  // rdi
+ );
+ }
+ 
+-void ScaleYUVToRGB32Row(const uint8* y_buf,  // rdi
+-                        const uint8* u_buf,  // rsi
+-                        const uint8* v_buf,  // rdx
+-                        uint8* rgb_buf,      // rcx
+-                        int width,           // r8
+-                        int scaled_dx) {     // r9
+-  asm(
+-  "xor    %%r11,%%r11\n"
+-  "sub    $0x2,%4\n"
+-  "js     scalenext\n"
+-
+-"scaleloop:"
+-  "mov    %%r11,%%r10\n"
+-  "sar    $0x5,%%r10\n"
+-  "movzb  (%1,%%r10,1),%%rax\n"
+-  "movq   2048(%5,%%rax,8),%%xmm0\n"
+-  "movzb  (%2,%%r10,1),%%rax\n"
+-  "movq   4096(%5,%%rax,8),%%xmm1\n"
+-  "lea    (%%r11,%6),%%r10\n"
+-  "sar    $0x4,%%r11\n"
+-  "movzb  (%0,%%r11,1),%%rax\n"
+-  "paddsw %%xmm1,%%xmm0\n"
+-  "movq   (%5,%%rax,8),%%xmm1\n"
+-  "lea    (%%r10,%6),%%r11\n"
+-  "sar    $0x4,%%r10\n"
+-  "movzb  (%0,%%r10,1),%%rax\n"
+-  "movq   (%5,%%rax,8),%%xmm2\n"
+-  "paddsw %%xmm0,%%xmm1\n"
+-  "paddsw %%xmm0,%%xmm2\n"
+-  "shufps $0x44,%%xmm2,%%xmm1\n"
+-  "psraw  $0x6,%%xmm1\n"
+-  "packuswb %%xmm1,%%xmm1\n"
+-  "movq   %%xmm1,0x0(%3)\n"
+-  "add    $0x8,%3\n"
+-  "sub    $0x2,%4\n"
+-  "jns    scaleloop\n"
+-
+-"scalenext:"
+-  "add    $0x1,%4\n"
+-  "js     scaledone\n"
+-
+-  "mov    %%r11,%%r10\n"
+-  "sar    $0x5,%%r10\n"
+-  "movzb  (%1,%%r10,1),%%rax\n"
+-  "movq   2048(%5,%%rax,8),%%xmm0\n"
+-  "movzb  (%2,%%r10,1),%%rax\n"
+-  "movq   4096(%5,%%rax,8),%%xmm1\n"
+-  "paddsw %%xmm1,%%xmm0\n"
+-  "sar    $0x4,%%r11\n"
+-  "movzb  (%0,%%r11,1),%%rax\n"
+-  "movq   (%5,%%rax,8),%%xmm1\n"
+-  "paddsw %%xmm0,%%xmm1\n"
+-  "psraw  $0x6,%%xmm1\n"
+-  "packuswb %%xmm1,%%xmm1\n"
+-  "movd   %%xmm1,0x0(%3)\n"
+-
+-"scaledone:"
+-  :
+-  : "r"(y_buf),  // %0
+-    "r"(u_buf),  // %1
+-    "r"(v_buf),  // %2
+-    "r"(rgb_buf),  // %3
+-    "r"(width),  // %4
+-    "r" (kCoefficientsRgbY),  // %5
+-    "r"(static_cast<long>(scaled_dx))  // %6
+-  : "memory", "r10", "r11", "rax", "xmm0", "xmm1", "xmm2"
+-);
+-}
+-
+ #else
+ 
+ void FastConvertYUVToRGB32Row(const uint8* y_buf,
+@@ -443,81 +366,6 @@ void FastConvertYUVToRGB32Row(const uint8* y_buf,
+   "ret\n"
+ );
+ 
+-
+-void ScaleYUVToRGB32Row(const uint8* y_buf,
+-                        const uint8* u_buf,
+-                        const uint8* v_buf,
+-                        uint8* rgb_buf,
+-                        int width,
+-                        int scaled_dx);
+-
+-  asm(
+-  ".global ScaleYUVToRGB32Row\n"
+-"ScaleYUVToRGB32Row:\n"
+-  "pusha\n"
+-  "mov    0x24(%esp),%edx\n"
+-  "mov    0x28(%esp),%edi\n"
+-  "mov    0x2c(%esp),%esi\n"
+-  "mov    0x30(%esp),%ebp\n"
+-  "mov    0x34(%esp),%ecx\n"
+-  "xor    %ebx,%ebx\n"
+-  "jmp    scaleend\n"
+-
+-"scaleloop:"
+-  "mov    %ebx,%eax\n"
+-  "sar    $0x5,%eax\n"
+-  "movzbl (%edi,%eax,1),%eax\n"
+-  "movq   kCoefficientsRgbY+2048(,%eax,8),%mm0\n"
+-  "mov    %ebx,%eax\n"
+-  "sar    $0x5,%eax\n"
+-  "movzbl (%esi,%eax,1),%eax\n"
+-  "paddsw kCoefficientsRgbY+4096(,%eax,8),%mm0\n"
+-  "mov    %ebx,%eax\n"
+-  "add    0x38(%esp),%ebx\n"
+-  "sar    $0x4,%eax\n"
+-  "movzbl (%edx,%eax,1),%eax\n"
+-  "movq   kCoefficientsRgbY(,%eax,8),%mm1\n"
+-  "mov    %ebx,%eax\n"
+-  "add    0x38(%esp),%ebx\n"
+-  "sar    $0x4,%eax\n"
+-  "movzbl (%edx,%eax,1),%eax\n"
+-  "movq   kCoefficientsRgbY(,%eax,8),%mm2\n"
+-  "paddsw %mm0,%mm1\n"
+-  "paddsw %mm0,%mm2\n"
+-  "psraw  $0x6,%mm1\n"
+-  "psraw  $0x6,%mm2\n"
+-  "packuswb %mm2,%mm1\n"
+-  "movntq %mm1,0x0(%ebp)\n"
+-  "add    $0x8,%ebp\n"
+-"scaleend:"
+-  "sub    $0x2,%ecx\n"
+-  "jns    scaleloop\n"
+-
+-  "and    $0x1,%ecx\n"
+-  "je     scaledone\n"
+-
+-  "mov    %ebx,%eax\n"
+-  "sar    $0x5,%eax\n"
+-  "movzbl (%edi,%eax,1),%eax\n"
+-  "movq   kCoefficientsRgbY+2048(,%eax,8),%mm0\n"
+-  "mov    %ebx,%eax\n"
+-  "sar    $0x5,%eax\n"
+-  "movzbl (%esi,%eax,1),%eax\n"
+-  "paddsw kCoefficientsRgbY+4096(,%eax,8),%mm0\n"
+-  "mov    %ebx,%eax\n"
+-  "sar    $0x4,%eax\n"
+-  "movzbl (%edx,%eax,1),%eax\n"
+-  "movq   kCoefficientsRgbY(,%eax,8),%mm1\n"
+-  "paddsw %mm0,%mm1\n"
+-  "psraw  $0x6,%mm1\n"
+-  "packuswb %mm1,%mm1\n"
+-  "movd   %mm1,0x0(%ebp)\n"
+-
+-"scaledone:"
+-  "popa\n"
+-  "ret\n"
+-);
+-
+ #endif
+ #endif // ARCH_CPU_ARM_FAMILY
+ }  // extern "C"
+diff --git a/gfx/ycbcr/yuv_row_mac.cpp b/gfx/ycbcr/yuv_row_mac.cpp
+index a7e8243..3515ada 100644
+--- a/gfx/ycbcr/yuv_row_mac.cpp
++++ b/gfx/ycbcr/yuv_row_mac.cpp
+@@ -18,14 +18,6 @@ void FastConvertYUVToRGB32Row(const uint8* y_buf,
+   FastConvertYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, width);
+ }
+  
+-void ScaleYUVToRGB32Row(const uint8* y_buf,
+-                        const uint8* u_buf,
+-                        const uint8* v_buf,
+-                        uint8* rgb_buf,
+-                        int width,
+-                        int scaled_dx) {
+-  ScaleYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, width, scaled_dx);
+-}
+ #else
+ 
+ #define RGBY(i) { \
+@@ -323,91 +315,6 @@ void FastConvertYUVToRGB32Row(const uint8* y_buf,
+                           &kCoefficientsRgbY[0][0]);
+ }
+ 
+-extern void MacScaleYUVToRGB32Row(const uint8* y_buf,
+-                               const uint8* u_buf,
+-                               const uint8* v_buf,
+-                               uint8* rgb_buf,
+-                               int width,
+-                               int scaled_dx,
+-                               int16 *kCoefficientsRgbY);
+-
+-  __asm__(
+-"_MacScaleYUVToRGB32Row:\n"
+-  "pusha\n"
+-  "mov    0x24(%esp),%edx\n"
+-  "mov    0x28(%esp),%edi\n"
+-  "mov    0x2c(%esp),%esi\n"
+-  "mov    0x30(%esp),%ebp\n"
+-  "mov    0x3c(%esp),%ecx\n"
+-  "xor    %ebx,%ebx\n"
+-  "jmp    Lscaleend\n"
+-
+-"Lscaleloop:"
+-  "mov    %ebx,%eax\n"
+-  "sar    $0x5,%eax\n"
+-  "movzbl (%edi,%eax,1),%eax\n"
+-  "movq   2048(%ecx,%eax,8),%mm0\n"
+-  "mov    %ebx,%eax\n"
+-  "sar    $0x5,%eax\n"
+-  "movzbl (%esi,%eax,1),%eax\n"
+-  "paddsw 4096(%ecx,%eax,8),%mm0\n"
+-  "mov    %ebx,%eax\n"
+-  "add    0x38(%esp),%ebx\n"
+-  "sar    $0x4,%eax\n"
+-  "movzbl (%edx,%eax,1),%eax\n"
+-  "movq   0(%ecx,%eax,8),%mm1\n"
+-  "mov    %ebx,%eax\n"
+-  "add    0x38(%esp),%ebx\n"
+-  "sar    $0x4,%eax\n"
+-  "movzbl (%edx,%eax,1),%eax\n"
+-  "movq   0(%ecx,%eax,8),%mm2\n"
+-  "paddsw %mm0,%mm1\n"
+-  "paddsw %mm0,%mm2\n"
+-  "psraw  $0x6,%mm1\n"
+-  "psraw  $0x6,%mm2\n"
+-  "packuswb %mm2,%mm1\n"
+-  "movntq %mm1,0x0(%ebp)\n"
+-  "add    $0x8,%ebp\n"
+-"Lscaleend:"
+-  "sub    $0x2,0x34(%esp)\n"
+-  "jns    Lscaleloop\n"
+-
+-  "and    $0x1,0x34(%esp)\n"
+-  "je     Lscaledone\n"
+-
+-  "mov    %ebx,%eax\n"
+-  "sar    $0x5,%eax\n"
+-  "movzbl (%edi,%eax,1),%eax\n"
+-  "movq   2048(%ecx,%eax,8),%mm0\n"
+-  "mov    %ebx,%eax\n"
+-  "sar    $0x5,%eax\n"
+-  "movzbl (%esi,%eax,1),%eax\n"
+-  "paddsw 4096(%ecx,%eax,8),%mm0\n"
+-  "mov    %ebx,%eax\n"
+-  "sar    $0x4,%eax\n"
+-  "movzbl (%edx,%eax,1),%eax\n"
+-  "movq   0(%ecx,%eax,8),%mm1\n"
+-  "paddsw %mm0,%mm1\n"
+-  "psraw  $0x6,%mm1\n"
+-  "packuswb %mm1,%mm1\n"
+-  "movd   %mm1,0x0(%ebp)\n"
+-
+-"Lscaledone:"
+-  "popa\n"
+-  "ret\n"
+-);
+-
+-
+-void ScaleYUVToRGB32Row(const uint8* y_buf,
+-                        const uint8* u_buf,
+-                        const uint8* v_buf,
+-                        uint8* rgb_buf,
+-                        int width,
+-                        int scaled_dx) {
+-
+-  MacScaleYUVToRGB32Row(y_buf, u_buf, v_buf, rgb_buf, width, scaled_dx,
+-                        &kCoefficientsRgbY[0][0]);
+-}
+ #endif // ARCH_CPU_PPC 
+ }  // extern "C"
+ 
+diff --git a/gfx/ycbcr/yuv_row_win.cpp b/gfx/ycbcr/yuv_row_win.cpp
+index a77a16f..f994931 100644
+--- a/gfx/ycbcr/yuv_row_win.cpp
++++ b/gfx/ycbcr/yuv_row_win.cpp
+@@ -297,273 +297,5 @@ void FastConvertYUVToRGB32Row(const uint8* y_buf,
+   }
+ }
+ 
+-__declspec(naked)
+-void ConvertYUVToRGB32Row(const uint8* y_buf,
+-                          const uint8* u_buf,
+-                          const uint8* v_buf,
+-                          uint8* rgb_buf,
+-                          int width,
+-                          int step) {
+-  __asm {
+-    pushad
+-    mov       edx, [esp + 32 + 4]   // Y
+-    mov       edi, [esp + 32 + 8]   // U
+-    mov       esi, [esp + 32 + 12]  // V
+-    mov       ebp, [esp + 32 + 16]  // rgb
+-    mov       ecx, [esp + 32 + 20]  // width
+-    mov       ebx, [esp + 32 + 24]  // step
+-    jmp       wend
+-
+- wloop :
+-    movzx     eax, byte ptr [edi]
+-    add       edi, ebx
+-    movq      mm0, [kCoefficientsRgbU + 8 * eax]
+-    movzx     eax, byte ptr [esi]
+-    add       esi, ebx
+-    paddsw    mm0, [kCoefficientsRgbV + 8 * eax]
+-    movzx     eax, byte ptr [edx]
+-    add       edx, ebx
+-    movq      mm1, [kCoefficientsRgbY + 8 * eax]
+-    movzx     eax, byte ptr [edx]
+-    add       edx, ebx
+-    movq      mm2, [kCoefficientsRgbY + 8 * eax]
+-    paddsw    mm1, mm0
+-    paddsw    mm2, mm0
+-    psraw     mm1, 6
+-    psraw     mm2, 6
+-    packuswb  mm1, mm2
+-    movntq    [ebp], mm1
+-    add       ebp, 8
+- wend :
+-    sub       ecx, 2
+-    jns       wloop
+-
+-    and       ecx, 1  // odd number of pixels?
+-    jz        wdone
+-
+-    movzx     eax, byte ptr [edi]
+-    movq      mm0, [kCoefficientsRgbU + 8 * eax]
+-    movzx     eax, byte ptr [esi]
+-    paddsw    mm0, [kCoefficientsRgbV + 8 * eax]
+-    movzx     eax, byte ptr [edx]
+-    movq      mm1, [kCoefficientsRgbY + 8 * eax]
+-    paddsw    mm1, mm0
+-    psraw     mm1, 6
+-    packuswb  mm1, mm1
+-    movd      [ebp], mm1
+- wdone :
+-
+-    popad
+-    ret
+-  }
+-}
+-
+-__declspec(naked)
+-void RotateConvertYUVToRGB32Row(const uint8* y_buf,
+-                                const uint8* u_buf,
+-                                const uint8* v_buf,
+-                                uint8* rgb_buf,
+-                                int width,
+-                                int ystep,
+-                                int uvstep) {
+-  __asm {
+-    pushad
+-    mov       edx, [esp + 32 + 4]   // Y
+-    mov       edi, [esp + 32 + 8]   // U
+-    mov       esi, [esp + 32 + 12]  // V
+-    mov       ebp, [esp + 32 + 16]  // rgb
+-    mov       ecx, [esp + 32 + 20]  // width
+-    jmp       wend
+-
+- wloop :
+-    movzx     eax, byte ptr [edi]
+-    mov       ebx, [esp + 32 + 28]  // uvstep
+-    add       edi, ebx
+-    movq      mm0, [kCoefficientsRgbU + 8 * eax]
+-    movzx     eax, byte ptr [esi]
+-    add       esi, ebx
+-    paddsw    mm0, [kCoefficientsRgbV + 8 * eax]
+-    movzx     eax, byte ptr [edx]
+-    mov       ebx, [esp + 32 + 24]  // ystep
+-    add       edx, ebx
+-    movq      mm1, [kCoefficientsRgbY + 8 * eax]
+-    movzx     eax, byte ptr [edx]
+-    add       edx, ebx
+-    movq      mm2, [kCoefficientsRgbY + 8 * eax]
+-    paddsw    mm1, mm0
+-    paddsw    mm2, mm0
+-    psraw     mm1, 6
+-    psraw     mm2, 6
+-    packuswb  mm1, mm2
+-    movntq    [ebp], mm1
+-    add       ebp, 8
+- wend :
+-    sub       ecx, 2
+-    jns       wloop
+-
+-    and       ecx, 1  // odd number of pixels?
+-    jz        wdone
+-
+-    movzx     eax, byte ptr [edi]
+-    movq      mm0, [kCoefficientsRgbU + 8 * eax]
+-    movzx     eax, byte ptr [esi]
+-    paddsw    mm0, [kCoefficientsRgbV + 8 * eax]
+-    movzx     eax, byte ptr [edx]
+-    movq      mm1, [kCoefficientsRgbY + 8 * eax]
+-    paddsw    mm1, mm0
+-    psraw     mm1, 6
+-    packuswb  mm1, mm1
+-    movd      [ebp], mm1
+- wdone :
+-
+-    popad
+-    ret
+-  }
+-}
+-
+-__declspec(naked)
+-void DoubleYUVToRGB32Row(const uint8* y_buf,
+-                         const uint8* u_buf,
+-                         const uint8* v_buf,
+-                         uint8* rgb_buf,
+-                         int width) {
+-  __asm {
+-    pushad
+-    mov       edx, [esp + 32 + 4]   // Y
+-    mov       edi, [esp + 32 + 8]   // U
+-    mov       esi, [esp + 32 + 12]  // V
+-    mov       ebp, [esp + 32 + 16]  // rgb
+-    mov       ecx, [esp + 32 + 20]  // width
+-    jmp       wend
+-
+- wloop :
+-    movzx     eax, byte ptr [edi]
+-    add       edi, 1
+-    movzx     ebx, byte ptr [esi]
+-    add       esi, 1
+-    movq      mm0, [kCoefficientsRgbU + 8 * eax]
+-    movzx     eax, byte ptr [edx]
+-    paddsw    mm0, [kCoefficientsRgbV + 8 * ebx]
+-    movq      mm1, [kCoefficientsRgbY + 8 * eax]
+-    paddsw    mm1, mm0
+-    psraw     mm1, 6
+-    packuswb  mm1, mm1
+-    punpckldq mm1, mm1
+-    movntq    [ebp], mm1
+-
+-    movzx     ebx, byte ptr [edx + 1]
+-    add       edx, 2
+-    paddsw    mm0, [kCoefficientsRgbY + 8 * ebx]
+-    psraw     mm0, 6
+-    packuswb  mm0, mm0
+-    punpckldq mm0, mm0
+-    movntq    [ebp+8], mm0
+-    add       ebp, 16
+- wend :
+-    sub       ecx, 4
+-    jns       wloop
+-
+-    add       ecx, 4
+-    jz        wdone
+-
+-    movzx     eax, byte ptr [edi]
+-    movq      mm0, [kCoefficientsRgbU + 8 * eax]
+-    movzx     eax, byte ptr [esi]
+-    paddsw    mm0, [kCoefficientsRgbV + 8 * eax]
+-    movzx     eax, byte ptr [edx]
+-    movq      mm1, [kCoefficientsRgbY + 8 * eax]
+-    paddsw    mm1, mm0
+-    psraw     mm1, 6
+-    packuswb  mm1, mm1
+-    jmp       wend1
+-
+- wloop1 :
+-    movd      [ebp], mm1
+-    add       ebp, 4
+- wend1 :
+-    sub       ecx, 1
+-    jns       wloop1
+- wdone :
+-    popad
+-    ret
+-  }
+-}
+-
+-// This version does general purpose scaling by any amount, up or down.
+-// The only thing it can not do it rotation by 90 or 270.
+-// For performance the chroma is under sampled, reducing cost of a 3x
+-// 1080p scale from 8.4 ms to 5.4 ms.
+-__declspec(naked)
+-void ScaleYUVToRGB32Row(const uint8* y_buf,
+-                        const uint8* u_buf,
+-                        const uint8* v_buf,
+-                        uint8* rgb_buf,
+-                        int width,
+-                        int dx) {
+-  __asm {
+-    pushad
+-    mov       edx, [esp + 32 + 4]   // Y
+-    mov       edi, [esp + 32 + 8]   // U
+-    mov       esi, [esp + 32 + 12]  // V
+-    mov       ebp, [esp + 32 + 16]  // rgb
+-    mov       ecx, [esp + 32 + 20]  // width
+-    xor       ebx, ebx              // x
+-    jmp       scaleend
+-
+- scaleloop :
+-    mov       eax, ebx
+-    sar       eax, 5
+-    movzx     eax, byte ptr [edi + eax]
+-    movq      mm0, [kCoefficientsRgbU + 8 * eax]
+-    mov       eax, ebx
+-    sar       eax, 5
+-    movzx     eax, byte ptr [esi + eax]
+-    paddsw    mm0, [kCoefficientsRgbV + 8 * eax]
+-    mov       eax, ebx
+-    add       ebx, [esp + 32 + 24]  // x += dx
+-    sar       eax, 4
+-    movzx     eax, byte ptr [edx + eax]
+-    movq      mm1, [kCoefficientsRgbY + 8 * eax]
+-    mov       eax, ebx
+-    add       ebx, [esp + 32 + 24]  // x += dx
+-    sar       eax, 4
+-    movzx     eax, byte ptr [edx + eax]
+-    movq      mm2, [kCoefficientsRgbY + 8 * eax]
+-    paddsw    mm1, mm0
+-    paddsw    mm2, mm0
+-    psraw     mm1, 6
+-    psraw     mm2, 6
+-    packuswb  mm1, mm2
+-    movntq    [ebp], mm1
+-    add       ebp, 8
+- scaleend :
+-    sub       ecx, 2
+-    jns       scaleloop
+-
+-    and       ecx, 1  // odd number of pixels?
+-    jz        scaledone
+-
+-    mov       eax, ebx
+-    sar       eax, 5
+-    movzx     eax, byte ptr [edi + eax]
+-    movq      mm0, [kCoefficientsRgbU + 8 * eax]
+-    mov       eax, ebx
+-    sar       eax, 5
+-    movzx     eax, byte ptr [esi + eax]
+-    paddsw    mm0, [kCoefficientsRgbV + 8 * eax]
+-    mov       eax, ebx
+-    sar       eax, 4
+-    movzx     eax, byte ptr [edx + eax]
+-    movq      mm1, [kCoefficientsRgbY + 8 * eax]
+-    paddsw    mm1, mm0
+-    psraw     mm1, 6
+-    packuswb  mm1, mm1
+-    movd      [ebp], mm1
+-
+- scaledone :
+-    popad
+-    ret
+-  }
+-}
+ }  // extern "C"
+ 
new file mode 100644
--- /dev/null
+++ b/gfx/ycbcr/update.sh
@@ -0,0 +1,11 @@
+# update.sh <chromium-src-directory>
+cp $1/media/base/yuv_convert.h .
+cp $1/media/base/yuv_convert.cc yuv_convert.cpp
+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
new file mode 100644
--- /dev/null
+++ b/gfx/ycbcr/yuv_convert.cpp
@@ -0,0 +1,83 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This webpage shows layout of YV12 and other YUV formats
+// 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
+//
+// 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"
+#include "mozilla/SSE.h"
+
+namespace mozilla {
+
+namespace gfx {
+
+// Convert a frame of YUV to 32 bit ARGB.
+void ConvertYCbCrToRGB32(const uint8* y_buf,
+                         const uint8* u_buf,
+                         const uint8* v_buf,
+                         uint8* rgb_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;
+  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);
+
+    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);
+      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);
+  }
+
+  // MMX used for FastConvertYUVToRGB32Row requires emms instruction.
+  if (has_mmx)
+    EMMS();
+}
+
+}  // namespace gfx
+}  // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/ycbcr/yuv_convert.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIA_BASE_YUV_CONVERT_H_
+#define MEDIA_BASE_YUV_CONVERT_H_
+
+#include "chromium_types.h"
+
+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.
+};
+
+// 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,
+                         int pic_x,
+                         int pic_y,
+                         int pic_width,
+                         int pic_height,
+                         int ystride,
+                         int uvstride,
+                         int rgbstride,
+                         YUVType yuv_type);
+
+}  // namespace gfx
+}  // namespace mozilla
+
+#endif  // MEDIA_BASE_YUV_CONVERT_H_
new file mode 100644
--- /dev/null
+++ b/gfx/ycbcr/yuv_row.h
@@ -0,0 +1,44 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// yuv_row internal functions to handle YUV conversion and scaling to RGB.
+// These functions are used from both yuv_convert.cc and yuv_scale.cc.
+
+// TODO(fbarchard): Write function that can handle rotation and scaling.
+
+#ifndef MEDIA_BASE_YUV_ROW_H_
+#define MEDIA_BASE_YUV_ROW_H_
+
+#include "chromium_types.h"
+
+extern "C" {
+// Can only do 1x.
+// This is the second fastest of the scalers.
+void FastConvertYUVToRGB32Row(const uint8* y_buf,
+                              const uint8* u_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);
+
+
+}  // 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
+#else
+#define EMMS() asm("emms")
+#endif
+#else
+#define EMMS()
+#endif
+
+#endif  // MEDIA_BASE_YUV_ROW_H_
new file mode 100644
--- /dev/null
+++ b/gfx/ycbcr/yuv_row_c.cpp
@@ -0,0 +1,176 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "yuv_row.h"
+
+#define DCHECK(a)
+
+// TODO(fbarchard): Move this to yuv_row_posix.cc to share with Mac.
+// TODO(fbarchard): Do 64 bit version.
+
+extern "C" {
+
+// Reference version of YUV converter.
+static const int kClipTableSize = 256;
+static const int kClipOverflow = 288;  // Cb max is 535.
+
+static uint8 kRgbClipTable[kClipOverflow +
+                           kClipTableSize +
+                           kClipOverflow] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 288 underflow values
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // clipped to 0.
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,  // Unclipped values.
+  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+  0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+  0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+  0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
+  0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+  0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
+  0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+  0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+  0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+  0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
+  0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+  0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
+  0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+  0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
+  0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+  0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
+  0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+  0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
+  0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
+  0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
+  0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
+  0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
+  0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+  0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
+  0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
+  0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
+  0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
+  0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
+  0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+  0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  // 288 overflow values
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  // clipped to 255.
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+};
+
+// Clip an rgb channel value to 0..255 range.
+// Source is signed fixed point 8.8.
+// Table allows for values to underflow or overflow by 128.
+// Therefore source range is -128 to 384.
+// Output clips to unsigned 0 to 255.
+static inline uint32 clip(int32 value) {
+  DCHECK(((value >> 8) + kClipOverflow) >= 0);
+  DCHECK(((value >> 8) + kClipOverflow) <
+         (kClipOverflow + kClipTableSize + kClipOverflow));
+  return static_cast<uint32>(kRgbClipTable[((value) >> 8) + kClipOverflow]);
+}
+
+static inline void YuvPixel(uint8 y,
+                            uint8 u,
+                            uint8 v,
+                            uint8* rgb_buf) {
+  int32 d = static_cast<int32>(u) - 128;
+  int32 e = static_cast<int32>(v) - 128;
+
+  int32 cb =   (516 * d + 128);
+  int32 cg = (- 100 * d - 208 * e + 128);
+  int32 cr =             (409 * e + 128);
+
+  int32 C298a = ((static_cast<int32>(y) - 16) * 298 + 128);
+  *reinterpret_cast<uint32*>(rgb_buf) = (clip(C298a + cb)) |
+                                        (clip(C298a + cg) << 8) |
+                                        (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) {
+  for (int x = 0; x < width; x += 2) {
+    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];
+      YuvPixel(y1, u, v, rgb_buf + 4);
+    }
+    rgb_buf += 8;  // Advance 2 pixels.
+  }
+}
+
+}  // extern "C"
+
new file mode 100644
--- /dev/null
+++ b/gfx/ycbcr/yuv_row_linux.cpp
@@ -0,0 +1,372 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "yuv_row.h"
+
+#define DCHECK(a)
+
+// TODO(fbarchard): Move this to yuv_row_posix.cc to share with Mac.
+// TODO(fbarchard): Do 64 bit version.
+
+extern "C" {
+
+#if defined(ARCH_CPU_ARM_FAMILY)
+// ARM implementation uses C fallback
+void FastConvertYUVToRGB32Row(const uint8* y_buf,
+                              const uint8* u_buf,
+                              const uint8* v_buf,
+                              uint8* rgb_buf,
+                              int width) {
+  FastConvertYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, width);
+}
+ 
+#else
+
+#define RGBY(i) { \
+  static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
+  static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
+  static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
+  0 \
+}
+
+#define RGBU(i) { \
+  static_cast<int16>(2.018 * 64 * (i - 128) + 0.5), \
+  static_cast<int16>(-0.391 * 64 * (i - 128) + 0.5), \
+  0, \
+  static_cast<int16>(256 * 64 - 1) \
+}
+
+#define RGBV(i) { \
+  0, \
+  static_cast<int16>(-0.813 * 64 * (i - 128) + 0.5), \
+  static_cast<int16>(1.596 * 64 * (i - 128) + 0.5), \
+  0 \
+}
+
+#define MMX_ALIGNED(var) var __attribute__((aligned(16)))
+
+
+MMX_ALIGNED(int16 kCoefficientsRgbY[768][4]) = {
+  RGBY(0x00), RGBY(0x01), RGBY(0x02), RGBY(0x03),
+  RGBY(0x04), RGBY(0x05), RGBY(0x06), RGBY(0x07),
+  RGBY(0x08), RGBY(0x09), RGBY(0x0A), RGBY(0x0B),
+  RGBY(0x0C), RGBY(0x0D), RGBY(0x0E), RGBY(0x0F),
+  RGBY(0x10), RGBY(0x11), RGBY(0x12), RGBY(0x13),
+  RGBY(0x14), RGBY(0x15), RGBY(0x16), RGBY(0x17),
+  RGBY(0x18), RGBY(0x19), RGBY(0x1A), RGBY(0x1B),
+  RGBY(0x1C), RGBY(0x1D), RGBY(0x1E), RGBY(0x1F),
+  RGBY(0x20), RGBY(0x21), RGBY(0x22), RGBY(0x23),
+  RGBY(0x24), RGBY(0x25), RGBY(0x26), RGBY(0x27),
+  RGBY(0x28), RGBY(0x29), RGBY(0x2A), RGBY(0x2B),
+  RGBY(0x2C), RGBY(0x2D), RGBY(0x2E), RGBY(0x2F),
+  RGBY(0x30), RGBY(0x31), RGBY(0x32), RGBY(0x33),
+  RGBY(0x34), RGBY(0x35), RGBY(0x36), RGBY(0x37),
+  RGBY(0x38), RGBY(0x39), RGBY(0x3A), RGBY(0x3B),
+  RGBY(0x3C), RGBY(0x3D), RGBY(0x3E), RGBY(0x3F),
+  RGBY(0x40), RGBY(0x41), RGBY(0x42), RGBY(0x43),
+  RGBY(0x44), RGBY(0x45), RGBY(0x46), RGBY(0x47),
+  RGBY(0x48), RGBY(0x49), RGBY(0x4A), RGBY(0x4B),
+  RGBY(0x4C), RGBY(0x4D), RGBY(0x4E), RGBY(0x4F),
+  RGBY(0x50), RGBY(0x51), RGBY(0x52), RGBY(0x53),
+  RGBY(0x54), RGBY(0x55), RGBY(0x56), RGBY(0x57),
+  RGBY(0x58), RGBY(0x59), RGBY(0x5A), RGBY(0x5B),
+  RGBY(0x5C), RGBY(0x5D), RGBY(0x5E), RGBY(0x5F),
+  RGBY(0x60), RGBY(0x61), RGBY(0x62), RGBY(0x63),
+  RGBY(0x64), RGBY(0x65), RGBY(0x66), RGBY(0x67),
+  RGBY(0x68), RGBY(0x69), RGBY(0x6A), RGBY(0x6B),
+  RGBY(0x6C), RGBY(0x6D), RGBY(0x6E), RGBY(0x6F),
+  RGBY(0x70), RGBY(0x71), RGBY(0x72), RGBY(0x73),
+  RGBY(0x74), RGBY(0x75), RGBY(0x76), RGBY(0x77),
+  RGBY(0x78), RGBY(0x79), RGBY(0x7A), RGBY(0x7B),
+  RGBY(0x7C), RGBY(0x7D), RGBY(0x7E), RGBY(0x7F),
+  RGBY(0x80), RGBY(0x81), RGBY(0x82), RGBY(0x83),
+  RGBY(0x84), RGBY(0x85), RGBY(0x86), RGBY(0x87),
+  RGBY(0x88), RGBY(0x89), RGBY(0x8A), RGBY(0x8B),
+  RGBY(0x8C), RGBY(0x8D), RGBY(0x8E), RGBY(0x8F),
+  RGBY(0x90), RGBY(0x91), RGBY(0x92), RGBY(0x93),
+  RGBY(0x94), RGBY(0x95), RGBY(0x96), RGBY(0x97),
+  RGBY(0x98), RGBY(0x99), RGBY(0x9A), RGBY(0x9B),
+  RGBY(0x9C), RGBY(0x9D), RGBY(0x9E), RGBY(0x9F),
+  RGBY(0xA0), RGBY(0xA1), RGBY(0xA2), RGBY(0xA3),
+  RGBY(0xA4), RGBY(0xA5), RGBY(0xA6), RGBY(0xA7),
+  RGBY(0xA8), RGBY(0xA9), RGBY(0xAA), RGBY(0xAB),
+  RGBY(0xAC), RGBY(0xAD), RGBY(0xAE), RGBY(0xAF),
+  RGBY(0xB0), RGBY(0xB1), RGBY(0xB2), RGBY(0xB3),
+  RGBY(0xB4), RGBY(0xB5), RGBY(0xB6), RGBY(0xB7),
+  RGBY(0xB8), RGBY(0xB9), RGBY(0xBA), RGBY(0xBB),
+  RGBY(0xBC), RGBY(0xBD), RGBY(0xBE), RGBY(0xBF),
+  RGBY(0xC0), RGBY(0xC1), RGBY(0xC2), RGBY(0xC3),
+  RGBY(0xC4), RGBY(0xC5), RGBY(0xC6), RGBY(0xC7),
+  RGBY(0xC8), RGBY(0xC9), RGBY(0xCA), RGBY(0xCB),
+  RGBY(0xCC), RGBY(0xCD), RGBY(0xCE), RGBY(0xCF),
+  RGBY(0xD0), RGBY(0xD1), RGBY(0xD2), RGBY(0xD3),
+  RGBY(0xD4), RGBY(0xD5), RGBY(0xD6), RGBY(0xD7),
+  RGBY(0xD8), RGBY(0xD9), RGBY(0xDA), RGBY(0xDB),
+  RGBY(0xDC), RGBY(0xDD), RGBY(0xDE), RGBY(0xDF),
+  RGBY(0xE0), RGBY(0xE1), RGBY(0xE2), RGBY(0xE3),
+  RGBY(0xE4), RGBY(0xE5), RGBY(0xE6), RGBY(0xE7),
+  RGBY(0xE8), RGBY(0xE9), RGBY(0xEA), RGBY(0xEB),
+  RGBY(0xEC), RGBY(0xED), RGBY(0xEE), RGBY(0xEF),
+  RGBY(0xF0), RGBY(0xF1), RGBY(0xF2), RGBY(0xF3),
+  RGBY(0xF4), RGBY(0xF5), RGBY(0xF6), RGBY(0xF7),
+  RGBY(0xF8), RGBY(0xF9), RGBY(0xFA), RGBY(0xFB),
+  RGBY(0xFC), RGBY(0xFD), RGBY(0xFE), RGBY(0xFF),
+
+  // Chroma U table.
+  RGBU(0x00), RGBU(0x01), RGBU(0x02), RGBU(0x03),
+  RGBU(0x04), RGBU(0x05), RGBU(0x06), RGBU(0x07),
+  RGBU(0x08), RGBU(0x09), RGBU(0x0A), RGBU(0x0B),
+  RGBU(0x0C), RGBU(0x0D), RGBU(0x0E), RGBU(0x0F),
+  RGBU(0x10), RGBU(0x11), RGBU(0x12), RGBU(0x13),
+  RGBU(0x14), RGBU(0x15), RGBU(0x16), RGBU(0x17),
+  RGBU(0x18), RGBU(0x19), RGBU(0x1A), RGBU(0x1B),
+  RGBU(0x1C), RGBU(0x1D), RGBU(0x1E), RGBU(0x1F),
+  RGBU(0x20), RGBU(0x21), RGBU(0x22), RGBU(0x23),
+  RGBU(0x24), RGBU(0x25), RGBU(0x26), RGBU(0x27),
+  RGBU(0x28), RGBU(0x29), RGBU(0x2A), RGBU(0x2B),
+  RGBU(0x2C), RGBU(0x2D), RGBU(0x2E), RGBU(0x2F),
+  RGBU(0x30), RGBU(0x31), RGBU(0x32), RGBU(0x33),
+  RGBU(0x34), RGBU(0x35), RGBU(0x36), RGBU(0x37),
+  RGBU(0x38), RGBU(0x39), RGBU(0x3A), RGBU(0x3B),
+  RGBU(0x3C), RGBU(0x3D), RGBU(0x3E), RGBU(0x3F),
+  RGBU(0x40), RGBU(0x41), RGBU(0x42), RGBU(0x43),
+  RGBU(0x44), RGBU(0x45), RGBU(0x46), RGBU(0x47),
+  RGBU(0x48), RGBU(0x49), RGBU(0x4A), RGBU(0x4B),
+  RGBU(0x4C), RGBU(0x4D), RGBU(0x4E), RGBU(0x4F),
+  RGBU(0x50), RGBU(0x51), RGBU(0x52), RGBU(0x53),
+  RGBU(0x54), RGBU(0x55), RGBU(0x56), RGBU(0x57),
+  RGBU(0x58), RGBU(0x59), RGBU(0x5A), RGBU(0x5B),
+  RGBU(0x5C), RGBU(0x5D), RGBU(0x5E), RGBU(0x5F),
+  RGBU(0x60), RGBU(0x61), RGBU(0x62), RGBU(0x63),
+  RGBU(0x64), RGBU(0x65), RGBU(0x66), RGBU(0x67),
+  RGBU(0x68), RGBU(0x69), RGBU(0x6A), RGBU(0x6B),
+  RGBU(0x6C), RGBU(0x6D), RGBU(0x6E), RGBU(0x6F),
+  RGBU(0x70), RGBU(0x71), RGBU(0x72), RGBU(0x73),
+  RGBU(0x74), RGBU(0x75), RGBU(0x76), RGBU(0x77),
+  RGBU(0x78), RGBU(0x79), RGBU(0x7A), RGBU(0x7B),
+  RGBU(0x7C), RGBU(0x7D), RGBU(0x7E), RGBU(0x7F),
+  RGBU(0x80), RGBU(0x81), RGBU(0x82), RGBU(0x83),
+  RGBU(0x84), RGBU(0x85), RGBU(0x86), RGBU(0x87),
+  RGBU(0x88), RGBU(0x89), RGBU(0x8A), RGBU(0x8B),
+  RGBU(0x8C), RGBU(0x8D), RGBU(0x8E), RGBU(0x8F),
+  RGBU(0x90), RGBU(0x91), RGBU(0x92), RGBU(0x93),
+  RGBU(0x94), RGBU(0x95), RGBU(0x96), RGBU(0x97),
+  RGBU(0x98), RGBU(0x99), RGBU(0x9A), RGBU(0x9B),
+  RGBU(0x9C), RGBU(0x9D), RGBU(0x9E), RGBU(0x9F),
+  RGBU(0xA0), RGBU(0xA1), RGBU(0xA2), RGBU(0xA3),
+  RGBU(0xA4), RGBU(0xA5), RGBU(0xA6), RGBU(0xA7),
+  RGBU(0xA8), RGBU(0xA9), RGBU(0xAA), RGBU(0xAB),
+  RGBU(0xAC), RGBU(0xAD), RGBU(0xAE), RGBU(0xAF),
+  RGBU(0xB0), RGBU(0xB1), RGBU(0xB2), RGBU(0xB3),
+  RGBU(0xB4), RGBU(0xB5), RGBU(0xB6), RGBU(0xB7),
+  RGBU(0xB8), RGBU(0xB9), RGBU(0xBA), RGBU(0xBB),
+  RGBU(0xBC), RGBU(0xBD), RGBU(0xBE), RGBU(0xBF),
+  RGBU(0xC0), RGBU(0xC1), RGBU(0xC2), RGBU(0xC3),
+  RGBU(0xC4), RGBU(0xC5), RGBU(0xC6), RGBU(0xC7),
+  RGBU(0xC8), RGBU(0xC9), RGBU(0xCA), RGBU(0xCB),
+  RGBU(0xCC), RGBU(0xCD), RGBU(0xCE), RGBU(0xCF),
+  RGBU(0xD0), RGBU(0xD1), RGBU(0xD2), RGBU(0xD3),
+  RGBU(0xD4), RGBU(0xD5), RGBU(0xD6), RGBU(0xD7),
+  RGBU(0xD8), RGBU(0xD9), RGBU(0xDA), RGBU(0xDB),
+  RGBU(0xDC), RGBU(0xDD), RGBU(0xDE), RGBU(0xDF),
+  RGBU(0xE0), RGBU(0xE1), RGBU(0xE2), RGBU(0xE3),
+  RGBU(0xE4), RGBU(0xE5), RGBU(0xE6), RGBU(0xE7),
+  RGBU(0xE8), RGBU(0xE9), RGBU(0xEA), RGBU(0xEB),
+  RGBU(0xEC), RGBU(0xED), RGBU(0xEE), RGBU(0xEF),
+  RGBU(0xF0), RGBU(0xF1), RGBU(0xF2), RGBU(0xF3),
+  RGBU(0xF4), RGBU(0xF5), RGBU(0xF6), RGBU(0xF7),
+  RGBU(0xF8), RGBU(0xF9), RGBU(0xFA), RGBU(0xFB),
+  RGBU(0xFC), RGBU(0xFD), RGBU(0xFE), RGBU(0xFF),
+
+  // Chroma V table.
+  RGBV(0x00), RGBV(0x01), RGBV(0x02), RGBV(0x03),
+  RGBV(0x04), RGBV(0x05), RGBV(0x06), RGBV(0x07),
+  RGBV(0x08), RGBV(0x09), RGBV(0x0A), RGBV(0x0B),
+  RGBV(0x0C), RGBV(0x0D), RGBV(0x0E), RGBV(0x0F),
+  RGBV(0x10), RGBV(0x11), RGBV(0x12), RGBV(0x13),
+  RGBV(0x14), RGBV(0x15), RGBV(0x16), RGBV(0x17),
+  RGBV(0x18), RGBV(0x19), RGBV(0x1A), RGBV(0x1B),
+  RGBV(0x1C), RGBV(0x1D), RGBV(0x1E), RGBV(0x1F),
+  RGBV(0x20), RGBV(0x21), RGBV(0x22), RGBV(0x23),
+  RGBV(0x24), RGBV(0x25), RGBV(0x26), RGBV(0x27),
+  RGBV(0x28), RGBV(0x29), RGBV(0x2A), RGBV(0x2B),
+  RGBV(0x2C), RGBV(0x2D), RGBV(0x2E), RGBV(0x2F),
+  RGBV(0x30), RGBV(0x31), RGBV(0x32), RGBV(0x33),
+  RGBV(0x34), RGBV(0x35), RGBV(0x36), RGBV(0x37),
+  RGBV(0x38), RGBV(0x39), RGBV(0x3A), RGBV(0x3B),
+  RGBV(0x3C), RGBV(0x3D), RGBV(0x3E), RGBV(0x3F),
+  RGBV(0x40), RGBV(0x41), RGBV(0x42), RGBV(0x43),
+  RGBV(0x44), RGBV(0x45), RGBV(0x46), RGBV(0x47),
+  RGBV(0x48), RGBV(0x49), RGBV(0x4A), RGBV(0x4B),
+  RGBV(0x4C), RGBV(0x4D), RGBV(0x4E), RGBV(0x4F),
+  RGBV(0x50), RGBV(0x51), RGBV(0x52), RGBV(0x53),
+  RGBV(0x54), RGBV(0x55), RGBV(0x56), RGBV(0x57),
+  RGBV(0x58), RGBV(0x59), RGBV(0x5A), RGBV(0x5B),
+  RGBV(0x5C), RGBV(0x5D), RGBV(0x5E), RGBV(0x5F),
+  RGBV(0x60), RGBV(0x61), RGBV(0x62), RGBV(0x63),
+  RGBV(0x64), RGBV(0x65), RGBV(0x66), RGBV(0x67),
+  RGBV(0x68), RGBV(0x69), RGBV(0x6A), RGBV(0x6B),
+  RGBV(0x6C), RGBV(0x6D), RGBV(0x6E), RGBV(0x6F),
+  RGBV(0x70), RGBV(0x71), RGBV(0x72), RGBV(0x73),
+  RGBV(0x74), RGBV(0x75), RGBV(0x76), RGBV(0x77),
+  RGBV(0x78), RGBV(0x79), RGBV(0x7A), RGBV(0x7B),
+  RGBV(0x7C), RGBV(0x7D), RGBV(0x7E), RGBV(0x7F),
+  RGBV(0x80), RGBV(0x81), RGBV(0x82), RGBV(0x83),
+  RGBV(0x84), RGBV(0x85), RGBV(0x86), RGBV(0x87),
+  RGBV(0x88), RGBV(0x89), RGBV(0x8A), RGBV(0x8B),
+  RGBV(0x8C), RGBV(0x8D), RGBV(0x8E), RGBV(0x8F),
+  RGBV(0x90), RGBV(0x91), RGBV(0x92), RGBV(0x93),
+  RGBV(0x94), RGBV(0x95), RGBV(0x96), RGBV(0x97),
+  RGBV(0x98), RGBV(0x99), RGBV(0x9A), RGBV(0x9B),
+  RGBV(0x9C), RGBV(0x9D), RGBV(0x9E), RGBV(0x9F),
+  RGBV(0xA0), RGBV(0xA1), RGBV(0xA2), RGBV(0xA3),
+  RGBV(0xA4), RGBV(0xA5), RGBV(0xA6), RGBV(0xA7),
+  RGBV(0xA8), RGBV(0xA9), RGBV(0xAA), RGBV(0xAB),
+  RGBV(0xAC), RGBV(0xAD), RGBV(0xAE), RGBV(0xAF),
+  RGBV(0xB0), RGBV(0xB1), RGBV(0xB2), RGBV(0xB3),
+  RGBV(0xB4), RGBV(0xB5), RGBV(0xB6), RGBV(0xB7),
+  RGBV(0xB8), RGBV(0xB9), RGBV(0xBA), RGBV(0xBB),
+  RGBV(0xBC), RGBV(0xBD), RGBV(0xBE), RGBV(0xBF),
+  RGBV(0xC0), RGBV(0xC1), RGBV(0xC2), RGBV(0xC3),
+  RGBV(0xC4), RGBV(0xC5), RGBV(0xC6), RGBV(0xC7),
+  RGBV(0xC8), RGBV(0xC9), RGBV(0xCA), RGBV(0xCB),
+  RGBV(0xCC), RGBV(0xCD), RGBV(0xCE), RGBV(0xCF),
+  RGBV(0xD0), RGBV(0xD1), RGBV(0xD2), RGBV(0xD3),
+  RGBV(0xD4), RGBV(0xD5), RGBV(0xD6), RGBV(0xD7),
+  RGBV(0xD8), RGBV(0xD9), RGBV(0xDA), RGBV(0xDB),
+  RGBV(0xDC), RGBV(0xDD), RGBV(0xDE), RGBV(0xDF),
+  RGBV(0xE0), RGBV(0xE1), RGBV(0xE2), RGBV(0xE3),
+  RGBV(0xE4), RGBV(0xE5), RGBV(0xE6), RGBV(0xE7),
+  RGBV(0xE8), RGBV(0xE9), RGBV(0xEA), RGBV(0xEB),
+  RGBV(0xEC), RGBV(0xED), RGBV(0xEE), RGBV(0xEF),
+  RGBV(0xF0), RGBV(0xF1), RGBV(0xF2), RGBV(0xF3),
+  RGBV(0xF4), RGBV(0xF5), RGBV(0xF6), RGBV(0xF7),
+  RGBV(0xF8), RGBV(0xF9), RGBV(0xFA), RGBV(0xFB),
+  RGBV(0xFC), RGBV(0xFD), RGBV(0xFE), RGBV(0xFF),
+};
+
+#if defined(ARCH_CPU_X86_64)
+
+// AMD64 ABI uses register paremters.
+void FastConvertYUVToRGB32Row(const uint8* y_buf,  // rdi
+                              const uint8* u_buf,  // rsi
+                              const uint8* v_buf,  // rdx
+                              uint8* rgb_buf,      // rcx
+                              int width) {         // r8
+  asm(
+  "jmp    convertend\n"
+"convertloop:"
+  "movzb  (%1),%%r10\n"
+  "add    $0x1,%1\n"
+  "movzb  (%2),%%r11\n"
+  "add    $0x1,%2\n"
+  "movq   2048(%5,%%r10,8),%%xmm0\n"
+  "movzb  (%0),%%r10\n"
+  "movq   4096(%5,%%r11,8),%%xmm1\n"
+  "movzb  0x1(%0),%%r11\n"
+  "paddsw %%xmm1,%%xmm0\n"
+  "movq   (%5,%%r10,8),%%xmm2\n"
+  "add    $0x2,%0\n"
+  "movq   (%5,%%r11,8),%%xmm3\n"
+  "paddsw %%xmm0,%%xmm2\n"
+  "paddsw %%xmm0,%%xmm3\n"
+  "shufps $0x44,%%xmm3,%%xmm2\n"
+  "psraw  $0x6,%%xmm2\n"
+  "packuswb %%xmm2,%%xmm2\n"
+  "movq   %%xmm2,0x0(%3)\n"
+  "add    $0x8,%3\n"
+"convertend:"
+  "sub    $0x2,%4\n"
+  "jns    convertloop\n"
+
+"convertnext:"
+  "add    $0x1,%4\n"
+  "js     convertdone\n"
+
+  "movzb  (%1),%%r10\n"
+  "movq   2048(%5,%%r10,8),%%xmm0\n"
+  "movzb  (%2),%%r10\n"
+  "movq   4096(%5,%%r10,8),%%xmm1\n"
+  "paddsw %%xmm1,%%xmm0\n"
+  "movzb  (%0),%%r10\n"
+  "movq   (%5,%%r10,8),%%xmm1\n"
+  "paddsw %%xmm0,%%xmm1\n"
+  "psraw  $0x6,%%xmm1\n"
+  "packuswb %%xmm1,%%xmm1\n"
+  "movd   %%xmm1,0x0(%3)\n"
+"convertdone:"
+  :
+  : "r"(y_buf),  // %0
+    "r"(u_buf),  // %1
+    "r"(v_buf),  // %2
+    "r"(rgb_buf),  // %3
+    "r"(width),  // %4
+    "r" (kCoefficientsRgbY)  // %5
+  : "memory", "r10", "r11", "xmm0", "xmm1", "xmm2", "xmm3"
+);
+}
+
+#else
+
+void FastConvertYUVToRGB32Row(const uint8* y_buf,
+                              const uint8* u_buf,
+                              const uint8* v_buf,
+                              uint8* rgb_buf,
+                              int width);
+  asm(
+  ".global FastConvertYUVToRGB32Row\n"
+"FastConvertYUVToRGB32Row:\n"
+  "pusha\n"
+  "mov    0x24(%esp),%edx\n"
+  "mov    0x28(%esp),%edi\n"
+  "mov    0x2c(%esp),%esi\n"
+  "mov    0x30(%esp),%ebp\n"
+  "mov    0x34(%esp),%ecx\n"
+  "jmp    convertend\n"
+
+"convertloop:"
+  "movzbl (%edi),%eax\n"
+  "add    $0x1,%edi\n"
+  "movzbl (%esi),%ebx\n"
+  "add    $0x1,%esi\n"
+  "movq   kCoefficientsRgbY+2048(,%eax,8),%mm0\n"
+  "movzbl (%edx),%eax\n"
+  "paddsw kCoefficientsRgbY+4096(,%ebx,8),%mm0\n"
+  "movzbl 0x1(%edx),%ebx\n"
+  "movq   kCoefficientsRgbY(,%eax,8),%mm1\n"
+  "add    $0x2,%edx\n"
+  "movq   kCoefficientsRgbY(,%ebx,8),%mm2\n"
+  "paddsw %mm0,%mm1\n"
+  "paddsw %mm0,%mm2\n"
+  "psraw  $0x6,%mm1\n"
+  "psraw  $0x6,%mm2\n"
+  "packuswb %mm2,%mm1\n"
+  "movntq %mm1,0x0(%ebp)\n"
+  "add    $0x8,%ebp\n"
+"convertend:"
+  "sub    $0x2,%ecx\n"
+  "jns    convertloop\n"
+
+  "and    $0x1,%ecx\n"
+  "je     convertdone\n"
+
+  "movzbl (%edi),%eax\n"
+  "movq   kCoefficientsRgbY+2048(,%eax,8),%mm0\n"
+  "movzbl (%esi),%eax\n"
+  "paddsw kCoefficientsRgbY+4096(,%eax,8),%mm0\n"
+  "movzbl (%edx),%eax\n"
+  "movq   kCoefficientsRgbY(,%eax,8),%mm1\n"
+  "paddsw %mm0,%mm1\n"
+  "psraw  $0x6,%mm1\n"
+  "packuswb %mm1,%mm1\n"
+  "movd   %mm1,0x0(%ebp)\n"
+"convertdone:"
+  "popa\n"
+  "ret\n"
+);
+
+#endif
+#endif // ARCH_CPU_ARM_FAMILY
+}  // extern "C"
+
new file mode 100644
--- /dev/null
+++ b/gfx/ycbcr/yuv_row_mac.cpp
@@ -0,0 +1,320 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "yuv_row.h"
+
+// TODO(fbarchard): Do 64 bit version.
+
+extern "C" {
+
+#if defined(ARCH_CPU_PPC)
+// PPC implementation uses C fallback
+void FastConvertYUVToRGB32Row(const uint8* y_buf,
+                              const uint8* u_buf,
+                              const uint8* v_buf,
+                              uint8* rgb_buf,
+                              int width) {
+  FastConvertYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, width);
+}
+ 
+#else
+
+#define RGBY(i) { \
+  static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
+  static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
+  static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
+  0 \
+}
+
+#define RGBU(i) { \
+  static_cast<int16>(2.018 * 64 * (i - 128) + 0.5), \
+  static_cast<int16>(-0.391 * 64 * (i - 128) + 0.5), \
+  0, \
+  static_cast<int16>(256 * 64 - 1) \
+}
+
+#define RGBV(i) { \
+  0, \
+  static_cast<int16>(-0.813 * 64 * (i - 128) + 0.5), \
+  static_cast<int16>(1.596 * 64 * (i - 128) + 0.5), \
+  0 \
+}
+
+#define MMX_ALIGNED(var) \
+  var __attribute__ ((section ("__TEXT,__text"))) __attribute__ ((aligned(16)))
+
+MMX_ALIGNED(int16 kCoefficientsRgbY[768][4]) = {
+  RGBY(0x00), RGBY(0x01), RGBY(0x02), RGBY(0x03),
+  RGBY(0x04), RGBY(0x05), RGBY(0x06), RGBY(0x07),
+  RGBY(0x08), RGBY(0x09), RGBY(0x0A), RGBY(0x0B),
+  RGBY(0x0C), RGBY(0x0D), RGBY(0x0E), RGBY(0x0F),
+  RGBY(0x10), RGBY(0x11), RGBY(0x12), RGBY(0x13),
+  RGBY(0x14), RGBY(0x15), RGBY(0x16), RGBY(0x17),
+  RGBY(0x18), RGBY(0x19), RGBY(0x1A), RGBY(0x1B),
+  RGBY(0x1C), RGBY(0x1D), RGBY(0x1E), RGBY(0x1F),
+  RGBY(0x20), RGBY(0x21), RGBY(0x22), RGBY(0x23),
+  RGBY(0x24), RGBY(0x25), RGBY(0x26), RGBY(0x27),
+  RGBY(0x28), RGBY(0x29), RGBY(0x2A), RGBY(0x2B),
+  RGBY(0x2C), RGBY(0x2D), RGBY(0x2E), RGBY(0x2F),
+  RGBY(0x30), RGBY(0x31), RGBY(0x32), RGBY(0x33),
+  RGBY(0x34), RGBY(0x35), RGBY(0x36), RGBY(0x37),
+  RGBY(0x38), RGBY(0x39), RGBY(0x3A), RGBY(0x3B),
+  RGBY(0x3C), RGBY(0x3D), RGBY(0x3E), RGBY(0x3F),
+  RGBY(0x40), RGBY(0x41), RGBY(0x42), RGBY(0x43),
+  RGBY(0x44), RGBY(0x45), RGBY(0x46), RGBY(0x47),
+  RGBY(0x48), RGBY(0x49), RGBY(0x4A), RGBY(0x4B),
+  RGBY(0x4C), RGBY(0x4D), RGBY(0x4E), RGBY(0x4F),
+  RGBY(0x50), RGBY(0x51), RGBY(0x52), RGBY(0x53),
+  RGBY(0x54), RGBY(0x55), RGBY(0x56), RGBY(0x57),
+  RGBY(0x58), RGBY(0x59), RGBY(0x5A), RGBY(0x5B),
+  RGBY(0x5C), RGBY(0x5D), RGBY(0x5E), RGBY(0x5F),
+  RGBY(0x60), RGBY(0x61), RGBY(0x62), RGBY(0x63),
+  RGBY(0x64), RGBY(0x65), RGBY(0x66), RGBY(0x67),
+  RGBY(0x68), RGBY(0x69), RGBY(0x6A), RGBY(0x6B),
+  RGBY(0x6C), RGBY(0x6D), RGBY(0x6E), RGBY(0x6F),
+  RGBY(0x70), RGBY(0x71), RGBY(0x72), RGBY(0x73),
+  RGBY(0x74), RGBY(0x75), RGBY(0x76), RGBY(0x77),
+  RGBY(0x78), RGBY(0x79), RGBY(0x7A), RGBY(0x7B),
+  RGBY(0x7C), RGBY(0x7D), RGBY(0x7E), RGBY(0x7F),
+  RGBY(0x80), RGBY(0x81), RGBY(0x82), RGBY(0x83),
+  RGBY(0x84), RGBY(0x85), RGBY(0x86), RGBY(0x87),
+  RGBY(0x88), RGBY(0x89), RGBY(0x8A), RGBY(0x8B),
+  RGBY(0x8C), RGBY(0x8D), RGBY(0x8E), RGBY(0x8F),
+  RGBY(0x90), RGBY(0x91), RGBY(0x92), RGBY(0x93),
+  RGBY(0x94), RGBY(0x95), RGBY(0x96), RGBY(0x97),
+  RGBY(0x98), RGBY(0x99), RGBY(0x9A), RGBY(0x9B),
+  RGBY(0x9C), RGBY(0x9D), RGBY(0x9E), RGBY(0x9F),
+  RGBY(0xA0), RGBY(0xA1), RGBY(0xA2), RGBY(0xA3),
+  RGBY(0xA4), RGBY(0xA5), RGBY(0xA6), RGBY(0xA7),
+  RGBY(0xA8), RGBY(0xA9), RGBY(0xAA), RGBY(0xAB),
+  RGBY(0xAC), RGBY(0xAD), RGBY(0xAE), RGBY(0xAF),
+  RGBY(0xB0), RGBY(0xB1), RGBY(0xB2), RGBY(0xB3),
+  RGBY(0xB4), RGBY(0xB5), RGBY(0xB6), RGBY(0xB7),
+  RGBY(0xB8), RGBY(0xB9), RGBY(0xBA), RGBY(0xBB),
+  RGBY(0xBC), RGBY(0xBD), RGBY(0xBE), RGBY(0xBF),
+  RGBY(0xC0), RGBY(0xC1), RGBY(0xC2), RGBY(0xC3),
+  RGBY(0xC4), RGBY(0xC5), RGBY(0xC6), RGBY(0xC7),
+  RGBY(0xC8), RGBY(0xC9), RGBY(0xCA), RGBY(0xCB),
+  RGBY(0xCC), RGBY(0xCD), RGBY(0xCE), RGBY(0xCF),
+  RGBY(0xD0), RGBY(0xD1), RGBY(0xD2), RGBY(0xD3),
+  RGBY(0xD4), RGBY(0xD5), RGBY(0xD6), RGBY(0xD7),
+  RGBY(0xD8), RGBY(0xD9), RGBY(0xDA), RGBY(0xDB),
+  RGBY(0xDC), RGBY(0xDD), RGBY(0xDE), RGBY(0xDF),
+  RGBY(0xE0), RGBY(0xE1), RGBY(0xE2), RGBY(0xE3),
+  RGBY(0xE4), RGBY(0xE5), RGBY(0xE6), RGBY(0xE7),
+  RGBY(0xE8), RGBY(0xE9), RGBY(0xEA), RGBY(0xEB),
+  RGBY(0xEC), RGBY(0xED), RGBY(0xEE), RGBY(0xEF),
+  RGBY(0xF0), RGBY(0xF1), RGBY(0xF2), RGBY(0xF3),
+  RGBY(0xF4), RGBY(0xF5), RGBY(0xF6), RGBY(0xF7),
+  RGBY(0xF8), RGBY(0xF9), RGBY(0xFA), RGBY(0xFB),
+  RGBY(0xFC), RGBY(0xFD), RGBY(0xFE), RGBY(0xFF),
+
+  // Chroma U table.
+  RGBU(0x00), RGBU(0x01), RGBU(0x02), RGBU(0x03),
+  RGBU(0x04), RGBU(0x05), RGBU(0x06), RGBU(0x07),
+  RGBU(0x08), RGBU(0x09), RGBU(0x0A), RGBU(0x0B),
+  RGBU(0x0C), RGBU(0x0D), RGBU(0x0E), RGBU(0x0F),
+  RGBU(0x10), RGBU(0x11), RGBU(0x12), RGBU(0x13),
+  RGBU(0x14), RGBU(0x15), RGBU(0x16), RGBU(0x17),
+  RGBU(0x18), RGBU(0x19), RGBU(0x1A), RGBU(0x1B),
+  RGBU(0x1C), RGBU(0x1D), RGBU(0x1E), RGBU(0x1F),
+  RGBU(0x20), RGBU(0x21), RGBU(0x22), RGBU(0x23),
+  RGBU(0x24), RGBU(0x25), RGBU(0x26), RGBU(0x27),
+  RGBU(0x28), RGBU(0x29), RGBU(0x2A), RGBU(0x2B),
+  RGBU(0x2C), RGBU(0x2D), RGBU(0x2E), RGBU(0x2F),
+  RGBU(0x30), RGBU(0x31), RGBU(0x32), RGBU(0x33),
+  RGBU(0x34), RGBU(0x35), RGBU(0x36), RGBU(0x37),
+  RGBU(0x38), RGBU(0x39), RGBU(0x3A), RGBU(0x3B),
+  RGBU(0x3C), RGBU(0x3D), RGBU(0x3E), RGBU(0x3F),
+  RGBU(0x40), RGBU(0x41), RGBU(0x42), RGBU(0x43),
+  RGBU(0x44), RGBU(0x45), RGBU(0x46), RGBU(0x47),
+  RGBU(0x48), RGBU(0x49), RGBU(0x4A), RGBU(0x4B),
+  RGBU(0x4C), RGBU(0x4D), RGBU(0x4E), RGBU(0x4F),
+  RGBU(0x50), RGBU(0x51), RGBU(0x52), RGBU(0x53),
+  RGBU(0x54), RGBU(0x55), RGBU(0x56), RGBU(0x57),
+  RGBU(0x58), RGBU(0x59), RGBU(0x5A), RGBU(0x5B),
+  RGBU(0x5C), RGBU(0x5D), RGBU(0x5E), RGBU(0x5F),
+  RGBU(0x60), RGBU(0x61), RGBU(0x62), RGBU(0x63),
+  RGBU(0x64), RGBU(0x65), RGBU(0x66), RGBU(0x67),
+  RGBU(0x68), RGBU(0x69), RGBU(0x6A), RGBU(0x6B),
+  RGBU(0x6C), RGBU(0x6D), RGBU(0x6E), RGBU(0x6F),
+  RGBU(0x70), RGBU(0x71), RGBU(0x72), RGBU(0x73),
+  RGBU(0x74), RGBU(0x75), RGBU(0x76), RGBU(0x77),
+  RGBU(0x78), RGBU(0x79), RGBU(0x7A), RGBU(0x7B),
+  RGBU(0x7C), RGBU(0x7D), RGBU(0x7E), RGBU(0x7F),
+  RGBU(0x80), RGBU(0x81), RGBU(0x82), RGBU(0x83),
+  RGBU(0x84), RGBU(0x85), RGBU(0x86), RGBU(0x87),
+  RGBU(0x88), RGBU(0x89), RGBU(0x8A), RGBU(0x8B),
+  RGBU(0x8C), RGBU(0x8D), RGBU(0x8E), RGBU(0x8F),
+  RGBU(0x90), RGBU(0x91), RGBU(0x92), RGBU(0x93),
+  RGBU(0x94), RGBU(0x95), RGBU(0x96), RGBU(0x97),
+  RGBU(0x98), RGBU(0x99), RGBU(0x9A), RGBU(0x9B),
+  RGBU(0x9C), RGBU(0x9D), RGBU(0x9E), RGBU(0x9F),
+  RGBU(0xA0), RGBU(0xA1), RGBU(0xA2), RGBU(0xA3),
+  RGBU(0xA4), RGBU(0xA5), RGBU(0xA6), RGBU(0xA7),
+  RGBU(0xA8), RGBU(0xA9), RGBU(0xAA), RGBU(0xAB),
+  RGBU(0xAC), RGBU(0xAD), RGBU(0xAE), RGBU(0xAF),
+  RGBU(0xB0), RGBU(0xB1), RGBU(0xB2), RGBU(0xB3),
+  RGBU(0xB4), RGBU(0xB5), RGBU(0xB6), RGBU(0xB7),
+  RGBU(0xB8), RGBU(0xB9), RGBU(0xBA), RGBU(0xBB),
+  RGBU(0xBC), RGBU(0xBD), RGBU(0xBE), RGBU(0xBF),
+  RGBU(0xC0), RGBU(0xC1), RGBU(0xC2), RGBU(0xC3),
+  RGBU(0xC4), RGBU(0xC5), RGBU(0xC6), RGBU(0xC7),
+  RGBU(0xC8), RGBU(0xC9), RGBU(0xCA), RGBU(0xCB),
+  RGBU(0xCC), RGBU(0xCD), RGBU(0xCE), RGBU(0xCF),
+  RGBU(0xD0), RGBU(0xD1), RGBU(0xD2), RGBU(0xD3),
+  RGBU(0xD4), RGBU(0xD5), RGBU(0xD6), RGBU(0xD7),
+  RGBU(0xD8), RGBU(0xD9), RGBU(0xDA), RGBU(0xDB),
+  RGBU(0xDC), RGBU(0xDD), RGBU(0xDE), RGBU(0xDF),
+  RGBU(0xE0), RGBU(0xE1), RGBU(0xE2), RGBU(0xE3),
+  RGBU(0xE4), RGBU(0xE5), RGBU(0xE6), RGBU(0xE7),
+  RGBU(0xE8), RGBU(0xE9), RGBU(0xEA), RGBU(0xEB),
+  RGBU(0xEC), RGBU(0xED), RGBU(0xEE), RGBU(0xEF),
+  RGBU(0xF0), RGBU(0xF1), RGBU(0xF2), RGBU(0xF3),
+  RGBU(0xF4), RGBU(0xF5), RGBU(0xF6), RGBU(0xF7),
+  RGBU(0xF8), RGBU(0xF9), RGBU(0xFA), RGBU(0xFB),
+  RGBU(0xFC), RGBU(0xFD), RGBU(0xFE), RGBU(0xFF),
+
+  // Chroma V table.
+  RGBV(0x00), RGBV(0x01), RGBV(0x02), RGBV(0x03),
+  RGBV(0x04), RGBV(0x05), RGBV(0x06), RGBV(0x07),
+  RGBV(0x08), RGBV(0x09), RGBV(0x0A), RGBV(0x0B),
+  RGBV(0x0C), RGBV(0x0D), RGBV(0x0E), RGBV(0x0F),
+  RGBV(0x10), RGBV(0x11), RGBV(0x12), RGBV(0x13),
+  RGBV(0x14), RGBV(0x15), RGBV(0x16), RGBV(0x17),
+  RGBV(0x18), RGBV(0x19), RGBV(0x1A), RGBV(0x1B),
+  RGBV(0x1C), RGBV(0x1D), RGBV(0x1E), RGBV(0x1F),
+  RGBV(0x20), RGBV(0x21), RGBV(0x22), RGBV(0x23),
+  RGBV(0x24), RGBV(0x25), RGBV(0x26), RGBV(0x27),
+  RGBV(0x28), RGBV(0x29), RGBV(0x2A), RGBV(0x2B),
+  RGBV(0x2C), RGBV(0x2D), RGBV(0x2E), RGBV(0x2F),
+  RGBV(0x30), RGBV(0x31), RGBV(0x32), RGBV(0x33),
+  RGBV(0x34), RGBV(0x35), RGBV(0x36), RGBV(0x37),
+  RGBV(0x38), RGBV(0x39), RGBV(0x3A), RGBV(0x3B),
+  RGBV(0x3C), RGBV(0x3D), RGBV(0x3E), RGBV(0x3F),
+  RGBV(0x40), RGBV(0x41), RGBV(0x42), RGBV(0x43),
+  RGBV(0x44), RGBV(0x45), RGBV(0x46), RGBV(0x47),
+  RGBV(0x48), RGBV(0x49), RGBV(0x4A), RGBV(0x4B),
+  RGBV(0x4C), RGBV(0x4D), RGBV(0x4E), RGBV(0x4F),
+  RGBV(0x50), RGBV(0x51), RGBV(0x52), RGBV(0x53),
+  RGBV(0x54), RGBV(0x55), RGBV(0x56), RGBV(0x57),
+  RGBV(0x58), RGBV(0x59), RGBV(0x5A), RGBV(0x5B),
+  RGBV(0x5C), RGBV(0x5D), RGBV(0x5E), RGBV(0x5F),
+  RGBV(0x60), RGBV(0x61), RGBV(0x62), RGBV(0x63),
+  RGBV(0x64), RGBV(0x65), RGBV(0x66), RGBV(0x67),
+  RGBV(0x68), RGBV(0x69), RGBV(0x6A), RGBV(0x6B),
+  RGBV(0x6C), RGBV(0x6D), RGBV(0x6E), RGBV(0x6F),
+  RGBV(0x70), RGBV(0x71), RGBV(0x72), RGBV(0x73),
+  RGBV(0x74), RGBV(0x75), RGBV(0x76), RGBV(0x77),
+  RGBV(0x78), RGBV(0x79), RGBV(0x7A), RGBV(0x7B),
+  RGBV(0x7C), RGBV(0x7D), RGBV(0x7E), RGBV(0x7F),
+  RGBV(0x80), RGBV(0x81), RGBV(0x82), RGBV(0x83),
+  RGBV(0x84), RGBV(0x85), RGBV(0x86), RGBV(0x87),
+  RGBV(0x88), RGBV(0x89), RGBV(0x8A), RGBV(0x8B),
+  RGBV(0x8C), RGBV(0x8D), RGBV(0x8E), RGBV(0x8F),
+  RGBV(0x90), RGBV(0x91), RGBV(0x92), RGBV(0x93),
+  RGBV(0x94), RGBV(0x95), RGBV(0x96), RGBV(0x97),
+  RGBV(0x98), RGBV(0x99), RGBV(0x9A), RGBV(0x9B),
+  RGBV(0x9C), RGBV(0x9D), RGBV(0x9E), RGBV(0x9F),
+  RGBV(0xA0), RGBV(0xA1), RGBV(0xA2), RGBV(0xA3),
+  RGBV(0xA4), RGBV(0xA5), RGBV(0xA6), RGBV(0xA7),
+  RGBV(0xA8), RGBV(0xA9), RGBV(0xAA), RGBV(0xAB),
+  RGBV(0xAC), RGBV(0xAD), RGBV(0xAE), RGBV(0xAF),
+  RGBV(0xB0), RGBV(0xB1), RGBV(0xB2), RGBV(0xB3),
+  RGBV(0xB4), RGBV(0xB5), RGBV(0xB6), RGBV(0xB7),
+  RGBV(0xB8), RGBV(0xB9), RGBV(0xBA), RGBV(0xBB),
+  RGBV(0xBC), RGBV(0xBD), RGBV(0xBE), RGBV(0xBF),
+  RGBV(0xC0), RGBV(0xC1), RGBV(0xC2), RGBV(0xC3),
+  RGBV(0xC4), RGBV(0xC5), RGBV(0xC6), RGBV(0xC7),
+  RGBV(0xC8), RGBV(0xC9), RGBV(0xCA), RGBV(0xCB),
+  RGBV(0xCC), RGBV(0xCD), RGBV(0xCE), RGBV(0xCF),
+  RGBV(0xD0), RGBV(0xD1), RGBV(0xD2), RGBV(0xD3),
+  RGBV(0xD4), RGBV(0xD5), RGBV(0xD6), RGBV(0xD7),
+  RGBV(0xD8), RGBV(0xD9), RGBV(0xDA), RGBV(0xDB),
+  RGBV(0xDC), RGBV(0xDD), RGBV(0xDE), RGBV(0xDF),
+  RGBV(0xE0), RGBV(0xE1), RGBV(0xE2), RGBV(0xE3),
+  RGBV(0xE4), RGBV(0xE5), RGBV(0xE6), RGBV(0xE7),
+  RGBV(0xE8), RGBV(0xE9), RGBV(0xEA), RGBV(0xEB),
+  RGBV(0xEC), RGBV(0xED), RGBV(0xEE), RGBV(0xEF),
+  RGBV(0xF0), RGBV(0xF1), RGBV(0xF2), RGBV(0xF3),
+  RGBV(0xF4), RGBV(0xF5), RGBV(0xF6), RGBV(0xF7),
+  RGBV(0xF8), RGBV(0xF9), RGBV(0xFA), RGBV(0xFB),
+  RGBV(0xFC), RGBV(0xFD), RGBV(0xFE), RGBV(0xFF),
+};
+
+#undef RGBY
+#undef RGBU
+#undef RGBV
+#undef MMX_ALIGNED
+
+extern void MacConvertYUVToRGB32Row(const uint8* y_buf,
+                                    const uint8* u_buf,
+                                    const uint8* v_buf,
+                                    uint8* rgb_buf,
+                                    int width,
+                                    int16 *kCoefficientsRgbY);
+  __asm__(
+"_MacConvertYUVToRGB32Row:\n"
+  "pusha\n"
+  "mov    0x24(%esp),%edx\n"
+  "mov    0x28(%esp),%edi\n"
+  "mov    0x2c(%esp),%esi\n"
+  "mov    0x30(%esp),%ebp\n"
+  "mov    0x38(%esp),%ecx\n"
+
+  "jmp    Lconvertend\n"
+
+"Lconvertloop:"
+  "movzbl (%edi),%eax\n"
+  "add    $0x1,%edi\n"
+  "movzbl (%esi),%ebx\n"
+  "add    $0x1,%esi\n"
+  "movq   2048(%ecx,%eax,8),%mm0\n"
+  "movzbl (%edx),%eax\n"
+  "paddsw 4096(%ecx,%ebx,8),%mm0\n"
+  "movzbl 0x1(%edx),%ebx\n"
+  "movq   0(%ecx,%eax,8),%mm1\n"
+  "add    $0x2,%edx\n"
+  "movq   0(%ecx,%ebx,8),%mm2\n"
+  "paddsw %mm0,%mm1\n"
+  "paddsw %mm0,%mm2\n"
+  "psraw  $0x6,%mm1\n"
+  "psraw  $0x6,%mm2\n"
+  "packuswb %mm2,%mm1\n"
+  "movntq %mm1,0x0(%ebp)\n"
+  "add    $0x8,%ebp\n"
+"Lconvertend:"
+  "sub    $0x2,0x34(%esp)\n"
+  "jns    Lconvertloop\n"
+
+  "and    $0x1,0x34(%esp)\n"
+  "je     Lconvertdone\n"
+
+  "movzbl (%edi),%eax\n"
+  "movq   2048(%ecx,%eax,8),%mm0\n"
+  "movzbl (%esi),%eax\n"
+  "paddsw 4096(%ecx,%eax,8),%mm0\n"
+  "movzbl (%edx),%eax\n"
+  "movq   0(%ecx,%eax,8),%mm1\n"
+  "paddsw %mm0,%mm1\n"
+  "psraw  $0x6,%mm1\n"
+  "packuswb %mm1,%mm1\n"
+  "movd   %mm1,0x0(%ebp)\n"
+"Lconvertdone:\n"
+  "popa\n"
+  "ret\n"
+);
+
+void FastConvertYUVToRGB32Row(const uint8* y_buf,
+                              const uint8* u_buf,
+                              const uint8* v_buf,
+                              uint8* rgb_buf,
+                              int width) {
+  MacConvertYUVToRGB32Row(y_buf, u_buf, v_buf, rgb_buf, width,
+                          &kCoefficientsRgbY[0][0]);
+}
+
+#endif // ARCH_CPU_PPC 
+}  // extern "C"
+
new file mode 100644
--- /dev/null
+++ b/gfx/ycbcr/yuv_row_win.cpp
@@ -0,0 +1,301 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "yuv_row.h"
+
+extern "C" {
+#define RGBY(i) { \
+  static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
+  static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
+  static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
+  0 \
+}
+
+#define RGBU(i) { \
+  static_cast<int16>(2.018 * 64 * (i - 128) + 0.5), \
+  static_cast<int16>(-0.391 * 64 * (i - 128) + 0.5), \
+  0, \
+  static_cast<int16>(256 * 64 - 1) \
+}
+
+#define RGBV(i) { \
+  0, \
+  static_cast<int16>(-0.813 * 64 * (i - 128) + 0.5), \
+  static_cast<int16>(1.596 * 64 * (i - 128) + 0.5), \
+  0 \
+}
+
+#define MMX_ALIGNED(var) __declspec(align(16)) var
+
+MMX_ALIGNED(int16 kCoefficientsRgbY[256][4]) = {
+  RGBY(0x00), RGBY(0x01), RGBY(0x02), RGBY(0x03),
+  RGBY(0x04), RGBY(0x05), RGBY(0x06), RGBY(0x07),
+  RGBY(0x08), RGBY(0x09), RGBY(0x0A), RGBY(0x0B),
+  RGBY(0x0C), RGBY(0x0D), RGBY(0x0E), RGBY(0x0F),
+  RGBY(0x10), RGBY(0x11), RGBY(0x12), RGBY(0x13),
+  RGBY(0x14), RGBY(0x15), RGBY(0x16), RGBY(0x17),
+  RGBY(0x18), RGBY(0x19), RGBY(0x1A), RGBY(0x1B),
+  RGBY(0x1C), RGBY(0x1D), RGBY(0x1E), RGBY(0x1F),
+  RGBY(0x20), RGBY(0x21), RGBY(0x22), RGBY(0x23),
+  RGBY(0x24), RGBY(0x25), RGBY(0x26), RGBY(0x27),
+  RGBY(0x28), RGBY(0x29), RGBY(0x2A), RGBY(0x2B),
+  RGBY(0x2C), RGBY(0x2D), RGBY(0x2E), RGBY(0x2F),
+  RGBY(0x30), RGBY(0x31), RGBY(0x32), RGBY(0x33),
+  RGBY(0x34), RGBY(0x35), RGBY(0x36), RGBY(0x37),
+  RGBY(0x38), RGBY(0x39), RGBY(0x3A), RGBY(0x3B),
+  RGBY(0x3C), RGBY(0x3D), RGBY(0x3E), RGBY(0x3F),
+  RGBY(0x40), RGBY(0x41), RGBY(0x42), RGBY(0x43),
+  RGBY(0x44), RGBY(0x45), RGBY(0x46), RGBY(0x47),
+  RGBY(0x48), RGBY(0x49), RGBY(0x4A), RGBY(0x4B),
+  RGBY(0x4C), RGBY(0x4D), RGBY(0x4E), RGBY(0x4F),
+  RGBY(0x50), RGBY(0x51), RGBY(0x52), RGBY(0x53),
+  RGBY(0x54), RGBY(0x55), RGBY(0x56), RGBY(0x57),
+  RGBY(0x58), RGBY(0x59), RGBY(0x5A), RGBY(0x5B),
+  RGBY(0x5C), RGBY(0x5D), RGBY(0x5E), RGBY(0x5F),
+  RGBY(0x60), RGBY(0x61), RGBY(0x62), RGBY(0x63),
+  RGBY(0x64), RGBY(0x65), RGBY(0x66), RGBY(0x67),
+  RGBY(0x68), RGBY(0x69), RGBY(0x6A), RGBY(0x6B),
+  RGBY(0x6C), RGBY(0x6D), RGBY(0x6E), RGBY(0x6F),
+  RGBY(0x70), RGBY(0x71), RGBY(0x72), RGBY(0x73),
+  RGBY(0x74), RGBY(0x75), RGBY(0x76), RGBY(0x77),
+  RGBY(0x78), RGBY(0x79), RGBY(0x7A), RGBY(0x7B),
+  RGBY(0x7C), RGBY(0x7D), RGBY(0x7E), RGBY(0x7F),
+  RGBY(0x80), RGBY(0x81), RGBY(0x82), RGBY(0x83),
+  RGBY(0x84), RGBY(0x85), RGBY(0x86), RGBY(0x87),
+  RGBY(0x88), RGBY(0x89), RGBY(0x8A), RGBY(0x8B),
+  RGBY(0x8C), RGBY(0x8D), RGBY(0x8E), RGBY(0x8F),
+  RGBY(0x90), RGBY(0x91), RGBY(0x92), RGBY(0x93),
+  RGBY(0x94), RGBY(0x95), RGBY(0x96), RGBY(0x97),
+  RGBY(0x98), RGBY(0x99), RGBY(0x9A), RGBY(0x9B),
+  RGBY(0x9C), RGBY(0x9D), RGBY(0x9E), RGBY(0x9F),
+  RGBY(0xA0), RGBY(0xA1), RGBY(0xA2), RGBY(0xA3),
+  RGBY(0xA4), RGBY(0xA5), RGBY(0xA6), RGBY(0xA7),
+  RGBY(0xA8), RGBY(0xA9), RGBY(0xAA), RGBY(0xAB),
+  RGBY(0xAC), RGBY(0xAD), RGBY(0xAE), RGBY(0xAF),
+  RGBY(0xB0), RGBY(0xB1), RGBY(0xB2), RGBY(0xB3),
+  RGBY(0xB4), RGBY(0xB5), RGBY(0xB6), RGBY(0xB7),
+  RGBY(0xB8), RGBY(0xB9), RGBY(0xBA), RGBY(0xBB),
+  RGBY(0xBC), RGBY(0xBD), RGBY(0xBE), RGBY(0xBF),
+  RGBY(0xC0), RGBY(0xC1), RGBY(0xC2), RGBY(0xC3),
+  RGBY(0xC4), RGBY(0xC5), RGBY(0xC6), RGBY(0xC7),
+  RGBY(0xC8), RGBY(0xC9), RGBY(0xCA), RGBY(0xCB),
+  RGBY(0xCC), RGBY(0xCD), RGBY(0xCE), RGBY(0xCF),
+  RGBY(0xD0), RGBY(0xD1), RGBY(0xD2), RGBY(0xD3),
+  RGBY(0xD4), RGBY(0xD5), RGBY(0xD6), RGBY(0xD7),
+  RGBY(0xD8), RGBY(0xD9), RGBY(0xDA), RGBY(0xDB),
+  RGBY(0xDC), RGBY(0xDD), RGBY(0xDE), RGBY(0xDF),
+  RGBY(0xE0), RGBY(0xE1), RGBY(0xE2), RGBY(0xE3),
+  RGBY(0xE4), RGBY(0xE5), RGBY(0xE6), RGBY(0xE7),
+  RGBY(0xE8), RGBY(0xE9), RGBY(0xEA), RGBY(0xEB),
+  RGBY(0xEC), RGBY(0xED), RGBY(0xEE), RGBY(0xEF),
+  RGBY(0xF0), RGBY(0xF1), RGBY(0xF2), RGBY(0xF3),
+  RGBY(0xF4), RGBY(0xF5), RGBY(0xF6), RGBY(0xF7),
+  RGBY(0xF8), RGBY(0xF9), RGBY(0xFA), RGBY(0xFB),
+  RGBY(0xFC), RGBY(0xFD), RGBY(0xFE), RGBY(0xFF),
+};
+
+MMX_ALIGNED(int16 kCoefficientsRgbU[256][4]) = {
+  RGBU(0x00), RGBU(0x01), RGBU(0x02), RGBU(0x03),
+  RGBU(0x04), RGBU(0x05), RGBU(0x06), RGBU(0x07),
+  RGBU(0x08), RGBU(0x09), RGBU(0x0A), RGBU(0x0B),
+  RGBU(0x0C), RGBU(0x0D), RGBU(0x0E), RGBU(0x0F),
+  RGBU(0x10), RGBU(0x11), RGBU(0x12), RGBU(0x13),
+  RGBU(0x14), RGBU(0x15), RGBU(0x16), RGBU(0x17),
+  RGBU(0x18), RGBU(0x19), RGBU(0x1A), RGBU(0x1B),
+  RGBU(0x1C), RGBU(0x1D), RGBU(0x1E), RGBU(0x1F),
+  RGBU(0x20), RGBU(0x21), RGBU(0x22), RGBU(0x23),
+  RGBU(0x24), RGBU(0x25), RGBU(0x26), RGBU(0x27),
+  RGBU(0x28), RGBU(0x29), RGBU(0x2A), RGBU(0x2B),
+  RGBU(0x2C), RGBU(0x2D), RGBU(0x2E), RGBU(0x2F),
+  RGBU(0x30), RGBU(0x31), RGBU(0x32), RGBU(0x33),
+  RGBU(0x34), RGBU(0x35), RGBU(0x36), RGBU(0x37),
+  RGBU(0x38), RGBU(0x39), RGBU(0x3A), RGBU(0x3B),
+  RGBU(0x3C), RGBU(0x3D), RGBU(0x3E), RGBU(0x3F),
+  RGBU(0x40), RGBU(0x41), RGBU(0x42), RGBU(0x43),
+  RGBU(0x44), RGBU(0x45), RGBU(0x46), RGBU(0x47),
+  RGBU(0x48), RGBU(0x49), RGBU(0x4A), RGBU(0x4B),
+  RGBU(0x4C), RGBU(0x4D), RGBU(0x4E), RGBU(0x4F),
+  RGBU(0x50), RGBU(0x51), RGBU(0x52), RGBU(0x53),
+  RGBU(0x54), RGBU(0x55), RGBU(0x56), RGBU(0x57),
+  RGBU(0x58), RGBU(0x59), RGBU(0x5A), RGBU(0x5B),
+  RGBU(0x5C), RGBU(0x5D), RGBU(0x5E), RGBU(0x5F),
+  RGBU(0x60), RGBU(0x61), RGBU(0x62), RGBU(0x63),
+  RGBU(0x64), RGBU(0x65), RGBU(0x66), RGBU(0x67),
+  RGBU(0x68), RGBU(0x69), RGBU(0x6A), RGBU(0x6B),
+  RGBU(0x6C), RGBU(0x6D), RGBU(0x6E), RGBU(0x6F),
+  RGBU(0x70), RGBU(0x71), RGBU(0x72), RGBU(0x73),
+  RGBU(0x74), RGBU(0x75), RGBU(0x76), RGBU(0x77),
+  RGBU(0x78), RGBU(0x79), RGBU(0x7A), RGBU(0x7B),
+  RGBU(0x7C), RGBU(0x7D), RGBU(0x7E), RGBU(0x7F),
+  RGBU(0x80), RGBU(0x81), RGBU(0x82), RGBU(0x83),
+  RGBU(0x84), RGBU(0x85), RGBU(0x86), RGBU(0x87),
+  RGBU(0x88), RGBU(0x89), RGBU(0x8A), RGBU(0x8B),
+  RGBU(0x8C), RGBU(0x8D), RGBU(0x8E), RGBU(0x8F),
+  RGBU(0x90), RGBU(0x91), RGBU(0x92), RGBU(0x93),
+  RGBU(0x94), RGBU(0x95), RGBU(0x96), RGBU(0x97),
+  RGBU(0x98), RGBU(0x99), RGBU(0x9A), RGBU(0x9B),
+  RGBU(0x9C), RGBU(0x9D), RGBU(0x9E), RGBU(0x9F),
+  RGBU(0xA0), RGBU(0xA1), RGBU(0xA2), RGBU(0xA3),
+  RGBU(0xA4), RGBU(0xA5), RGBU(0xA6), RGBU(0xA7),
+  RGBU(0xA8), RGBU(0xA9), RGBU(0xAA), RGBU(0xAB),
+  RGBU(0xAC), RGBU(0xAD), RGBU(0xAE), RGBU(0xAF),
+  RGBU(0xB0), RGBU(0xB1), RGBU(0xB2), RGBU(0xB3),
+  RGBU(0xB4), RGBU(0xB5), RGBU(0xB6), RGBU(0xB7),
+  RGBU(0xB8), RGBU(0xB9), RGBU(0xBA), RGBU(0xBB),
+  RGBU(0xBC), RGBU(0xBD), RGBU(0xBE), RGBU(0xBF),
+  RGBU(0xC0), RGBU(0xC1), RGBU(0xC2), RGBU(0xC3),
+  RGBU(0xC4), RGBU(0xC5), RGBU(0xC6), RGBU(0xC7),
+  RGBU(0xC8), RGBU(0xC9), RGBU(0xCA), RGBU(0xCB),
+  RGBU(0xCC), RGBU(0xCD), RGBU(0xCE), RGBU(0xCF),
+  RGBU(0xD0), RGBU(0xD1), RGBU(0xD2), RGBU(0xD3),
+  RGBU(0xD4), RGBU(0xD5), RGBU(0xD6), RGBU(0xD7),
+  RGBU(0xD8), RGBU(0xD9), RGBU(0xDA), RGBU(0xDB),
+  RGBU(0xDC), RGBU(0xDD), RGBU(0xDE), RGBU(0xDF),
+  RGBU(0xE0), RGBU(0xE1), RGBU(0xE2), RGBU(0xE3),
+  RGBU(0xE4), RGBU(0xE5), RGBU(0xE6), RGBU(0xE7),
+  RGBU(0xE8), RGBU(0xE9), RGBU(0xEA), RGBU(0xEB),
+  RGBU(0xEC), RGBU(0xED), RGBU(0xEE), RGBU(0xEF),
+  RGBU(0xF0), RGBU(0xF1), RGBU(0xF2), RGBU(0xF3),
+  RGBU(0xF4), RGBU(0xF5), RGBU(0xF6), RGBU(0xF7),
+  RGBU(0xF8), RGBU(0xF9), RGBU(0xFA), RGBU(0xFB),
+  RGBU(0xFC), RGBU(0xFD), RGBU(0xFE), RGBU(0xFF),
+};
+
+MMX_ALIGNED(int16 kCoefficientsRgbV[256][4]) = {
+  RGBV(0x00), RGBV(0x01), RGBV(0x02), RGBV(0x03),
+  RGBV(0x04), RGBV(0x05), RGBV(0x06), RGBV(0x07),
+  RGBV(0x08), RGBV(0x09), RGBV(0x0A), RGBV(0x0B),
+  RGBV(0x0C), RGBV(0x0D), RGBV(0x0E), RGBV(0x0F),
+  RGBV(0x10), RGBV(0x11), RGBV(0x12), RGBV(0x13),
+  RGBV(0x14), RGBV(0x15), RGBV(0x16), RGBV(0x17),
+  RGBV(0x18), RGBV(0x19), RGBV(0x1A), RGBV(0x1B),
+  RGBV(0x1C), RGBV(0x1D), RGBV(0x1E), RGBV(0x1F),
+  RGBV(0x20), RGBV(0x21), RGBV(0x22), RGBV(0x23),
+  RGBV(0x24), RGBV(0x25), RGBV(0x26), RGBV(0x27),
+  RGBV(0x28), RGBV(0x29), RGBV(0x2A), RGBV(0x2B),
+  RGBV(0x2C), RGBV(0x2D), RGBV(0x2E), RGBV(0x2F),
+  RGBV(0x30), RGBV(0x31), RGBV(0x32), RGBV(0x33),
+  RGBV(0x34), RGBV(0x35), RGBV(0x36), RGBV(0x37),
+  RGBV(0x38), RGBV(0x39), RGBV(0x3A), RGBV(0x3B),
+  RGBV(0x3C), RGBV(0x3D), RGBV(0x3E), RGBV(0x3F),
+  RGBV(0x40), RGBV(0x41), RGBV(0x42), RGBV(0x43),
+  RGBV(0x44), RGBV(0x45), RGBV(0x46), RGBV(0x47),
+  RGBV(0x48), RGBV(0x49), RGBV(0x4A), RGBV(0x4B),
+  RGBV(0x4C), RGBV(0x4D), RGBV(0x4E), RGBV(0x4F),
+  RGBV(0x50), RGBV(0x51), RGBV(0x52), RGBV(0x53),
+  RGBV(0x54), RGBV(0x55), RGBV(0x56), RGBV(0x57),
+  RGBV(0x58), RGBV(0x59), RGBV(0x5A), RGBV(0x5B),
+  RGBV(0x5C), RGBV(0x5D), RGBV(0x5E), RGBV(0x5F),
+  RGBV(0x60), RGBV(0x61), RGBV(0x62), RGBV(0x63),
+  RGBV(0x64), RGBV(0x65), RGBV(0x66), RGBV(0x67),
+  RGBV(0x68), RGBV(0x69), RGBV(0x6A), RGBV(0x6B),
+  RGBV(0x6C), RGBV(0x6D), RGBV(0x6E), RGBV(0x6F),
+  RGBV(0x70), RGBV(0x71), RGBV(0x72), RGBV(0x73),
+  RGBV(0x74), RGBV(0x75), RGBV(0x76), RGBV(0x77),
+  RGBV(0x78), RGBV(0x79), RGBV(0x7A), RGBV(0x7B),
+  RGBV(0x7C), RGBV(0x7D), RGBV(0x7E), RGBV(0x7F),
+  RGBV(0x80), RGBV(0x81), RGBV(0x82), RGBV(0x83),
+  RGBV(0x84), RGBV(0x85), RGBV(0x86), RGBV(0x87),
+  RGBV(0x88), RGBV(0x89), RGBV(0x8A), RGBV(0x8B),
+  RGBV(0x8C), RGBV(0x8D), RGBV(0x8E), RGBV(0x8F),
+  RGBV(0x90), RGBV(0x91), RGBV(0x92), RGBV(0x93),
+  RGBV(0x94), RGBV(0x95), RGBV(0x96), RGBV(0x97),
+  RGBV(0x98), RGBV(0x99), RGBV(0x9A), RGBV(0x9B),
+  RGBV(0x9C), RGBV(0x9D), RGBV(0x9E), RGBV(0x9F),
+  RGBV(0xA0), RGBV(0xA1), RGBV(0xA2), RGBV(0xA3),
+  RGBV(0xA4), RGBV(0xA5), RGBV(0xA6), RGBV(0xA7),
+  RGBV(0xA8), RGBV(0xA9), RGBV(0xAA), RGBV(0xAB),
+  RGBV(0xAC), RGBV(0xAD), RGBV(0xAE), RGBV(0xAF),
+  RGBV(0xB0), RGBV(0xB1), RGBV(0xB2), RGBV(0xB3),
+  RGBV(0xB4), RGBV(0xB5), RGBV(0xB6), RGBV(0xB7),
+  RGBV(0xB8), RGBV(0xB9), RGBV(0xBA), RGBV(0xBB),
+  RGBV(0xBC), RGBV(0xBD), RGBV(0xBE), RGBV(0xBF),
+  RGBV(0xC0), RGBV(0xC1), RGBV(0xC2), RGBV(0xC3),
+  RGBV(0xC4), RGBV(0xC5), RGBV(0xC6), RGBV(0xC7),
+  RGBV(0xC8), RGBV(0xC9), RGBV(0xCA), RGBV(0xCB),
+  RGBV(0xCC), RGBV(0xCD), RGBV(0xCE), RGBV(0xCF),
+  RGBV(0xD0), RGBV(0xD1), RGBV(0xD2), RGBV(0xD3),
+  RGBV(0xD4), RGBV(0xD5), RGBV(0xD6), RGBV(0xD7),
+  RGBV(0xD8), RGBV(0xD9), RGBV(0xDA), RGBV(0xDB),
+  RGBV(0xDC), RGBV(0xDD), RGBV(0xDE), RGBV(0xDF),
+  RGBV(0xE0), RGBV(0xE1), RGBV(0xE2), RGBV(0xE3),
+  RGBV(0xE4), RGBV(0xE5), RGBV(0xE6), RGBV(0xE7),
+  RGBV(0xE8), RGBV(0xE9), RGBV(0xEA), RGBV(0xEB),
+  RGBV(0xEC), RGBV(0xED), RGBV(0xEE), RGBV(0xEF),
+  RGBV(0xF0), RGBV(0xF1), RGBV(0xF2), RGBV(0xF3),
+  RGBV(0xF4), RGBV(0xF5), RGBV(0xF6), RGBV(0xF7),
+  RGBV(0xF8), RGBV(0xF9), RGBV(0xFA), RGBV(0xFB),
+  RGBV(0xFC), RGBV(0xFD), RGBV(0xFE), RGBV(0xFF),
+};
+
+#undef RGBHY
+#undef RGBY
+#undef RGBU
+#undef RGBV
+#undef MMX_ALIGNED
+
+// Warning C4799: function has no EMMS instruction.
+// EMMS() is slow and should be called by the calling function once per image.
+#pragma warning(disable: 4799)
+
+__declspec(naked)
+void FastConvertYUVToRGB32Row(const uint8* y_buf,
+                              const uint8* u_buf,
+                              const uint8* v_buf,
+                              uint8* rgb_buf,
+                              int width) {
+  __asm {
+    pushad
+    mov       edx, [esp + 32 + 4]   // Y
+    mov       edi, [esp + 32 + 8]   // U
+    mov       esi, [esp + 32 + 12]  // V
+    mov       ebp, [esp + 32 + 16]  // rgb
+    mov       ecx, [esp + 32 + 20]  // width
+    jmp       convertend
+
+ convertloop :
+    movzx     eax, byte ptr [edi]
+    add       edi, 1
+    movzx     ebx, byte ptr [esi]
+    add       esi, 1
+    movq      mm0, [kCoefficientsRgbU + 8 * eax]
+    movzx     eax, byte ptr [edx]
+    paddsw    mm0, [kCoefficientsRgbV + 8 * ebx]
+    movzx     ebx, byte ptr [edx + 1]
+    movq      mm1, [kCoefficientsRgbY + 8 * eax]
+    add       edx, 2
+    movq      mm2, [kCoefficientsRgbY + 8 * ebx]
+    paddsw    mm1, mm0
+    paddsw    mm2, mm0
+    psraw     mm1, 6
+    psraw     mm2, 6
+    packuswb  mm1, mm2
+    movntq    [ebp], mm1
+    add       ebp, 8
+ convertend :
+    sub       ecx, 2
+    jns       convertloop
+
+    and       ecx, 1  // odd number of pixels?
+    jz        convertdone
+
+    movzx     eax, byte ptr [edi]
+    movq      mm0, [kCoefficientsRgbU + 8 * eax]
+    movzx     eax, byte ptr [esi]
+    paddsw    mm0, [kCoefficientsRgbV + 8 * eax]
+    movzx     eax, byte ptr [edx]
+    movq      mm1, [kCoefficientsRgbY + 8 * eax]
+    paddsw    mm1, mm0
+    psraw     mm1, 6
+    packuswb  mm1, mm1
+    movd      [ebp], mm1
+ convertdone :
+
+    popad
+    ret
+  }
+}
+
+}  // extern "C"
+
--- a/layout/build/Makefile.in
+++ b/layout/build/Makefile.in
@@ -56,17 +56,17 @@ EXPORT_LIBRARY = 1
 IS_COMPONENT	= 1
 MODULE_NAME	= nsLayoutModule
 GRE_MODULE	= 1
 LIBXUL_LIBRARY	= 1
 
 ifndef MOZ_ENABLE_LIBXUL
 EXTRA_DSO_LIBS	= gkgfx
 endif
-EXTRA_DSO_LIBS	+= thebes layers
+EXTRA_DSO_LIBS	+= thebes layers ycbcr
 
 
 CPPSRCS		= \
 		nsLayoutModule.cpp \
 		nsContentDLF.cpp \
 		nsLayoutStatics.cpp \
 		$(NULL)
 
--- a/toolkit/content/license.html
+++ b/toolkit/content/license.html
@@ -2159,17 +2159,18 @@ WITH THE USE OR PERFORMANCE OF THIS SOFT
 </pre>
 
 
     <hr>
 
     <h1><a name="chromium"></a>Chromium License</h1>
 
     <p class="correctme">This license applies to some files in the directory
-      <span class="path">ipc/chromium/</span>.
+      <span class="path">ipc/chromium/</span> and
+      <span class="path">gfx/ycbcr</span>.
     </p>
 
 <pre>
 Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 met:
--- a/toolkit/library/libxul-config.mk
+++ b/toolkit/library/libxul-config.mk
@@ -303,17 +303,17 @@ endif
 
 ifneq (,$(filter icon,$(MOZ_IMG_DECODERS)))
 ifndef MOZ_ENABLE_GTK2
 DEFINES += -DICON_DECODER
 COMPONENT_LIBS += imgicon
 endif
 endif
 
-STATIC_LIBS += thebes layers
+STATIC_LIBS += thebes layers ycbcr
 COMPONENT_LIBS += gkgfxthebes
 
 ifeq (windows,$(MOZ_WIDGET_TOOLKIT))
 COMPONENT_LIBS += gkwidget
 endif
 ifeq (beos,$(MOZ_WIDGET_TOOLKIT))
 COMPONENT_LIBS += widget_beos
 endif
--- a/toolkit/toolkit-makefiles.sh
+++ b/toolkit/toolkit-makefiles.sh
@@ -116,16 +116,17 @@ MAKEFILES_xmlparser="
   parser/expat/lib/Makefile
   parser/xml/Makefile
   parser/xml/public/Makefile
   parser/xml/src/Makefile
 "
 
 MAKEFILES_gfx="
   gfx/Makefile
+  gfx/ycbcr/Makefile
   gfx/idl/Makefile
   gfx/layers/Makefile
   gfx/public/Makefile
   gfx/src/Makefile
   gfx/src/psshared/Makefile
   gfx/src/thebes/Makefile
   gfx/tests/Makefile
   gfx/thebes/Makefile