summaryrefslogtreecommitdiffstats
path: root/dom/media/mediasource/ResourceQueue.cpp
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /dom/media/mediasource/ResourceQueue.cpp
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'dom/media/mediasource/ResourceQueue.cpp')
-rw-r--r--dom/media/mediasource/ResourceQueue.cpp214
1 files changed, 214 insertions, 0 deletions
diff --git a/dom/media/mediasource/ResourceQueue.cpp b/dom/media/mediasource/ResourceQueue.cpp
new file mode 100644
index 000000000..5ca29ad37
--- /dev/null
+++ b/dom/media/mediasource/ResourceQueue.cpp
@@ -0,0 +1,214 @@
+/* -*- 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/. */
+
+#include "ResourceQueue.h"
+#include "nsDeque.h"
+#include "MediaData.h"
+#include "mozilla/ErrorResult.h"
+#include "mozilla/Logging.h"
+#include "mozilla/Sprintf.h"
+
+extern mozilla::LogModule* GetSourceBufferResourceLog();
+
+#define SBR_DEBUG(arg, ...) MOZ_LOG(GetSourceBufferResourceLog(), mozilla::LogLevel::Debug, ("ResourceQueue(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
+#define SBR_DEBUGV(arg, ...) MOZ_LOG(GetSourceBufferResourceLog(), mozilla::LogLevel::Verbose, ("ResourceQueue(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
+
+namespace mozilla {
+
+ResourceItem::ResourceItem(MediaByteBuffer* aData)
+ : mData(aData)
+{
+}
+
+size_t
+ResourceItem::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
+{
+ // size including this
+ size_t size = aMallocSizeOf(this);
+
+ // size excluding this
+ size += mData->ShallowSizeOfExcludingThis(aMallocSizeOf);
+
+ return size;
+}
+
+class ResourceQueueDeallocator : public nsDequeFunctor {
+ void* operator() (void* aObject) override {
+ delete static_cast<ResourceItem*>(aObject);
+ return nullptr;
+ }
+};
+
+ResourceQueue::ResourceQueue()
+ : nsDeque(new ResourceQueueDeallocator())
+ , mLogicalLength(0)
+ , mOffset(0)
+{
+}
+
+uint64_t
+ResourceQueue::GetOffset()
+{
+ return mOffset;
+}
+
+uint64_t
+ResourceQueue::GetLength()
+{
+ return mLogicalLength;
+}
+
+void
+ResourceQueue::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
+ResourceQueue::AppendItem(MediaByteBuffer* aData)
+{
+ mLogicalLength += aData->Length();
+ Push(new ResourceItem(aData));
+}
+
+uint32_t
+ResourceQueue::Evict(uint64_t aOffset, uint32_t aSizeToEvict,
+ ErrorResult& aRv)
+{
+ SBR_DEBUG("Evict(aOffset=%llu, aSizeToEvict=%u)",
+ aOffset, aSizeToEvict);
+ return EvictBefore(std::min(aOffset, mOffset + (uint64_t)aSizeToEvict), aRv);
+}
+
+uint32_t ResourceQueue::EvictBefore(uint64_t aOffset, ErrorResult& aRv)
+{
+ SBR_DEBUG("EvictBefore(%llu)", aOffset);
+ uint32_t evicted = 0;
+ while (ResourceItem* item = ResourceAt(0)) {
+ SBR_DEBUG("item=%p length=%d offset=%llu",
+ item, item->mData->Length(), mOffset);
+ if (item->mData->Length() + mOffset >= aOffset) {
+ if (aOffset <= mOffset) {
+ break;
+ }
+ uint32_t offset = aOffset - mOffset;
+ mOffset += offset;
+ evicted += offset;
+ RefPtr<MediaByteBuffer> data = new MediaByteBuffer;
+ if (!data->AppendElements(item->mData->Elements() + offset,
+ item->mData->Length() - offset,
+ fallible)) {
+ aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
+ return 0;
+ }
+
+ item->mData = data;
+ break;
+ }
+ mOffset += item->mData->Length();
+ evicted += item->mData->Length();
+ delete PopFront();
+ }
+ return evicted;
+}
+
+uint32_t
+ResourceQueue::EvictAll()
+{
+ SBR_DEBUG("EvictAll()");
+ uint32_t evicted = 0;
+ while (ResourceItem* item = ResourceAt(0)) {
+ SBR_DEBUG("item=%p length=%d offset=%llu",
+ item, item->mData->Length(), mOffset);
+ mOffset += item->mData->Length();
+ evicted += item->mData->Length();
+ delete PopFront();
+ }
+ return evicted;
+}
+
+size_t
+ResourceQueue::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;
+}
+
+#if defined(DEBUG)
+void
+ResourceQueue::Dump(const char* aPath)
+{
+ for (uint32_t i = 0; i < uint32_t(GetSize()); ++i) {
+ ResourceItem* item = ResourceAt(i);
+
+ char buf[255];
+ SprintfLiteral(buf, "%s/%08u.bin", aPath, i);
+ FILE* fp = fopen(buf, "wb");
+ if (!fp) {
+ return;
+ }
+ fwrite(item->mData->Elements(), item->mData->Length(), 1, fp);
+ fclose(fp);
+ }
+}
+#endif
+
+ResourceItem*
+ResourceQueue::ResourceAt(uint32_t aIndex) const
+{
+ return static_cast<ResourceItem*>(ObjectAt(aIndex));
+}
+
+uint32_t
+ResourceQueue::GetAtOffset(uint64_t aOffset, uint32_t *aResourceOffset)
+{
+ MOZ_RELEASE_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*
+ResourceQueue::PopFront()
+{
+ return static_cast<ResourceItem*>(nsDeque::PopFront());
+}
+
+#undef SBR_DEBUG
+#undef SBR_DEBUGV
+
+} // namespace mozilla