--- a/dom/media/BufferMediaResource.h
+++ b/dom/media/BufferMediaResource.h
@@ -76,24 +76,25 @@ private:
int64_t GetLength() override { return mLength; }
int64_t GetNextCachedData(int64_t aOffset) override { return aOffset; }
int64_t GetCachedDataEnd(int64_t aOffset) override { return mLength; }
bool IsDataCachedToEndOfResource(int64_t aOffset) override { return true; }
bool IsSuspendedByCache() override { return false; }
bool IsSuspended() override { return false; }
nsresult ReadFromCache(char* aBuffer,
int64_t aOffset,
- uint32_t aCount) override
+ uint32_t aCount,
+ uint32_t* aBytes) override
{
if (aOffset < 0) {
return NS_ERROR_FAILURE;
}
- uint32_t bytes = std::min(mLength - static_cast<uint32_t>(aOffset), aCount);
- memcpy(aBuffer, mBuffer + aOffset, bytes);
+ *aBytes = std::min(mLength - static_cast<uint32_t>(aOffset), aCount);
+ memcpy(aBuffer, mBuffer + aOffset, *aBytes);
return NS_OK;
}
nsresult Open(nsIStreamListener** aStreamListener) override
{
return NS_ERROR_FAILURE;
}
--- a/dom/media/MediaCache.cpp
+++ b/dom/media/MediaCache.cpp
@@ -2333,17 +2333,18 @@ MediaCacheStream::ReadAt(int64_t aOffset
ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
nsresult rv = Seek(nsISeekableStream::NS_SEEK_SET, aOffset);
if (NS_FAILED(rv)) return rv;
return Read(aBuffer, aCount, aBytes);
}
nsresult
-MediaCacheStream::ReadFromCache(char* aBuffer, int64_t aOffset, int64_t aCount)
+MediaCacheStream::ReadFromCache(
+ char* aBuffer, int64_t aOffset, int64_t aCount, uint32_t* aBytes)
{
ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
// Read one block (or part of a block) at a time
uint32_t count = 0;
int64_t streamOffset = aOffset;
while (count < aCount) {
if (mClosed) {
@@ -2391,16 +2392,17 @@ MediaCacheStream::ReadFromCache(char* aB
if (NS_FAILED(rv)) {
return rv;
}
}
streamOffset += bytes;
count += bytes;
}
+ *aBytes = count;
return NS_OK;
}
nsresult
MediaCacheStream::Init()
{
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
--- a/dom/media/MediaCache.h
+++ b/dom/media/MediaCache.h
@@ -305,17 +305,18 @@ public:
nsresult GetCachedRanges(MediaByteRangeSet& aRanges);
// Reads from buffered data only. Will fail if not all data to be read is
// in the cache. Will not mark blocks as read. Can be called from the main
// thread. It's the caller's responsibility to wrap the call in a pin/unpin,
// and also to check that the range they want is cached before calling this.
nsresult ReadFromCache(char* aBuffer,
int64_t aOffset,
- int64_t aCount);
+ int64_t aCount,
+ uint32_t* aBytes);
// IsDataCachedToEndOfStream returns true if all the data from
// aOffset to the end of the stream (the server-reported end, if the
// real end is not known) is in cache. If we know nothing about the
// end of the stream, this returns false.
bool IsDataCachedToEndOfStream(int64_t aOffset);
// The mode is initially MODE_PLAYBACK.
void SetReadMode(ReadMode aMode);
--- a/dom/media/MediaResource.cpp
+++ b/dom/media/MediaResource.cpp
@@ -667,19 +667,20 @@ void ChannelMediaResource::CloseChannel(
// at the moment.
mChannel->Cancel(NS_ERROR_PARSED_DATA_CACHED);
mChannel = nullptr;
}
}
nsresult ChannelMediaResource::ReadFromCache(char* aBuffer,
int64_t aOffset,
- uint32_t aCount)
+ uint32_t aCount,
+ uint32_t* aBytes)
{
- return mCacheStream.ReadFromCache(aBuffer, aOffset, aCount);
+ return mCacheStream.ReadFromCache(aBuffer, aOffset, aCount, aBytes);
}
nsresult ChannelMediaResource::ReadAt(int64_t aOffset,
char* aBuffer,
uint32_t aCount,
uint32_t* aBytes)
{
NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
@@ -1138,17 +1139,17 @@ public:
// Main thread
nsresult Open(nsIStreamListener** aStreamListener) override;
nsresult Close() override;
void Suspend(bool aCloseImmediately) override {}
void Resume() override {}
already_AddRefed<nsIPrincipal> GetCurrentPrincipal() override;
bool CanClone() override;
already_AddRefed<MediaResource> CloneData(MediaResourceCallback* aCallback) override;
- nsresult ReadFromCache(char* aBuffer, int64_t aOffset, uint32_t aCount) override;
+ nsresult ReadFromCache(char* aBuffer, int64_t aOffset, uint32_t aCount, uint32_t* aBytes) override;
// These methods are called off the main thread.
// Other thread
void SetReadMode(MediaCacheStream::ReadMode aMode) override {}
void SetPlaybackRate(uint32_t aBytesPerSecond) override {}
nsresult ReadAt(int64_t aOffset, char* aBuffer,
uint32_t aCount, uint32_t* aBytes) override;
@@ -1378,17 +1379,18 @@ already_AddRefed<MediaResource> FileMedi
if (NS_FAILED(rv))
return nullptr;
RefPtr<MediaResource> resource(new FileMediaResource(aCallback, channel, mURI, GetContentType()));
return resource.forget();
}
-nsresult FileMediaResource::ReadFromCache(char* aBuffer, int64_t aOffset, uint32_t aCount)
+nsresult FileMediaResource::ReadFromCache(
+ char* aBuffer, int64_t aOffset, uint32_t aCount, uint32_t* aBytes)
{
MutexAutoLock lock(mLock);
EnsureSizeInitialized();
if (!aCount) {
return NS_OK;
}
int64_t offset = 0;
@@ -1409,16 +1411,18 @@ nsresult FileMediaResource::ReadFromCach
// Reset read head to original position so we don't disturb any other
// reading thread.
nsresult seekres = mSeekable->Seek(nsISeekableStream::NS_SEEK_SET, offset);
// If a read failed in the loop above, we want to return its failure code.
NS_ENSURE_SUCCESS(res,res);
+ *aBytes = bytesRead;
+
// Else we succeed if the reset-seek succeeds.
return seekres;
}
nsresult FileMediaResource::UnsafeRead(char* aBuffer, uint32_t aCount, uint32_t* aBytes)
{
EnsureSizeInitialized();
return mInput->Read(aBuffer, aCount, aBytes);
--- a/dom/media/MediaResource.h
+++ b/dom/media/MediaResource.h
@@ -301,17 +301,18 @@ public:
virtual bool IsSuspended() = 0;
// Reads only data which is cached in the media cache. If you try to read
// any data which overlaps uncached data, or if aCount bytes otherwise can't
// be read, this function will return failure. This function be called from
// any thread, and it is the only read operation which is safe to call on
// the main thread, since it's guaranteed to be non blocking.
virtual nsresult ReadFromCache(char* aBuffer,
int64_t aOffset,
- uint32_t aCount) = 0;
+ uint32_t aCount,
+ uint32_t* aBytes) = 0;
// Returns true if the resource can be seeked to unbuffered ranges, i.e.
// for an HTTP network stream this returns true if HTTP1.1 Byte Range
// requests are supported by the connection/server.
virtual bool IsTransportSeekable() = 0;
/**
* Create a resource, reading data from the channel. Call on main thread only.
* The caller must follow up by calling resource->Open().
@@ -566,17 +567,17 @@ public:
// |ChannelMediaResource| will create it's own statistics objects in |Open|.
void RecordStatisticsTo(MediaChannelStatistics *aStatistics) override {
NS_ASSERTION(aStatistics, "Statistics param cannot be null!");
MutexAutoLock lock(mLock);
if (!mChannelStatistics) {
mChannelStatistics = aStatistics;
}
}
- nsresult ReadFromCache(char* aBuffer, int64_t aOffset, uint32_t aCount) override;
+ nsresult ReadFromCache(char* aBuffer, int64_t aOffset, uint32_t aCount, uint32_t* aBytes) override;
void EnsureCacheUpToDate() override;
// Other thread
void SetReadMode(MediaCacheStream::ReadMode aMode) override;
void SetPlaybackRate(uint32_t aBytesPerSecond) override;
nsresult ReadAt(int64_t offset, char* aBuffer,
uint32_t aCount, uint32_t* aBytes) override;
already_AddRefed<MediaByteBuffer> MediaReadAt(int64_t aOffset, uint32_t aCount) override;
--- a/dom/media/fmp4/MP4Stream.cpp
+++ b/dom/media/fmp4/MP4Stream.cpp
@@ -75,24 +75,24 @@ MP4Stream::CachedReadAt(int64_t aOffset,
for (size_t i = 0; i < mCache.Length(); ++i) {
if (mCache[i].mOffset == aOffset && mCache[i].mCount >= aCount) {
memcpy(aBuffer, mCache[i].Buffer(), aCount);
*aBytesRead = aCount;
return true;
}
}
- nsresult rv =
- mResource.GetResource()->ReadFromCache(reinterpret_cast<char*>(aBuffer),
- aOffset, aCount);
+ uint32_t bytesRead = 0;
+ nsresult rv = mResource.GetResource()->ReadFromCache(
+ reinterpret_cast<char*>(aBuffer), aOffset, aCount, &bytesRead);
if (NS_FAILED(rv)) {
*aBytesRead = 0;
return false;
}
- *aBytesRead = aCount;
+ *aBytesRead = bytesRead;
return true;
}
bool
MP4Stream::Length(int64_t* aSize)
{
if (mResource.GetLength() < 0)
return false;
--- a/dom/media/gtest/MockMediaResource.h
+++ b/dom/media/gtest/MockMediaResource.h
@@ -45,22 +45,22 @@ public:
int64_t GetCachedDataEnd(int64_t aOffset) override;
bool IsDataCachedToEndOfResource(int64_t aOffset) override
{
return false;
}
bool IsSuspendedByCache() override { return false; }
bool IsSuspended() override { return false; }
nsresult ReadFromCache(char* aBuffer, int64_t aOffset,
- uint32_t aCount) override
+ uint32_t aCount, uint32_t* aBytes) override
{
- uint32_t bytesRead = 0;
- nsresult rv = ReadAt(aOffset, aBuffer, aCount, &bytesRead);
+ *aBytes = 0;
+ nsresult rv = ReadAt(aOffset, aBuffer, aCount, aBytes);
NS_ENSURE_SUCCESS(rv, rv);
- return bytesRead == aCount ? NS_OK : NS_ERROR_FAILURE;
+ return *aBytes == aCount ? NS_OK : NS_ERROR_FAILURE;
}
bool IsTransportSeekable() override { return true; }
nsresult Open(nsIStreamListener** aStreamListener) override;
nsresult GetCachedRanges(MediaByteRangeSet& aRanges) override;
const MediaContainerType& GetContentType() const override
{
return mContainerType;
--- a/dom/media/mediasource/ContainerParser.cpp
+++ b/dom/media/mediasource/ContainerParser.cpp
@@ -239,17 +239,18 @@ public:
MOZ_ASSERT(mParser.mInitEndOffset <= mResource->GetLength());
if (!mInitData->SetLength(mParser.mInitEndOffset, fallible)) {
// Super unlikely OOM
return NS_ERROR_OUT_OF_MEMORY;
}
mCompleteInitSegmentRange =
MediaByteRange(0, mParser.mInitEndOffset) + mGlobalOffset;
char* buffer = reinterpret_cast<char*>(mInitData->Elements());
- mResource->ReadFromCache(buffer, 0, mParser.mInitEndOffset);
+ uint32_t bytesRead = 0;
+ mResource->ReadFromCache(buffer, 0, mParser.mInitEndOffset, &bytesRead);
MSE_DEBUG(WebMContainerParser, "Stashed init of %" PRId64 " bytes.",
mParser.mInitEndOffset);
mResource = nullptr;
} else {
MSE_DEBUG(WebMContainerParser, "Incomplete init found.");
}
mHasInitData = true;
}
@@ -524,17 +525,18 @@ public:
MediaByteRange& range = mParser->mInitRange;
if (range.Length()) {
mCompleteInitSegmentRange = range + mGlobalOffset;
if (!mInitData->SetLength(range.Length(), fallible)) {
// Super unlikely OOM
return NS_ERROR_OUT_OF_MEMORY;
}
char* buffer = reinterpret_cast<char*>(mInitData->Elements());
- mResource->ReadFromCache(buffer, range.mStart, range.Length());
+ uint32_t bytesRead = 0;
+ mResource->ReadFromCache(buffer, range.mStart, range.Length(), &bytesRead);
MSE_DEBUG(MP4ContainerParser ,"Stashed init of %" PRIu64 " bytes.",
range.Length());
} else {
MSE_DEBUG(MP4ContainerParser, "Incomplete init found.");
}
mHasInitData = true;
}
mTotalParsed += aData->Length();
--- a/dom/media/mediasource/MediaSourceResource.h
+++ b/dom/media/mediasource/MediaSourceResource.h
@@ -43,17 +43,17 @@ public:
void Unpin() override { UNIMPLEMENTED(); }
double GetDownloadRate(bool* aIsReliable) override { UNIMPLEMENTED(); *aIsReliable = false; return 0; }
int64_t GetLength() override { UNIMPLEMENTED(); return -1; }
int64_t GetNextCachedData(int64_t aOffset) override { UNIMPLEMENTED(); return -1; }
int64_t GetCachedDataEnd(int64_t aOffset) override { UNIMPLEMENTED(); return -1; }
bool IsDataCachedToEndOfResource(int64_t aOffset) override { UNIMPLEMENTED(); return false; }
bool IsSuspendedByCache() override { UNIMPLEMENTED(); return false; }
bool IsSuspended() override { UNIMPLEMENTED(); return false; }
- nsresult ReadFromCache(char* aBuffer, int64_t aOffset, uint32_t aCount) override { UNIMPLEMENTED(); return NS_ERROR_FAILURE; }
+ nsresult ReadFromCache(char* aBuffer, int64_t aOffset, uint32_t aCount, uint32_t* aBytes) override { UNIMPLEMENTED(); return NS_ERROR_FAILURE; }
nsresult Open(nsIStreamListener** aStreamListener) override { UNIMPLEMENTED(); return NS_ERROR_FAILURE; }
already_AddRefed<nsIPrincipal> GetCurrentPrincipal() override
{
return RefPtr<nsIPrincipal>(mPrincipal).forget();
}
nsresult GetCachedRanges(MediaByteRangeSet& aRanges) override
--- a/dom/media/mediasource/SourceBufferResource.cpp
+++ b/dom/media/mediasource/SourceBufferResource.cpp
@@ -89,27 +89,27 @@ SourceBufferResource::ReadAtInternal(int
mInputBuffer.CopyData(aOffset, count, aBuffer);
*aBytes = count;
return NS_OK;
}
nsresult
-SourceBufferResource::ReadFromCache(char* aBuffer, int64_t aOffset, uint32_t aCount)
+SourceBufferResource::ReadFromCache(
+ char* aBuffer, int64_t aOffset, uint32_t aCount, uint32_t* aBytes)
{
SBR_DEBUG("ReadFromCache(aBuffer=%p, aOffset=%" PRId64 ", aCount=%u)",
aBuffer, aOffset, aCount);
ReentrantMonitorAutoEnter mon(mMonitor);
- uint32_t bytesRead;
- nsresult rv = ReadAtInternal(aOffset, aBuffer, aCount, &bytesRead, /* aMayBlock = */ false);
+ nsresult rv = ReadAtInternal(aOffset, aBuffer, aCount, aBytes, /* 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;
+ return *aBytes == aCount ? NS_OK : NS_ERROR_FAILURE;
}
uint32_t
SourceBufferResource::EvictData(uint64_t aPlaybackOffset, int64_t aThreshold,
ErrorResult& aRv)
{
SBR_DEBUG("EvictData(aPlaybackOffset=%" PRIu64 ","
"aThreshold=%" PRId64 ")", aPlaybackOffset, aThreshold);
--- a/dom/media/mediasource/SourceBufferResource.h
+++ b/dom/media/mediasource/SourceBufferResource.h
@@ -60,17 +60,17 @@ public:
return -1;
}
return aOffset;
}
int64_t GetCachedDataEnd(int64_t aOffset) override { UNIMPLEMENTED(); return -1; }
bool IsDataCachedToEndOfResource(int64_t aOffset) override { return false; }
bool IsSuspendedByCache() override { UNIMPLEMENTED(); return false; }
bool IsSuspended() override { UNIMPLEMENTED(); return false; }
- nsresult ReadFromCache(char* aBuffer, int64_t aOffset, uint32_t aCount) override;
+ nsresult ReadFromCache(char* aBuffer, int64_t aOffset, uint32_t aCount, uint32_t* aBytes) override;
bool IsTransportSeekable() override { UNIMPLEMENTED(); return true; }
nsresult Open(nsIStreamListener** aStreamListener) override { UNIMPLEMENTED(); return NS_ERROR_FAILURE; }
nsresult GetCachedRanges(MediaByteRangeSet& aRanges) override
{
ReentrantMonitorAutoEnter mon(mMonitor);
if (mInputBuffer.GetLength()) {
aRanges += MediaByteRange(mInputBuffer.GetOffset(),
--- a/dom/media/ogg/OggDemuxer.cpp
+++ b/dom/media/ogg/OggDemuxer.cpp
@@ -1243,20 +1243,19 @@ OggDemuxer::PageSync(MediaResourceIndex*
int64_t bytesToRead = std::min(static_cast<int64_t>(PAGE_STEP),
aEndOffset - readHead);
NS_ASSERTION(bytesToRead <= UINT32_MAX, "bytesToRead range check");
if (bytesToRead <= 0) {
return PAGE_SYNC_END_OF_RANGE;
}
nsresult rv = NS_OK;
if (aCachedDataOnly) {
- rv = aResource->GetResource()->ReadFromCache(buffer, readHead,
- static_cast<uint32_t>(bytesToRead));
+ rv = aResource->GetResource()->ReadFromCache(
+ buffer, readHead, static_cast<uint32_t>(bytesToRead), &bytesRead);
NS_ENSURE_SUCCESS(rv,PAGE_SYNC_ERROR);
- bytesRead = static_cast<uint32_t>(bytesToRead);
} else {
rv = aResource->Seek(nsISeekableStream::NS_SEEK_SET, readHead);
NS_ENSURE_SUCCESS(rv,PAGE_SYNC_ERROR);
rv = aResource->Read(buffer,
static_cast<uint32_t>(bytesToRead),
&bytesRead);
NS_ENSURE_SUCCESS(rv,PAGE_SYNC_ERROR);
}
@@ -1532,19 +1531,19 @@ OggDemuxer::RangeEndTime(TrackInfo::Trac
limit = std::max(static_cast<int64_t>(0), limit);
limit = std::min(limit, static_cast<int64_t>(step));
uint32_t bytesToRead = static_cast<uint32_t>(limit);
uint32_t bytesRead = 0;
char* buffer = ogg_sync_buffer(&sync.mState, bytesToRead);
NS_ASSERTION(buffer, "Must have buffer");
nsresult res;
if (aCachedDataOnly) {
- res = Resource(aType)->GetResource()->ReadFromCache(buffer, readHead, bytesToRead);
+ res = Resource(aType)->GetResource()->ReadFromCache(
+ buffer, readHead, bytesToRead, &bytesRead);
NS_ENSURE_SUCCESS(res, -1);
- bytesRead = bytesToRead;
} else {
NS_ASSERTION(readHead < aEndOffset,
"resource pos must be before range end");
res = Resource(aType)->Seek(nsISeekableStream::NS_SEEK_SET, readHead);
NS_ENSURE_SUCCESS(res, -1);
res = Resource(aType)->Read(buffer, bytesToRead, &bytesRead);
NS_ENSURE_SUCCESS(res, -1);
}
--- a/media/libstagefright/binding/ResourceStream.cpp
+++ b/media/libstagefright/binding/ResourceStream.cpp
@@ -40,23 +40,24 @@ ResourceStream::ReadAt(int64_t aOffset,
*aBytesRead = sum;
return true;
}
bool
ResourceStream::CachedReadAt(int64_t aOffset, void* aBuffer, size_t aCount,
size_t* aBytesRead)
{
+ uint32_t bytesRead = 0;
nsresult rv = mResource->ReadFromCache(reinterpret_cast<char*>(aBuffer),
- aOffset, aCount);
+ aOffset, aCount, &bytesRead);
if (NS_FAILED(rv)) {
*aBytesRead = 0;
return false;
}
- *aBytesRead = aCount;
+ *aBytesRead = bytesRead;
return true;
}
bool
ResourceStream::Length(int64_t* aSize)
{
if (mResource->GetLength() < 0)
return false;