mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1182933: Implement MediaReadAt. r=bholley
Ensure SilentReadAt seek back to original position even in case of error. Properly set the MediaByteBuffer length.
This commit is contained in:
parent
3f3b036b5f
commit
d2d40f98bd
@ -759,25 +759,27 @@ nsresult ChannelMediaResource::ReadAt(int64_t aOffset,
|
||||
}
|
||||
|
||||
already_AddRefed<MediaByteBuffer>
|
||||
ChannelMediaResource::SilentReadAt(int64_t aOffset, uint32_t aCount)
|
||||
ChannelMediaResource::MediaReadAt(int64_t aOffset, uint32_t aCount)
|
||||
{
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
|
||||
|
||||
nsRefPtr<MediaByteBuffer> bytes = new MediaByteBuffer();
|
||||
bool ok = bytes->SetCapacity(aCount, fallible);
|
||||
bool ok = bytes->SetLength(aCount, fallible);
|
||||
NS_ENSURE_TRUE(ok, nullptr);
|
||||
int64_t pos = mCacheStream.Tell();
|
||||
char* curr = reinterpret_cast<char*>(bytes->Elements());
|
||||
const char* start = curr;
|
||||
while (aCount > 0) {
|
||||
uint32_t bytesRead;
|
||||
nsresult rv = mCacheStream.ReadAt(aOffset, curr, aCount, &bytesRead);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
NS_ENSURE_TRUE(bytesRead > 0, nullptr);
|
||||
if (!bytesRead) {
|
||||
break;
|
||||
}
|
||||
aOffset += bytesRead;
|
||||
aCount -= bytesRead;
|
||||
curr += bytesRead;
|
||||
}
|
||||
mCacheStream.Seek(nsISeekableStream::NS_SEEK_SET, pos);
|
||||
bytes->SetLength(curr - start);
|
||||
return bytes.forget();
|
||||
}
|
||||
|
||||
@ -1217,6 +1219,7 @@ public:
|
||||
virtual nsresult Read(char* aBuffer, uint32_t aCount, uint32_t* aBytes) override;
|
||||
virtual nsresult ReadAt(int64_t aOffset, char* aBuffer,
|
||||
uint32_t aCount, uint32_t* aBytes) override;
|
||||
virtual already_AddRefed<MediaByteBuffer> MediaReadAt(int64_t aOffset, uint32_t aCount) override;
|
||||
virtual already_AddRefed<MediaByteBuffer> SilentReadAt(int64_t aOffset, uint32_t aCount) override;
|
||||
virtual nsresult Seek(int32_t aWhence, int64_t aOffset) override;
|
||||
virtual int64_t Tell() override;
|
||||
@ -1281,6 +1284,8 @@ private:
|
||||
// Ensures mSize is initialized, if it can be.
|
||||
// mLock must be held when this is called, and mInput must be non-null.
|
||||
void EnsureSizeInitialized();
|
||||
already_AddRefed<MediaByteBuffer> UnsafeMediaReadAt(
|
||||
int64_t aOffset, uint32_t aCount);
|
||||
|
||||
// The file size, or -1 if not known. Immutable after Open().
|
||||
// Can be used from any thread.
|
||||
@ -1541,31 +1546,52 @@ nsresult FileMediaResource::ReadAt(int64_t aOffset, char* aBuffer,
|
||||
return rv;
|
||||
}
|
||||
|
||||
already_AddRefed<MediaByteBuffer>
|
||||
FileMediaResource::MediaReadAt(int64_t aOffset, uint32_t aCount)
|
||||
{
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
|
||||
|
||||
MutexAutoLock lock(mLock);
|
||||
return UnsafeMediaReadAt(aOffset, aCount);
|
||||
}
|
||||
|
||||
already_AddRefed<MediaByteBuffer>
|
||||
FileMediaResource::UnsafeMediaReadAt(int64_t aOffset, uint32_t aCount)
|
||||
{
|
||||
nsRefPtr<MediaByteBuffer> bytes = new MediaByteBuffer();
|
||||
bool ok = bytes->SetLength(aCount, fallible);
|
||||
NS_ENSURE_TRUE(ok, nullptr);
|
||||
nsresult rv = UnsafeSeek(nsISeekableStream::NS_SEEK_SET, aOffset);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
char* curr = reinterpret_cast<char*>(bytes->Elements());
|
||||
const char* start = curr;
|
||||
while (aCount > 0) {
|
||||
uint32_t bytesRead;
|
||||
rv = UnsafeRead(curr, aCount, &bytesRead);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
if (!bytesRead) {
|
||||
break;
|
||||
}
|
||||
aCount -= bytesRead;
|
||||
curr += bytesRead;
|
||||
}
|
||||
bytes->SetLength(curr - start);
|
||||
return bytes.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<MediaByteBuffer>
|
||||
FileMediaResource::SilentReadAt(int64_t aOffset, uint32_t aCount)
|
||||
{
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
|
||||
|
||||
MutexAutoLock lock(mLock);
|
||||
nsRefPtr<MediaByteBuffer> bytes = new MediaByteBuffer();
|
||||
bool ok = bytes->SetCapacity(aCount, fallible);
|
||||
NS_ENSURE_TRUE(ok, nullptr);
|
||||
int64_t pos = 0;
|
||||
NS_ENSURE_TRUE(mSeekable, nullptr);
|
||||
nsresult rv = mSeekable->Tell(&pos);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
rv = UnsafeSeek(nsISeekableStream::NS_SEEK_SET, aOffset);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
char* curr = reinterpret_cast<char*>(bytes->Elements());
|
||||
while (aCount > 0) {
|
||||
uint32_t bytesRead;
|
||||
rv = UnsafeRead(curr, aCount, &bytesRead);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
NS_ENSURE_TRUE(bytesRead > 0, nullptr);
|
||||
aCount -= bytesRead;
|
||||
curr += bytesRead;
|
||||
}
|
||||
nsRefPtr<MediaByteBuffer> bytes = UnsafeMediaReadAt(aOffset, aCount);
|
||||
UnsafeSeek(nsISeekableStream::NS_SEEK_SET, pos);
|
||||
NS_ENSURE_TRUE(bytes && bytes->Length() == aCount, nullptr);
|
||||
return bytes.forget();
|
||||
}
|
||||
|
||||
|
@ -289,6 +289,31 @@ public:
|
||||
// results and requirements are the same as per the Read method.
|
||||
virtual nsresult ReadAt(int64_t aOffset, char* aBuffer,
|
||||
uint32_t aCount, uint32_t* aBytes) = 0;
|
||||
// This method returns nullptr if anything fails.
|
||||
// Otherwise, it returns an owned buffer.
|
||||
// MediaReadAt may return fewer bytes than requested if end of stream is
|
||||
// encountered. There is no need to call it again to get more data.
|
||||
virtual already_AddRefed<MediaByteBuffer> MediaReadAt(int64_t aOffset, uint32_t aCount)
|
||||
{
|
||||
nsRefPtr<MediaByteBuffer> bytes = new MediaByteBuffer();
|
||||
bool ok = bytes->SetLength(aCount, fallible);
|
||||
NS_ENSURE_TRUE(ok, nullptr);
|
||||
char* curr = reinterpret_cast<char*>(bytes->Elements());
|
||||
const char* start = curr;
|
||||
while (aCount > 0) {
|
||||
uint32_t bytesRead;
|
||||
nsresult rv = ReadAt(aOffset, curr, aCount, &bytesRead);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
if (!bytesRead) {
|
||||
break;
|
||||
}
|
||||
aOffset += bytesRead;
|
||||
aCount -= bytesRead;
|
||||
curr += bytesRead;
|
||||
}
|
||||
bytes->SetLength(curr - start);
|
||||
return bytes.forget();
|
||||
}
|
||||
|
||||
// ReadAt without side-effects. Given that our MediaResource infrastructure
|
||||
// is very side-effecty, this accomplishes its job by checking the initial
|
||||
@ -299,21 +324,10 @@ public:
|
||||
// aCount bytes. Otherwise, it returns an owned buffer.
|
||||
virtual already_AddRefed<MediaByteBuffer> SilentReadAt(int64_t aOffset, uint32_t aCount)
|
||||
{
|
||||
nsRefPtr<MediaByteBuffer> bytes = new MediaByteBuffer();
|
||||
bool ok = bytes->SetCapacity(aCount, fallible);
|
||||
NS_ENSURE_TRUE(ok, nullptr);
|
||||
int64_t pos = Tell();
|
||||
char* curr = reinterpret_cast<char*>(bytes->Elements());
|
||||
while (aCount > 0) {
|
||||
uint32_t bytesRead;
|
||||
nsresult rv = ReadAt(aOffset, curr, aCount, &bytesRead);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
NS_ENSURE_TRUE(bytesRead > 0, nullptr);
|
||||
aOffset += bytesRead;
|
||||
aCount -= bytesRead;
|
||||
curr += bytesRead;
|
||||
}
|
||||
nsRefPtr<MediaByteBuffer> bytes = MediaReadAt(aOffset, aCount);
|
||||
Seek(nsISeekableStream::NS_SEEK_SET, pos);
|
||||
NS_ENSURE_TRUE(bytes && bytes->Length() == aCount, nullptr);
|
||||
return bytes.forget();
|
||||
}
|
||||
|
||||
@ -640,7 +654,7 @@ public:
|
||||
virtual nsresult Read(char* aBuffer, uint32_t aCount, uint32_t* aBytes) override;
|
||||
virtual nsresult ReadAt(int64_t offset, char* aBuffer,
|
||||
uint32_t aCount, uint32_t* aBytes) override;
|
||||
virtual already_AddRefed<MediaByteBuffer> SilentReadAt(int64_t aOffset, uint32_t aCount) override;
|
||||
virtual already_AddRefed<MediaByteBuffer> MediaReadAt(int64_t aOffset, uint32_t aCount) override;
|
||||
virtual nsresult Seek(int32_t aWhence, int64_t aOffset) override;
|
||||
virtual int64_t Tell() override;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user