Backed out changesets b8e0173c9c47, b087e84a99f1, and 66c055120ca7 (bug 1049133) for Android and B2G bustage.

CLOSED TREE
This commit is contained in:
Ryan VanderMeulen 2014-08-17 22:28:34 -04:00
Родитель 564dd7ae57
Коммит e5df4919ce
9 изменённых файлов: 57 добавлений и 132 удалений

Просмотреть файл

@ -159,7 +159,6 @@ public:
// Only used by WebMReader and MediaOmxReader for now, so stub here rather // Only used by WebMReader and MediaOmxReader for now, so stub here rather
// than in every reader than inherits from MediaDecoderReader. // than in every reader than inherits from MediaDecoderReader.
virtual void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset) {} virtual void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset) {}
virtual int64_t GetEvictionOffset(double aTime) { return -1; }
virtual MediaQueue<AudioData>& AudioQueue() { return mAudioQueue; } virtual MediaQueue<AudioData>& AudioQueue() { return mAudioQueue; }
virtual MediaQueue<VideoData>& VideoQueue() { return mVideoQueue; } virtual MediaQueue<VideoData>& VideoQueue() { return mVideoQueue; }

Просмотреть файл

@ -109,6 +109,7 @@ MP4Reader::MP4Reader(AbstractMediaDecoder* aDecoder)
, mVideo("MP4 video decoder data", Preferences::GetUint("media.mp4-video-decode-ahead", 2)) , mVideo("MP4 video decoder data", Preferences::GetUint("media.mp4-video-decode-ahead", 2))
, mLastReportedNumDecodedFrames(0) , mLastReportedNumDecodedFrames(0)
, mLayersBackendType(layers::LayersBackend::LAYERS_NONE) , mLayersBackendType(layers::LayersBackend::LAYERS_NONE)
, mTimeRangesMonitor("MP4Reader::TimeRanges")
, mDemuxerInitialized(false) , mDemuxerInitialized(false)
, mIsEncrypted(false) , mIsEncrypted(false)
{ {
@ -768,36 +769,29 @@ MP4Reader::NotifyDataArrived(const char* aBuffer, uint32_t aLength,
void void
MP4Reader::UpdateIndex() MP4Reader::UpdateIndex()
{ {
nsTArray<MediaByteRange> ranges;
nsTArray<Interval<Microseconds>> timeRanges;
MediaResource* resource = mDecoder->GetResource(); MediaResource* resource = mDecoder->GetResource();
resource->Pin(); resource->Pin();
nsTArray<MediaByteRange> ranges;
if (NS_SUCCEEDED(resource->GetCachedRanges(ranges))) { if (NS_SUCCEEDED(resource->GetCachedRanges(ranges))) {
mDemuxer->UpdateIndex(ranges); mDemuxer->ConvertByteRangesToTime(ranges, &timeRanges);
} }
resource->Unpin(); resource->Unpin();
MonitorAutoLock mon(mTimeRangesMonitor);
mTimeRanges = timeRanges;
} }
int64_t
MP4Reader::GetEvictionOffset(double aTime)
{
return mDemuxer->GetEvictionOffset(aTime * 1000000.0);
}
nsresult nsresult
MP4Reader::GetBuffered(dom::TimeRanges* aBuffered, int64_t aStartTime) MP4Reader::GetBuffered(dom::TimeRanges* aBuffered, int64_t aStartTime)
{ {
MediaResource* resource = mDecoder->GetResource(); MonitorAutoLock mon(mTimeRangesMonitor);
resource->Pin(); for (size_t i = 0; i < mTimeRanges.Length(); i++) {
nsTArray<MediaByteRange> ranges; aBuffered->Add((mTimeRanges[i].start - aStartTime) / 1000000.0,
if (NS_SUCCEEDED(resource->GetCachedRanges(ranges))) { (mTimeRanges[i].end - aStartTime) / 1000000.0);
nsTArray<Interval<Microseconds>> timeRanges;
mDemuxer->ConvertByteRangesToTime(ranges, &timeRanges);
for (size_t i = 0; i < timeRanges.Length(); i++) {
aBuffered->Add((timeRanges[i].start - aStartTime) / 1000000.0,
(timeRanges[i].end - aStartTime) / 1000000.0);
} }
}
resource->Unpin();
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -55,8 +55,6 @@ public:
virtual void NotifyDataArrived(const char* aBuffer, uint32_t aLength, virtual void NotifyDataArrived(const char* aBuffer, uint32_t aLength,
int64_t aOffset) MOZ_OVERRIDE; int64_t aOffset) MOZ_OVERRIDE;
virtual int64_t GetEvictionOffset(double aTime) MOZ_OVERRIDE;
virtual nsresult GetBuffered(dom::TimeRanges* aBuffered, virtual nsresult GetBuffered(dom::TimeRanges* aBuffered,
int64_t aStartTime) MOZ_OVERRIDE; int64_t aStartTime) MOZ_OVERRIDE;
@ -182,6 +180,8 @@ private:
layers::LayersBackend mLayersBackendType; layers::LayersBackend mLayersBackendType;
nsTArray<nsTArray<uint8_t>> mInitDataEncountered; nsTArray<nsTArray<uint8_t>> mInitDataEncountered;
Monitor mTimeRangesMonitor;
nsTArray<mp4_demuxer::Interval<Microseconds>> mTimeRanges;
// True if we've read the streams' metadata. // True if we've read the streams' metadata.
bool mDemuxerInitialized; bool mDemuxerInitialized;

Просмотреть файл

@ -112,16 +112,11 @@ SubBufferDecoder::GetBuffered(dom::TimeRanges* aBuffered)
int64_t int64_t
SubBufferDecoder::ConvertToByteOffset(double aTime) SubBufferDecoder::ConvertToByteOffset(double aTime)
{ {
int64_t readerOffset = mReader->GetEvictionOffset(aTime);
if (readerOffset >= 0) {
return readerOffset;
}
// Uses a conversion based on (aTime/duration) * length. For the // Uses a conversion based on (aTime/duration) * length. For the
// purposes of eviction this should be adequate since we have the // purposes of eviction this should be adequate since we have the
// byte threshold as well to ensure data actually gets evicted and // byte threshold as well to ensure data actually gets evicted and
// we ensure we don't evict before the current playable point. // we ensure we don't evict before the current playable point.
if (mMediaDuration <= 0) { if (mMediaDuration == -1) {
return -1; return -1;
} }
int64_t length = GetResource()->GetLength(); int64_t length = GetResource()->GetLength();

Просмотреть файл

@ -85,55 +85,44 @@ Index::Index(const stagefright::Vector<MediaSource::Indice>& aIndex,
Index::~Index() {} Index::~Index() {}
void
Index::UpdateMoofIndex(const nsTArray<MediaByteRange>& aByteRanges)
{
if (!mMoofParser) {
return;
}
MonitorAutoLock mon(mMonitor);
mMoofParser->RebuildFragmentedIndex(aByteRanges);
}
void void
Index::ConvertByteRangesToTimeRanges( Index::ConvertByteRangesToTimeRanges(
const nsTArray<MediaByteRange>& aByteRanges, const nsTArray<MediaByteRange>& aByteRanges,
nsTArray<Interval<Microseconds>>* aTimeRanges) nsTArray<Interval<Microseconds>>* aTimeRanges)
{ {
MonitorAutoLock mon(mMonitor);
RangeFinder rangeFinder(aByteRanges); RangeFinder rangeFinder(aByteRanges);
nsTArray<Interval<Microseconds>> timeRanges; nsTArray<Interval<Microseconds>> timeRanges;
nsTArray<nsTArray<stagefright::MediaSource::Indice>*> indexes; nsTArray<stagefright::MediaSource::Indice> moofIndex;
nsTArray<stagefright::MediaSource::Indice>* index;
if (mMoofParser) { if (mMoofParser) {
{
MonitorAutoLock mon(mMonitor);
mMoofParser->RebuildFragmentedIndex(aByteRanges);
// We take the index out of the moof parser and move it into a local // We take the index out of the moof parser and move it into a local
// variable so we don't get concurrency issues. It gets freed when we // variable so we don't get concurrency issues. It gets freed when we
// exit this function. // exit this function.
for (int i = 0; i < mMoofParser->mMoofs.Length(); i++) { for (int i = 0; i < mMoofParser->mMoofs.Length(); i++) {
Moof& moof = mMoofParser->mMoofs[i]; Moof& moof = mMoofParser->mMoofs[i];
if (rangeFinder.Contains(moof.mRange) &&
// We need the entire moof in order to play anything rangeFinder.Contains(moof.mMdatRange)) {
if (rangeFinder.Contains(moof.mRange)) {
if (rangeFinder.Contains(moof.mMdatRange)) {
timeRanges.AppendElements(moof.mTimeRanges); timeRanges.AppendElements(moof.mTimeRanges);
} else { } else {
indexes.AppendElement(&moof.mIndex); moofIndex.AppendElements(mMoofParser->mMoofs[i].mIndex);
} }
} }
} }
index = &moofIndex;
} else { } else {
indexes.AppendElement(&mIndex); index = &mIndex;
} }
bool hasSync = false; bool hasSync = false;
for (size_t i = 0; i < indexes.Length(); i++) { for (size_t i = 0; i < index->Length(); i++) {
nsTArray<stagefright::MediaSource::Indice>* index = indexes[i]; const MediaSource::Indice& indice = (*index)[i];
for (size_t j = 0; j < index->Length(); j++) { if (!rangeFinder.Contains(MediaByteRange(indice.start_offset,
const MediaSource::Indice& indice = (*index)[j]; indice.end_offset))) {
if (!rangeFinder.Contains(
MediaByteRange(indice.start_offset, indice.end_offset))) {
// We process the index in decode order so we clear hasSync when we hit // We process the index in decode order so we clear hasSync when we hit
// a range that isn't buffered. // a range that isn't buffered.
hasSync = false; hasSync = false;
@ -145,8 +134,13 @@ Index::ConvertByteRangesToTimeRanges(
continue; continue;
} }
Interval<Microseconds>::SemiNormalAppend( // This is an optimisation for when the file is decoded in composition
timeRanges, Interval<Microseconds>(indice.start_composition, // order. It means that Normalise() below doesn't need to do a sort.
size_t s = timeRanges.Length();
if (s && timeRanges[s - 1].end == indice.start_composition) {
timeRanges[s - 1].end = indice.end_composition;
} else {
timeRanges.AppendElement(Interval<Microseconds>(indice.start_composition,
indice.end_composition)); indice.end_composition));
} }
} }
@ -154,32 +148,4 @@ Index::ConvertByteRangesToTimeRanges(
// This fixes up when the compositon order differs from the byte range order // This fixes up when the compositon order differs from the byte range order
Interval<Microseconds>::Normalize(timeRanges, aTimeRanges); Interval<Microseconds>::Normalize(timeRanges, aTimeRanges);
} }
uint64_t
Index::GetEvictionOffset(Microseconds aTime)
{
uint64_t offset = std::numeric_limits<uint64_t>::max();
if (mMoofParser) {
// We need to keep the whole moof if we're keeping any of it because the
// parser doesn't keep parsed moofs.
for (int i = 0; i < mMoofParser->mMoofs.Length(); i++) {
Moof& moof = mMoofParser->mMoofs[i];
if (!moof.mTimeRanges.IsEmpty() && moof.mTimeRanges[0].end > aTime) {
offset = std::min(offset, uint64_t(std::min(moof.mRange.mStart,
moof.mMdatRange.mStart)));
}
}
} else {
// We've already parsed and stored the moov so we don't need to keep it.
// All we need to keep is the sample data itself.
for (size_t i = 0; i < mIndex.Length(); i++) {
const MediaSource::Indice& indice = mIndex[i];
if (aTime >= indice.start_composition) {
offset = std::min(offset, indice.start_offset);
}
}
}
return offset;
}
} }

Просмотреть файл

@ -22,11 +22,9 @@ public:
Stream* aSource, uint32_t aTrackId); Stream* aSource, uint32_t aTrackId);
~Index(); ~Index();
void UpdateMoofIndex(const nsTArray<mozilla::MediaByteRange>& aByteRanges);
void ConvertByteRangesToTimeRanges( void ConvertByteRangesToTimeRanges(
const nsTArray<mozilla::MediaByteRange>& aByteRanges, const nsTArray<mozilla::MediaByteRange>& aByteRanges,
nsTArray<Interval<Microseconds>>* aTimeRanges); nsTArray<Interval<Microseconds>>* aTimeRanges);
uint64_t GetEvictionOffset(Microseconds aTime);
private: private:
mozilla::Monitor mMonitor; mozilla::Monitor mMonitor;

Просмотреть файл

@ -61,7 +61,7 @@ struct Interval
} }
MOZ_ASSERT(aNormalized->IsEmpty()); MOZ_ASSERT(aNormalized->IsEmpty());
nsTArray<Interval<T>> sorted; nsTArray<Interval<T> > sorted;
sorted = aIntervals; sorted = aIntervals;
sorted.Sort(Compare()); sorted.Sort(Compare());
@ -81,9 +81,9 @@ struct Interval
aNormalized->AppendElement(current); aNormalized->AppendElement(current);
} }
static void Intersection(const nsTArray<Interval<T>>& a0, static void Intersection(const nsTArray<Interval<T> >& a0,
const nsTArray<Interval<T>>& a1, const nsTArray<Interval<T> >& a1,
nsTArray<Interval<T>>* aIntersection) nsTArray<Interval<T> >* aIntersection)
{ {
MOZ_ASSERT(IsNormalized(a0)); MOZ_ASSERT(IsNormalized(a0));
MOZ_ASSERT(IsNormalized(a1)); MOZ_ASSERT(IsNormalized(a1));
@ -106,7 +106,7 @@ struct Interval
} }
} }
static bool IsNormalized(const nsTArray<Interval<T>>& aIntervals) static bool IsNormalized(const nsTArray<Interval<T> >& aIntervals)
{ {
for (size_t i = 1; i < aIntervals.Length(); i++) { for (size_t i = 1; i < aIntervals.Length(); i++) {
if (aIntervals[i - 1].end >= aIntervals[i].start) { if (aIntervals[i - 1].end >= aIntervals[i].start) {

Просмотреть файл

@ -59,13 +59,9 @@ public:
const AudioDecoderConfig& AudioConfig() { return mAudioConfig; } const AudioDecoderConfig& AudioConfig() { return mAudioConfig; }
const VideoDecoderConfig& VideoConfig() { return mVideoConfig; } const VideoDecoderConfig& VideoConfig() { return mVideoConfig; }
void UpdateIndex(const nsTArray<mozilla::MediaByteRange>& aByteRanges);
void ConvertByteRangesToTime( void ConvertByteRangesToTime(
const nsTArray<mozilla::MediaByteRange>& aByteRanges, const nsTArray<mozilla::MediaByteRange>& aByteRanges,
nsTArray<Interval<Microseconds>>* aIntervals); nsTArray<Interval<Microseconds> >* aIntervals);
int64_t GetEvictionOffset(Microseconds aTime);
private: private:
AudioDecoderConfig mAudioConfig; AudioDecoderConfig mAudioConfig;

Просмотреть файл

@ -12,7 +12,6 @@
#include <stdint.h> #include <stdint.h>
#include <algorithm> #include <algorithm>
#include <limits>
using namespace stagefright; using namespace stagefright;
@ -195,14 +194,6 @@ MP4Demuxer::DemuxVideoSample()
return sample.forget(); return sample.forget();
} }
void
MP4Demuxer::UpdateIndex(const nsTArray<mozilla::MediaByteRange>& aByteRanges)
{
for (int i = 0; i < mPrivate->mIndexes.Length(); i++) {
mPrivate->mIndexes[i]->UpdateMoofIndex(aByteRanges);
}
}
void void
MP4Demuxer::ConvertByteRangesToTime( MP4Demuxer::ConvertByteRangesToTime(
const nsTArray<mozilla::MediaByteRange>& aByteRanges, const nsTArray<mozilla::MediaByteRange>& aByteRanges,
@ -224,18 +215,4 @@ MP4Demuxer::ConvertByteRangesToTime(
} }
} }
int64_t
MP4Demuxer::GetEvictionOffset(Microseconds aTime)
{
if (mPrivate->mIndexes.IsEmpty()) {
return 0;
}
uint64_t offset = std::numeric_limits<uint64_t>::max();
for (int i = 0; i < mPrivate->mIndexes.Length(); i++) {
offset = std::min(offset, mPrivate->mIndexes[i]->GetEvictionOffset(aTime));
}
return offset;
}
} // namespace mp4_demuxer } // namespace mp4_demuxer