gecko-dev/dom/media/mediasource/SourceBufferResource.h

161 строка
4.3 KiB
C
Исходник Обычный вид История

/* -*- 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_SOURCEBUFFERRESOURCE_H_
#define MOZILLA_SOURCEBUFFERRESOURCE_H_
#include "mozilla/Logging.h"
#include "MediaResource.h"
#include "nsIPrincipal.h"
#include "ResourceQueue.h"
#define UNIMPLEMENTED() { /* Logging this is too spammy to do by default */ }
namespace mozilla {
class MediaByteBuffer;
class TaskQueue;
namespace dom {
class SourceBuffer;
} // namespace dom
// SourceBufferResource is not thread safe.
class SourceBufferResource final : public MediaResource
{
public:
SourceBufferResource();
nsresult Close();
already_AddRefed<nsIPrincipal> GetCurrentPrincipal() override
{
UNIMPLEMENTED();
return nullptr;
}
nsresult ReadAt(int64_t aOffset,
char* aBuffer,
uint32_t aCount,
uint32_t* aBytes) override;
// Memory-based and no locks, caching discouraged.
bool ShouldCacheReads() override { return false; }
int64_t Tell() override { return mOffset; }
void Pin() override { UNIMPLEMENTED(); }
void Unpin() override { UNIMPLEMENTED(); }
int64_t GetLength() override { return mInputBuffer.GetLength(); }
int64_t GetNextCachedData(int64_t aOffset) override
{
MOZ_ASSERT(OnTaskQueue());
MOZ_ASSERT(aOffset >= 0);
if (uint64_t(aOffset) < mInputBuffer.GetOffset()) {
return mInputBuffer.GetOffset();
} else if (aOffset == GetLength()) {
return -1;
}
return aOffset;
}
int64_t GetCachedDataEnd(int64_t aOffset) override
{
MOZ_ASSERT(OnTaskQueue());
MOZ_ASSERT(aOffset >= 0);
if (uint64_t(aOffset) < mInputBuffer.GetOffset() ||
aOffset >= GetLength()) {
// aOffset is outside of the buffered range.
return aOffset;
}
return GetLength();
}
bool IsDataCachedToEndOfResource(int64_t aOffset) override { return false; }
nsresult ReadFromCache(char* aBuffer,
int64_t aOffset,
uint32_t aCount) override;
nsresult GetCachedRanges(MediaByteRangeSet& aRanges) override
{
MOZ_ASSERT(OnTaskQueue());
if (mInputBuffer.GetLength()) {
aRanges += MediaByteRange(mInputBuffer.GetOffset(),
mInputBuffer.GetLength());
}
return NS_OK;
}
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override
{
MOZ_ASSERT(OnTaskQueue());
size_t size = MediaResource::SizeOfExcludingThis(aMallocSizeOf);
size += mInputBuffer.SizeOfExcludingThis(aMallocSizeOf);
return size;
}
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override
{
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
// Used by SourceBuffer.
void AppendData(MediaByteBuffer* aData);
void Ended();
bool IsEnded()
{
MOZ_ASSERT(OnTaskQueue());
return mEnded;
}
// Remove data from resource if it holds more than the threshold reduced by
// the given number of bytes. Returns amount evicted.
uint32_t EvictData(uint64_t aPlaybackOffset, int64_t aThresholdReduct,
ErrorResult& aRv);
// Remove data from resource before the given offset.
void EvictBefore(uint64_t aOffset, ErrorResult& aRv);
Bug 1055904 - Improve MSE eviction calculation - r=jya Fixes a bug in the SourceBufferResource eviction code where it was using the mOffset of the resource as the min bound for what to evict. This offset is almost always zero though due to ReadFromCache being used which never updates the offset. This prevented eviction from happening in most cases. Moves the code to remove old decoders so that it does this during the same loop as that which remove data from existing decoders. This more aggressively prunes old decoders and is more likely to keep data in the current playing decoder around for seeking, etc. Prevent removing any decoder that the MediaSourceReader is currently using for playback to prevent RemoveDecoder crashes. Add a threshold to subtract from the current time when working out the time bound to evict before to make it less likely to evict current data that is needed for current playback. Remove all data from evicted decoders in the initial iteration then iterate after to remove empty decoders to put the RemoveDecoder logic in one place. Iterate decoders in order that they were added rather than sorted by time so the logic that removes entire decoders can do it only to those old decoders that existed before the existing one was created. Keeps track of the time that was evicted from the current decoder and uses that as the time to EvictBefore for all decoders in the track buffer when doing MediaSource::NotifyEvict. --HG-- extra : rebase_source : f7b4fe263a8041b3882585caea389742b2a1a9b3
2015-01-16 06:14:56 +03:00
// Remove all data from the resource
uint32_t EvictAll();
// Returns the amount of data currently retained by this resource.
int64_t GetSize()
{
MOZ_ASSERT(OnTaskQueue());
return mInputBuffer.GetLength() - mInputBuffer.GetOffset();
}
#if defined(DEBUG)
void Dump(const char* aPath)
{
mInputBuffer.Dump(aPath);
}
#endif
private:
virtual ~SourceBufferResource();
nsresult ReadAtInternal(int64_t aOffset,
char* aBuffer,
uint32_t aCount,
uint32_t* aBytes);
#if defined(DEBUG)
const RefPtr<TaskQueue> mTaskQueue;
// TaskQueue methods and objects.
AbstractThread* GetTaskQueue() const;
bool OnTaskQueue() const;
#endif
// The buffer holding resource data.
ResourceQueue mInputBuffer;
uint64_t mOffset;
bool mClosed;
bool mEnded;
};
} // namespace mozilla
#undef UNIMPLEMENTED
#endif /* MOZILLA_SOURCEBUFFERRESOURCE_H_ */