michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim: set ts=8 sts=2 et sw=2 tw=80: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "SourceBufferList.h" michael@0: michael@0: #include "AsyncEventRunner.h" michael@0: #include "mozilla/ErrorResult.h" michael@0: #include "mozilla/dom/SourceBufferListBinding.h" michael@0: #include "mozilla/mozalloc.h" michael@0: #include "nsCOMPtr.h" michael@0: #include "nsIEventTarget.h" michael@0: #include "nsIRunnable.h" michael@0: #include "nsStringGlue.h" michael@0: #include "nsThreadUtils.h" michael@0: #include "prlog.h" michael@0: michael@0: struct JSContext; michael@0: class JSObject; michael@0: michael@0: #ifdef PR_LOGGING michael@0: extern PRLogModuleInfo* gMediaSourceLog; michael@0: #define MSE_DEBUG(...) PR_LOG(gMediaSourceLog, PR_LOG_DEBUG, (__VA_ARGS__)) michael@0: #else michael@0: #define MSE_DEBUG(...) michael@0: #endif michael@0: michael@0: namespace mozilla { michael@0: michael@0: namespace dom { michael@0: michael@0: SourceBuffer* michael@0: SourceBufferList::IndexedGetter(uint32_t aIndex, bool& aFound) michael@0: { michael@0: aFound = aIndex < mSourceBuffers.Length(); michael@0: return aFound ? mSourceBuffers[aIndex] : nullptr; michael@0: } michael@0: michael@0: uint32_t michael@0: SourceBufferList::Length() michael@0: { michael@0: return mSourceBuffers.Length(); michael@0: } michael@0: michael@0: void michael@0: SourceBufferList::Append(SourceBuffer* aSourceBuffer) michael@0: { michael@0: mSourceBuffers.AppendElement(aSourceBuffer); michael@0: QueueAsyncSimpleEvent("addsourcebuffer"); michael@0: } michael@0: michael@0: void michael@0: SourceBufferList::Remove(SourceBuffer* aSourceBuffer) michael@0: { michael@0: MOZ_ALWAYS_TRUE(mSourceBuffers.RemoveElement(aSourceBuffer)); michael@0: aSourceBuffer->Detach(); michael@0: QueueAsyncSimpleEvent("removesourcebuffer"); michael@0: } michael@0: michael@0: bool michael@0: SourceBufferList::Contains(SourceBuffer* aSourceBuffer) michael@0: { michael@0: return mSourceBuffers.Contains(aSourceBuffer); michael@0: } michael@0: michael@0: void michael@0: SourceBufferList::Clear() michael@0: { michael@0: for (uint32_t i = 0; i < mSourceBuffers.Length(); ++i) { michael@0: mSourceBuffers[i]->Detach(); michael@0: } michael@0: mSourceBuffers.Clear(); michael@0: QueueAsyncSimpleEvent("removesourcebuffer"); michael@0: } michael@0: michael@0: bool michael@0: SourceBufferList::IsEmpty() michael@0: { michael@0: return mSourceBuffers.IsEmpty(); michael@0: } michael@0: michael@0: bool michael@0: SourceBufferList::AnyUpdating() michael@0: { michael@0: for (uint32_t i = 0; i < mSourceBuffers.Length(); ++i) { michael@0: if (mSourceBuffers[i]->Updating()) { michael@0: return true; michael@0: } michael@0: } michael@0: return false; michael@0: } michael@0: michael@0: void michael@0: SourceBufferList::Remove(double aStart, double aEnd, ErrorResult& aRv) michael@0: { michael@0: for (uint32_t i = 0; i < mSourceBuffers.Length(); ++i) { michael@0: mSourceBuffers[i]->Remove(aStart, aEnd, aRv); michael@0: if (aRv.Failed()) { michael@0: return; michael@0: } michael@0: } michael@0: } michael@0: michael@0: void michael@0: SourceBufferList::Evict(double aStart, double aEnd) michael@0: { michael@0: for (uint32_t i = 0; i < mSourceBuffers.Length(); ++i) { michael@0: mSourceBuffers[i]->Evict(aStart, aEnd); michael@0: } michael@0: } michael@0: michael@0: bool michael@0: SourceBufferList::AllContainsTime(double aTime) michael@0: { michael@0: for (uint32_t i = 0; i < mSourceBuffers.Length(); ++i) { michael@0: if (!mSourceBuffers[i]->ContainsTime(aTime)) { michael@0: return false; michael@0: } michael@0: } michael@0: return mSourceBuffers.Length() > 0; michael@0: } michael@0: michael@0: void michael@0: SourceBufferList::Ended() michael@0: { michael@0: for (uint32_t i = 0; i < mSourceBuffers.Length(); ++i) { michael@0: mSourceBuffers[i]->Ended(); michael@0: } michael@0: } michael@0: michael@0: void michael@0: SourceBufferList::DispatchSimpleEvent(const char* aName) michael@0: { michael@0: MSE_DEBUG("%p Dispatching event %s to SourceBufferList", this, aName); michael@0: DispatchTrustedEvent(NS_ConvertUTF8toUTF16(aName)); michael@0: } michael@0: michael@0: void michael@0: SourceBufferList::QueueAsyncSimpleEvent(const char* aName) michael@0: { michael@0: MSE_DEBUG("%p Queuing event %s to SourceBufferList", this, aName); michael@0: nsCOMPtr event = new AsyncEventRunner(this, aName); michael@0: NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL); michael@0: } michael@0: michael@0: SourceBufferList::SourceBufferList(MediaSource* aMediaSource) michael@0: : DOMEventTargetHelper(aMediaSource->GetParentObject()) michael@0: , mMediaSource(aMediaSource) michael@0: { michael@0: MOZ_ASSERT(aMediaSource); michael@0: } michael@0: michael@0: MediaSource* michael@0: SourceBufferList::GetParentObject() const michael@0: { michael@0: return mMediaSource; michael@0: } michael@0: michael@0: JSObject* michael@0: SourceBufferList::WrapObject(JSContext* aCx) michael@0: { michael@0: return SourceBufferListBinding::Wrap(aCx, this); michael@0: } michael@0: michael@0: NS_IMPL_CYCLE_COLLECTION_INHERITED(SourceBufferList, DOMEventTargetHelper, michael@0: mMediaSource, mSourceBuffers) michael@0: michael@0: NS_IMPL_ADDREF_INHERITED(SourceBufferList, DOMEventTargetHelper) michael@0: NS_IMPL_RELEASE_INHERITED(SourceBufferList, DOMEventTargetHelper) michael@0: michael@0: NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(SourceBufferList) michael@0: NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper) michael@0: michael@0: } // namespace dom michael@0: michael@0: } // namespace mozilla