Bug 1274192 part 1 - make the MediaDecoderReaderWrapper as a proxy of WaitForData(); r=jwwang
MozReview-Commit-ID: 5wYLuZRKJhA
--- a/dom/media/MediaDecoderReaderWrapper.cpp
+++ b/dom/media/MediaDecoderReaderWrapper.cpp
@@ -141,16 +141,18 @@ private:
MediaDecoderReaderWrapper::MediaDecoderReaderWrapper(bool aIsRealTime,
AbstractThread* aOwnerThread,
MediaDecoderReader* aReader)
: mForceZeroStartTime(aIsRealTime || aReader->ForceZeroStartTime())
, mOwnerThread(aOwnerThread)
, mReader(aReader)
, mAudioCallbackID("AudioCallbackID")
, mVideoCallbackID("VideoCallbackID")
+ , mWaitAudioCallbackID("WaitAudioCallbackID")
+ , mWaitVideoCallbackID("WaitVideoCallbackID")
{}
MediaDecoderReaderWrapper::~MediaDecoderReaderWrapper()
{}
media::TimeUnit
MediaDecoderReaderWrapper::StartTime() const
{
@@ -194,16 +196,34 @@ MediaDecoderReaderWrapper::CancelVideoCa
{
MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
MOZ_ASSERT(aID == mVideoCallbackID);
++mVideoCallbackID;
mRequestVideoDataCB = nullptr;
}
void
+MediaDecoderReaderWrapper::CancelWaitAudioCallback(CallbackID aID)
+{
+ MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
+ MOZ_ASSERT(aID == mWaitAudioCallbackID);
+ ++mWaitAudioCallbackID;
+ mWaitAudioDataCB = nullptr;
+}
+
+void
+MediaDecoderReaderWrapper::CancelWaitVideoCallback(CallbackID aID)
+{
+ MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
+ MOZ_ASSERT(aID == mWaitVideoCallbackID);
+ ++mWaitVideoCallbackID;
+ mWaitVideoDataCB = nullptr;
+}
+
+void
MediaDecoderReaderWrapper::RequestAudioData()
{
MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
MOZ_ASSERT(!mShutdown);
MOZ_ASSERT(mRequestAudioDataCB, "Request audio data without callback!");
auto p = InvokeAsync(mReader->OwnerThread(), mReader.get(), __func__,
&MediaDecoderReader::RequestAudioData);
@@ -280,16 +300,30 @@ MediaDecoderReaderWrapper::IsRequestingA
bool
MediaDecoderReaderWrapper::IsRequestingVideoData() const
{
MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
return mVideoDataRequest.Exists();
}
+bool
+MediaDecoderReaderWrapper::IsWaitingAudioData() const
+{
+ MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
+ return mAudioWaitRequest.Exists();
+}
+
+bool
+MediaDecoderReaderWrapper::IsWaitingVideoData() const
+{
+ MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
+ return mVideoWaitRequest.Exists();
+}
+
RefPtr<MediaDecoderReader::SeekPromise>
MediaDecoderReaderWrapper::Seek(SeekTarget aTarget, media::TimeUnit aEndTime)
{
MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
aTarget.SetTime(aTarget.GetTime() + StartTime());
return InvokeAsync(mReader->OwnerThread(), mReader.get(), __func__,
&MediaDecoderReader::Seek, aTarget,
aEndTime.ToMicroseconds());
@@ -331,16 +365,18 @@ MediaDecoderReaderWrapper::SetIdle()
void
MediaDecoderReaderWrapper::ResetDecode(TargetQueues aQueues)
{
MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
mAudioDataRequest.DisconnectIfExists();
mVideoDataRequest.DisconnectIfExists();
+ mAudioWaitRequest.DisconnectIfExists();
+ mVideoWaitRequest.DisconnectIfExists();
nsCOMPtr<nsIRunnable> r =
NewRunnableMethod<TargetQueues>(mReader,
&MediaDecoderReader::ResetDecode,
aQueues);
mReader->OwnerThread()->Dispatch(r.forget());
}
--- a/dom/media/MediaDecoderReaderWrapper.h
+++ b/dom/media/MediaDecoderReaderWrapper.h
@@ -159,16 +159,68 @@ class MediaDecoderReaderWrapper {
{
mRejectFunction(aReason);
}
ResolveFunctionType mResolveFuntion;
RejectFunctionType mRejectFunction;
};
+ struct WaitForDataCallbackBase
+ {
+ virtual ~WaitForDataCallbackBase() {}
+ virtual void OnResolved(MediaData::Type aType) = 0;
+ virtual void OnRejected(WaitForDataRejectValue aRejection) = 0;
+ };
+
+ template<typename ThisType, typename ResolveMethodType, typename RejectMethodType>
+ struct WaitForDataMethodCallback : public WaitForDataCallbackBase
+ {
+ WaitForDataMethodCallback(ThisType* aThis, ResolveMethodType aResolveMethod, RejectMethodType aRejectMethod)
+ : mThis(aThis), mResolveMethod(aResolveMethod), mRejectMethod(aRejectMethod)
+ {
+ }
+
+ void OnResolved(MediaData::Type aType) override
+ {
+ (mThis->*mResolveMethod)(aType);
+ }
+
+ void OnRejected(WaitForDataRejectValue aRejection) override
+ {
+ (mThis->*mRejectMethod)(aRejection);
+ }
+
+ RefPtr<ThisType> mThis;
+ ResolveMethodType mResolveMethod;
+ RejectMethodType mRejectMethod;
+ };
+
+ template<typename ResolveFunctionType, typename RejectFunctionType>
+ struct WaitForDataFunctionCallback : public WaitForDataCallbackBase
+ {
+ WaitForDataFunctionCallback(ResolveFunctionType&& aResolveFuntion, RejectFunctionType&& aRejectFunction)
+ : mResolveFuntion(Move(aResolveFuntion)), mRejectFunction(Move(aRejectFunction))
+ {
+ }
+
+ void OnResolved(MediaData::Type aType) override
+ {
+ mResolveFuntion(aType);
+ }
+
+ void OnRejected(WaitForDataRejectValue aRejection) override
+ {
+ mRejectFunction(aRejection);
+ }
+
+ ResolveFunctionType mResolveFuntion;
+ RejectFunctionType mRejectFunction;
+ };
+
public:
MediaDecoderReaderWrapper(bool aIsRealTime,
AbstractThread* aOwnerThread,
MediaDecoderReader* aReader);
media::TimeUnit StartTime() const;
RefPtr<MetadataPromise> ReadMetadata();
RefPtr<HaveStartTimePromise> AwaitStartTime();
@@ -234,25 +286,95 @@ public:
mRequestVideoDataCB.reset(
new FunctionCallback<ResolveFunction, RejectFunction>(
Move(aResolveFunction), Move(aRejectFunction)));
return mVideoCallbackID;
}
+ template<typename ThisType, typename ResolveMethodType, typename RejectMethodType>
+ CallbackID
+ SetWaitAudioCallback(ThisType* aThisVal,
+ ResolveMethodType aResolveMethod,
+ RejectMethodType aRejectMethod)
+ {
+ MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
+ MOZ_ASSERT(!mWaitAudioDataCB,
+ "Please cancel the original callback before setting a new one.");
+
+ mWaitAudioDataCB.reset(
+ new WaitForDataMethodCallback<ThisType, ResolveMethodType, RejectMethodType>(
+ aThisVal, aResolveMethod, aRejectMethod));
+
+ return mWaitAudioCallbackID;
+ }
+
+ template<typename ResolveFunction, typename RejectFunction>
+ CallbackID
+ SetWaitAudioCallback(ResolveFunction&& aResolveFunction,
+ RejectFunction&& aRejectFunction)
+ {
+ MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
+ MOZ_ASSERT(!mWaitAudioDataCB,
+ "Please cancel the original callback before setting a new one.");
+
+ mWaitAudioDataCB.reset(
+ new WaitForDataFunctionCallback<ResolveFunction, RejectFunction>(
+ Move(aResolveFunction), Move(aRejectFunction)));
+
+ return mWaitAudioCallbackID;
+ }
+
+ template<typename ThisType, typename ResolveMethodType, typename RejectMethodType>
+ CallbackID
+ SetWaitVideoCallback(ThisType* aThisVal,
+ ResolveMethodType aResolveMethod,
+ RejectMethodType aRejectMethod)
+ {
+ MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
+ MOZ_ASSERT(!mWaitVideoDataCB,
+ "Please cancel the original callback before setting a new one.");
+
+ mWaitVideoDataCB.reset(
+ new WaitForDataMethodCallback<ThisType, ResolveMethodType, RejectMethodType>(
+ aThisVal, aResolveMethod, aRejectMethod));
+
+ return mWaitVideoCallbackID;
+ }
+
+ template<typename ResolveFunction, typename RejectFunction>
+ CallbackID
+ SetWaitVideoCallback(ResolveFunction&& aResolveFunction,
+ RejectFunction&& aRejectFunction)
+ {
+ MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
+ MOZ_ASSERT(!mWaitVideoDataCB,
+ "Please cancel the original callback before setting a new one.");
+
+ mWaitVideoDataCB.reset(
+ new WaitForDataFunctionCallback<ResolveFunction, RejectFunction>(
+ Move(aResolveFunction), Move(aRejectFunction)));
+
+ return mWaitVideoCallbackID;
+ }
+
void CancelAudioCallback(CallbackID aID);
void CancelVideoCallback(CallbackID aID);
+ void CancelWaitAudioCallback(CallbackID aID);
+ void CancelWaitVideoCallback(CallbackID aID);
// NOTE: please set callbacks before requesting audio/video data!
void RequestAudioData();
void RequestVideoData(bool aSkipToNextKeyframe, media::TimeUnit aTimeThreshold);
bool IsRequestingAudioData() const;
bool IsRequestingVideoData() const;
+ bool IsWaitingAudioData() const;
+ bool IsWaitingVideoData() const;
RefPtr<SeekPromise> Seek(SeekTarget aTarget, media::TimeUnit aEndTime);
RefPtr<WaitForDataPromise> WaitForData(MediaData::Type aType);
RefPtr<BufferedUpdatePromise> UpdateBufferedWithPromise();
RefPtr<ShutdownPromise> Shutdown();
void ReleaseMediaResources();
void SetIdle();
@@ -310,21 +432,27 @@ private:
const RefPtr<AbstractThread> mOwnerThread;
const RefPtr<MediaDecoderReader> mReader;
bool mShutdown = false;
RefPtr<StartTimeRendezvous> mStartTimeRendezvous;
UniquePtr<CallbackBase> mRequestAudioDataCB;
UniquePtr<CallbackBase> mRequestVideoDataCB;
+ UniquePtr<WaitForDataCallbackBase> mWaitAudioDataCB;
+ UniquePtr<WaitForDataCallbackBase> mWaitVideoDataCB;
MozPromiseRequestHolder<MediaDataPromise> mAudioDataRequest;
MozPromiseRequestHolder<MediaDataPromise> mVideoDataRequest;
+ MozPromiseRequestHolder<WaitForDataPromise> mAudioWaitRequest;
+ MozPromiseRequestHolder<WaitForDataPromise> mVideoWaitRequest;
/*
* These callback ids are used to prevent mis-canceling callback.
*/
CallbackID mAudioCallbackID;
CallbackID mVideoCallbackID;
+ CallbackID mWaitAudioCallbackID;
+ CallbackID mWaitVideoCallbackID;
};
} // namespace mozilla
#endif // MediaDecoderReaderWrapper_h_