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:
Robert O'Callahan 2012-12-04 23:59:36 +13:00
Родитель 3bce45872a
Коммит 6d3e2a837c
2 изменённых файлов: 42 добавлений и 8 удалений

Просмотреть файл

@ -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