Bug 1126465 - Introduce machinery to hold onto MediaPromise::Consumer references, and use it for MediaSourceReader subdecoders. r=mattwoodrow

This commit is contained in:
Bobby Holley 2015-01-28 18:54:11 -08:00
parent 3a9994d3e4
commit 1ca435bbc6
3 changed files with 74 additions and 17 deletions

View File

@ -252,8 +252,8 @@ public:
template<typename TargetType, typename ThisType,
typename ResolveMethodType, typename RejectMethodType>
void Then(TargetType* aResponseTarget, const char* aCallSite, ThisType* aThisVal,
ResolveMethodType aResolveMethod, RejectMethodType aRejectMethod)
already_AddRefed<Consumer> RefableThen(TargetType* aResponseTarget, const char* aCallSite, ThisType* aThisVal,
ResolveMethodType aResolveMethod, RejectMethodType aRejectMethod)
{
MutexAutoLock lock(mMutex);
MOZ_RELEASE_ASSERT(!IsExclusive || !mHaveConsumer);
@ -269,6 +269,18 @@ public:
} else {
mThenValues.AppendElement(thenValue);
}
return thenValue.forget();
}
template<typename TargetType, typename ThisType,
typename ResolveMethodType, typename RejectMethodType>
void Then(TargetType* aResponseTarget, const char* aCallSite, ThisType* aThisVal,
ResolveMethodType aResolveMethod, RejectMethodType aRejectMethod)
{
nsRefPtr<Consumer> c =
RefableThen(aResponseTarget, aCallSite, aThisVal, aResolveMethod, aRejectMethod);
return;
}
void ChainTo(already_AddRefed<MediaPromise> aChainedPromise, const char* aCallSite)
@ -436,6 +448,35 @@ private:
nsRefPtr<PromiseType> mPromise;
};
/*
* Class to encapsulate a MediaPromise::Consumer reference. Use this as the member
* variable for a class waiting on a media promise.
*/
template<typename PromiseType>
class MediaPromiseConsumerHolder
{
public:
MediaPromiseConsumerHolder() {}
~MediaPromiseConsumerHolder() { MOZ_ASSERT(!mConsumer); }
void Begin(already_AddRefed<typename PromiseType::Consumer> aConsumer)
{
MOZ_RELEASE_ASSERT(!Exists());
mConsumer = aConsumer;
}
void Complete()
{
MOZ_RELEASE_ASSERT(Exists());
mConsumer = nullptr;
}
bool Exists() { return !!mConsumer; }
private:
nsRefPtr<typename PromiseType::Consumer> mConsumer;
};
#undef PROMISE_LOG
} // namespace mozilla

View File

@ -148,9 +148,10 @@ MediaSourceReader::RequestAudioData()
void
MediaSourceReader::RequestAudioDataComplete(int64_t aTime)
{
mAudioReader->RequestAudioData()->Then(GetTaskQueue(), __func__, this,
&MediaSourceReader::OnAudioDecoded,
&MediaSourceReader::OnAudioNotDecoded);
mAudioRequest.Begin(mAudioReader->RequestAudioData()
->RefableThen(GetTaskQueue(), __func__, this,
&MediaSourceReader::OnAudioDecoded,
&MediaSourceReader::OnAudioNotDecoded));
}
void
@ -162,15 +163,18 @@ MediaSourceReader::RequestAudioDataFailed(nsresult aResult)
void
MediaSourceReader::OnAudioDecoded(AudioData* aSample)
{
mAudioRequest.Complete();
MSE_DEBUGV("MediaSourceReader(%p)::OnAudioDecoded [mTime=%lld mDuration=%lld mDiscontinuity=%d]",
this, aSample->mTime, aSample->mDuration, aSample->mDiscontinuity);
if (mDropAudioBeforeThreshold) {
if (aSample->mTime < mTimeThreshold) {
MSE_DEBUG("MediaSourceReader(%p)::OnAudioDecoded mTime=%lld < mTimeThreshold=%lld",
this, aSample->mTime, mTimeThreshold);
mAudioReader->RequestAudioData()->Then(GetTaskQueue(), __func__, this,
&MediaSourceReader::OnAudioDecoded,
&MediaSourceReader::OnAudioNotDecoded);
mAudioRequest.Begin(mAudioReader->RequestAudioData()
->RefableThen(GetTaskQueue(), __func__, this,
&MediaSourceReader::OnAudioDecoded,
&MediaSourceReader::OnAudioNotDecoded));
return;
}
mDropAudioBeforeThreshold = false;
@ -215,6 +219,8 @@ AdjustEndTime(int64_t* aEndTime, MediaDecoderReader* aReader)
void
MediaSourceReader::OnAudioNotDecoded(NotDecodedReason aReason)
{
mAudioRequest.Complete();
MSE_DEBUG("MediaSourceReader(%p)::OnAudioNotDecoded aReason=%u IsEnded: %d", this, aReason, IsEnded());
if (aReason == DECODE_ERROR || aReason == CANCELED) {
mAudioPromise.Reject(aReason, __func__);
@ -279,9 +285,10 @@ MediaSourceReader::RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThres
}
// Fallback to using current reader.
default:
mVideoReader->RequestVideoData(aSkipToNextKeyframe, aTimeThreshold)
->Then(GetTaskQueue(), __func__, this,
&MediaSourceReader::OnVideoDecoded, &MediaSourceReader::OnVideoNotDecoded);
mVideoRequest.Begin(mVideoReader->RequestVideoData(aSkipToNextKeyframe, aTimeThreshold)
->RefableThen(GetTaskQueue(), __func__, this,
&MediaSourceReader::OnVideoDecoded,
&MediaSourceReader::OnVideoNotDecoded));
break;
}
@ -291,9 +298,10 @@ MediaSourceReader::RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThres
void
MediaSourceReader::RequestVideoDataComplete(int64_t aTime)
{
mVideoReader->RequestVideoData(false, 0)
->Then(GetTaskQueue(), __func__, this,
&MediaSourceReader::OnVideoDecoded, &MediaSourceReader::OnVideoNotDecoded);
mVideoRequest.Begin(mVideoReader->RequestVideoData(false, 0)
->RefableThen(GetTaskQueue(), __func__, this,
&MediaSourceReader::OnVideoDecoded,
&MediaSourceReader::OnVideoNotDecoded));
}
void
@ -305,15 +313,18 @@ MediaSourceReader::RequestVideoDataFailed(nsresult aResult)
void
MediaSourceReader::OnVideoDecoded(VideoData* aSample)
{
mVideoRequest.Complete();
MSE_DEBUGV("MediaSourceReader(%p)::OnVideoDecoded [mTime=%lld mDuration=%lld mDiscontinuity=%d]",
this, aSample->mTime, aSample->mDuration, aSample->mDiscontinuity);
if (mDropVideoBeforeThreshold) {
if (aSample->mTime < mTimeThreshold) {
MSE_DEBUG("MediaSourceReader(%p)::OnVideoDecoded mTime=%lld < mTimeThreshold=%lld",
this, aSample->mTime, mTimeThreshold);
mVideoReader->RequestVideoData(false, 0)->Then(GetTaskQueue(), __func__, this,
&MediaSourceReader::OnVideoDecoded,
&MediaSourceReader::OnVideoNotDecoded);
mVideoRequest.Begin(mVideoReader->RequestVideoData(false, 0)
->RefableThen(GetTaskQueue(), __func__, this,
&MediaSourceReader::OnVideoDecoded,
&MediaSourceReader::OnVideoNotDecoded));
return;
}
mDropVideoBeforeThreshold = false;
@ -332,6 +343,8 @@ MediaSourceReader::OnVideoDecoded(VideoData* aSample)
void
MediaSourceReader::OnVideoNotDecoded(NotDecodedReason aReason)
{
mVideoRequest.Complete();
MSE_DEBUG("MediaSourceReader(%p)::OnVideoNotDecoded aReason=%u IsEnded: %d", this, aReason, IsEnded());
if (aReason == DECODE_ERROR || aReason == CANCELED) {
mVideoPromise.Reject(aReason, __func__);

View File

@ -183,6 +183,9 @@ private:
nsRefPtr<TrackBuffer> mAudioTrack;
nsRefPtr<TrackBuffer> mVideoTrack;
MediaPromiseConsumerHolder<AudioDataPromise> mAudioRequest;
MediaPromiseConsumerHolder<VideoDataPromise> mVideoRequest;
MediaPromiseHolder<AudioDataPromise> mAudioPromise;
MediaPromiseHolder<VideoDataPromise> mVideoPromise;