Bug 1091008 - Hoist stream pinning into the MediaDecoderReaders and make MediaDecoderStateMachine::GetBuffered just forward to them. r=cpearce

Whether or not we ping a stream depends a lot on what kind of decoder we're
dealing with. In particular, it doesn't really make sense for MSE.
This commit is contained in:
Bobby Holley 2014-11-05 10:08:58 +01:00
Родитель 461d13b4d5
Коммит 5a2f54ca85
9 изменённых файлов: 41 добавлений и 23 удалений

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

@ -6,6 +6,7 @@
#include "MediaDecoderReader.h" #include "MediaDecoderReader.h"
#include "AbstractMediaDecoder.h" #include "AbstractMediaDecoder.h"
#include "MediaResource.h"
#include "VideoUtils.h" #include "VideoUtils.h"
#include "ImageContainer.h" #include "ImageContainer.h"
@ -131,7 +132,7 @@ MediaDecoderReader::SetStartTime(int64_t aStartTime)
nsresult nsresult
MediaDecoderReader::GetBuffered(mozilla::dom::TimeRanges* aBuffered) MediaDecoderReader::GetBuffered(mozilla::dom::TimeRanges* aBuffered)
{ {
MediaResource* stream = mDecoder->GetResource(); AutoPinned<MediaResource> stream(mDecoder->GetResource());
int64_t durationUs = 0; int64_t durationUs = 0;
{ {
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());

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

@ -2985,15 +2985,6 @@ void MediaDecoderStateMachine::StartBuffering()
#endif #endif
} }
nsresult MediaDecoderStateMachine::GetBuffered(dom::TimeRanges* aBuffered) {
MediaResource* resource = mDecoder->GetResource();
NS_ENSURE_TRUE(resource, NS_ERROR_FAILURE);
resource->Pin();
nsresult res = mReader->GetBuffered(aBuffered);
resource->Unpin();
return res;
}
void MediaDecoderStateMachine::SetPlayStartTime(const TimeStamp& aTimeStamp) void MediaDecoderStateMachine::SetPlayStartTime(const TimeStamp& aTimeStamp)
{ {
AssertCurrentThreadInMonitor(); AssertCurrentThreadInMonitor();

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

@ -254,7 +254,9 @@ public:
return mState == DECODER_STATE_SEEKING; return mState == DECODER_STATE_SEEKING;
} }
nsresult GetBuffered(dom::TimeRanges* aBuffered); nsresult GetBuffered(dom::TimeRanges* aBuffered) {
return mReader->GetBuffered(aBuffered);
}
void SetPlaybackRate(double aPlaybackRate); void SetPlaybackRate(double aPlaybackRate);
void SetPreservesPitch(bool aPreservesPitch); void SetPreservesPitch(bool aPreservesPitch);

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

@ -718,6 +718,33 @@ protected:
bool mIsTransportSeekable; bool mIsTransportSeekable;
}; };
/**
* RAII class that handles pinning and unpinning for MediaResource and derived.
* This should be used when making calculations that involve potentially-cached
* MediaResource data, so that the state of the world can't change out from under
* us.
*/
template<class T>
class MOZ_STACK_CLASS AutoPinned {
public:
explicit AutoPinned(T* aResource MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : mResource(aResource) {
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
MOZ_ASSERT(mResource);
mResource->Pin();
}
~AutoPinned() {
mResource->Unpin();
}
operator T*() const { return mResource; }
T* operator->() const { return mResource; }
private:
T* mResource;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
} // namespace mozilla } // namespace mozilla
#endif #endif

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

@ -800,13 +800,11 @@ MP4Reader::UpdateIndex()
return; return;
} }
MediaResource* resource = mDecoder->GetResource(); AutoPinned<MediaResource> resource(mDecoder->GetResource());
resource->Pin();
nsTArray<MediaByteRange> ranges; nsTArray<MediaByteRange> ranges;
if (NS_SUCCEEDED(resource->GetCachedRanges(ranges))) { if (NS_SUCCEEDED(resource->GetCachedRanges(ranges))) {
mDemuxer->UpdateIndex(ranges); mDemuxer->UpdateIndex(ranges);
} }
resource->Unpin();
} }
int64_t int64_t
@ -829,11 +827,9 @@ MP4Reader::GetBuffered(dom::TimeRanges* aBuffered)
} }
MOZ_ASSERT(mStartTime != -1, "Need to finish metadata decode first"); MOZ_ASSERT(mStartTime != -1, "Need to finish metadata decode first");
MediaResource* resource = mDecoder->GetResource(); AutoPinned<MediaResource> resource(mDecoder->GetResource());
nsTArray<MediaByteRange> ranges; nsTArray<MediaByteRange> ranges;
resource->Pin();
nsresult rv = resource->GetCachedRanges(ranges); nsresult rv = resource->GetCachedRanges(ranges);
resource->Unpin();
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
nsTArray<Interval<Microseconds>> timeRanges; nsTArray<Interval<Microseconds>> timeRanges;

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

@ -824,7 +824,7 @@ nsresult GStreamerReader::GetBuffered(dom::TimeRanges* aBuffered)
#if GST_VERSION_MAJOR == 0 #if GST_VERSION_MAJOR == 0
GstFormat format = GST_FORMAT_TIME; GstFormat format = GST_FORMAT_TIME;
#endif #endif
MediaResource* resource = mDecoder->GetResource(); AutoPinned<MediaResource> resource(mDecoder->GetResource());
nsTArray<MediaByteRange> ranges; nsTArray<MediaByteRange> ranges;
resource->GetCachedRanges(ranges); resource->GetCachedRanges(ranges);

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

@ -1900,7 +1900,7 @@ nsresult OggReader::GetBuffered(dom::TimeRanges* aBuffered)
return NS_OK; return NS_OK;
} }
MediaResource* resource = mDecoder->GetResource(); AutoPinned<MediaResource> resource(mDecoder->GetResource());
nsTArray<MediaByteRange> ranges; nsTArray<MediaByteRange> ranges;
nsresult res = resource->GetCachedRanges(ranges); nsresult res = resource->GetCachedRanges(ranges);
NS_ENSURE_SUCCESS(res, res); NS_ENSURE_SUCCESS(res, res);

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

@ -283,9 +283,10 @@ nsresult WaveReader::GetBuffered(dom::TimeRanges* aBuffered)
if (!mInfo.HasAudio()) { if (!mInfo.HasAudio()) {
return NS_OK; return NS_OK;
} }
int64_t startOffset = mDecoder->GetResource()->GetNextCachedData(mWavePCMOffset); AutoPinned<MediaResource> resource(mDecoder->GetResource());
int64_t startOffset = resource->GetNextCachedData(mWavePCMOffset);
while (startOffset >= 0) { while (startOffset >= 0) {
int64_t endOffset = mDecoder->GetResource()->GetCachedDataEnd(startOffset); int64_t endOffset = resource->GetCachedDataEnd(startOffset);
// Bytes [startOffset..endOffset] are cached. // Bytes [startOffset..endOffset] are cached.
NS_ASSERTION(startOffset >= mWavePCMOffset, "Integer underflow in GetBuffered"); NS_ASSERTION(startOffset >= mWavePCMOffset, "Integer underflow in GetBuffered");
NS_ASSERTION(endOffset >= mWavePCMOffset, "Integer underflow in GetBuffered"); NS_ASSERTION(endOffset >= mWavePCMOffset, "Integer underflow in GetBuffered");
@ -295,7 +296,7 @@ nsresult WaveReader::GetBuffered(dom::TimeRanges* aBuffered)
// the media element. // the media element.
aBuffered->Add(RoundToUsecs(BytesToTime(startOffset - mWavePCMOffset)), aBuffered->Add(RoundToUsecs(BytesToTime(startOffset - mWavePCMOffset)),
RoundToUsecs(BytesToTime(endOffset - mWavePCMOffset))); RoundToUsecs(BytesToTime(endOffset - mWavePCMOffset)));
startOffset = mDecoder->GetResource()->GetNextCachedData(endOffset); startOffset = resource->GetNextCachedData(endOffset);
} }
return NS_OK; return NS_OK;
} }

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

@ -1092,7 +1092,7 @@ nsresult WebMReader::GetBuffered(dom::TimeRanges* aBuffered)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
MediaResource* resource = mDecoder->GetResource(); AutoPinned<MediaResource> resource(mDecoder->GetResource());
// Special case completely cached files. This also handles local files. // Special case completely cached files. This also handles local files.
if (mContext && resource->IsDataCachedToEndOfResource(0)) { if (mContext && resource->IsDataCachedToEndOfResource(0)) {