mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1172390 - Align stream blocking of decoded stream with play state of MDSM. r=roc.
This commit is contained in:
parent
1bf24e0cc5
commit
9b52f419be
@ -165,18 +165,10 @@ AudioSink::SetPreservesPitch(bool aPreservesPitch)
|
||||
}
|
||||
|
||||
void
|
||||
AudioSink::StartPlayback()
|
||||
AudioSink::SetPlaying(bool aPlaying)
|
||||
{
|
||||
AssertCurrentThreadInMonitor();
|
||||
mPlaying = true;
|
||||
GetReentrantMonitor().NotifyAll();
|
||||
}
|
||||
|
||||
void
|
||||
AudioSink::StopPlayback()
|
||||
{
|
||||
AssertCurrentThreadInMonitor();
|
||||
mPlaying = false;
|
||||
mPlaying = aPlaying;
|
||||
GetReentrantMonitor().NotifyAll();
|
||||
}
|
||||
|
||||
|
@ -42,8 +42,7 @@ public:
|
||||
void SetPlaybackRate(double aPlaybackRate);
|
||||
void SetPreservesPitch(bool aPreservesPitch);
|
||||
|
||||
void StartPlayback();
|
||||
void StopPlayback();
|
||||
void SetPlaying(bool aPlaying);
|
||||
|
||||
private:
|
||||
~AudioSink() {}
|
||||
|
@ -69,6 +69,19 @@ private:
|
||||
bool mStreamFinishedOnMainThread;
|
||||
};
|
||||
|
||||
static void
|
||||
UpdateStreamBlocking(MediaStream* aStream, bool aBlocking)
|
||||
{
|
||||
int32_t delta = aBlocking ? 1 : -1;
|
||||
if (NS_IsMainThread()) {
|
||||
aStream->ChangeExplicitBlockerCount(delta);
|
||||
} else {
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethodWithArg<int32_t>(
|
||||
aStream, &MediaStream::ChangeExplicitBlockerCount, delta);
|
||||
AbstractThread::MainThread()->Dispatch(r.forget());
|
||||
}
|
||||
}
|
||||
|
||||
DecodedStreamData::DecodedStreamData(SourceMediaStream* aStream)
|
||||
: mAudioFramesWritten(0)
|
||||
, mNextVideoTime(-1)
|
||||
@ -78,14 +91,13 @@ DecodedStreamData::DecodedStreamData(SourceMediaStream* aStream)
|
||||
, mHaveSentFinishAudio(false)
|
||||
, mHaveSentFinishVideo(false)
|
||||
, mStream(aStream)
|
||||
, mHaveBlockedForPlayState(false)
|
||||
, mHaveBlockedForStateMachineNotPlaying(false)
|
||||
, mPlaying(false)
|
||||
, mEOSVideoCompensation(false)
|
||||
{
|
||||
mListener = new DecodedStreamGraphListener(mStream);
|
||||
mStream->AddListener(mListener);
|
||||
// Block the stream until the initialization is done.
|
||||
mStream->ChangeExplicitBlockerCount(1);
|
||||
// Block the stream as mPlaying is initially false.
|
||||
UpdateStreamBlocking(mStream, true);
|
||||
}
|
||||
|
||||
DecodedStreamData::~DecodedStreamData()
|
||||
@ -106,6 +118,15 @@ DecodedStreamData::GetPosition() const
|
||||
return mListener->GetLastOutputTime();
|
||||
}
|
||||
|
||||
void
|
||||
DecodedStreamData::SetPlaying(bool aPlaying)
|
||||
{
|
||||
if (mPlaying != aPlaying) {
|
||||
mPlaying = aPlaying;
|
||||
UpdateStreamBlocking(mStream, !mPlaying);
|
||||
}
|
||||
}
|
||||
|
||||
class OutputStreamListener : public MediaStreamListener {
|
||||
typedef MediaStreamListener::MediaStreamGraphEvent MediaStreamGraphEvent;
|
||||
public:
|
||||
@ -290,4 +311,12 @@ DecodedStream::Connect(ProcessedMediaStream* aStream, bool aFinishWhenEnded)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DecodedStream::SetPlaying(bool aPlaying)
|
||||
{
|
||||
GetReentrantMonitor().AssertCurrentThreadIn();
|
||||
MOZ_ASSERT(mData);
|
||||
mData->SetPlaying(aPlaying);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -41,6 +41,7 @@ public:
|
||||
~DecodedStreamData();
|
||||
bool IsFinished() const;
|
||||
int64_t GetPosition() const;
|
||||
void SetPlaying(bool aPlaying);
|
||||
|
||||
/* The following group of fields are protected by the decoder's monitor
|
||||
* and can be read or written on any thread.
|
||||
@ -66,12 +67,7 @@ public:
|
||||
// The decoder is responsible for calling Destroy() on this stream.
|
||||
const nsRefPtr<SourceMediaStream> mStream;
|
||||
nsRefPtr<DecodedStreamGraphListener> mListener;
|
||||
// True when we've explicitly blocked this stream because we're
|
||||
// not in PLAY_STATE_PLAYING. Used on the main thread only.
|
||||
bool mHaveBlockedForPlayState;
|
||||
// We also have an explicit blocker on the stream when
|
||||
// mDecoderStateMachine is non-null and MediaDecoderStateMachine is false.
|
||||
bool mHaveBlockedForStateMachineNotPlaying;
|
||||
bool mPlaying;
|
||||
// True if we need to send a compensation video frame to ensure the
|
||||
// StreamTime going forward.
|
||||
bool mEOSVideoCompensation;
|
||||
@ -96,6 +92,7 @@ public:
|
||||
nsTArray<OutputStreamData>& OutputStreams();
|
||||
ReentrantMonitor& GetReentrantMonitor() const;
|
||||
void Connect(ProcessedMediaStream* aStream, bool aFinishWhenEnded);
|
||||
void SetPlaying(bool aPlaying);
|
||||
|
||||
private:
|
||||
void Connect(OutputStreamData* aStream);
|
||||
|
@ -314,8 +314,6 @@ MediaDecoderStateMachine::InitializationTask()
|
||||
mWatchManager.Watch(mObservedDuration, &MediaDecoderStateMachine::RecomputeDuration);
|
||||
mWatchManager.Watch(mPlayState, &MediaDecoderStateMachine::PlayStateChanged);
|
||||
mWatchManager.Watch(mLogicallySeeking, &MediaDecoderStateMachine::LogicallySeekingChanged);
|
||||
mWatchManager.Watch(mPlayState, &MediaDecoderStateMachine::UpdateStreamBlockingForPlayState);
|
||||
mWatchManager.Watch(mLogicallySeeking, &MediaDecoderStateMachine::UpdateStreamBlockingForPlayState);
|
||||
}
|
||||
|
||||
bool MediaDecoderStateMachine::HasFutureAudio()
|
||||
@ -430,19 +428,6 @@ static bool ZeroDurationAtLastChunk(VideoSegment& aInput)
|
||||
return lastVideoStratTime == aInput.GetDuration();
|
||||
}
|
||||
|
||||
static void
|
||||
UpdateStreamBlocking(MediaStream* aStream, bool aBlocking)
|
||||
{
|
||||
int32_t delta = aBlocking ? 1 : -1;
|
||||
if (NS_IsMainThread()) {
|
||||
aStream->ChangeExplicitBlockerCount(delta);
|
||||
} else {
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethodWithArg<int32_t>(
|
||||
aStream, &MediaStream::ChangeExplicitBlockerCount, delta);
|
||||
AbstractThread::MainThread()->Dispatch(r.forget());
|
||||
}
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::SendStreamData()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
@ -481,12 +466,6 @@ void MediaDecoderStateMachine::SendStreamData()
|
||||
}
|
||||
mediaStream->FinishAddTracks();
|
||||
stream->mStreamInitialized = true;
|
||||
|
||||
// Make sure stream blocking is updated before sending stream data so we
|
||||
// don't 'leak' data when the stream is supposed to be blocked.
|
||||
UpdateStreamBlockingForPlayState();
|
||||
UpdateStreamBlockingForStateMachinePlaying();
|
||||
UpdateStreamBlocking(mediaStream, false);
|
||||
}
|
||||
|
||||
if (mInfo.HasAudio()) {
|
||||
@ -1295,7 +1274,6 @@ void MediaDecoderStateMachine::StopPlayback()
|
||||
// so it can pause audio playback.
|
||||
mDecoder->GetReentrantMonitor().NotifyAll();
|
||||
NS_ASSERTION(!IsPlaying(), "Should report not playing at end of StopPlayback()");
|
||||
UpdateStreamBlockingForStateMachinePlaying();
|
||||
|
||||
DispatchDecodeTasksIfNeeded();
|
||||
}
|
||||
@ -1333,7 +1311,6 @@ void MediaDecoderStateMachine::MaybeStartPlayback()
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
|
||||
mDecoder->GetReentrantMonitor().NotifyAll();
|
||||
UpdateStreamBlockingForStateMachinePlaying();
|
||||
DispatchDecodeTasksIfNeeded();
|
||||
}
|
||||
|
||||
@ -3296,13 +3273,11 @@ void MediaDecoderStateMachine::SetPlayStartTime(const TimeStamp& aTimeStamp)
|
||||
{
|
||||
AssertCurrentThreadInMonitor();
|
||||
mPlayStartTime = aTimeStamp;
|
||||
if (!mAudioSink) {
|
||||
return;
|
||||
}
|
||||
if (!mPlayStartTime.IsNull()) {
|
||||
mAudioSink->StartPlayback();
|
||||
} else {
|
||||
mAudioSink->StopPlayback();
|
||||
|
||||
if (mAudioSink) {
|
||||
mAudioSink->SetPlaying(!mPlayStartTime.IsNull());
|
||||
} else if (mAudioCaptured) {
|
||||
mDecodedStream.SetPlaying(!mPlayStartTime.IsNull());
|
||||
}
|
||||
}
|
||||
|
||||
@ -3526,44 +3501,12 @@ void MediaDecoderStateMachine::AddOutputStream(ProcessedMediaStream* aStream,
|
||||
DispatchAudioCaptured();
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::UpdateStreamBlockingForPlayState()
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
|
||||
auto stream = GetDecodedStream();
|
||||
if (!stream) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool blocking = mPlayState != MediaDecoder::PLAY_STATE_PLAYING ||
|
||||
mLogicallySeeking;
|
||||
if (blocking != stream->mHaveBlockedForPlayState) {
|
||||
stream->mHaveBlockedForPlayState = blocking;
|
||||
UpdateStreamBlocking(stream->mStream, blocking);
|
||||
}
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::UpdateStreamBlockingForStateMachinePlaying()
|
||||
{
|
||||
AssertCurrentThreadInMonitor();
|
||||
|
||||
auto stream = GetDecodedStream();
|
||||
if (!stream) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool blocking = !IsPlaying();
|
||||
if (blocking != stream->mHaveBlockedForStateMachineNotPlaying) {
|
||||
stream->mHaveBlockedForStateMachineNotPlaying = blocking;
|
||||
UpdateStreamBlocking(stream->mStream, blocking);
|
||||
}
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::RecreateDecodedStream(MediaStreamGraph* aGraph)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
mDecodedStream.RecreateData(aGraph);
|
||||
mDecodedStream.SetPlaying(IsPlaying());
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -162,13 +162,6 @@ private:
|
||||
|
||||
void DispatchAudioCaptured();
|
||||
|
||||
// Update blocking state of mDecodedStream when mPlayState or
|
||||
// mLogicallySeeking change. Decoder monitor must be held.
|
||||
void UpdateStreamBlockingForPlayState();
|
||||
|
||||
// Call this IsPlaying() changes. Decoder monitor must be held.
|
||||
void UpdateStreamBlockingForStateMachinePlaying();
|
||||
|
||||
// Recreates mDecodedStream. Call this to create mDecodedStream at first,
|
||||
// and when seeking, to ensure a new stream is set up with fresh buffers.
|
||||
// Decoder monitor must be held.
|
||||
|
Loading…
Reference in New Issue
Block a user