mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1126465 - Introduce machinery to hold onto MediaPromise::Consumer references, and use it for MediaSourceReader subdecoders. r=mattwoodrow
This commit is contained in:
parent
3a9994d3e4
commit
1ca435bbc6
@ -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
|
||||
|
@ -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__);
|
||||
|
@ -183,6 +183,9 @@ private:
|
||||
nsRefPtr<TrackBuffer> mAudioTrack;
|
||||
nsRefPtr<TrackBuffer> mVideoTrack;
|
||||
|
||||
MediaPromiseConsumerHolder<AudioDataPromise> mAudioRequest;
|
||||
MediaPromiseConsumerHolder<VideoDataPromise> mVideoRequest;
|
||||
|
||||
MediaPromiseHolder<AudioDataPromise> mAudioPromise;
|
||||
MediaPromiseHolder<VideoDataPromise> mVideoPromise;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user