mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Back out 5 changesets (bug 1098126) for failing like they did on try
Backed out changeset 81bdd9d3aa25 (bug 1098126) Backed out changeset 4b8bb6132ae1 (bug 1098126) Backed out changeset 4e7a358bdd20 (bug 1098126) Backed out changeset 36f3e9c34b70 (bug 1098126) Backed out changeset bd8b11d1e93b (bug 1098126)
This commit is contained in:
parent
1f35112a50
commit
621b1fac62
@ -165,8 +165,6 @@ public:
|
||||
std::max(mEnd, aByteRange.mEnd));
|
||||
}
|
||||
|
||||
int64_t Length() { return mEnd - mStart; }
|
||||
|
||||
int64_t mStart, mEnd;
|
||||
};
|
||||
|
||||
|
@ -13,7 +13,7 @@ using namespace mozilla;
|
||||
namespace mp4_demuxer {
|
||||
|
||||
Box::Box(BoxContext* aContext, uint64_t aOffset, const Box* aParent)
|
||||
: mContext(aContext), mParent(aParent)
|
||||
: mContext(aContext), mType(0), mParent(aParent)
|
||||
{
|
||||
uint8_t header[8];
|
||||
MediaByteRange headerRange(aOffset, aOffset + sizeof(header));
|
||||
@ -69,7 +69,7 @@ Box::Box(BoxContext* aContext, uint64_t aOffset, const Box* aParent)
|
||||
}
|
||||
|
||||
Box::Box()
|
||||
: mContext(nullptr)
|
||||
: mContext(nullptr), mType(0)
|
||||
{}
|
||||
|
||||
Box
|
||||
|
@ -2,7 +2,6 @@
|
||||
* 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/. */
|
||||
|
||||
#include "mp4_demuxer/ByteReader.h"
|
||||
#include "mp4_demuxer/Index.h"
|
||||
#include "mp4_demuxer/Interval.h"
|
||||
#include "mp4_demuxer/MoofParser.h"
|
||||
@ -76,117 +75,8 @@ RangeFinder::Contains(MediaByteRange aByteRange)
|
||||
return false;
|
||||
}
|
||||
|
||||
SampleIterator::SampleIterator(Index* aIndex)
|
||||
: mIndex(aIndex)
|
||||
, mCurrentMoof(0)
|
||||
, mCurrentSample(0)
|
||||
{
|
||||
}
|
||||
|
||||
MP4Sample* SampleIterator::GetNext()
|
||||
{
|
||||
Sample* s(Get());
|
||||
if (!s) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Next();
|
||||
|
||||
nsAutoPtr<MP4Sample> sample(new MP4Sample());
|
||||
sample->decode_timestamp = s->mDecodeTime;
|
||||
sample->composition_timestamp = s->mCompositionRange.start;
|
||||
sample->duration = s->mCompositionRange.Length();
|
||||
sample->byte_offset = s->mByteRange.mStart;
|
||||
sample->is_sync_point = s->mSync;
|
||||
sample->size = s->mByteRange.Length();
|
||||
|
||||
// Do the blocking read
|
||||
sample->data = sample->extra_buffer = new uint8_t[sample->size];
|
||||
|
||||
size_t bytesRead;
|
||||
if (!mIndex->mSource->ReadAt(sample->byte_offset, sample->data, sample->size,
|
||||
&bytesRead) || bytesRead != sample->size) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!s->mCencRange.IsNull()) {
|
||||
// The size comes from an 8 bit field
|
||||
nsAutoTArray<uint8_t, 256> cenc;
|
||||
cenc.SetLength(s->mCencRange.Length());
|
||||
if (!mIndex->mSource->ReadAt(s->mCencRange.mStart, &cenc[0], cenc.Length(),
|
||||
&bytesRead) || bytesRead != cenc.Length()) {
|
||||
return nullptr;
|
||||
}
|
||||
ByteReader reader(cenc);
|
||||
sample->crypto.valid = true;
|
||||
reader.ReadArray(sample->crypto.iv, 16);
|
||||
if (reader.Remaining()) {
|
||||
uint16_t count = reader.ReadU16();
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
sample->crypto.plain_sizes.AppendElement(reader.ReadU16());
|
||||
sample->crypto.encrypted_sizes.AppendElement(reader.ReadU32());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sample.forget();
|
||||
}
|
||||
|
||||
Sample* SampleIterator::Get()
|
||||
{
|
||||
if (!mIndex->mMoofParser) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsTArray<Moof>& moofs = mIndex->mMoofParser->mMoofs;
|
||||
while (true) {
|
||||
if (mCurrentMoof == moofs.Length()) {
|
||||
if (!mIndex->mMoofParser->BlockingReadNextMoof()) {
|
||||
return nullptr;
|
||||
}
|
||||
MOZ_ASSERT(mCurrentMoof < moofs.Length());
|
||||
}
|
||||
if (mCurrentSample < moofs[mCurrentMoof].mIndex.Length()) {
|
||||
break;
|
||||
}
|
||||
mCurrentSample = 0;
|
||||
++mCurrentMoof;
|
||||
}
|
||||
return &moofs[mCurrentMoof].mIndex[mCurrentSample];
|
||||
}
|
||||
|
||||
void SampleIterator::Next()
|
||||
{
|
||||
++mCurrentSample;
|
||||
}
|
||||
|
||||
void SampleIterator::Seek(Microseconds aTime)
|
||||
{
|
||||
size_t syncMoof = 0;
|
||||
size_t syncSample = 0;
|
||||
mCurrentMoof = 0;
|
||||
mCurrentSample = 0;
|
||||
Sample* sample;
|
||||
while (!!(sample = Get())) {
|
||||
if (sample->mCompositionRange.start > aTime) {
|
||||
break;
|
||||
}
|
||||
if (sample->mSync) {
|
||||
syncMoof = mCurrentMoof;
|
||||
syncSample = mCurrentSample;
|
||||
}
|
||||
if (sample->mCompositionRange.start == aTime) {
|
||||
break;
|
||||
}
|
||||
Next();
|
||||
}
|
||||
mCurrentMoof = syncMoof;
|
||||
mCurrentSample = syncSample;
|
||||
}
|
||||
|
||||
Index::Index(const stagefright::Vector<MediaSource::Indice>& aIndex,
|
||||
Stream* aSource, uint32_t aTrackId)
|
||||
: mSource(aSource)
|
||||
{
|
||||
if (aIndex.isEmpty()) {
|
||||
mMoofParser = new MoofParser(aSource, aTrackId);
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
#include "mp4_demuxer/MoofParser.h"
|
||||
#include "mp4_demuxer/Box.h"
|
||||
#include <limits>
|
||||
|
||||
namespace mp4_demuxer
|
||||
{
|
||||
@ -13,17 +12,12 @@ using namespace stagefright;
|
||||
using namespace mozilla;
|
||||
|
||||
void
|
||||
MoofParser::RebuildFragmentedIndex(
|
||||
const nsTArray<mozilla::MediaByteRange>& aByteRanges)
|
||||
MoofParser::RebuildFragmentedIndex(const nsTArray<MediaByteRange>& aByteRanges)
|
||||
{
|
||||
BoxContext context(mSource, aByteRanges);
|
||||
RebuildFragmentedIndex(context);
|
||||
}
|
||||
|
||||
void
|
||||
MoofParser::RebuildFragmentedIndex(BoxContext& aContext)
|
||||
{
|
||||
for (Box box(&aContext, mOffset); box.IsAvailable(); box = box.Next()) {
|
||||
Box box(&context, mOffset);
|
||||
for (; box.IsAvailable(); box = box.Next()) {
|
||||
if (box.IsType("moov")) {
|
||||
mInitRange = MediaByteRange(0, box.Range().mEnd);
|
||||
ParseMoov(box);
|
||||
@ -42,54 +36,6 @@ MoofParser::RebuildFragmentedIndex(BoxContext& aContext)
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
byteRanges.AppendElement(
|
||||
MediaByteRange(0, 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)
|
||||
{
|
||||
@ -172,71 +118,6 @@ Moof::Moof(Box& aBox, Trex& aTrex, Mdhd& aMdhd, Edts& aEdts) :
|
||||
ParseTraf(box, aTrex, aMdhd, aEdts);
|
||||
}
|
||||
}
|
||||
ProcessCenc();
|
||||
}
|
||||
|
||||
bool
|
||||
Moof::GetAuxInfo(AtomType aType, nsTArray<MediaByteRange>* aByteRanges)
|
||||
{
|
||||
aByteRanges->Clear();
|
||||
|
||||
Saiz* saiz = nullptr;
|
||||
for (int i = 0; ; i++) {
|
||||
if (i == mSaizs.Length()) {
|
||||
return false;
|
||||
}
|
||||
if (mSaizs[i].mAuxInfoType == aType) {
|
||||
saiz = &mSaizs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
Saio* saio = nullptr;
|
||||
for (int i = 0; ; i++) {
|
||||
if (i == mSaios.Length()) {
|
||||
return false;
|
||||
}
|
||||
if (mSaios[i].mAuxInfoType == aType) {
|
||||
saio = &mSaios[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (saio->mOffsets.Length() == 1) {
|
||||
aByteRanges->SetCapacity(saiz->mSampleInfoSize.Length());
|
||||
uint64_t offset = mRange.mStart + saio->mOffsets[0];
|
||||
for (size_t i = 0; i < saiz->mSampleInfoSize.Length(); i++) {
|
||||
aByteRanges->AppendElement(
|
||||
MediaByteRange(offset, offset + saiz->mSampleInfoSize[i]));
|
||||
offset += saiz->mSampleInfoSize[i];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (saio->mOffsets.Length() == saiz->mSampleInfoSize.Length()) {
|
||||
aByteRanges->SetCapacity(saiz->mSampleInfoSize.Length());
|
||||
for (size_t i = 0; i < saio->mOffsets.Length(); i++) {
|
||||
uint64_t offset = mRange.mStart + saio->mOffsets[i];
|
||||
aByteRanges->AppendElement(
|
||||
MediaByteRange(offset, offset + saiz->mSampleInfoSize[i]));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
Moof::ProcessCenc()
|
||||
{
|
||||
nsTArray<MediaByteRange> cencRanges;
|
||||
if (!GetAuxInfo(AtomType("cenc"), &cencRanges) ||
|
||||
cencRanges.Length() != mIndex.Length()) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < cencRanges.Length(); i++) {
|
||||
mIndex[i].mCencRange = cencRanges[i];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
@ -255,10 +136,6 @@ Moof::ParseTraf(Box& aBox, Trex& aTrex, Mdhd& aMdhd, Edts& aEdts)
|
||||
if (!aTrex.mTrackId || tfhd.mTrackId == aTrex.mTrackId) {
|
||||
ParseTrun(box, tfhd, tfdt, aMdhd, aEdts);
|
||||
}
|
||||
} else if (box.IsType("saiz")) {
|
||||
mSaizs.AppendElement(Saiz(box));
|
||||
} else if (box.IsType("saio")) {
|
||||
mSaios.AppendElement(Saio(box));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -333,7 +210,6 @@ Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Tfdt& aTfdt, Mdhd& aMdhd, Edts& aEdts)
|
||||
sample.mByteRange = MediaByteRange(offset, offset + sampleSize);
|
||||
offset += sampleSize;
|
||||
|
||||
sample.mDecodeTime = decodeTime;
|
||||
sample.mCompositionRange = Interval<Microseconds>(
|
||||
aMdhd.ToMicroseconds(decodeTime + ctsOffset - aEdts.mMediaStart),
|
||||
aMdhd.ToMicroseconds(decodeTime + ctsOffset + sampleDuration - aEdts.mMediaStart));
|
||||
@ -353,7 +229,7 @@ Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Tfdt& aTfdt, Mdhd& aMdhd, Edts& aEdts)
|
||||
}
|
||||
ctsOrder.Sort(CtsComparator());
|
||||
|
||||
for (size_t i = 0; i < ctsOrder.Length(); i++) {
|
||||
for (int i = 0; i < ctsOrder.Length(); i++) {
|
||||
if (i + 1 < ctsOrder.Length()) {
|
||||
ctsOrder[i]->mCompositionRange.end = ctsOrder[i + 1]->mCompositionRange.start;
|
||||
}
|
||||
@ -485,48 +361,4 @@ Edts::Edts(Box& aBox)
|
||||
NS_ASSERTION(segment_duration == 0, "Can't handle edits with fixed durations");
|
||||
reader->DiscardRemaining();
|
||||
}
|
||||
|
||||
Saiz::Saiz(Box& aBox) : mAuxInfoType("sinf"), mAuxInfoTypeParameter(0)
|
||||
{
|
||||
BoxReader reader(aBox);
|
||||
uint32_t flags = reader->ReadU32();
|
||||
uint8_t version = flags >> 24;
|
||||
|
||||
if (flags & 1) {
|
||||
mAuxInfoType = reader->ReadU32();
|
||||
mAuxInfoTypeParameter = reader->ReadU32();
|
||||
}
|
||||
uint8_t defaultSampleInfoSize = reader->ReadU8();
|
||||
uint32_t count = reader->ReadU32();
|
||||
if (defaultSampleInfoSize) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
mSampleInfoSize.AppendElement(defaultSampleInfoSize);
|
||||
}
|
||||
} else {
|
||||
reader->ReadArray(mSampleInfoSize, count);
|
||||
}
|
||||
}
|
||||
|
||||
Saio::Saio(Box& aBox) : mAuxInfoType("sinf"), mAuxInfoTypeParameter(0)
|
||||
{
|
||||
BoxReader reader(aBox);
|
||||
uint32_t flags = reader->ReadU32();
|
||||
uint8_t version = flags >> 24;
|
||||
|
||||
if (flags & 1) {
|
||||
mAuxInfoType = reader->ReadU32();
|
||||
mAuxInfoTypeParameter = reader->ReadU32();
|
||||
}
|
||||
size_t count = reader->ReadU32();
|
||||
mOffsets.SetCapacity(count);
|
||||
if (version == 0) {
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
mOffsets.AppendElement(reader->ReadU32());
|
||||
}
|
||||
} else {
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
mOffsets.AppendElement(reader->ReadU64());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,30 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef ATOM_TYPE_H_
|
||||
#define ATOM_TYPE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "mozilla/Endian.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
namespace mp4_demuxer {
|
||||
|
||||
class AtomType
|
||||
{
|
||||
public:
|
||||
AtomType() : mType(0) { }
|
||||
AtomType(uint32_t aType) : mType(aType) { }
|
||||
AtomType(const char* aType) : mType(BigEndian::readUint32(aType)) { }
|
||||
bool operator==(const AtomType& aType) const { return mType == aType.mType; }
|
||||
|
||||
private:
|
||||
uint32_t mType;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -11,7 +11,6 @@
|
||||
#include "nsTArray.h"
|
||||
#include "MediaResource.h"
|
||||
#include "mozilla/Endian.h"
|
||||
#include "mp4_demuxer/AtomType.h"
|
||||
#include "mp4_demuxer/ByteReader.h"
|
||||
|
||||
using namespace mozilla;
|
||||
@ -43,8 +42,13 @@ public:
|
||||
uint64_t Length() const { return mRange.mEnd - mRange.mStart; }
|
||||
uint64_t NextOffset() const { return mRange.mEnd; }
|
||||
const MediaByteRange& Range() const { return mRange; }
|
||||
|
||||
const Box* Parent() const { return mParent; }
|
||||
bool IsType(const char* aType) const { return mType == AtomType(aType); }
|
||||
|
||||
bool IsType(const char* aType) const
|
||||
{
|
||||
return mType == BigEndian::readUint32(aType);
|
||||
}
|
||||
|
||||
Box Next() const;
|
||||
Box FirstChild() const;
|
||||
@ -55,7 +59,7 @@ private:
|
||||
BoxContext* mContext;
|
||||
mozilla::MediaByteRange mRange;
|
||||
uint64_t mChildOffset;
|
||||
AtomType mType;
|
||||
uint32_t mType;
|
||||
const Box* mParent;
|
||||
};
|
||||
|
||||
|
@ -23,12 +23,6 @@ public:
|
||||
: mPtr(aData), mRemaining(aSize)
|
||||
{
|
||||
}
|
||||
template<size_t S>
|
||||
ByteReader(const nsAutoTArray<uint8_t, S>& aData)
|
||||
: mPtr(&aData[0]), mRemaining(aData.Length())
|
||||
{
|
||||
}
|
||||
|
||||
void SetData(const nsTArray<uint8_t>& aData)
|
||||
{
|
||||
MOZ_ASSERT(!mPtr && !mRemaining);
|
||||
|
@ -165,6 +165,7 @@ public:
|
||||
|
||||
void Prepend(const uint8_t* aData, size_t aSize);
|
||||
|
||||
private:
|
||||
nsAutoArrayPtr<uint8_t> extra_buffer;
|
||||
};
|
||||
}
|
||||
|
@ -14,30 +14,13 @@ namespace mp4_demuxer
|
||||
template <typename T> class Interval;
|
||||
class MoofParser;
|
||||
class Sample;
|
||||
class Index;
|
||||
|
||||
class SampleIterator
|
||||
{
|
||||
public:
|
||||
SampleIterator(Index* aIndex);
|
||||
MP4Sample* GetNext();
|
||||
void Seek(Microseconds aTime);
|
||||
|
||||
private:
|
||||
Sample* Get();
|
||||
void Next();
|
||||
nsRefPtr<Index> mIndex;
|
||||
size_t mCurrentMoof;
|
||||
size_t mCurrentSample;
|
||||
};
|
||||
|
||||
class Index
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Index)
|
||||
|
||||
Index(const stagefright::Vector<stagefright::MediaSource::Indice>& aIndex,
|
||||
Stream* aSource, uint32_t aTrackId);
|
||||
~Index();
|
||||
|
||||
void UpdateMoofIndex(const nsTArray<mozilla::MediaByteRange>& aByteRanges);
|
||||
Microseconds GetEndCompositionIfBuffered(
|
||||
@ -46,14 +29,8 @@ public:
|
||||
const nsTArray<mozilla::MediaByteRange>& aByteRanges,
|
||||
nsTArray<Interval<Microseconds>>* aTimeRanges);
|
||||
uint64_t GetEvictionOffset(Microseconds aTime);
|
||||
bool IsFragmented() { return mMoofParser; }
|
||||
|
||||
friend class SampleIterator;
|
||||
|
||||
private:
|
||||
~Index();
|
||||
|
||||
Stream* mSource;
|
||||
nsTArray<Sample> mIndex;
|
||||
nsAutoPtr<MoofParser> mMoofParser;
|
||||
};
|
||||
|
@ -5,7 +5,6 @@
|
||||
#ifndef MOOF_PARSER_H_
|
||||
#define MOOF_PARSER_H_
|
||||
|
||||
#include "mp4_demuxer/AtomType.h"
|
||||
#include "mp4_demuxer/mp4_demuxer.h"
|
||||
#include "MediaResource.h"
|
||||
|
||||
@ -13,7 +12,6 @@ namespace mp4_demuxer {
|
||||
|
||||
class Stream;
|
||||
class Box;
|
||||
class BoxContext;
|
||||
class Moof;
|
||||
|
||||
class Tkhd
|
||||
@ -110,49 +108,14 @@ public:
|
||||
struct Sample
|
||||
{
|
||||
mozilla::MediaByteRange mByteRange;
|
||||
mozilla::MediaByteRange mCencRange;
|
||||
Microseconds mDecodeTime;
|
||||
Interval<Microseconds> mCompositionRange;
|
||||
bool mSync;
|
||||
};
|
||||
|
||||
class Saiz
|
||||
{
|
||||
public:
|
||||
Saiz(Box& aBox);
|
||||
|
||||
AtomType mAuxInfoType;
|
||||
uint32_t mAuxInfoTypeParameter;
|
||||
nsTArray<uint8_t> mSampleInfoSize;
|
||||
};
|
||||
|
||||
class Saio
|
||||
{
|
||||
public:
|
||||
Saio(Box& aBox);
|
||||
|
||||
AtomType mAuxInfoType;
|
||||
uint32_t mAuxInfoTypeParameter;
|
||||
nsTArray<uint64_t> mOffsets;
|
||||
};
|
||||
|
||||
class AuxInfo {
|
||||
public:
|
||||
AuxInfo(int64_t aMoofOffset, Saiz& aSaiz, Saio& aSaio);
|
||||
bool GetByteRanges(nsTArray<MediaByteRange>* aByteRanges);
|
||||
|
||||
private:
|
||||
|
||||
int64_t mMoofOffset;
|
||||
Saiz& mSaiz;
|
||||
Saio& mSaio;
|
||||
};
|
||||
|
||||
class Moof
|
||||
{
|
||||
public:
|
||||
Moof(Box& aBox, Trex& aTrex, Mdhd& aMdhd, Edts& aEdts);
|
||||
bool GetAuxInfo(AtomType aType, nsTArray<MediaByteRange>* aByteRanges);
|
||||
void FixRounding(const Moof& aMoof);
|
||||
|
||||
mozilla::MediaByteRange mRange;
|
||||
@ -160,15 +123,9 @@ public:
|
||||
Interval<Microseconds> mTimeRange;
|
||||
nsTArray<Sample> mIndex;
|
||||
|
||||
nsTArray<Saiz> mSaizs;
|
||||
nsTArray<Saio> mSaios;
|
||||
|
||||
private:
|
||||
void ParseTraf(Box& aBox, Trex& aTrex, Mdhd& aMdhd, Edts& aEdts);
|
||||
void ParseTrun(Box& aBox, Tfhd& aTfhd, Tfdt& aTfdt, Mdhd& aMdhd, Edts& aEdts);
|
||||
void ParseSaiz(Box& aBox);
|
||||
void ParseSaio(Box& aBox);
|
||||
bool ProcessCenc();
|
||||
uint64_t mMaxRoundingError;
|
||||
};
|
||||
|
||||
@ -183,7 +140,6 @@ public:
|
||||
}
|
||||
void RebuildFragmentedIndex(
|
||||
const nsTArray<mozilla::MediaByteRange>& aByteRanges);
|
||||
void RebuildFragmentedIndex(BoxContext& aContext);
|
||||
Interval<Microseconds> GetCompositionRange(
|
||||
const nsTArray<mozilla::MediaByteRange>& aByteRanges);
|
||||
bool ReachedEnd();
|
||||
@ -192,8 +148,6 @@ public:
|
||||
void ParseMdia(Box& aBox, Tkhd& aTkhd);
|
||||
void ParseMvex(Box& aBox);
|
||||
|
||||
bool BlockingReadNextMoof();
|
||||
|
||||
mozilla::MediaByteRange mInitRange;
|
||||
nsRefPtr<Stream> mSource;
|
||||
uint64_t mOffset;
|
||||
|
@ -26,13 +26,11 @@ struct StageFrightPrivate
|
||||
|
||||
sp<MediaSource> mAudio;
|
||||
MediaSource::ReadOptions mAudioOptions;
|
||||
nsAutoPtr<SampleIterator> mAudioIterator;
|
||||
|
||||
sp<MediaSource> mVideo;
|
||||
MediaSource::ReadOptions mVideoOptions;
|
||||
nsAutoPtr<SampleIterator> mVideoIterator;
|
||||
|
||||
nsTArray<nsRefPtr<Index>> mIndexes;
|
||||
nsTArray<nsAutoPtr<Index>> mIndexes;
|
||||
};
|
||||
|
||||
class DataSourceAdapter : public DataSource
|
||||
@ -102,31 +100,21 @@ MP4Demuxer::Init()
|
||||
}
|
||||
|
||||
if (!mPrivate->mAudio.get() && !strncmp(mimeType, "audio/", 6)) {
|
||||
sp<MediaSource> track = e->getTrack(i);
|
||||
if (track->start() != OK) {
|
||||
mPrivate->mAudio = e->getTrack(i);
|
||||
if (mPrivate->mAudio->start() != OK) {
|
||||
return false;
|
||||
}
|
||||
mPrivate->mAudio = track;
|
||||
mAudioConfig.Update(metaData, mimeType);
|
||||
nsRefPtr<Index> index = new Index(mPrivate->mAudio->exportIndex(),
|
||||
mSource, mAudioConfig.mTrackId);
|
||||
mPrivate->mIndexes.AppendElement(index);
|
||||
if (index->IsFragmented() && !mAudioConfig.crypto.valid) {
|
||||
mPrivate->mAudioIterator = new SampleIterator(index);
|
||||
}
|
||||
mPrivate->mIndexes.AppendElement(new Index(
|
||||
mPrivate->mAudio->exportIndex(), mSource, mAudioConfig.mTrackId));
|
||||
} else if (!mPrivate->mVideo.get() && !strncmp(mimeType, "video/", 6)) {
|
||||
sp<MediaSource> track = e->getTrack(i);
|
||||
if (track->start() != OK) {
|
||||
mPrivate->mVideo = e->getTrack(i);
|
||||
if (mPrivate->mVideo->start() != OK) {
|
||||
return false;
|
||||
}
|
||||
mPrivate->mVideo = track;
|
||||
mVideoConfig.Update(metaData, mimeType);
|
||||
nsRefPtr<Index> index = new Index(mPrivate->mVideo->exportIndex(),
|
||||
mSource, mVideoConfig.mTrackId);
|
||||
mPrivate->mIndexes.AppendElement(index);
|
||||
if (index->IsFragmented() && !mVideoConfig.crypto.valid) {
|
||||
mPrivate->mVideoIterator = new SampleIterator(index);
|
||||
}
|
||||
mPrivate->mIndexes.AppendElement(new Index(
|
||||
mPrivate->mVideo->exportIndex(), mSource, mVideoConfig.mTrackId));
|
||||
}
|
||||
}
|
||||
sp<MetaData> metaData = e->getMetaData();
|
||||
@ -162,40 +150,20 @@ MP4Demuxer::CanSeek()
|
||||
void
|
||||
MP4Demuxer::SeekAudio(Microseconds aTime)
|
||||
{
|
||||
if (mPrivate->mAudioIterator) {
|
||||
mPrivate->mAudioIterator->Seek(aTime);
|
||||
} else {
|
||||
mPrivate->mAudioOptions.setSeekTo(
|
||||
aTime, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
|
||||
}
|
||||
mPrivate->mAudioOptions.setSeekTo(
|
||||
aTime, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
|
||||
}
|
||||
|
||||
void
|
||||
MP4Demuxer::SeekVideo(Microseconds aTime)
|
||||
{
|
||||
if (mPrivate->mVideoIterator) {
|
||||
mPrivate->mVideoIterator->Seek(aTime);
|
||||
} else {
|
||||
mPrivate->mVideoOptions.setSeekTo(
|
||||
aTime, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
|
||||
}
|
||||
mPrivate->mVideoOptions.setSeekTo(
|
||||
aTime, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
|
||||
}
|
||||
|
||||
MP4Sample*
|
||||
MP4Demuxer::DemuxAudioSample()
|
||||
{
|
||||
if (mPrivate->mAudioIterator) {
|
||||
nsAutoPtr<MP4Sample> sample(mPrivate->mAudioIterator->GetNext());
|
||||
if (sample) {
|
||||
if (sample->crypto.valid) {
|
||||
sample->crypto.mode = mAudioConfig.crypto.mode;
|
||||
sample->crypto.iv_size = mAudioConfig.crypto.iv_size;
|
||||
sample->crypto.key.AppendElements(mAudioConfig.crypto.key);
|
||||
}
|
||||
}
|
||||
return sample.forget();
|
||||
}
|
||||
|
||||
nsAutoPtr<MP4Sample> sample(new MP4Sample());
|
||||
status_t status =
|
||||
mPrivate->mAudio->read(&sample->mMediaBuffer, &mPrivate->mAudioOptions);
|
||||
@ -213,19 +181,6 @@ MP4Demuxer::DemuxAudioSample()
|
||||
MP4Sample*
|
||||
MP4Demuxer::DemuxVideoSample()
|
||||
{
|
||||
if (mPrivate->mVideoIterator) {
|
||||
nsAutoPtr<MP4Sample> sample(mPrivate->mVideoIterator->GetNext());
|
||||
if (sample) {
|
||||
sample->prefix_data = mVideoConfig.annex_b;
|
||||
if (sample->crypto.valid) {
|
||||
sample->crypto.mode = mVideoConfig.crypto.mode;
|
||||
sample->crypto.iv_size = mVideoConfig.crypto.iv_size;
|
||||
sample->crypto.key.AppendElements(mVideoConfig.crypto.key);
|
||||
}
|
||||
}
|
||||
return sample.forget();
|
||||
}
|
||||
|
||||
nsAutoPtr<MP4Sample> sample(new MP4Sample());
|
||||
status_t status =
|
||||
mPrivate->mVideo->read(&sample->mMediaBuffer, &mPrivate->mVideoOptions);
|
||||
|
@ -112,7 +112,6 @@ private:
|
||||
status_t parseSampleAuxiliaryInformationSizes(off64_t offset, off64_t size);
|
||||
status_t parseSampleAuxiliaryInformationOffsets(off64_t offset, off64_t size);
|
||||
void lookForMoof();
|
||||
status_t moveToNextFragment();
|
||||
|
||||
struct TrackFragmentHeaderInfo {
|
||||
enum Flags {
|
||||
@ -3584,34 +3583,6 @@ status_t MPEG4Source::read(
|
||||
}
|
||||
}
|
||||
|
||||
status_t MPEG4Source::moveToNextFragment() {
|
||||
off64_t nextMoof = mNextMoofOffset;
|
||||
mCurrentSamples.clear();
|
||||
mDeferredSaio.clear();
|
||||
mDeferredSaiz.clear();
|
||||
mCurrentSampleIndex = 0;
|
||||
uint32_t hdr[2];
|
||||
do {
|
||||
if (mDataSource->readAt(nextMoof, hdr, 8) < 8) {
|
||||
return ERROR_END_OF_STREAM;
|
||||
}
|
||||
uint64_t chunk_size = ntohl(hdr[0]);
|
||||
uint32_t chunk_type = ntohl(hdr[1]);
|
||||
|
||||
// Skip over anything that isn't a moof
|
||||
if (chunk_type != FOURCC('m', 'o', 'o', 'f')) {
|
||||
nextMoof += chunk_size;
|
||||
continue;
|
||||
}
|
||||
mCurrentMoofOffset = nextMoof;
|
||||
status_t ret = parseChunk(&nextMoof);
|
||||
if (ret != OK) {
|
||||
return ret;
|
||||
}
|
||||
} while (mCurrentSamples.size() == 0);
|
||||
return OK;
|
||||
}
|
||||
|
||||
status_t MPEG4Source::fragmentedRead(
|
||||
MediaBuffer **out, const ReadOptions *options) {
|
||||
|
||||
@ -3627,6 +3598,10 @@ status_t MPEG4Source::fragmentedRead(
|
||||
ReadOptions::SeekMode mode;
|
||||
if (options && options->getSeekTo(&seekTimeUs, &mode)) {
|
||||
|
||||
mCurrentSamples.clear();
|
||||
mDeferredSaio.clear();
|
||||
mDeferredSaiz.clear();
|
||||
mCurrentSampleIndex = 0;
|
||||
int numSidxEntries = mSegments.size();
|
||||
if (numSidxEntries != 0) {
|
||||
int64_t totalTime = 0;
|
||||
@ -3649,21 +3624,37 @@ status_t MPEG4Source::fragmentedRead(
|
||||
totalOffset += se->mSize;
|
||||
}
|
||||
mCurrentMoofOffset = totalOffset;
|
||||
mCurrentSamples.clear();
|
||||
mDeferredSaio.clear();
|
||||
mDeferredSaiz.clear();
|
||||
mCurrentSampleIndex = 0;
|
||||
mCurrentTime = totalTime * mTimescale / 1000000ll;
|
||||
mNextMoofOffset = totalOffset;
|
||||
mCurrentTime = totalTime * mTimescale / 1000000ll;
|
||||
}
|
||||
else {
|
||||
mNextMoofOffset = mFirstMoofOffset;
|
||||
uint32_t seekTime = (int32_t) ((seekTimeUs * mTimescale) / 1000000ll);
|
||||
while (true) {
|
||||
status_t ret = moveToNextFragment();
|
||||
if (ret != OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t hdr[2];
|
||||
do {
|
||||
off64_t moofOffset = mNextMoofOffset; // lastSample.offset + lastSample.size;
|
||||
if (mDataSource->readAt(moofOffset, hdr, 8) < 8) {
|
||||
ALOGV("Seek ERROR_END_OF_STREAM\n");
|
||||
return ERROR_END_OF_STREAM;
|
||||
}
|
||||
uint64_t chunk_size = ntohl(hdr[0]);
|
||||
uint32_t chunk_type = ntohl(hdr[1]);
|
||||
char chunk[5];
|
||||
MakeFourCCString(chunk_type, chunk);
|
||||
|
||||
// If we're pointing to a segment type or sidx box then we skip them.
|
||||
if (chunk_type != FOURCC('m', 'o', 'o', 'f')) {
|
||||
mNextMoofOffset += chunk_size;
|
||||
continue;
|
||||
}
|
||||
mCurrentMoofOffset = moofOffset;
|
||||
status_t ret = parseChunk(&moofOffset);
|
||||
if (ret != OK) {
|
||||
return ret;
|
||||
}
|
||||
} while (mCurrentSamples.size() == 0);
|
||||
uint32_t time = mCurrentTime;
|
||||
int i;
|
||||
for (i = 0; i < mCurrentSamples.size() && time <= seekTime; i++) {
|
||||
@ -3677,6 +3668,11 @@ status_t MPEG4Source::fragmentedRead(
|
||||
if (i != mCurrentSamples.size()) {
|
||||
break;
|
||||
}
|
||||
|
||||
mCurrentSamples.clear();
|
||||
mDeferredSaio.clear();
|
||||
mDeferredSaiz.clear();
|
||||
mCurrentSampleIndex = 0;
|
||||
}
|
||||
ALOGV("Seeking offset %d; %ldus\n", mCurrentTime - seekTime,
|
||||
(((int64_t) mCurrentTime - seekTime) * 1000000ll) / mTimescale);
|
||||
@ -3701,10 +3697,32 @@ status_t MPEG4Source::fragmentedRead(
|
||||
newBuffer = true;
|
||||
|
||||
if (mCurrentSampleIndex >= mCurrentSamples.size()) {
|
||||
status_t ret = moveToNextFragment();
|
||||
if (ret != OK) {
|
||||
return ret;
|
||||
}
|
||||
// move to next fragment
|
||||
off64_t nextMoof = mNextMoofOffset; // lastSample.offset + lastSample.size;
|
||||
mCurrentSamples.clear();
|
||||
mDeferredSaio.clear();
|
||||
mDeferredSaiz.clear();
|
||||
mCurrentSampleIndex = 0;
|
||||
uint32_t hdr[2];
|
||||
do {
|
||||
if (mDataSource->readAt(nextMoof, hdr, 8) < 8) {
|
||||
return ERROR_END_OF_STREAM;
|
||||
}
|
||||
uint64_t chunk_size = ntohl(hdr[0]);
|
||||
uint32_t chunk_type = ntohl(hdr[1]);
|
||||
|
||||
// If we're pointing to a segment type or sidx box then we skip them.
|
||||
if (chunk_type == FOURCC('s', 't', 'y', 'p') ||
|
||||
chunk_type == FOURCC('s', 'i', 'd', 'x')) {
|
||||
nextMoof += chunk_size;
|
||||
continue;
|
||||
}
|
||||
mCurrentMoofOffset = nextMoof;
|
||||
status_t ret = parseChunk(&nextMoof);
|
||||
if (ret != OK) {
|
||||
return ret;
|
||||
}
|
||||
} while (mCurrentSamples.size() == 0);
|
||||
}
|
||||
|
||||
const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex];
|
||||
|
@ -50,7 +50,6 @@ if CONFIG['OS_TARGET'] != 'Android':
|
||||
EXPORTS.mp4_demuxer += [
|
||||
'binding/include/mp4_demuxer/Adts.h',
|
||||
'binding/include/mp4_demuxer/AnnexB.h',
|
||||
'binding/include/mp4_demuxer/AtomType.h',
|
||||
'binding/include/mp4_demuxer/BufferStream.h',
|
||||
'binding/include/mp4_demuxer/ByteReader.h',
|
||||
'binding/include/mp4_demuxer/DecoderData.h',
|
||||
|
Loading…
Reference in New Issue
Block a user