123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* 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 "SourceBufferResource.h"
- #include <algorithm>
- #include "nsISeekableStream.h"
- #include "nsISupports.h"
- #include "mozilla/Logging.h"
- #include "MediaData.h"
- mozilla::LogModule* GetSourceBufferResourceLog()
- {
- static mozilla::LazyLogModule sLogModule("SourceBufferResource");
- return sLogModule;
- }
- #define SBR_DEBUG(arg, ...) MOZ_LOG(GetSourceBufferResourceLog(), mozilla::LogLevel::Debug, ("SourceBufferResource(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
- #define SBR_DEBUGV(arg, ...) MOZ_LOG(GetSourceBufferResourceLog(), mozilla::LogLevel::Verbose, ("SourceBufferResource(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
- namespace mozilla {
- nsresult
- SourceBufferResource::Close()
- {
- ReentrantMonitorAutoEnter mon(mMonitor);
- SBR_DEBUG("Close");
- //MOZ_ASSERT(!mClosed);
- mClosed = true;
- mon.NotifyAll();
- return NS_OK;
- }
- nsresult
- SourceBufferResource::ReadAt(int64_t aOffset, char* aBuffer, uint32_t aCount, uint32_t* aBytes)
- {
- SBR_DEBUG("ReadAt(aOffset=%lld, aBuffer=%p, aCount=%u, aBytes=%p)",
- aOffset, aBytes, aCount, aBytes);
- ReentrantMonitorAutoEnter mon(mMonitor);
- return ReadAtInternal(aOffset, aBuffer, aCount, aBytes, /* aMayBlock = */ true);
- }
- nsresult
- SourceBufferResource::ReadAtInternal(int64_t aOffset, char* aBuffer, uint32_t aCount, uint32_t* aBytes,
- bool aMayBlock)
- {
- mMonitor.AssertCurrentThreadIn();
- MOZ_ASSERT_IF(!aMayBlock, aBytes);
- if (mClosed ||
- aOffset < 0 ||
- uint64_t(aOffset) < mInputBuffer.GetOffset() ||
- aOffset > GetLength()) {
- return NS_ERROR_FAILURE;
- }
- while (aMayBlock &&
- !mEnded &&
- aOffset + aCount > GetLength()) {
- SBR_DEBUGV("waiting for data");
- mMonitor.Wait();
- // The callers of this function should have checked this, but it's
- // possible that we had an eviction while waiting on the monitor.
- if (uint64_t(aOffset) < mInputBuffer.GetOffset()) {
- return NS_ERROR_FAILURE;
- }
- }
- uint32_t available = GetLength() - aOffset;
- uint32_t count = std::min(aCount, available);
- // Keep the position of the last read to have Tell() approximately give us
- // the position we're up to in the stream.
- mOffset = aOffset + count;
- SBR_DEBUGV("offset=%llu GetLength()=%u available=%u count=%u mEnded=%d",
- aOffset, GetLength(), available, count, mEnded);
- if (available == 0) {
- SBR_DEBUGV("reached EOF");
- *aBytes = 0;
- return NS_OK;
- }
- mInputBuffer.CopyData(aOffset, count, aBuffer);
- *aBytes = count;
- return NS_OK;
- }
- nsresult
- SourceBufferResource::ReadFromCache(char* aBuffer, int64_t aOffset, uint32_t aCount)
- {
- SBR_DEBUG("ReadFromCache(aBuffer=%p, aOffset=%lld, aCount=%u)",
- aBuffer, aOffset, aCount);
- ReentrantMonitorAutoEnter mon(mMonitor);
- uint32_t bytesRead;
- nsresult rv = ReadAtInternal(aOffset, aBuffer, aCount, &bytesRead, /* aMayBlock = */ false);
- NS_ENSURE_SUCCESS(rv, rv);
- // ReadFromCache return failure if not all the data is cached.
- return bytesRead == aCount ? NS_OK : NS_ERROR_FAILURE;
- }
- uint32_t
- SourceBufferResource::EvictData(uint64_t aPlaybackOffset, int64_t aThreshold,
- ErrorResult& aRv)
- {
- SBR_DEBUG("EvictData(aPlaybackOffset=%llu,"
- "aThreshold=%u)", aPlaybackOffset, aThreshold);
- ReentrantMonitorAutoEnter mon(mMonitor);
- uint32_t result = mInputBuffer.Evict(aPlaybackOffset, aThreshold, aRv);
- if (result > 0) {
- // Wake up any waiting threads in case a ReadInternal call
- // is now invalid.
- mon.NotifyAll();
- }
- return result;
- }
- void
- SourceBufferResource::EvictBefore(uint64_t aOffset, ErrorResult& aRv)
- {
- SBR_DEBUG("EvictBefore(aOffset=%llu)", aOffset);
- ReentrantMonitorAutoEnter mon(mMonitor);
- mInputBuffer.EvictBefore(aOffset, aRv);
- // Wake up any waiting threads in case a ReadInternal call
- // is now invalid.
- mon.NotifyAll();
- }
- uint32_t
- SourceBufferResource::EvictAll()
- {
- SBR_DEBUG("EvictAll()");
- ReentrantMonitorAutoEnter mon(mMonitor);
- return mInputBuffer.EvictAll();
- }
- void
- SourceBufferResource::AppendData(MediaByteBuffer* aData)
- {
- SBR_DEBUG("AppendData(aData=%p, aLength=%u)",
- aData->Elements(), aData->Length());
- ReentrantMonitorAutoEnter mon(mMonitor);
- mInputBuffer.AppendItem(aData);
- mEnded = false;
- mon.NotifyAll();
- }
- void
- SourceBufferResource::Ended()
- {
- SBR_DEBUG("");
- ReentrantMonitorAutoEnter mon(mMonitor);
- mEnded = true;
- mon.NotifyAll();
- }
- SourceBufferResource::~SourceBufferResource()
- {
- SBR_DEBUG("");
- MOZ_COUNT_DTOR(SourceBufferResource);
- }
- SourceBufferResource::SourceBufferResource(const nsACString& aType)
- : mType(aType)
- , mMonitor("mozilla::SourceBufferResource::mMonitor")
- , mOffset(0)
- , mClosed(false)
- , mEnded(false)
- {
- SBR_DEBUG("");
- MOZ_COUNT_CTOR(SourceBufferResource);
- }
- #undef SBR_DEBUG
- #undef SBR_DEBUGV
- } // namespace mozilla
|