b=811730 - Take skip into account when copying video frames into shared memory. r=cpeterson
authorNicolas Silva <nical.bugzilla@gmail.com>
Tue, 04 Dec 2012 11:36:33 +0100
changeset 115041 aa649086ab5b49e34bf4cb5708f33c5587ae3494
parent 115040 69c58da431407c035eea3edb89bfb666cb2eca5e
child 115042 256dd5fd93382712e426e7d21de3853b2c62b94d
push id19126
push usernsilva@mozilla.com
push dateWed, 05 Dec 2012 13:37:58 +0000
treeherdermozilla-inbound@aa649086ab5b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpeterson
bugs811730
milestone20.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
b=811730 - Take skip into account when copying video frames into shared memory. r=cpeterson
gfx/layers/ipc/ImageContainerChild.cpp
gfx/layers/ipc/ShmemYCbCrImage.cpp
gfx/layers/ipc/ShmemYCbCrImage.h
--- a/gfx/layers/ipc/ImageContainerChild.cpp
+++ b/gfx/layers/ipc/ImageContainerChild.cpp
@@ -130,19 +130,21 @@ bool ImageContainerChild::CopyDataIntoSh
       (dest->type() == SharedImage::TYCbCrImage)) {
     PlanarYCbCrImage *planarYCbCrImage = static_cast<PlanarYCbCrImage*>(src);
     const PlanarYCbCrImage::Data *data = planarYCbCrImage->GetData();
     NS_ASSERTION(data, "Must be able to retrieve yuv data from image!");
     YCbCrImage& yuv = dest->get_YCbCrImage();
 
     ShmemYCbCrImage shmemImage(yuv.data(), yuv.offset());
 
+    MOZ_ASSERT(data->mCbSkip == data->mCrSkip);
     if (!shmemImage.CopyData(data->mYChannel, data->mCbChannel, data->mCrChannel,
                              data->mYSize, data->mYStride,
-                             data->mCbCrSize, data->mCbCrStride)) {
+                             data->mCbCrSize, data->mCbCrStride,
+                             data->mYSkip, data->mCbSkip)) {
       NS_WARNING("Failed to copy image data!");
       return false;
     }
     return true;
   }
   return false; // TODO: support more image formats
 }
 
@@ -510,20 +512,21 @@ public:
     // do not set mBuffer like in PlanarYCbCrImage because the later
     // will try to manage this memory without knowing it belongs to a
     // shmem.
     mBufferSize = ShmemYCbCrImage::ComputeMinBufferSize(mData.mYSize,
                                                         mData.mCbCrSize);
     mSize = mData.mPicSize;
 
     ShmemYCbCrImage shmImg(mShmem);
-
+    MOZ_ASSERT(aData.mCbSkip == aData.mCrSkip);
     if (!shmImg.CopyData(aData.mYChannel, aData.mCbChannel, aData.mCrChannel,
                          aData.mYSize, aData.mYStride,
-                         aData.mCbCrSize, aData.mCbCrStride)) {
+                         aData.mCbCrSize, aData.mCbCrStride,
+                         aData.mYSkip, aData.mCbSkip)) {
       NS_WARNING("Failed to copy image data!");
     }
     mData.mYChannel = shmImg.GetYData();
     mData.mCbChannel = shmImg.GetCbData();
     mData.mCrChannel = shmImg.GetCrData();
   }
 
   virtual bool Allocate(PlanarYCbCrImage::Data& aData)
--- a/gfx/layers/ipc/ShmemYCbCrImage.cpp
+++ b/gfx/layers/ipc/ShmemYCbCrImage.cpp
@@ -145,34 +145,63 @@ bool ShmemYCbCrImage::IsValid()
   if (mShmem.Size<uint8_t>() < bufferInfoSize ||
       GetYCbCrBufferInfo(mShmem, mOffset)->mYOffset != bufferInfoSize ||
       mShmem.Size<uint8_t>() < mOffset + ComputeMinBufferSize(GetYSize(),GetCbCrSize())) {
     return false;
   }
   return true;
 }
 
-bool ShmemYCbCrImage::CopyData(uint8_t* aYData, uint8_t* aCbData, uint8_t* aCrData,
+static void CopyLineWithSkip(const uint8_t* src, uint8_t* dst, uint32_t len, uint32_t skip) {
+  for (uint32_t i = 0; i < len; ++i) {
+    *dst = *src;
+    src += 1 + skip;
+    ++dst;
+  }
+}
+
+bool ShmemYCbCrImage::CopyData(const uint8_t* aYData,
+                               const uint8_t* aCbData, const uint8_t* aCrData,
                                gfxIntSize aYSize, uint32_t aYStride,
-                               gfxIntSize aCbCrSize, uint32_t aCbCrStride)
+                               gfxIntSize aCbCrSize, uint32_t aCbCrStride,
+                               uint32_t aYSkip, uint32_t aCbCrSkip)
 {
   if (!IsValid() || GetYSize() != aYSize || GetCbCrSize() != aCbCrSize) {
     return false;
   }
-  for (int i = 0; i < aYSize.height; i++) {
-    memcpy(GetYData() + i * GetYStride(),
-           aYData + i * aYStride,
-           aYSize.width);
+  for (int i = 0; i < aYSize.height; ++i) {
+    if (aYSkip == 0) {
+      // fast path
+      memcpy(GetYData() + i * GetYStride(),
+             aYData + i * aYStride,
+             aYSize.width);
+    } else {
+      // slower path
+      CopyLineWithSkip(aYData + i * aYStride,
+                       GetYData() + i * GetYStride(),
+                       aYSize.width, aYSkip);
+    }
   }
-  for (int i = 0; i < aCbCrSize.height; i++) {
-    memcpy(GetCbData() + i * GetCbCrStride(),
-           aCbData + i * aCbCrStride,
-           aCbCrSize.width);
-    memcpy(GetCrData() + i * GetCbCrStride(),
-           aCrData + i * aCbCrStride,
-           aCbCrSize.width);
+  for (int i = 0; i < aCbCrSize.height; ++i) {
+    if (aCbCrSkip == 0) {
+      // fast path
+      memcpy(GetCbData() + i * GetCbCrStride(),
+             aCbData + i * aCbCrStride,
+             aCbCrSize.width);
+      memcpy(GetCrData() + i * GetCbCrStride(),
+             aCrData + i * aCbCrStride,
+             aCbCrSize.width);
+    } else {
+      // slower path
+      CopyLineWithSkip(aCbData + i * aCbCrStride,
+                       GetCbData() + i * GetCbCrStride(),
+                       aCbCrSize.width, aCbCrSkip);
+      CopyLineWithSkip(aCrData + i * aCbCrStride,
+                       GetCrData() + i * GetCbCrStride(),
+                       aCbCrSize.width, aCbCrSkip);
+    }
   }
   return true;
 }
 
 
 } // namespace
 } // namespace
--- a/gfx/layers/ipc/ShmemYCbCrImage.h
+++ b/gfx/layers/ipc/ShmemYCbCrImage.h
@@ -91,19 +91,21 @@ public:
   /**
    * Returns the dimensions of the Cb and Cr Channel.
    */
   gfxIntSize GetCbCrSize();
 
   /**
    * Copies the data passed in parameter into the shmem.
    */
-  bool CopyData(uint8_t* aYData, uint8_t* aCbData, uint8_t* aCrData,
+  bool CopyData(const uint8_t* aYData,
+                const uint8_t* aCbData, const uint8_t* aCrData,
                 gfxIntSize aYSize, uint32_t aYStride,
-                gfxIntSize aCbCrSize, uint32_t aCbCrStride);
+                gfxIntSize aCbCrSize, uint32_t aCbCrStride,
+                uint32_t aYSkip, uint32_t aCbCrSkip);
 
 private:
   bool Open(Shmem& aShmem, size_t aOffset = 0);
 
   ipc::Shmem mShmem;
   size_t mOffset;
 };