Bug 1056455 - Move ResourceQueue to a separate header. r=cajbir
authorMatthew Gregan <kinetik@flim.org>
Wed, 20 Aug 2014 20:14:00 +1200
changeset 200756 ec92489ea416887c7a3020f632b4a1aff7e9f01b
parent 200755 151a4beda6efc3a54c5b3717e84fc72598129870
child 200757 c8387e2ab3352848eefa848fa27772d320a3fa7b
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerscajbir
bugs1056455
milestone34.0a1
Bug 1056455 - Move ResourceQueue to a separate header. r=cajbir
content/media/mediasource/MediaSource.cpp
content/media/mediasource/MediaSourceReader.h
content/media/mediasource/ResourceQueue.h
content/media/mediasource/SourceBuffer.h
content/media/mediasource/SourceBufferList.cpp
content/media/mediasource/SourceBufferResource.cpp
content/media/mediasource/SourceBufferResource.h
--- a/content/media/mediasource/MediaSource.cpp
+++ b/content/media/mediasource/MediaSource.cpp
@@ -19,17 +19,17 @@
 #include "mozilla/dom/TimeRanges.h"
 #include "mozilla/mozalloc.h"
 #include "nsContentTypeParser.h"
 #include "nsDebug.h"
 #include "nsError.h"
 #include "nsIEventTarget.h"
 #include "nsIRunnable.h"
 #include "nsPIDOMWindow.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsThreadUtils.h"
 #include "prlog.h"
 
 struct JSContext;
 class JSObject;
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* GetMediaSourceLog()
--- a/content/media/mediasource/MediaSourceReader.h
+++ b/content/media/mediasource/MediaSourceReader.h
@@ -6,17 +6,17 @@
 
 #ifndef MOZILLA_MEDIASOURCEREADER_H_
 #define MOZILLA_MEDIASOURCEREADER_H_
 
 #include "mozilla/Attributes.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "nsCOMPtr.h"
 #include "nsError.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsTArray.h"
 #include "MediaDecoderReader.h"
 
 namespace mozilla {
 
 class MediaSourceDecoder;
 class SubBufferDecoder;
 
new file mode 100644
--- /dev/null
+++ b/content/media/mediasource/ResourceQueue.h
@@ -0,0 +1,178 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef MOZILLA_RESOURCEQUEUE_H_
+#define MOZILLA_RESOURCEQUEUE_H_
+
+#include <algorithm>
+#include "nsDeque.h"
+#include "nsTArray.h"
+#include "prlog.h"
+
+#ifdef PR_LOGGING
+extern PRLogModuleInfo* GetSourceBufferResourceLog();
+
+#define SBR_DEBUG(...) PR_LOG(GetSourceBufferResourceLog(), PR_LOG_DEBUG, (__VA_ARGS__))
+#define SBR_DEBUGV(...) PR_LOG(GetSourceBufferResourceLog(), PR_LOG_DEBUG+1, (__VA_ARGS__))
+#else
+#define SBR_DEBUG(...)
+#define SBR_DEBUGV(...)
+#endif
+
+namespace mozilla {
+
+// A SourceBufferResource has a queue containing the data that is appended
+// to it. The queue holds instances of ResourceItem which is an array of the
+// bytes. Appending data to the SourceBufferResource pushes this onto the
+// queue.
+
+// Data is evicted once it reaches a size threshold. This pops the items off
+// the front of the queue and deletes it.  If an eviction happens then the
+// MediaSource is notified (done in SourceBuffer::AppendData) which then
+// requests all SourceBuffers to evict data up to approximately the same
+// timepoint.
+
+struct ResourceItem {
+  ResourceItem(const uint8_t* aData, uint32_t aSize) {
+    mData.AppendElements(aData, aSize);
+  }
+
+  size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
+    // size including this
+    size_t size = aMallocSizeOf(this);
+
+    // size excluding this
+    size += mData.SizeOfExcludingThis(aMallocSizeOf);
+
+    return size;
+  }
+
+  nsTArray<uint8_t> mData;
+};
+
+class ResourceQueueDeallocator : public nsDequeFunctor {
+  virtual void* operator() (void* aObject) {
+    delete static_cast<ResourceItem*>(aObject);
+    return nullptr;
+  }
+};
+
+class ResourceQueue : private nsDeque {
+public:
+  ResourceQueue()
+    : nsDeque(new ResourceQueueDeallocator())
+    , mLogicalLength(0)
+    , mOffset(0)
+  {
+  }
+
+  // Returns the logical byte offset of the start of the data.
+  uint64_t GetOffset() {
+    return mOffset;
+  }
+
+  // Returns the length of all items in the queue plus the offset.
+  // This is the logical length of the resource.
+  uint64_t GetLength() {
+    return mLogicalLength;
+  }
+
+  // Copies aCount bytes from aOffset in the queue into aDest.
+  void CopyData(uint64_t aOffset, uint32_t aCount, char* aDest) {
+    uint32_t offset = 0;
+    uint32_t start = GetAtOffset(aOffset, &offset);
+    uint32_t end = std::min(GetAtOffset(aOffset + aCount, nullptr) + 1, uint32_t(GetSize()));
+    for (uint32_t i = start; i < end; ++i) {
+      ResourceItem* item = ResourceAt(i);
+      uint32_t bytes = std::min(aCount, uint32_t(item->mData.Length() - offset));
+      if (bytes != 0) {
+        memcpy(aDest, &item->mData[offset], bytes);
+        offset = 0;
+        aCount -= bytes;
+        aDest += bytes;
+      }
+    }
+  }
+
+  void AppendItem(const uint8_t* aData, uint32_t aLength) {
+    mLogicalLength += aLength;
+    Push(new ResourceItem(aData, aLength));
+  }
+
+  // Evict data in queue if the total queue size is greater than
+  // aThreshold past the offset. Returns true if some data was
+  // actually evicted.
+  bool Evict(uint64_t aOffset, uint32_t aThreshold) {
+    bool evicted = false;
+    while (GetLength() - mOffset > aThreshold) {
+      ResourceItem* item = ResourceAt(0);
+      if (item->mData.Length() + mOffset > aOffset) {
+        break;
+      }
+      mOffset += item->mData.Length();
+      SBR_DEBUGV("ResourceQueue(%p)::Evict(%llu, %u) removed chunk length=%u",
+                 this, aOffset, aThreshold, item->mData.Length());
+      delete PopFront();
+      evicted = true;
+    }
+    return evicted;
+  }
+
+  size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const {
+    // Calculate the size of the internal deque.
+    size_t size = nsDeque::SizeOfExcludingThis(aMallocSizeOf);
+
+    // Sum the ResourceItems.
+    for (uint32_t i = 0; i < uint32_t(GetSize()); ++i) {
+      const ResourceItem* item = ResourceAt(i);
+      size += item->SizeOfIncludingThis(aMallocSizeOf);
+    }
+
+    return size;
+  }
+
+private:
+  ResourceItem* ResourceAt(uint32_t aIndex) const {
+    return static_cast<ResourceItem*>(ObjectAt(aIndex));
+  }
+
+  // Returns the index of the resource that contains the given
+  // logical offset. aResourceOffset will contain the offset into
+  // the resource at the given index returned if it is not null.  If
+  // no such resource exists, returns GetSize() and aOffset is
+  // untouched.
+  uint32_t GetAtOffset(uint64_t aOffset, uint32_t *aResourceOffset) {
+    MOZ_ASSERT(aOffset >= mOffset);
+    uint64_t offset = mOffset;
+    for (uint32_t i = 0; i < uint32_t(GetSize()); ++i) {
+      ResourceItem* item = ResourceAt(i);
+      // If the item contains the start of the offset we want to
+      // break out of the loop.
+      if (item->mData.Length() + offset > aOffset) {
+        if (aResourceOffset) {
+          *aResourceOffset = aOffset - offset;
+        }
+        return i;
+      }
+      offset += item->mData.Length();
+    }
+    return GetSize();
+  }
+
+  ResourceItem* PopFront() {
+    return static_cast<ResourceItem*>(nsDeque::PopFront());
+  }
+
+  // Logical length of the resource.
+  uint64_t mLogicalLength;
+
+  // Logical offset into the resource of the first element in the queue.
+  uint64_t mOffset;
+};
+
+
+} // namespace mozilla
+#endif /* MOZILLA_RESOURCEQUEUE_H_ */
--- a/content/media/mediasource/SourceBuffer.h
+++ b/content/media/mediasource/SourceBuffer.h
@@ -16,17 +16,17 @@
 #include "mozilla/dom/TypedArray.h"
 #include "mozilla/DOMEventTargetHelper.h"
 #include "mozilla/mozalloc.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionNoteChild.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsISupports.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nscore.h"
 
 class JSObject;
 struct JSContext;
 
 namespace mozilla {
 
 class ContainerParser;
--- a/content/media/mediasource/SourceBufferList.cpp
+++ b/content/media/mediasource/SourceBufferList.cpp
@@ -8,17 +8,17 @@
 
 #include "AsyncEventRunner.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/SourceBufferListBinding.h"
 #include "mozilla/mozalloc.h"
 #include "nsCOMPtr.h"
 #include "nsIEventTarget.h"
 #include "nsIRunnable.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsThreadUtils.h"
 #include "prlog.h"
 
 struct JSContext;
 class JSObject;
 
 #ifdef PR_LOGGING
 extern PRLogModuleInfo* GetMediaSourceLog();
--- a/content/media/mediasource/SourceBufferResource.cpp
+++ b/content/media/mediasource/SourceBufferResource.cpp
@@ -6,17 +6,16 @@
 
 #include "SourceBufferResource.h"
 
 #include <string.h>
 #include <algorithm>
 
 #include "nsISeekableStream.h"
 #include "nsISupportsImpl.h"
-#include "prenv.h"
 #include "prlog.h"
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* GetSourceBufferResourceLog()
 {
   static PRLogModuleInfo* sLogModule;
   if (!sLogModule) {
     sLogModule = PR_NewLogModule("SourceBufferResource");
@@ -167,17 +166,17 @@ SourceBufferResource::EvictBefore(uint64
   }
 }
 
 void
 SourceBufferResource::AppendData(const uint8_t* aData, uint32_t aLength)
 {
   SBR_DEBUG("SourceBufferResource(%p)::AppendData(aData=%p, aLength=%u)", this, aData, aLength);
   ReentrantMonitorAutoEnter mon(mMonitor);
-  mInputBuffer.PushBack(new ResourceItem(aData, aLength));
+  mInputBuffer.AppendItem(aData, aLength);
   mon.NotifyAll();
 }
 
 void
 SourceBufferResource::Ended()
 {
   SBR_DEBUG("SourceBufferResource(%p)::Ended()", this);
   ReentrantMonitorAutoEnter mon(mMonitor);
--- a/content/media/mediasource/SourceBufferResource.h
+++ b/content/media/mediasource/SourceBufferResource.h
@@ -2,204 +2,45 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_SOURCEBUFFERRESOURCE_H_
 #define MOZILLA_SOURCEBUFFERRESOURCE_H_
 
-#include <algorithm>
 #include "MediaCache.h"
 #include "MediaResource.h"
+#include "ResourceQueue.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "nsCOMPtr.h"
 #include "nsError.h"
 #include "nsIPrincipal.h"
-#include "nsStringGlue.h"
+#include "nsString.h"
 #include "nsTArray.h"
-#include "nsDeque.h"
 #include "nscore.h"
 
 class nsIStreamListener;
 
 namespace mozilla {
 
 class MediaDecoder;
 
 namespace dom {
 
 class SourceBuffer;
 
 }  // namespace dom
 
 class SourceBufferResource MOZ_FINAL : public MediaResource
 {
-private:
-  // A SourceBufferResource has a queue containing the data
-  // that is appended to it. The queue holds instances of
-  // ResourceItem which is an array of the bytes. Appending
-  // data to the SourceBufferResource pushes this onto the
-  // queue. As items are played they are taken off the front
-  // of the queue.
-  // Data is evicted once it reaches a size threshold. This
-  // pops the items off the front of the queue and deletes it.
-  // If an eviction happens then the MediaSource is notified
-  // (done in SourceBuffer::AppendData) which then requests
-  // all SourceBuffers to evict data up to approximately
-  // the same timepoint.
-  struct ResourceItem {
-    ResourceItem(uint8_t const* aData, uint32_t aSize) {
-      mData.AppendElements(aData, aSize);
-    }
-    nsTArray<uint8_t> mData;
-
-    size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
-      // size including this
-      size_t size = aMallocSizeOf(this);
-
-      // size excluding this
-      size += mData.SizeOfExcludingThis(aMallocSizeOf);
-
-      return size;
-    }
-  };
-
-  class ResourceQueueDeallocator : public nsDequeFunctor {
-    virtual void* operator() (void* aObject) {
-      delete static_cast<ResourceItem*>(aObject);
-      return nullptr;
-    }
-  };
-
-  class ResourceQueue : private nsDeque {
-  public:
-    ResourceQueue() :
-      nsDeque(new ResourceQueueDeallocator()),
-      mLogicalLength(0),
-      mOffset(0)
-    {
-    }
-
-    // Returns the logical byte offset of the start of the data.
-    inline uint64_t GetOffset() {
-      return mOffset;
-    }
-
-    // Returns the length of all items in the queue plus the offset.
-    // This is the logical length of the resource.
-    inline uint64_t GetLength() {
-      return mLogicalLength;
-    }
-
-    // Copies aCount bytes from aOffset in the queue into aDest.
-    inline void CopyData(uint64_t aOffset, uint32_t aCount, char* aDest) {
-      uint32_t offset = 0;
-      uint32_t start = GetAtOffset(aOffset, &offset);
-      uint32_t end = std::min(GetAtOffset(aOffset + aCount, nullptr) + 1, GetSize());
-      for (uint32_t i = start; i < end; ++i) {
-        ResourceItem* item = ResourceAt(i);
-        uint32_t bytes = std::min(aCount, uint32_t(item->mData.Length() - offset));
-        if (bytes != 0) {
-          memcpy(aDest, &item->mData[offset], bytes);
-          offset = 0;
-          aCount -= bytes;
-          aDest += bytes;
-        }
-      }
-    }
-
-    inline void PushBack(ResourceItem* aItem) {
-      mLogicalLength += aItem->mData.Length();
-      nsDeque::Push(aItem);
-    }
-
-    // Evict data in queue if the total queue size is greater than
-    // aThreshold past the offset. Returns true if some data was
-    // actually evicted.
-    inline bool Evict(uint64_t aOffset, uint32_t aThreshold) {
-      bool evicted = false;
-      while (GetLength() - mOffset > aThreshold) {
-        ResourceItem* item = ResourceAt(0);
-        if (item->mData.Length() + mOffset > aOffset) {
-          break;
-        }
-        mOffset += item->mData.Length();
-        delete PopFront();
-        evicted = true;
-      }
-      return evicted;
-    }
-
-    size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const {
-      // Calculate the size of the internal deque.
-      size_t size = nsDeque::SizeOfExcludingThis(aMallocSizeOf);
-
-      // Sum the ResourceItems.
-      for (int32_t i = 0; i < nsDeque::GetSize(); ++i) {
-        const ResourceItem* item =
-            static_cast<const ResourceItem*>(nsDeque::ObjectAt(i));
-        size += item->SizeOfIncludingThis(aMallocSizeOf);
-      }
-
-      return size;
-    }
-
-  private:
-    // Returns the number of items in the queue
-    inline uint32_t GetSize() {
-      return nsDeque::GetSize();
-    }
-
-    inline ResourceItem* ResourceAt(uint32_t aIndex) {
-      return static_cast<ResourceItem*>(nsDeque::ObjectAt(aIndex));
-    }
-
-    // Returns the index of the resource that contains the given
-    // logical offset. aResourceOffset will contain the offset into
-    // the resource at the given index returned if it is not null.  If
-    // no such resource exists, returns GetSize() and aOffset is
-    // untouched.
-    inline uint32_t GetAtOffset(uint64_t aOffset, uint32_t *aResourceOffset) {
-      MOZ_ASSERT(aOffset >= mOffset);
-      uint64_t offset = mOffset;
-      for (uint32_t i = 0; i < GetSize(); ++i) {
-        ResourceItem* item = ResourceAt(i);
-        // If the item contains the start of the offset we want to
-        // break out of the loop.
-        if (item->mData.Length() + offset > aOffset) {
-          if (aResourceOffset) {
-            *aResourceOffset = aOffset - offset;
-          }
-          return i;
-        }
-        offset += item->mData.Length();
-      }
-      return GetSize();
-    }
-
-    inline ResourceItem* PopFront() {
-      return static_cast<ResourceItem*>(nsDeque::PopFront());
-    }
-
-    // Logical length of the resource.
-    uint64_t mLogicalLength;
-
-    // Logical offset into the resource of the first element in the queue.
-    uint64_t mOffset;
-  };
-
 public:
   SourceBufferResource(nsIPrincipal* aPrincipal,
                        const nsACString& aType);
-protected:
-  ~SourceBufferResource();
-
-public:
   virtual nsresult Close() MOZ_OVERRIDE;
   virtual void Suspend(bool aCloseImmediately) MOZ_OVERRIDE {}
   virtual void Resume() MOZ_OVERRIDE {}
 
   virtual already_AddRefed<nsIPrincipal> GetCurrentPrincipal() MOZ_OVERRIDE
   {
     return nsCOMPtr<nsIPrincipal>(mPrincipal).forget();
   }
@@ -267,28 +108,29 @@ public:
   // Remove data from resource if it holds more than the threshold
   // number of bytes. Returns true if some data was evicted.
   bool EvictData(uint32_t aThreshold);
 
   // Remove data from resource before the given offset.
   void EvictBefore(uint64_t aOffset);
 
 private:
+  ~SourceBufferResource();
   nsresult SeekInternal(int64_t aOffset);
 
   nsCOMPtr<nsIPrincipal> mPrincipal;
   const nsCString mType;
 
   // Provides synchronization between SourceBuffers and InputAdapters.
   // Protects all of the member variables below.  Read() will await a
   // Notify() (from Seek, AppendData, Ended, or Close) when insufficient
   // data is available in mData.
   mutable ReentrantMonitor mMonitor;
 
-  // The buffer holding resource data is a queue of ResourceItem's.
+  // The buffer holding resource data.
   ResourceQueue mInputBuffer;
 
   uint64_t mOffset;
   bool mClosed;
   bool mEnded;
 };
 
 } // namespace mozilla