зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1054153 - Fix MP4 demuxer is init vs buffered range race; r=edwin
This commit is contained in:
Родитель
09a1c22d2a
Коммит
2acb0169a4
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
Загрузка…
Ссылка в новой задаче