Bug 767480 - Remove offset field from PlanarYCbCrImage::Data. r=roc
authorKan-Ru Chen (陳侃如) <kanru@kanru.info>
Sun, 26 Aug 2012 00:22:51 -0300
changeset 105506 f26d6c5a2d93719516da85b0481d173fa8a5a8c4
parent 105505 c4f20a024113801c6df7037d6cbb391f8fe96f4d
child 105507 b8893f7f80c5c76f739b9396a36822852329bc59
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
reviewersroc
bugs767480
milestone17.0a1
Bug 767480 - Remove offset field from PlanarYCbCrImage::Data. r=roc
content/media/nsBuiltinDecoderReader.cpp
gfx/layers/ImageContainer.cpp
gfx/layers/ImageContainer.h
--- a/content/media/nsBuiltinDecoderReader.cpp
+++ b/content/media/nsBuiltinDecoderReader.cpp
@@ -213,28 +213,25 @@ VideoData* VideoData::Create(nsVideoInfo
     return nullptr;
   }
   NS_ASSERTION(v->mImage->GetFormat() == PLANAR_YCBCR ||
                v->mImage->GetFormat() == GRALLOC_PLANAR_YCBCR,
                "Wrong format?");
   PlanarYCbCrImage* videoImage = static_cast<PlanarYCbCrImage*>(v->mImage.get());
 
   PlanarYCbCrImage::Data data;
-  data.mYChannel = Y.mData;
+  data.mYChannel = Y.mData + Y.mOffset;
   data.mYSize = gfxIntSize(Y.mWidth, Y.mHeight);
   data.mYStride = Y.mStride;
-  data.mYOffset = Y.mOffset;
   data.mYSkip = Y.mSkip;
-  data.mCbChannel = Cb.mData;
-  data.mCrChannel = Cr.mData;
+  data.mCbChannel = Cb.mData + Cb.mOffset;
+  data.mCrChannel = Cr.mData + Cr.mOffset;
   data.mCbCrSize = gfxIntSize(Cb.mWidth, Cb.mHeight);
   data.mCbCrStride = Cb.mStride;
-  data.mCbOffset = Cb.mOffset;
   data.mCbSkip = Cb.mSkip;
-  data.mCrOffset = Cr.mOffset;
   data.mCrSkip = Cr.mSkip;
   data.mPicX = aPicture.x;
   data.mPicY = aPicture.y;
   data.mPicSize = gfxIntSize(aPicture.width, aPicture.height);
   data.mStereoMode = aInfo.mStereoMode;
 
   videoImage->SetData(data);
   return v.forget();
--- a/gfx/layers/ImageContainer.cpp
+++ b/gfx/layers/ImageContainer.cpp
@@ -408,41 +408,35 @@ PlanarYCbCrImage::~PlanarYCbCrImage()
 uint8_t* 
 PlanarYCbCrImage::AllocateBuffer(uint32_t aSize)
 {
   return mRecycleBin->GetBuffer(aSize); 
 }
 
 static void
 CopyPlane(uint8_t *aDst, uint8_t *aSrc,
-          const gfxIntSize &aSize, int32_t aStride,
-          int32_t aOffset, int32_t aSkip)
+          const gfxIntSize &aSize, int32_t aStride, int32_t aSkip)
 {
-  if (!aOffset && !aSkip) {
+  if (!aSkip) {
     // Fast path: planar input.
     memcpy(aDst, aSrc, aSize.height * aStride);
   } else {
     int32_t height = aSize.height;
     int32_t width = aSize.width;
     for (int y = 0; y < height; ++y) {
-      uint8_t *src = aSrc + aOffset;
+      uint8_t *src = aSrc;
       uint8_t *dst = aDst;
-      if (!aSkip) {
-        // Fast path: offset only, no per-pixel skip.
-        memcpy(dst, src, width);
-      } else {
-        // Slow path
-        for (int x = 0; x < width; ++x) {
-          *dst++ = *src++;
-          src += aSkip;
-        }
+      // Slow path
+      for (int x = 0; x < width; ++x) {
+        *dst++ = *src++;
+        src += aSkip;
       }
-      aSrc += aStride;
-      aDst += aStride;
     }
+    aSrc += aStride;
+    aDst += aStride;
   }
 }
 
 void
 PlanarYCbCrImage::CopyData(const Data& aData)
 {
   mData = aData;
 
@@ -455,24 +449,21 @@ PlanarYCbCrImage::CopyData(const Data& a
   if (!mBuffer)
     return;
 
   mData.mYChannel = mBuffer;
   mData.mCbChannel = mData.mYChannel + mData.mYStride * mData.mYSize.height;
   mData.mCrChannel = mData.mCbChannel + mData.mCbCrStride * mData.mCbCrSize.height;
 
   CopyPlane(mData.mYChannel, aData.mYChannel,
-            mData.mYSize, mData.mYStride,
-            mData.mYOffset, mData.mYSkip);
+            mData.mYSize, mData.mYStride, mData.mYSkip);
   CopyPlane(mData.mCbChannel, aData.mCbChannel,
-            mData.mCbCrSize, mData.mCbCrStride,
-            mData.mCbOffset, mData.mCbSkip);
+            mData.mCbCrSize, mData.mCbCrStride, mData.mCbSkip);
   CopyPlane(mData.mCrChannel, aData.mCrChannel,
-            mData.mCbCrSize, mData.mCbCrStride,
-            mData.mCrOffset, mData.mCrSkip);
+            mData.mCbCrSize, mData.mCbCrStride, mData.mCrSkip);
 
   mSize = aData.mPicSize;
 }
 
 void
 PlanarYCbCrImage::SetData(const Data &aData)
 {
   CopyData(aData);
--- a/gfx/layers/ImageContainer.h
+++ b/gfx/layers/ImageContainer.h
@@ -604,38 +604,47 @@ private:
  *
  * 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.
  *
- * mYOffset, mYSkip, mCbOffset, mCbSkip, mCrOffset, mCrSkip are added
- * to support various output formats from hardware decoder. m*Offset
- * are the extra left stride and m*Skip are per-pixel skips in the
+ * mYSkip, mCbSkip, mCrSkip are added to support various output
+ * formats from hardware decoder. They are per-pixel skips in the
  * source image.
+ *
+ * For example when image width is 640, mYStride is 670, mYSkip is 3,
+ * the mYChannel buffer looks like:
+ *
+ * |<----------------------- mYStride ----------------------------->|
+ * |<----------------- mYSize.width --------------->|
+ *  0   3   6   9   12  15  18  21                659             669
+ * |----------------------------------------------------------------|
+ * |Y___Y___Y___Y___Y___Y___Y___Y...                      |%%%%%%%%%|
+ * |Y___Y___Y___Y___Y___Y___Y___Y...                      |%%%%%%%%%|
+ * |Y___Y___Y___Y___Y___Y___Y___Y...                      |%%%%%%%%%|
+ * |            |<->|
+ *                mYSkip
  */
 class THEBES_API PlanarYCbCrImage : public Image {
 public:
   struct Data {
     // Luminance buffer
     uint8_t* mYChannel;
     int32_t mYStride;
     gfxIntSize mYSize;
-    int32_t mYOffset;
     int32_t mYSkip;
     // Chroma buffers
     uint8_t* mCbChannel;
     uint8_t* mCrChannel;
     int32_t mCbCrStride;
     gfxIntSize mCbCrSize;
-    int32_t mCbOffset;
     int32_t mCbSkip;
-    int32_t mCrOffset;
     int32_t mCrSkip;
     // Picture region
     uint32_t mPicX;
     uint32_t mPicY;
     gfxIntSize mPicSize;
     StereoMode mStereoMode;
 
     nsIntRect GetPictureRect() const {