Bug 1098126 - MoofParser forced moof read; r=mattwoodrow

This commit is contained in:
Anthony Jones 2014-12-05 14:17:23 -08:00
parent e08fdd4d44
commit 6c9fd7426d
3 changed files with 70 additions and 5 deletions

View File

@ -112,8 +112,11 @@ MP4Sample* SampleIterator::Get()
nsTArray<Moof>& moofs = mIndex->mMoofParser->mMoofs;
while (true) {
if (mCurrentMoof >= moofs.Length()) {
return nsAutoPtr<MP4Sample>();
if (mCurrentMoof == moofs.Length()) {
if (!mIndex->mMoofParser->BlockingReadNextMoof()) {
return nsAutoPtr<MP4Sample>();
}
MOZ_ASSERT(mCurrentMoof < moofs.Length());
}
if (mCurrentSample < moofs[mCurrentMoof].mIndex.Length()) {
break;
@ -154,6 +157,9 @@ void SampleIterator::Seek(Microseconds aTime)
syncMoof = mCurrentMoof;
syncSample = mCurrentSample;
}
if (sample->composition_timestamp == aTime) {
break;
}
Next();
}
mCurrentMoof = syncMoof;

View File

@ -12,12 +12,17 @@ using namespace stagefright;
using namespace mozilla;
void
MoofParser::RebuildFragmentedIndex(const nsTArray<MediaByteRange>& aByteRanges)
MoofParser::RebuildFragmentedIndex(
const nsTArray<mozilla::MediaByteRange>& aByteRanges)
{
BoxContext context(mSource, aByteRanges);
RebuildFragmentedIndex(context);
}
Box box(&context, mOffset);
for (; box.IsAvailable(); box = box.Next()) {
void
MoofParser::RebuildFragmentedIndex(BoxContext& aContext)
{
for (Box box(&aContext, mOffset); box.IsAvailable(); box = box.Next()) {
if (box.IsType("moov")) {
mInitRange = MediaByteRange(0, box.Range().mEnd);
ParseMoov(box);
@ -36,6 +41,56 @@ MoofParser::RebuildFragmentedIndex(const nsTArray<MediaByteRange>& aByteRanges)
}
}
class BlockingStream : public Stream {
public:
BlockingStream(Stream* aStream) : mStream(aStream)
{
}
bool ReadAt(int64_t offset, void* data, size_t size, size_t* bytes_read)
MOZ_OVERRIDE
{
return mStream->ReadAt(offset, data, size, bytes_read);
}
bool CachedReadAt(int64_t offset, void* data, size_t size, size_t* bytes_read)
MOZ_OVERRIDE
{
return mStream->ReadAt(offset, data, size, bytes_read);
}
virtual bool Length(int64_t* size) MOZ_OVERRIDE
{
return mStream->Length(size);
}
private:
nsRefPtr<Stream> mStream;
};
bool
MoofParser::BlockingReadNextMoof()
{
nsTArray<MediaByteRange> byteRanges;
int64_t size;
bool hasSize = mSource->Length(&size);
byteRanges.AppendElement(
MediaByteRange(0,hasSize ? size : std::numeric_limits<int64_t>::max()));
mp4_demuxer::BlockingStream* stream = new BlockingStream(mSource);
BoxContext context(stream, byteRanges);
for (Box box(&context, mOffset); box.IsAvailable(); box = box.Next()) {
if (box.IsType("moof")) {
byteRanges.Clear();
byteRanges.AppendElement(MediaByteRange(mOffset, box.Range().mEnd));
RebuildFragmentedIndex(context);
return true;
}
}
return false;
}
Interval<Microseconds>
MoofParser::GetCompositionRange(const nsTArray<MediaByteRange>& aByteRanges)
{

View File

@ -12,6 +12,7 @@ namespace mp4_demuxer {
class Stream;
class Box;
class BoxContext;
class Moof;
class Tkhd
@ -141,6 +142,7 @@ public:
}
void RebuildFragmentedIndex(
const nsTArray<mozilla::MediaByteRange>& aByteRanges);
void RebuildFragmentedIndex(BoxContext& aContext);
Interval<Microseconds> GetCompositionRange(
const nsTArray<mozilla::MediaByteRange>& aByteRanges);
bool ReachedEnd();
@ -149,6 +151,8 @@ public:
void ParseMdia(Box& aBox, Tkhd& aTkhd);
void ParseMvex(Box& aBox);
bool BlockingReadNextMoof();
mozilla::MediaByteRange mInitRange;
nsRefPtr<Stream> mSource;
uint64_t mOffset;