mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 01:48:05 +00:00
Bug 1195073: [MSE/webm] P4. Limit nestegg reads to the last block's boundaries. r=kinetik
This prevent entering into an unrecoverable error state when parsing incomplete data as often seen with MSE.
This commit is contained in:
parent
83205f837d
commit
3cd00ea187
@ -100,6 +100,11 @@ public:
|
||||
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
||||
virtual bool IsExpectingMoreData() override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Used by SourceBuffer.
|
||||
void AppendData(MediaByteBuffer* aData);
|
||||
void Ended();
|
||||
|
@ -36,40 +36,39 @@ extern PRLogModuleInfo* gNesteggLog;
|
||||
|
||||
// Functions for reading and seeking using WebMDemuxer required for
|
||||
// nestegg_io. The 'user data' passed to these functions is the
|
||||
// demuxer's MediaResourceIndex
|
||||
// demuxer.
|
||||
static int webmdemux_read(void* aBuffer, size_t aLength, void* aUserData)
|
||||
{
|
||||
MOZ_ASSERT(aUserData);
|
||||
MediaResourceIndex* resource =
|
||||
reinterpret_cast<MediaResourceIndex*>(aUserData);
|
||||
int64_t length = resource->GetLength();
|
||||
MOZ_ASSERT(aLength < UINT32_MAX);
|
||||
WebMDemuxer* demuxer = reinterpret_cast<WebMDemuxer*>(aUserData);
|
||||
int64_t length = demuxer->GetEndDataOffset();
|
||||
uint32_t count = aLength;
|
||||
if (length >= 0 && count + resource->Tell() > length) {
|
||||
count = uint32_t(length - resource->Tell());
|
||||
int64_t position = demuxer->GetResource()->Tell();
|
||||
if (length >= 0 && count + position > length) {
|
||||
count = length - position;
|
||||
}
|
||||
|
||||
uint32_t bytes = 0;
|
||||
nsresult rv = resource->Read(static_cast<char*>(aBuffer), count, &bytes);
|
||||
bool eof = !bytes;
|
||||
nsresult rv =
|
||||
demuxer->GetResource()->Read(static_cast<char*>(aBuffer), count, &bytes);
|
||||
bool eof = bytes < aLength;
|
||||
return NS_FAILED(rv) ? -1 : eof ? 0 : 1;
|
||||
}
|
||||
|
||||
static int webmdemux_seek(int64_t aOffset, int aWhence, void* aUserData)
|
||||
{
|
||||
MOZ_ASSERT(aUserData);
|
||||
MediaResourceIndex* resource =
|
||||
reinterpret_cast<MediaResourceIndex*>(aUserData);
|
||||
nsresult rv = resource->Seek(aWhence, aOffset);
|
||||
WebMDemuxer* demuxer = reinterpret_cast<WebMDemuxer*>(aUserData);
|
||||
nsresult rv = demuxer->GetResource()->Seek(aWhence, aOffset);
|
||||
return NS_SUCCEEDED(rv) ? 0 : -1;
|
||||
}
|
||||
|
||||
static int64_t webmdemux_tell(void* aUserData)
|
||||
{
|
||||
MOZ_ASSERT(aUserData);
|
||||
MediaResourceIndex* resource =
|
||||
reinterpret_cast<MediaResourceIndex*>(aUserData);
|
||||
return resource->Tell();
|
||||
WebMDemuxer* demuxer = reinterpret_cast<WebMDemuxer*>(aUserData);
|
||||
return demuxer->GetResource()->Tell();
|
||||
}
|
||||
|
||||
static void webmdemux_log(nestegg* aContext,
|
||||
@ -130,6 +129,8 @@ WebMDemuxer::WebMDemuxer(MediaResource* aResource)
|
||||
, mHasVideo(false)
|
||||
, mHasAudio(false)
|
||||
, mNeedReIndex(true)
|
||||
, mLastWebMBlockOffset(-1)
|
||||
, mIsExpectingMoreData(true)
|
||||
{
|
||||
if (!gNesteggLog) {
|
||||
gNesteggLog = PR_NewLogModule("Nestegg");
|
||||
@ -254,7 +255,7 @@ WebMDemuxer::ReadMetadata()
|
||||
io.read = webmdemux_read;
|
||||
io.seek = webmdemux_seek;
|
||||
io.tell = webmdemux_tell;
|
||||
io.userdata = &mResource;
|
||||
io.userdata = this;
|
||||
int64_t maxOffset = mBufferedState->GetInitEndOffset();
|
||||
if (maxOffset == -1) {
|
||||
maxOffset = mResource.GetLength();
|
||||
@ -443,6 +444,8 @@ WebMDemuxer::EnsureUpToDateIndex()
|
||||
if (!mInitData && mBufferedState->GetInitEndOffset() != -1) {
|
||||
mInitData = mResource.MediaReadAt(0, mBufferedState->GetInitEndOffset());
|
||||
}
|
||||
mLastWebMBlockOffset = mBufferedState->GetLastBlockOffset();
|
||||
mIsExpectingMoreData = mResource.GetResource()->IsExpectingMoreData();
|
||||
mNeedReIndex = false;
|
||||
}
|
||||
|
||||
@ -469,6 +472,8 @@ WebMDemuxer::GetCrypto()
|
||||
bool
|
||||
WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSamples)
|
||||
{
|
||||
EnsureUpToDateIndex();
|
||||
|
||||
nsRefPtr<NesteggPacketHolder> holder(NextPacket(aType));
|
||||
|
||||
if (!holder) {
|
||||
|
@ -85,6 +85,18 @@ public:
|
||||
// Pushes a packet to the front of the video packet queue.
|
||||
virtual void PushVideoPacket(NesteggPacketHolder* aItem);
|
||||
|
||||
// Public accessor for nestegg callbacks
|
||||
MediaResourceIndex* GetResource()
|
||||
{
|
||||
return &mResource;
|
||||
}
|
||||
|
||||
int64_t GetEndDataOffset()
|
||||
{
|
||||
return mLastWebMBlockOffset < 0 || mIsExpectingMoreData
|
||||
? mResource.GetLength() : mLastWebMBlockOffset;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class WebMTrackDemuxer;
|
||||
|
||||
@ -152,6 +164,12 @@ private:
|
||||
bool mHasVideo;
|
||||
bool mHasAudio;
|
||||
bool mNeedReIndex;
|
||||
|
||||
// The last complete block parsed by the WebMBufferedState. -1 if not set.
|
||||
// We cache those values rather than retrieving them for performance reasons
|
||||
// as nestegg only performs 1-byte read at a time.
|
||||
int64_t mLastWebMBlockOffset;
|
||||
bool mIsExpectingMoreData;
|
||||
};
|
||||
|
||||
class WebMTrackDemuxer : public MediaTrackDemuxer
|
||||
|
Loading…
Reference in New Issue
Block a user