mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1185407. Part 1 - have AudioSink::Init() return a promise. r=kinetik.
This commit is contained in:
parent
309ea5e508
commit
179648e075
@ -38,26 +38,27 @@ AudioSink::AudioSink(MediaDecoderStateMachine* aStateMachine,
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsRefPtr<GenericPromise>
|
||||
AudioSink::Init()
|
||||
{
|
||||
nsRefPtr<GenericPromise> p = mEndPromise.Ensure(__func__);
|
||||
nsresult rv = NS_NewNamedThread("Media Audio",
|
||||
getter_AddRefs(mThread),
|
||||
nullptr,
|
||||
MEDIA_THREAD_STACK_SIZE);
|
||||
if (NS_FAILED(rv)) {
|
||||
mStateMachine->OnAudioSinkError();
|
||||
return rv;
|
||||
mEndPromise.Reject(rv, __func__);
|
||||
return p;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &AudioSink::AudioLoop);
|
||||
rv = mThread->Dispatch(event, NS_DISPATCH_NORMAL);
|
||||
if (NS_FAILED(rv)) {
|
||||
mStateMachine->OnAudioSinkError();
|
||||
return rv;
|
||||
mEndPromise.Reject(rv, __func__);
|
||||
return p;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return p;
|
||||
}
|
||||
|
||||
int64_t
|
||||
@ -142,9 +143,10 @@ AudioSink::AudioLoop()
|
||||
AssertOnAudioThread();
|
||||
SINK_LOG("AudioLoop started");
|
||||
|
||||
if (NS_FAILED(InitializeAudioStream())) {
|
||||
nsresult rv = InitializeAudioStream();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Initializing AudioStream failed.");
|
||||
mStateMachine->DispatchOnAudioSinkError();
|
||||
mEndPromise.Reject(rv, __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -235,11 +237,7 @@ AudioSink::Cleanup()
|
||||
AssertCurrentThreadInMonitor();
|
||||
nsRefPtr<AudioStream> audioStream;
|
||||
audioStream.swap(mAudioStream);
|
||||
// Suppress the callback when the stop is requested by MediaDecoderStateMachine.
|
||||
// See Bug 115334.
|
||||
if (!mStopAudioThread) {
|
||||
mStateMachine->DispatchOnAudioSinkComplete();
|
||||
}
|
||||
mEndPromise.Resolve(true, __func__);
|
||||
|
||||
ReentrantMonitorAutoExit exit(GetReentrantMonitor());
|
||||
audioStream->Shutdown();
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "MediaDecoderReader.h"
|
||||
#include "mozilla/dom/AudioChannelBinding.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -23,7 +24,9 @@ public:
|
||||
AudioSink(MediaDecoderStateMachine* aStateMachine,
|
||||
int64_t aStartTime, AudioInfo aInfo, dom::AudioChannel aChannel);
|
||||
|
||||
nsresult Init();
|
||||
// Return a promise which will be resolved when AudioSink finishes playing,
|
||||
// or rejected if any error.
|
||||
nsRefPtr<GenericPromise> Init();
|
||||
|
||||
int64_t GetPosition();
|
||||
|
||||
@ -140,6 +143,8 @@ private:
|
||||
bool mSetPreservesPitch;
|
||||
|
||||
bool mPlaying;
|
||||
|
||||
MozPromiseHolder<GenericPromise> mEndPromise;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -1086,8 +1086,7 @@ void MediaDecoderStateMachine::MaybeStartPlayback()
|
||||
SetPlayStartTime(TimeStamp::Now());
|
||||
MOZ_ASSERT(IsPlaying());
|
||||
|
||||
nsresult rv = StartAudioThread();
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
StartAudioThread();
|
||||
|
||||
// Tell DecodedStream to start playback with specified start time and media
|
||||
// info. This is consistent with how we create AudioSink in StartAudioThread().
|
||||
@ -1481,6 +1480,7 @@ void MediaDecoderStateMachine::StopAudioThread()
|
||||
}
|
||||
mAudioSink = nullptr;
|
||||
}
|
||||
mAudioSinkPromise.DisconnectIfExists();
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -1783,31 +1783,31 @@ MediaDecoderStateMachine::RequestVideoData()
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
void
|
||||
MediaDecoderStateMachine::StartAudioThread()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
AssertCurrentThreadInMonitor();
|
||||
if (mAudioCaptured) {
|
||||
MOZ_ASSERT(!mAudioSink);
|
||||
return NS_OK;
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasAudio() && !mAudioSink) {
|
||||
auto audioStartTime = GetMediaTime();
|
||||
mAudioCompleted = false;
|
||||
mAudioSink = new AudioSink(this, audioStartTime,
|
||||
mAudioSink = new AudioSink(this, GetMediaTime(),
|
||||
mInfo.mAudio, mDecoder->GetAudioChannel());
|
||||
// OnAudioSinkError() will be called before Init() returns if an error
|
||||
// occurs during initialization.
|
||||
nsresult rv = mAudioSink->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mAudioSinkPromise.Begin(
|
||||
mAudioSink->Init()->Then(
|
||||
OwnerThread(), __func__, this,
|
||||
&MediaDecoderStateMachine::OnAudioSinkComplete,
|
||||
&MediaDecoderStateMachine::OnAudioSinkError));
|
||||
|
||||
mAudioSink->SetVolume(mVolume);
|
||||
mAudioSink->SetPlaybackRate(mPlaybackRate);
|
||||
mAudioSink->SetPreservesPitch(mPreservesPitch);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
int64_t MediaDecoderStateMachine::AudioDecodedUsecs()
|
||||
@ -3122,11 +3122,12 @@ void MediaDecoderStateMachine::OnAudioSinkComplete()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
if (mAudioCaptured) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(!mAudioCaptured, "Should be disconnected when capturing audio.");
|
||||
|
||||
mAudioSinkPromise.Complete();
|
||||
ResyncAudioClock();
|
||||
mAudioCompleted = true;
|
||||
|
||||
// Kick the decode thread; it may be sleeping waiting for this to finish.
|
||||
mDecoder->GetReentrantMonitor().NotifyAll();
|
||||
}
|
||||
@ -3135,11 +3136,9 @@ void MediaDecoderStateMachine::OnAudioSinkError()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
// AudioSink not used with captured streams, so ignore errors in this case.
|
||||
if (mAudioCaptured) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(!mAudioCaptured, "Should be disconnected when capturing audio.");
|
||||
|
||||
mAudioSinkPromise.Complete();
|
||||
ResyncAudioClock();
|
||||
mAudioCompleted = true;
|
||||
|
||||
|
@ -517,7 +517,7 @@ protected:
|
||||
|
||||
// Starts the audio thread. The decoder monitor must be held with exactly
|
||||
// one lock count. Called on the state machine thread.
|
||||
nsresult StartAudioThread();
|
||||
void StartAudioThread();
|
||||
|
||||
// Notification method invoked when mPlayState changes.
|
||||
void PlayStateChanged();
|
||||
@ -1317,6 +1317,8 @@ private:
|
||||
// Media data resource from the decoder.
|
||||
nsRefPtr<MediaResource> mResource;
|
||||
|
||||
MozPromiseRequestHolder<GenericPromise> mAudioSinkPromise;
|
||||
|
||||
private:
|
||||
// The buffered range. Mirrored from the decoder thread.
|
||||
Mirror<media::TimeIntervals> mBuffered;
|
||||
|
Loading…
Reference in New Issue
Block a user