2008-10-19 07:39:21 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
2012-05-21 11:12:37 +00:00
|
|
|
/* 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/. */
|
2011-08-11 13:29:50 +00:00
|
|
|
|
2012-02-15 04:35:01 +00:00
|
|
|
#include "MediaResource.h"
|
2017-11-13 06:16:06 +00:00
|
|
|
#include "mozilla/DebugOnly.h"
|
2017-10-04 18:57:11 +00:00
|
|
|
#include "mozilla/Logging.h"
|
2017-11-13 06:16:06 +00:00
|
|
|
#include "mozilla/MathAlgorithms.h"
|
2017-10-04 18:57:11 +00:00
|
|
|
#include "mozilla/ErrorNames.h"
|
2020-04-07 15:16:33 +00:00
|
|
|
#include "mozilla/SchedulerGroup.h"
|
2011-08-11 13:29:50 +00:00
|
|
|
|
2015-05-28 19:13:56 +00:00
|
|
|
using mozilla::media::TimeUnit;
|
|
|
|
|
2017-05-30 02:12:38 +00:00
|
|
|
#undef ILOG
|
2017-04-05 09:38:20 +00:00
|
|
|
|
2017-05-30 02:12:38 +00:00
|
|
|
mozilla::LazyLogModule gMediaResourceIndexLog("MediaResourceIndex");
|
|
|
|
// Debug logging macro with object pointer and class name.
|
|
|
|
#define ILOG(msg, ...) \
|
2017-10-13 05:31:59 +00:00
|
|
|
DDMOZ_LOG(gMediaResourceIndexLog, mozilla::LogLevel::Debug, msg, \
|
|
|
|
##__VA_ARGS__)
|
2017-05-30 02:12:38 +00:00
|
|
|
|
2012-11-14 19:45:33 +00:00
|
|
|
namespace mozilla {
|
2009-04-11 09:39:24 +00:00
|
|
|
|
2017-11-13 06:16:06 +00:00
|
|
|
static const uint32_t kMediaResourceIndexCacheSize = 8192;
|
|
|
|
static_assert(IsPowerOfTwo(kMediaResourceIndexCacheSize),
|
|
|
|
"kMediaResourceIndexCacheSize cache size must be a power of 2");
|
|
|
|
|
2017-10-04 19:25:19 +00:00
|
|
|
MediaResourceIndex::MediaResourceIndex(MediaResource* aResource)
|
|
|
|
: mResource(aResource),
|
|
|
|
mOffset(0),
|
|
|
|
mCacheBlockSize(
|
|
|
|
aResource->ShouldCacheReads() ? kMediaResourceIndexCacheSize : 0),
|
|
|
|
mCachedOffset(0),
|
|
|
|
mCachedBytes(0),
|
|
|
|
mCachedBlock(MakeUnique<char[]>(mCacheBlockSize)) {
|
Bug 1407810 - Use DDLogger in media stack - r=jwwang
Mostly-mechanical additions:
- Log constructions&destructions, usually by just inheriting from
DecoderDoctorLifeLogger, otherwise with explicit log commands (for internal
classes for which DecoderDoctorTraits can't be specialized),
- Log links between most objects, e.g.: Media element -> decoder -> state
machine -> reader -> demuxer -> resource, etc.
And logging some important properties and events (JS events, duration change,
frames being decoded, etc.)
More will be added later on, from just converting MOZ_LOGs, and as needed.
MozReview-Commit-ID: KgNhHSz35t0
--HG--
extra : rebase_source : dd7206e350e32671adc6f3b9e54ebf777251de2c
2017-10-10 06:55:27 +00:00
|
|
|
DDLINKCHILD("resource", aResource);
|
2017-10-04 19:25:19 +00:00
|
|
|
}
|
|
|
|
|
2015-08-13 01:15:48 +00:00
|
|
|
nsresult MediaResourceIndex::Read(char* aBuffer, uint32_t aCount,
|
|
|
|
uint32_t* aBytes) {
|
|
|
|
NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
|
|
|
|
|
|
|
|
// We purposefuly don't check that we may attempt to read past
|
|
|
|
// mResource->GetLength() as the resource's length may change over time.
|
|
|
|
|
2015-08-13 01:18:34 +00:00
|
|
|
nsresult rv = ReadAt(mOffset, aBuffer, aCount, aBytes);
|
2015-08-13 01:15:48 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
mOffset += *aBytes;
|
2017-08-01 02:07:55 +00:00
|
|
|
if (mOffset < 0) {
|
|
|
|
// Very unlikely overflow; just return to position 0.
|
|
|
|
mOffset = 0;
|
|
|
|
}
|
2015-08-13 01:15:48 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
static nsCString ResultName(nsresult aResult) {
|
|
|
|
nsCString name;
|
|
|
|
GetErrorName(aResult, name);
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult MediaResourceIndex::ReadAt(int64_t aOffset, char* aBuffer,
|
|
|
|
uint32_t aCount, uint32_t* aBytes) {
|
2017-05-30 09:43:28 +00:00
|
|
|
if (mCacheBlockSize == 0) {
|
|
|
|
return UncachedReadAt(aOffset, aBuffer, aCount, aBytes);
|
|
|
|
}
|
|
|
|
|
2015-08-13 01:18:34 +00:00
|
|
|
*aBytes = 0;
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
|
|
|
|
if (aCount == 0) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
const int64_t endOffset = aOffset + aCount;
|
2017-08-01 02:07:55 +00:00
|
|
|
if (aOffset < 0 || endOffset < aOffset) {
|
|
|
|
return NS_ERROR_ILLEGAL_VALUE;
|
|
|
|
}
|
|
|
|
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
const int64_t lastBlockOffset = CacheOffsetContaining(endOffset - 1);
|
|
|
|
|
|
|
|
if (mCachedBytes != 0 && mCachedOffset + mCachedBytes >= aOffset &&
|
|
|
|
mCachedOffset < endOffset) {
|
|
|
|
// There is data in the cache that is not completely before aOffset and not
|
|
|
|
// completely after endOffset, so it could be usable (with potential
|
|
|
|
// top-up).
|
|
|
|
if (aOffset < mCachedOffset) {
|
|
|
|
// We need to read before the cached data.
|
|
|
|
const uint32_t toRead = uint32_t(mCachedOffset - aOffset);
|
|
|
|
MOZ_ASSERT(toRead > 0);
|
|
|
|
MOZ_ASSERT(toRead < aCount);
|
|
|
|
uint32_t read = 0;
|
|
|
|
nsresult rv = UncachedReadAt(aOffset, aBuffer, toRead, &read);
|
|
|
|
if (NS_FAILED(rv)) {
|
2017-05-30 02:12:38 +00:00
|
|
|
ILOG("ReadAt(%" PRIu32 "@%" PRId64
|
|
|
|
") uncached read before cache -> %s, %" PRIu32,
|
|
|
|
aCount, aOffset, ResultName(rv).get(), *aBytes);
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
*aBytes = read;
|
|
|
|
if (read < toRead) {
|
|
|
|
// Could not read everything we wanted, we're done.
|
2017-05-30 02:12:38 +00:00
|
|
|
ILOG("ReadAt(%" PRIu32 "@%" PRId64
|
|
|
|
") uncached read before cache, incomplete -> OK, %" PRIu32,
|
|
|
|
aCount, aOffset, *aBytes);
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2017-05-30 02:12:38 +00:00
|
|
|
ILOG("ReadAt(%" PRIu32 "@%" PRId64
|
|
|
|
") uncached read before cache: %" PRIu32 ", remaining: %" PRIu32
|
|
|
|
"@%" PRId64 "...",
|
|
|
|
aCount, aOffset, read, aCount - read, aOffset + read);
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
aOffset += read;
|
|
|
|
aBuffer += read;
|
|
|
|
aCount -= read;
|
|
|
|
// We should have reached the cache.
|
|
|
|
MOZ_ASSERT(aOffset == mCachedOffset);
|
|
|
|
}
|
|
|
|
MOZ_ASSERT(aOffset >= mCachedOffset);
|
|
|
|
|
|
|
|
// We've reached our cache.
|
|
|
|
const uint32_t toCopy =
|
|
|
|
std::min(aCount, uint32_t(mCachedOffset + mCachedBytes - aOffset));
|
|
|
|
// Note that we could in fact be just after the last byte of the cache, in
|
|
|
|
// which case we can't actually read from it! (But we will top-up next.)
|
|
|
|
if (toCopy != 0) {
|
|
|
|
memcpy(aBuffer, &mCachedBlock[IndexInCache(aOffset)], toCopy);
|
|
|
|
*aBytes += toCopy;
|
|
|
|
aCount -= toCopy;
|
|
|
|
if (aCount == 0) {
|
|
|
|
// All done!
|
2017-05-30 02:12:38 +00:00
|
|
|
ILOG("ReadAt(%" PRIu32 "@%" PRId64 ") copied everything (%" PRIu32
|
|
|
|
") from cache(%" PRIu32 "@%" PRId64 ") :-D -> OK, %" PRIu32,
|
|
|
|
aCount, aOffset, toCopy, mCachedBytes, mCachedOffset, *aBytes);
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
aOffset += toCopy;
|
|
|
|
aBuffer += toCopy;
|
2017-05-30 02:12:38 +00:00
|
|
|
ILOG("ReadAt(%" PRIu32 "@%" PRId64 ") copied %" PRIu32
|
|
|
|
" from cache(%" PRIu32 "@%" PRId64 ") :-), remaining: %" PRIu32
|
|
|
|
"@%" PRId64 "...",
|
|
|
|
aCount + toCopy, aOffset - toCopy, toCopy, mCachedBytes,
|
|
|
|
mCachedOffset, aCount, aOffset);
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (aOffset - 1 >= lastBlockOffset) {
|
|
|
|
// We were already reading cached data from the last block, we need more
|
|
|
|
// from it -> try to top-up, read what we can, and we'll be done.
|
|
|
|
MOZ_ASSERT(aOffset == mCachedOffset + mCachedBytes);
|
2017-05-30 09:43:28 +00:00
|
|
|
MOZ_ASSERT(endOffset <= lastBlockOffset + mCacheBlockSize);
|
2017-05-30 02:12:38 +00:00
|
|
|
return CacheOrReadAt(aOffset, aBuffer, aCount, aBytes);
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// We were not in the last block (but we may just have crossed the line now)
|
|
|
|
MOZ_ASSERT(aOffset <= lastBlockOffset);
|
|
|
|
// Continue below...
|
|
|
|
} else if (aOffset >= lastBlockOffset) {
|
|
|
|
// There was nothing we could get from the cache.
|
|
|
|
// But we're already in the last block -> Cache or read what we can.
|
|
|
|
// Make sure to invalidate the cache first.
|
|
|
|
mCachedBytes = 0;
|
2017-05-30 02:12:38 +00:00
|
|
|
return CacheOrReadAt(aOffset, aBuffer, aCount, aBytes);
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// If we're here, either there was nothing usable in the cache, or we've just
|
|
|
|
// read what was in the cache but there's still more to read.
|
|
|
|
|
|
|
|
if (aOffset < lastBlockOffset) {
|
|
|
|
// We need to read before the last block.
|
|
|
|
// Start with an uncached read up to the last block.
|
|
|
|
const uint32_t toRead = uint32_t(lastBlockOffset - aOffset);
|
|
|
|
MOZ_ASSERT(toRead > 0);
|
|
|
|
MOZ_ASSERT(toRead < aCount);
|
|
|
|
uint32_t read = 0;
|
|
|
|
nsresult rv = UncachedReadAt(aOffset, aBuffer, toRead, &read);
|
|
|
|
if (NS_FAILED(rv)) {
|
2017-05-30 02:12:38 +00:00
|
|
|
ILOG("ReadAt(%" PRIu32 "@%" PRId64
|
|
|
|
") uncached read before last block failed -> %s, %" PRIu32,
|
|
|
|
aCount, aOffset, ResultName(rv).get(), *aBytes);
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
if (read == 0) {
|
2017-05-30 02:12:38 +00:00
|
|
|
ILOG("ReadAt(%" PRIu32 "@%" PRId64
|
|
|
|
") uncached read 0 before last block -> OK, %" PRIu32,
|
|
|
|
aCount, aOffset, *aBytes);
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
*aBytes += read;
|
|
|
|
if (read < toRead) {
|
|
|
|
// Could not read everything we wanted, we're done.
|
2017-05-30 02:12:38 +00:00
|
|
|
ILOG("ReadAt(%" PRIu32 "@%" PRId64
|
|
|
|
") uncached read before last block, incomplete -> OK, %" PRIu32,
|
|
|
|
aCount, aOffset, *aBytes);
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2017-05-30 02:12:38 +00:00
|
|
|
ILOG("ReadAt(%" PRIu32 "@%" PRId64 ") read %" PRIu32
|
|
|
|
" before last block, remaining: %" PRIu32 "@%" PRId64 "...",
|
|
|
|
aCount, aOffset, read, aCount - read, aOffset + read);
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
aOffset += read;
|
|
|
|
aBuffer += read;
|
|
|
|
aCount -= read;
|
|
|
|
}
|
|
|
|
|
|
|
|
// We should just have reached the start of the last block.
|
|
|
|
MOZ_ASSERT(aOffset == lastBlockOffset);
|
2017-05-30 09:43:28 +00:00
|
|
|
MOZ_ASSERT(aCount <= mCacheBlockSize);
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
// Make sure to invalidate the cache first.
|
|
|
|
mCachedBytes = 0;
|
2017-05-30 02:12:38 +00:00
|
|
|
return CacheOrReadAt(aOffset, aBuffer, aCount, aBytes);
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
}
|
|
|
|
|
2017-05-30 02:12:38 +00:00
|
|
|
nsresult MediaResourceIndex::CacheOrReadAt(int64_t aOffset, char* aBuffer,
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
uint32_t aCount, uint32_t* aBytes) {
|
|
|
|
// We should be here because there is more data to read.
|
|
|
|
MOZ_ASSERT(aCount > 0);
|
|
|
|
// We should be in the last block, so we shouldn't try to read past it.
|
2017-05-30 09:43:28 +00:00
|
|
|
MOZ_ASSERT(IndexInCache(aOffset) + aCount <= mCacheBlockSize);
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
|
|
|
|
const int64_t length = GetLength();
|
|
|
|
// If length is unknown (-1), look at resource-cached data.
|
|
|
|
// If length is known and equal or greater than requested, also look at
|
|
|
|
// resource-cached data.
|
|
|
|
// Otherwise, if length is known but same, or less than(!?), requested, don't
|
|
|
|
// attempt to access resource-cached data, as we're not expecting it to ever
|
|
|
|
// be greater than the length.
|
|
|
|
if (length < 0 || length >= aOffset + aCount) {
|
|
|
|
// Is there cached data covering at least the requested range?
|
|
|
|
const int64_t cachedDataEnd = mResource->GetCachedDataEnd(aOffset);
|
|
|
|
if (cachedDataEnd >= aOffset + aCount) {
|
|
|
|
// Try to read as much resource-cached data as can fill our local cache.
|
Bug 1374180 - MediaResourceIndex won't use ReadFromCache, to keep MediaCache more consistent - r=cpearce
Bug 1368837 (Add lockless cache to MediaResourceIndex) used
MediaResource::ReadFromCache when trying to fill its local cache. But this
meant that these reads would not count as "real reads" for the MediaCache,
which could lead to unexpected states, e.g. "Played block after the current
stream position?"
To solve this, this patch reverts to using normal ReadAt() calls, which let
the MediaCache update itself properly.
While still trying to read more than what is requested (to hopefully fulfill
future reads from the local cache), we don't want to be reading so much that
we block waiting for data past the caller-expected point.
To do this, MediaResourceIndex::UncachedRangedReadAt() is called to try and
read as much as could fill the local cache, but if a single
MediaResource::ReadAt() ends before we can fill the local cache, but *after*
the minimum caller-requested size, we stop trying to read, as such extra read
is at risk of blocking (assuming that the caller knows not to read too far.)
MozReview-Commit-ID: 6fGvJpmkuLz
--HG--
extra : rebase_source : bf8e9f20599a05c8f3f221b55d678f0b5da447a9
2017-06-20 23:35:00 +00:00
|
|
|
// Assume we can read as much as is cached without blocking.
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
const uint32_t cacheIndex = IndexInCache(aOffset);
|
2017-05-30 09:43:28 +00:00
|
|
|
const uint32_t toRead = uint32_t(std::min(
|
|
|
|
cachedDataEnd - aOffset, int64_t(mCacheBlockSize - cacheIndex)));
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
MOZ_ASSERT(toRead >= aCount);
|
Bug 1374180 - MediaResourceIndex won't use ReadFromCache, to keep MediaCache more consistent - r=cpearce
Bug 1368837 (Add lockless cache to MediaResourceIndex) used
MediaResource::ReadFromCache when trying to fill its local cache. But this
meant that these reads would not count as "real reads" for the MediaCache,
which could lead to unexpected states, e.g. "Played block after the current
stream position?"
To solve this, this patch reverts to using normal ReadAt() calls, which let
the MediaCache update itself properly.
While still trying to read more than what is requested (to hopefully fulfill
future reads from the local cache), we don't want to be reading so much that
we block waiting for data past the caller-expected point.
To do this, MediaResourceIndex::UncachedRangedReadAt() is called to try and
read as much as could fill the local cache, but if a single
MediaResource::ReadAt() ends before we can fill the local cache, but *after*
the minimum caller-requested size, we stop trying to read, as such extra read
is at risk of blocking (assuming that the caller knows not to read too far.)
MozReview-Commit-ID: 6fGvJpmkuLz
--HG--
extra : rebase_source : bf8e9f20599a05c8f3f221b55d678f0b5da447a9
2017-06-20 23:35:00 +00:00
|
|
|
uint32_t read = 0;
|
|
|
|
// We would like `toRead` if possible, but ok with at least `aCount`.
|
|
|
|
nsresult rv = UncachedRangedReadAt(aOffset, &mCachedBlock[cacheIndex],
|
|
|
|
aCount, toRead - aCount, &read);
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
Bug 1374180 - MediaResourceIndex won't use ReadFromCache, to keep MediaCache more consistent - r=cpearce
Bug 1368837 (Add lockless cache to MediaResourceIndex) used
MediaResource::ReadFromCache when trying to fill its local cache. But this
meant that these reads would not count as "real reads" for the MediaCache,
which could lead to unexpected states, e.g. "Played block after the current
stream position?"
To solve this, this patch reverts to using normal ReadAt() calls, which let
the MediaCache update itself properly.
While still trying to read more than what is requested (to hopefully fulfill
future reads from the local cache), we don't want to be reading so much that
we block waiting for data past the caller-expected point.
To do this, MediaResourceIndex::UncachedRangedReadAt() is called to try and
read as much as could fill the local cache, but if a single
MediaResource::ReadAt() ends before we can fill the local cache, but *after*
the minimum caller-requested size, we stop trying to read, as such extra read
is at risk of blocking (assuming that the caller knows not to read too far.)
MozReview-Commit-ID: 6fGvJpmkuLz
--HG--
extra : rebase_source : bf8e9f20599a05c8f3f221b55d678f0b5da447a9
2017-06-20 23:35:00 +00:00
|
|
|
if (read == 0) {
|
|
|
|
ILOG("ReadAt(%" PRIu32 "@%" PRId64 ") - UncachedRangedReadAt(%" PRIu32
|
|
|
|
"..%" PRIu32 "@%" PRId64
|
|
|
|
") to top-up succeeded but read nothing -> OK anyway",
|
|
|
|
aCount, aOffset, aCount, toRead, aOffset);
|
|
|
|
// Couldn't actually read anything, but didn't error out, so count
|
|
|
|
// that as success.
|
|
|
|
return NS_OK;
|
|
|
|
}
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
if (mCachedOffset + mCachedBytes == aOffset) {
|
|
|
|
// We were topping-up the cache, just update its size.
|
Bug 1374180 - MediaResourceIndex won't use ReadFromCache, to keep MediaCache more consistent - r=cpearce
Bug 1368837 (Add lockless cache to MediaResourceIndex) used
MediaResource::ReadFromCache when trying to fill its local cache. But this
meant that these reads would not count as "real reads" for the MediaCache,
which could lead to unexpected states, e.g. "Played block after the current
stream position?"
To solve this, this patch reverts to using normal ReadAt() calls, which let
the MediaCache update itself properly.
While still trying to read more than what is requested (to hopefully fulfill
future reads from the local cache), we don't want to be reading so much that
we block waiting for data past the caller-expected point.
To do this, MediaResourceIndex::UncachedRangedReadAt() is called to try and
read as much as could fill the local cache, but if a single
MediaResource::ReadAt() ends before we can fill the local cache, but *after*
the minimum caller-requested size, we stop trying to read, as such extra read
is at risk of blocking (assuming that the caller knows not to read too far.)
MozReview-Commit-ID: 6fGvJpmkuLz
--HG--
extra : rebase_source : bf8e9f20599a05c8f3f221b55d678f0b5da447a9
2017-06-20 23:35:00 +00:00
|
|
|
ILOG("ReadAt(%" PRIu32 "@%" PRId64 ") - UncachedRangedReadAt(%" PRIu32
|
|
|
|
"..%" PRIu32 "@%" PRId64 ") to top-up succeeded to read %" PRIu32
|
|
|
|
"...",
|
|
|
|
aCount, aOffset, aCount, toRead, aOffset, read);
|
|
|
|
mCachedBytes += read;
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
} else {
|
|
|
|
// We were filling the cache from scratch, save new cache information.
|
Bug 1374180 - MediaResourceIndex won't use ReadFromCache, to keep MediaCache more consistent - r=cpearce
Bug 1368837 (Add lockless cache to MediaResourceIndex) used
MediaResource::ReadFromCache when trying to fill its local cache. But this
meant that these reads would not count as "real reads" for the MediaCache,
which could lead to unexpected states, e.g. "Played block after the current
stream position?"
To solve this, this patch reverts to using normal ReadAt() calls, which let
the MediaCache update itself properly.
While still trying to read more than what is requested (to hopefully fulfill
future reads from the local cache), we don't want to be reading so much that
we block waiting for data past the caller-expected point.
To do this, MediaResourceIndex::UncachedRangedReadAt() is called to try and
read as much as could fill the local cache, but if a single
MediaResource::ReadAt() ends before we can fill the local cache, but *after*
the minimum caller-requested size, we stop trying to read, as such extra read
is at risk of blocking (assuming that the caller knows not to read too far.)
MozReview-Commit-ID: 6fGvJpmkuLz
--HG--
extra : rebase_source : bf8e9f20599a05c8f3f221b55d678f0b5da447a9
2017-06-20 23:35:00 +00:00
|
|
|
ILOG("ReadAt(%" PRIu32 "@%" PRId64 ") - UncachedRangedReadAt(%" PRIu32
|
|
|
|
"..%" PRIu32 "@%" PRId64
|
|
|
|
") to fill cache succeeded to read %" PRIu32 "...",
|
|
|
|
aCount, aOffset, aCount, toRead, aOffset, read);
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
mCachedOffset = aOffset;
|
Bug 1374180 - MediaResourceIndex won't use ReadFromCache, to keep MediaCache more consistent - r=cpearce
Bug 1368837 (Add lockless cache to MediaResourceIndex) used
MediaResource::ReadFromCache when trying to fill its local cache. But this
meant that these reads would not count as "real reads" for the MediaCache,
which could lead to unexpected states, e.g. "Played block after the current
stream position?"
To solve this, this patch reverts to using normal ReadAt() calls, which let
the MediaCache update itself properly.
While still trying to read more than what is requested (to hopefully fulfill
future reads from the local cache), we don't want to be reading so much that
we block waiting for data past the caller-expected point.
To do this, MediaResourceIndex::UncachedRangedReadAt() is called to try and
read as much as could fill the local cache, but if a single
MediaResource::ReadAt() ends before we can fill the local cache, but *after*
the minimum caller-requested size, we stop trying to read, as such extra read
is at risk of blocking (assuming that the caller knows not to read too far.)
MozReview-Commit-ID: 6fGvJpmkuLz
--HG--
extra : rebase_source : bf8e9f20599a05c8f3f221b55d678f0b5da447a9
2017-06-20 23:35:00 +00:00
|
|
|
mCachedBytes = read;
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
}
|
|
|
|
// Copy relevant part into output.
|
Bug 1374180 - MediaResourceIndex won't use ReadFromCache, to keep MediaCache more consistent - r=cpearce
Bug 1368837 (Add lockless cache to MediaResourceIndex) used
MediaResource::ReadFromCache when trying to fill its local cache. But this
meant that these reads would not count as "real reads" for the MediaCache,
which could lead to unexpected states, e.g. "Played block after the current
stream position?"
To solve this, this patch reverts to using normal ReadAt() calls, which let
the MediaCache update itself properly.
While still trying to read more than what is requested (to hopefully fulfill
future reads from the local cache), we don't want to be reading so much that
we block waiting for data past the caller-expected point.
To do this, MediaResourceIndex::UncachedRangedReadAt() is called to try and
read as much as could fill the local cache, but if a single
MediaResource::ReadAt() ends before we can fill the local cache, but *after*
the minimum caller-requested size, we stop trying to read, as such extra read
is at risk of blocking (assuming that the caller knows not to read too far.)
MozReview-Commit-ID: 6fGvJpmkuLz
--HG--
extra : rebase_source : bf8e9f20599a05c8f3f221b55d678f0b5da447a9
2017-06-20 23:35:00 +00:00
|
|
|
uint32_t toCopy = std::min(aCount, read);
|
|
|
|
memcpy(aBuffer, &mCachedBlock[cacheIndex], toCopy);
|
|
|
|
*aBytes += toCopy;
|
2017-05-30 02:12:38 +00:00
|
|
|
ILOG("ReadAt(%" PRIu32 "@%" PRId64 ") - copied %" PRIu32 "@%" PRId64
|
|
|
|
" -> OK, %" PRIu32,
|
|
|
|
aCount, aOffset, toCopy, aOffset, *aBytes);
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
// We may not have read all that was requested, but we got everything
|
|
|
|
// we could get, so we're done.
|
|
|
|
return NS_OK;
|
|
|
|
}
|
Bug 1374180 - MediaResourceIndex won't use ReadFromCache, to keep MediaCache more consistent - r=cpearce
Bug 1368837 (Add lockless cache to MediaResourceIndex) used
MediaResource::ReadFromCache when trying to fill its local cache. But this
meant that these reads would not count as "real reads" for the MediaCache,
which could lead to unexpected states, e.g. "Played block after the current
stream position?"
To solve this, this patch reverts to using normal ReadAt() calls, which let
the MediaCache update itself properly.
While still trying to read more than what is requested (to hopefully fulfill
future reads from the local cache), we don't want to be reading so much that
we block waiting for data past the caller-expected point.
To do this, MediaResourceIndex::UncachedRangedReadAt() is called to try and
read as much as could fill the local cache, but if a single
MediaResource::ReadAt() ends before we can fill the local cache, but *after*
the minimum caller-requested size, we stop trying to read, as such extra read
is at risk of blocking (assuming that the caller knows not to read too far.)
MozReview-Commit-ID: 6fGvJpmkuLz
--HG--
extra : rebase_source : bf8e9f20599a05c8f3f221b55d678f0b5da447a9
2017-06-20 23:35:00 +00:00
|
|
|
ILOG("ReadAt(%" PRIu32 "@%" PRId64 ") - UncachedRangedReadAt(%" PRIu32
|
|
|
|
"..%" PRIu32 "@%" PRId64
|
|
|
|
") failed: %s, will fallback to blocking read...",
|
2017-05-30 02:12:38 +00:00
|
|
|
aCount, aOffset, aCount, toRead, aOffset, ResultName(rv).get());
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
// Failure during reading. Note that this may be due to the cache
|
Bug 1374180 - MediaResourceIndex won't use ReadFromCache, to keep MediaCache more consistent - r=cpearce
Bug 1368837 (Add lockless cache to MediaResourceIndex) used
MediaResource::ReadFromCache when trying to fill its local cache. But this
meant that these reads would not count as "real reads" for the MediaCache,
which could lead to unexpected states, e.g. "Played block after the current
stream position?"
To solve this, this patch reverts to using normal ReadAt() calls, which let
the MediaCache update itself properly.
While still trying to read more than what is requested (to hopefully fulfill
future reads from the local cache), we don't want to be reading so much that
we block waiting for data past the caller-expected point.
To do this, MediaResourceIndex::UncachedRangedReadAt() is called to try and
read as much as could fill the local cache, but if a single
MediaResource::ReadAt() ends before we can fill the local cache, but *after*
the minimum caller-requested size, we stop trying to read, as such extra read
is at risk of blocking (assuming that the caller knows not to read too far.)
MozReview-Commit-ID: 6fGvJpmkuLz
--HG--
extra : rebase_source : bf8e9f20599a05c8f3f221b55d678f0b5da447a9
2017-06-20 23:35:00 +00:00
|
|
|
// changing between `GetCachedDataEnd` and `ReadAt`, so it's not
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
// totally unexpected, just hopefully rare; but we do need to handle it.
|
|
|
|
|
|
|
|
// Invalidate part of cache that may have been partially overridden.
|
|
|
|
if (mCachedOffset + mCachedBytes == aOffset) {
|
|
|
|
// We were topping-up the cache, just keep the old untouched data.
|
|
|
|
// (i.e., nothing to do here.)
|
|
|
|
} else {
|
|
|
|
// We were filling the cache from scratch, invalidate cache.
|
|
|
|
mCachedBytes = 0;
|
|
|
|
}
|
|
|
|
} else {
|
2017-05-30 02:12:38 +00:00
|
|
|
ILOG("ReadAt(%" PRIu32 "@%" PRId64
|
|
|
|
") - no cached data, will fallback to blocking read...",
|
|
|
|
aCount, aOffset);
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
}
|
|
|
|
} else {
|
2017-05-30 02:12:38 +00:00
|
|
|
ILOG("ReadAt(%" PRIu32 "@%" PRId64 ") - length is %" PRId64
|
|
|
|
" (%s), will fallback to blocking read as the caller requested...",
|
|
|
|
aCount, aOffset, length, length < 0 ? "unknown" : "too short!");
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
}
|
|
|
|
uint32_t read = 0;
|
|
|
|
nsresult rv = UncachedReadAt(aOffset, aBuffer, aCount, &read);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
*aBytes += read;
|
2017-05-30 02:12:38 +00:00
|
|
|
ILOG("ReadAt(%" PRIu32 "@%" PRId64 ") - fallback uncached read got %" PRIu32
|
|
|
|
" bytes -> %s, %" PRIu32,
|
|
|
|
aCount, aOffset, read, ResultName(rv).get(), *aBytes);
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
} else {
|
2017-05-30 02:12:38 +00:00
|
|
|
ILOG("ReadAt(%" PRIu32 "@%" PRId64
|
|
|
|
") - fallback uncached read failed -> %s, %" PRIu32,
|
|
|
|
aCount, aOffset, ResultName(rv).get(), *aBytes);
|
Bug 1368837 - MediaResourceIndex::ReadAt tries to cache last-read block - r=cpearce
This is the core of this bug:
- We try to read past the end of the requested range, and save a block-full of
cached data. ("Block" is a memory range, with an alignment and size being a
power of two, to match existing caching happening in MediaCache and
FileBlockCache, and to play nice with the memory allocator.)
- If part of a requested read touches the existing cache, we can just read from
the cache, which means we don't involve any of the locking and IOs that normal
reads use.
The small extra work needed to cache more data in some reads is largely offset
by all the lock&IO-heavy reads that we can subsequently avoid.
UncachedReadAt, which is used internally by CachedReadAt, is left public
because it could be useful if the caller knows for sure that a particular read
is isolated.
(Note: The printfs, and comparison code in ReadAt, will be removed in later
patches. Also the block size will be later controlled by a pref.)
MozReview-Commit-ID: GFiaP5Io7Hf
--HG--
extra : rebase_source : 2bebcdb7854989b55f2026e92338a00ac29a5376
2017-05-30 02:59:30 +00:00
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult MediaResourceIndex::UncachedReadAt(int64_t aOffset, char* aBuffer,
|
|
|
|
uint32_t aCount,
|
|
|
|
uint32_t* aBytes) const {
|
2017-08-01 02:07:55 +00:00
|
|
|
if (aOffset < 0) {
|
|
|
|
return NS_ERROR_ILLEGAL_VALUE;
|
|
|
|
}
|
2017-10-30 04:44:24 +00:00
|
|
|
if (aCount == 0) {
|
|
|
|
*aBytes = 0;
|
|
|
|
return NS_OK;
|
2015-08-13 01:18:34 +00:00
|
|
|
}
|
2017-10-30 04:44:24 +00:00
|
|
|
return mResource->ReadAt(aOffset, aBuffer, aCount, aBytes);
|
2015-08-13 01:18:34 +00:00
|
|
|
}
|
|
|
|
|
Bug 1374180 - MediaResourceIndex won't use ReadFromCache, to keep MediaCache more consistent - r=cpearce
Bug 1368837 (Add lockless cache to MediaResourceIndex) used
MediaResource::ReadFromCache when trying to fill its local cache. But this
meant that these reads would not count as "real reads" for the MediaCache,
which could lead to unexpected states, e.g. "Played block after the current
stream position?"
To solve this, this patch reverts to using normal ReadAt() calls, which let
the MediaCache update itself properly.
While still trying to read more than what is requested (to hopefully fulfill
future reads from the local cache), we don't want to be reading so much that
we block waiting for data past the caller-expected point.
To do this, MediaResourceIndex::UncachedRangedReadAt() is called to try and
read as much as could fill the local cache, but if a single
MediaResource::ReadAt() ends before we can fill the local cache, but *after*
the minimum caller-requested size, we stop trying to read, as such extra read
is at risk of blocking (assuming that the caller knows not to read too far.)
MozReview-Commit-ID: 6fGvJpmkuLz
--HG--
extra : rebase_source : bf8e9f20599a05c8f3f221b55d678f0b5da447a9
2017-06-20 23:35:00 +00:00
|
|
|
nsresult MediaResourceIndex::UncachedRangedReadAt(int64_t aOffset,
|
|
|
|
char* aBuffer,
|
|
|
|
uint32_t aRequestedCount,
|
|
|
|
uint32_t aExtraCount,
|
|
|
|
uint32_t* aBytes) const {
|
|
|
|
uint32_t count = aRequestedCount + aExtraCount;
|
2017-08-01 02:07:55 +00:00
|
|
|
if (aOffset < 0 || count < aRequestedCount) {
|
|
|
|
return NS_ERROR_ILLEGAL_VALUE;
|
|
|
|
}
|
2017-10-30 04:44:24 +00:00
|
|
|
if (count == 0) {
|
|
|
|
*aBytes = 0;
|
|
|
|
return NS_OK;
|
Bug 1374180 - MediaResourceIndex won't use ReadFromCache, to keep MediaCache more consistent - r=cpearce
Bug 1368837 (Add lockless cache to MediaResourceIndex) used
MediaResource::ReadFromCache when trying to fill its local cache. But this
meant that these reads would not count as "real reads" for the MediaCache,
which could lead to unexpected states, e.g. "Played block after the current
stream position?"
To solve this, this patch reverts to using normal ReadAt() calls, which let
the MediaCache update itself properly.
While still trying to read more than what is requested (to hopefully fulfill
future reads from the local cache), we don't want to be reading so much that
we block waiting for data past the caller-expected point.
To do this, MediaResourceIndex::UncachedRangedReadAt() is called to try and
read as much as could fill the local cache, but if a single
MediaResource::ReadAt() ends before we can fill the local cache, but *after*
the minimum caller-requested size, we stop trying to read, as such extra read
is at risk of blocking (assuming that the caller knows not to read too far.)
MozReview-Commit-ID: 6fGvJpmkuLz
--HG--
extra : rebase_source : bf8e9f20599a05c8f3f221b55d678f0b5da447a9
2017-06-20 23:35:00 +00:00
|
|
|
}
|
2017-10-30 04:44:24 +00:00
|
|
|
return mResource->ReadAt(aOffset, aBuffer, count, aBytes);
|
Bug 1374180 - MediaResourceIndex won't use ReadFromCache, to keep MediaCache more consistent - r=cpearce
Bug 1368837 (Add lockless cache to MediaResourceIndex) used
MediaResource::ReadFromCache when trying to fill its local cache. But this
meant that these reads would not count as "real reads" for the MediaCache,
which could lead to unexpected states, e.g. "Played block after the current
stream position?"
To solve this, this patch reverts to using normal ReadAt() calls, which let
the MediaCache update itself properly.
While still trying to read more than what is requested (to hopefully fulfill
future reads from the local cache), we don't want to be reading so much that
we block waiting for data past the caller-expected point.
To do this, MediaResourceIndex::UncachedRangedReadAt() is called to try and
read as much as could fill the local cache, but if a single
MediaResource::ReadAt() ends before we can fill the local cache, but *after*
the minimum caller-requested size, we stop trying to read, as such extra read
is at risk of blocking (assuming that the caller knows not to read too far.)
MozReview-Commit-ID: 6fGvJpmkuLz
--HG--
extra : rebase_source : bf8e9f20599a05c8f3f221b55d678f0b5da447a9
2017-06-20 23:35:00 +00:00
|
|
|
}
|
|
|
|
|
2015-08-13 01:15:48 +00:00
|
|
|
nsresult MediaResourceIndex::Seek(int32_t aWhence, int64_t aOffset) {
|
|
|
|
switch (aWhence) {
|
|
|
|
case SEEK_SET:
|
|
|
|
break;
|
|
|
|
case SEEK_CUR:
|
|
|
|
aOffset += mOffset;
|
|
|
|
break;
|
|
|
|
case SEEK_END: {
|
|
|
|
int64_t length = mResource->GetLength();
|
|
|
|
if (length == -1 || length - aOffset < 0) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
aOffset = mResource->GetLength() - aOffset;
|
|
|
|
} break;
|
|
|
|
default:
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2017-08-01 02:07:55 +00:00
|
|
|
if (aOffset < 0) {
|
|
|
|
return NS_ERROR_ILLEGAL_VALUE;
|
|
|
|
}
|
2015-08-13 01:15:48 +00:00
|
|
|
mOffset = aOffset;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2017-10-04 19:25:19 +00:00
|
|
|
already_AddRefed<MediaByteBuffer> MediaResourceIndex::MediaReadAt(
|
|
|
|
int64_t aOffset, uint32_t aCount) const {
|
2017-10-30 04:44:24 +00:00
|
|
|
NS_ENSURE_TRUE(aOffset >= 0, nullptr);
|
2017-10-04 19:25:19 +00:00
|
|
|
RefPtr<MediaByteBuffer> bytes = new MediaByteBuffer();
|
|
|
|
bool ok = bytes->SetLength(aCount, fallible);
|
|
|
|
NS_ENSURE_TRUE(ok, nullptr);
|
2017-10-30 04:44:24 +00:00
|
|
|
|
|
|
|
uint32_t bytesRead = 0;
|
|
|
|
nsresult rv = mResource->ReadAt(
|
|
|
|
aOffset, reinterpret_cast<char*>(bytes->Elements()), aCount, &bytesRead);
|
|
|
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
|
|
|
|
|
|
|
bytes->SetLength(bytesRead);
|
2017-10-04 19:25:19 +00:00
|
|
|
return bytes.forget();
|
|
|
|
}
|
|
|
|
|
|
|
|
already_AddRefed<MediaByteBuffer> MediaResourceIndex::CachedMediaReadAt(
|
|
|
|
int64_t aOffset, uint32_t aCount) const {
|
|
|
|
RefPtr<MediaByteBuffer> bytes = new MediaByteBuffer();
|
|
|
|
bool ok = bytes->SetLength(aCount, fallible);
|
|
|
|
NS_ENSURE_TRUE(ok, nullptr);
|
|
|
|
char* curr = reinterpret_cast<char*>(bytes->Elements());
|
|
|
|
nsresult rv = mResource->ReadFromCache(curr, aOffset, aCount);
|
|
|
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
|
|
|
return bytes.forget();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the length of the stream in bytes. Returns -1 if not known.
|
|
|
|
// This can change over time; after a seek operation, a misbehaving
|
|
|
|
// server may give us a resource of a different length to what it had
|
|
|
|
// reported previously --- or it may just lie in its Content-Length
|
|
|
|
// header and give us more or less data than it reported. We will adjust
|
|
|
|
// the result of GetLength to reflect the data that's actually arriving.
|
|
|
|
int64_t MediaResourceIndex::GetLength() const { return mResource->GetLength(); }
|
|
|
|
|
|
|
|
uint32_t MediaResourceIndex::IndexInCache(int64_t aOffsetInFile) const {
|
|
|
|
const uint32_t index = uint32_t(aOffsetInFile) & (mCacheBlockSize - 1);
|
|
|
|
MOZ_ASSERT(index == aOffsetInFile % mCacheBlockSize);
|
|
|
|
return index;
|
|
|
|
}
|
|
|
|
|
|
|
|
int64_t MediaResourceIndex::CacheOffsetContaining(int64_t aOffsetInFile) const {
|
|
|
|
const int64_t offset = aOffsetInFile & ~(int64_t(mCacheBlockSize) - 1);
|
|
|
|
MOZ_ASSERT(offset == aOffsetInFile - IndexInCache(aOffsetInFile));
|
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
2012-11-14 19:45:33 +00:00
|
|
|
} // namespace mozilla
|
|
|
|
|
2017-04-05 09:38:20 +00:00
|
|
|
// avoid redefined macro in unified build
|
2017-05-30 02:12:38 +00:00
|
|
|
#undef ILOG
|