Bug 1038091 - Pause the player instead of stopping it to avoid resetting playback position and resulting in audio clock going backward. r=kinetik

This commit is contained in:
JW Wang 2014-09-28 19:36:00 -04:00
parent bae8838328
commit 787d7762f5
3 changed files with 12 additions and 3 deletions

View File

@ -141,6 +141,7 @@ AudioStream::AudioStream()
, mNeedsStart(false)
, mShouldDropFrames(false)
, mPendingAudioInitTask(false)
, mLastGoodPosition(0)
{
// keep a ref in case we shut down later than nsLayoutStatics
mLatencyLog = AsyncLatencyLogger::Get(true);
@ -856,7 +857,12 @@ AudioStream::GetPositionInFramesUnlocked()
}
}
return std::min<uint64_t>(position, INT64_MAX);
MOZ_ASSERT(position >= mLastGoodPosition, "cubeb position shouldn't go backward");
// This error handling/recovery keeps us in good shape in release build.
if (position >= mLastGoodPosition) {
mLastGoodPosition = position;
}
return std::min<uint64_t>(mLastGoodPosition, INT64_MAX);
}
int64_t

View File

@ -402,6 +402,9 @@ private:
// True if there is a pending AudioInitTask. Shutdown() will wait until the
// pending AudioInitTask is finished.
bool mPendingAudioInitTask;
// The last good position returned by cubeb_stream_get_position(). Used to
// check if the cubeb position is going backward.
uint64_t mLastGoodPosition;
};
class AudioInitTask : public nsRunnable

View File

@ -83,7 +83,7 @@ play_callback(SLPlayItf caller, void * user_ptr, SLuint32 event)
assert(stm->draining);
pthread_mutex_unlock(&stm->mutex);
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_DRAINED);
(*stm->play)->SetPlayState(stm->play, SL_PLAYSTATE_STOPPED);
(*stm->play)->SetPlayState(stm->play, SL_PLAYSTATE_PAUSED);
break;
default:
break;
@ -116,7 +116,7 @@ bufferqueue_callback(SLBufferQueueItf caller, void * user_ptr)
written = cubeb_resampler_fill(stm->resampler, buf,
stm->queuebuf_len / stm->framesize);
if (written < 0 || written * stm->framesize > stm->queuebuf_len) {
(*stm->play)->SetPlayState(stm->play, SL_PLAYSTATE_STOPPED);
(*stm->play)->SetPlayState(stm->play, SL_PLAYSTATE_PAUSED);
return;
}
}