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:
Phil Ringnalda 2014-12-10 20:01:08 -08:00
parent 1f35112a50
commit 621b1fac62
13 changed files with 88 additions and 496 deletions

View File

@ -165,8 +165,6 @@ public:
std::max(mEnd, aByteRange.mEnd));
}
int64_t Length() { return mEnd - mStart; }
int64_t mStart, mEnd;
};

View File

@ -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

View File

@ -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);

View File

@ -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());
}
}
}
}

View File

@ -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

View File

@ -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;
};

View File

@ -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);

View File

@ -165,6 +165,7 @@ public:
void Prepend(const uint8_t* aData, size_t aSize);
private:
nsAutoArrayPtr<uint8_t> extra_buffer;
};
}

View File

@ -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;
};

View File

@ -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;

View File

@ -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);

View File

@ -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];

View File

@ -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',