зеркало из https://github.com/mozilla/gecko-dev.git
Bug 794426. Don't call StopAudioThread from the main thread when we start capturing audio to a MediaStream. Instead, let the state machine thread call StopAudioThread. r=cpearce
This commit is contained in:
Родитель
3bce45872a
Коммит
6d3e2a837c
|
@ -26,7 +26,7 @@
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
using namespace layers;
|
||||
using namespace mozilla::layers;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
|
@ -493,8 +493,8 @@ void MediaDecoderStateMachine::DecodeThreadRun()
|
|||
}
|
||||
|
||||
void MediaDecoderStateMachine::SendStreamAudio(AudioData* aAudio,
|
||||
DecodedStreamData* aStream,
|
||||
AudioSegment* aOutput)
|
||||
DecodedStreamData* aStream,
|
||||
AudioSegment* aOutput)
|
||||
{
|
||||
NS_ASSERTION(OnDecodeThread(), "Should be on decode thread.");
|
||||
mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
|
||||
|
@ -564,7 +564,8 @@ static const TrackRate RATE_VIDEO = USECS_PER_S;
|
|||
|
||||
void MediaDecoderStateMachine::SendStreamData()
|
||||
{
|
||||
NS_ASSERTION(OnDecodeThread(), "Should be on decode thread.");
|
||||
NS_ASSERTION(OnDecodeThread() ||
|
||||
OnStateMachineThread(), "Should be on decode thread or state machine thread");
|
||||
mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
|
||||
|
||||
DecodedStreamData* stream = mDecoder->GetDecodedStream();
|
||||
|
@ -574,6 +575,13 @@ void MediaDecoderStateMachine::SendStreamData()
|
|||
if (mState == DECODER_STATE_DECODING_METADATA)
|
||||
return;
|
||||
|
||||
// If there's still an audio thread alive, then we can't send any stream
|
||||
// data yet since both SendStreamData and the audio thread want to be in
|
||||
// charge of popping the audio queue. We're waiting for the audio thread
|
||||
// to die before sending anything to our stream.
|
||||
if (mAudioThread)
|
||||
return;
|
||||
|
||||
int64_t minLastAudioPacketTime = INT64_MAX;
|
||||
SourceMediaStream* mediaStream = stream->mStream;
|
||||
StreamTime endPosition = 0;
|
||||
|
@ -1324,8 +1332,12 @@ void MediaDecoderStateMachine::SetAudioCaptured(bool aCaptured)
|
|||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
if (!mAudioCaptured && aCaptured) {
|
||||
StopAudioThread();
|
||||
if (!mAudioCaptured && aCaptured && !mStopAudioThread) {
|
||||
// Make sure the state machine runs as soon as possible. That will
|
||||
// stop the audio thread.
|
||||
// If mStopAudioThread is true then we're already stopping the audio thread
|
||||
// and since we set mAudioCaptured to true, nothing can start it again.
|
||||
ScheduleStateMachine();
|
||||
}
|
||||
mAudioCaptured = aCaptured;
|
||||
}
|
||||
|
@ -1549,7 +1561,15 @@ void MediaDecoderStateMachine::StopDecodeThread()
|
|||
|
||||
void MediaDecoderStateMachine::StopAudioThread()
|
||||
{
|
||||
NS_ASSERTION(OnDecodeThread() ||
|
||||
OnStateMachineThread(), "Should be on decode thread or state machine thread");
|
||||
mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
|
||||
|
||||
if (mStopAudioThread) {
|
||||
// Nothing to do, since the thread is already stopping
|
||||
return;
|
||||
}
|
||||
|
||||
mStopAudioThread = true;
|
||||
mDecoder->GetReentrantMonitor().NotifyAll();
|
||||
if (mAudioThread) {
|
||||
|
@ -1559,6 +1579,9 @@ void MediaDecoderStateMachine::StopAudioThread()
|
|||
mAudioThread->Shutdown();
|
||||
}
|
||||
mAudioThread = nullptr;
|
||||
// Now that the audio thread is dead, try sending data to our MediaStream(s).
|
||||
// That may have been waiting for the audio thread to stop.
|
||||
SendStreamData();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1635,8 +1658,13 @@ MediaDecoderStateMachine::StartAudioThread()
|
|||
NS_ASSERTION(OnStateMachineThread() || OnDecodeThread(),
|
||||
"Should be on state machine or decode thread.");
|
||||
mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
|
||||
if (mAudioCaptured) {
|
||||
NS_ASSERTION(mStopAudioThread, "mStopAudioThread must always be true if audio is captured");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mStopAudioThread = false;
|
||||
if (HasAudio() && !mAudioThread && !mAudioCaptured) {
|
||||
if (HasAudio() && !mAudioThread) {
|
||||
nsresult rv = NS_NewNamedThread("Media Audio",
|
||||
getter_AddRefs(mAudioThread),
|
||||
nullptr,
|
||||
|
@ -2539,6 +2567,11 @@ nsresult MediaDecoderStateMachine::CallRunStateMachine()
|
|||
// This flag prevents us from dispatching
|
||||
mDispatchedRunEvent = false;
|
||||
|
||||
// If audio is being captured, stop the audio thread if it's running
|
||||
if (mAudioCaptured) {
|
||||
StopAudioThread();
|
||||
}
|
||||
|
||||
mTimeout = TimeStamp();
|
||||
|
||||
mIsRunning = true;
|
||||
|
|
|
@ -702,7 +702,8 @@ private:
|
|||
// been consumed by the play state machine thread.
|
||||
uint32_t mAmpleVideoFrames;
|
||||
// True if we shouldn't play our audio (but still write it to any capturing
|
||||
// streams).
|
||||
// streams). When this is true, mStopAudioThread is always true and
|
||||
// the audio thread will never start again after it has stopped.
|
||||
bool mAudioCaptured;
|
||||
|
||||
// True if the media resource can be seeked on a transport level. Accessed
|
||||
|
|
Загрузка…
Ссылка в новой задаче