Bug 1054153 - Fix MP4 demuxer is init vs buffered range race; r=edwin

This commit is contained in:
Anthony Jones 2014-08-19 14:13:56 +12:00
Родитель 09a1c22d2a
Коммит 2acb0169a4
4 изменённых файлов: 32 добавлений и 8 удалений

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

@ -111,6 +111,8 @@ MP4Reader::MP4Reader(AbstractMediaDecoder* aDecoder)
, mLayersBackendType(layers::LayersBackend::LAYERS_NONE) , mLayersBackendType(layers::LayersBackend::LAYERS_NONE)
, mDemuxerInitialized(false) , mDemuxerInitialized(false)
, mIsEncrypted(false) , mIsEncrypted(false)
, mIndexReady(false)
, mIndexMonitor("MP4 index")
{ {
MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread."); MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
MOZ_COUNT_CTOR(MP4Reader); MOZ_COUNT_CTOR(MP4Reader);
@ -303,6 +305,11 @@ MP4Reader::ReadMetadata(MediaInfo* aInfo,
bool ok = mDemuxer->Init(); bool ok = mDemuxer->Init();
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE); NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
{
MonitorAutoLock mon(mIndexMonitor);
mIndexReady = true;
}
mInfo.mVideo.mHasVideo = mVideo.mActive = mDemuxer->HasValidVideo(); mInfo.mVideo.mHasVideo = mVideo.mActive = mDemuxer->HasValidVideo();
const VideoDecoderConfig& video = mDemuxer->VideoConfig(); const VideoDecoderConfig& video = mDemuxer->VideoConfig();
// If we have video, we *only* allow H.264 to be decoded. // If we have video, we *only* allow H.264 to be decoded.
@ -416,6 +423,8 @@ MP4Reader::ReadMetadata(MediaInfo* aInfo,
*aInfo = mInfo; *aInfo = mInfo;
*aTags = nullptr; *aTags = nullptr;
UpdateIndex();
return NS_OK; return NS_OK;
} }
@ -773,6 +782,11 @@ MP4Reader::NotifyDataArrived(const char* aBuffer, uint32_t aLength,
void void
MP4Reader::UpdateIndex() MP4Reader::UpdateIndex()
{ {
MonitorAutoLock mon(mIndexMonitor);
if (!mIndexReady) {
return;
}
MediaResource* resource = mDecoder->GetResource(); MediaResource* resource = mDecoder->GetResource();
resource->Pin(); resource->Pin();
nsTArray<MediaByteRange> ranges; nsTArray<MediaByteRange> ranges;
@ -785,16 +799,29 @@ MP4Reader::UpdateIndex()
int64_t int64_t
MP4Reader::GetEvictionOffset(double aTime) MP4Reader::GetEvictionOffset(double aTime)
{ {
MonitorAutoLock mon(mIndexMonitor);
if (!mIndexReady) {
return 0;
}
return mDemuxer->GetEvictionOffset(aTime * 1000000.0); return mDemuxer->GetEvictionOffset(aTime * 1000000.0);
} }
nsresult nsresult
MP4Reader::GetBuffered(dom::TimeRanges* aBuffered, int64_t aStartTime) MP4Reader::GetBuffered(dom::TimeRanges* aBuffered, int64_t aStartTime)
{ {
MonitorAutoLock mon(mIndexMonitor);
if (!mIndexReady) {
return NS_OK;
}
MediaResource* resource = mDecoder->GetResource(); MediaResource* resource = mDecoder->GetResource();
resource->Pin();
nsTArray<MediaByteRange> ranges; nsTArray<MediaByteRange> ranges;
if (NS_SUCCEEDED(resource->GetCachedRanges(ranges))) { resource->Pin();
nsresult rv = resource->GetCachedRanges(ranges);
resource->Unpin();
if (NS_SUCCEEDED(rv)) {
nsTArray<Interval<Microseconds>> timeRanges; nsTArray<Interval<Microseconds>> timeRanges;
mDemuxer->ConvertByteRangesToTime(ranges, &timeRanges); mDemuxer->ConvertByteRangesToTime(ranges, &timeRanges);
for (size_t i = 0; i < timeRanges.Length(); i++) { for (size_t i = 0; i < timeRanges.Length(); i++) {
@ -802,7 +829,6 @@ MP4Reader::GetBuffered(dom::TimeRanges* aBuffered, int64_t aStartTime)
(timeRanges[i].end - aStartTime) / 1000000.0); (timeRanges[i].end - aStartTime) / 1000000.0);
} }
} }
resource->Unpin();
return NS_OK; return NS_OK;
} }

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

@ -189,6 +189,9 @@ private:
// Synchronized by decoder monitor. // Synchronized by decoder monitor.
bool mIsEncrypted; bool mIsEncrypted;
bool mIndexReady;
Monitor mIndexMonitor;
}; };
} // namespace mozilla } // namespace mozilla

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

@ -77,7 +77,6 @@ RangeFinder::Contains(MediaByteRange aByteRange)
Index::Index(const stagefright::Vector<MediaSource::Indice>& aIndex, Index::Index(const stagefright::Vector<MediaSource::Indice>& aIndex,
Stream* aSource, uint32_t aTrackId) Stream* aSource, uint32_t aTrackId)
: mMonitor("mp4_demuxer::Index")
{ {
if (aIndex.isEmpty()) { if (aIndex.isEmpty()) {
mMoofParser = new MoofParser(aSource, aTrackId); mMoofParser = new MoofParser(aSource, aTrackId);
@ -95,7 +94,6 @@ Index::UpdateMoofIndex(const nsTArray<MediaByteRange>& aByteRanges)
return; return;
} }
MonitorAutoLock mon(mMonitor);
mMoofParser->RebuildFragmentedIndex(aByteRanges); mMoofParser->RebuildFragmentedIndex(aByteRanges);
} }
@ -104,8 +102,6 @@ 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;

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

@ -29,7 +29,6 @@ public:
uint64_t GetEvictionOffset(Microseconds aTime); uint64_t GetEvictionOffset(Microseconds aTime);
private: private:
mozilla::Monitor mMonitor;
nsTArray<stagefright::MediaSource::Indice> mIndex; nsTArray<stagefright::MediaSource::Indice> mIndex;
nsAutoPtr<MoofParser> mMoofParser; nsAutoPtr<MoofParser> mMoofParser;
}; };