Bug 1743834 - Wait for the audio callbacks to start being called before using the audio clock. r=alwu,media-playback-reviewers

Because we're generally using high latency on the cubeb stream used by
AudioStream instance, it can take some time for the callbacks to start being
called, and the for the audio clock (cubeb_stream_get_position(...)) to advance.

This waits for the first callback to be called before using the clock of the
audio stream, and the system clock keeps being in use until then.

Differential Revision: https://phabricator.services.mozilla.com/D136235
This commit is contained in:
Paul Adenot 2022-05-24 13:09:06 +00:00
Родитель 024b4fe28b
Коммит f048891e77
4 изменённых файлов: 19 добавлений и 5 удалений

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

@ -148,7 +148,9 @@ AudioStream::AudioStream(DataSource& aSource, uint32_t aInRate,
mSandboxed(CubebUtils::SandboxEnabled()),
mPlaybackComplete(false),
mPlaybackRate(1.0f),
mPreservesPitch(true) {}
mPreservesPitch(true),
mCallbacksStarted(false)
{}
AudioStream::~AudioStream() {
LOG("deleted, state %d", mState.load());
@ -231,8 +233,8 @@ nsresult AudioStream::Init(AudioDeviceInfo* aSinkInfo)
auto startTime = TimeStamp::Now();
TRACE("AudioStream::Init");
LOG("%s channels: %d, rate: %d", __FUNCTION__, mOutChannels,
mAudioClock.GetInputRate());
LOG("%s channels: %d, rate: %d", __FUNCTION__, mOutChannels, mAudioClock.GetInputRate());
mSinkInfo = aSinkInfo;
cubeb_stream_params params;
@ -595,6 +597,9 @@ long AudioStream::DataCallback(void* aBuffer, long aFrames) {
CubebUtils::GetAudioThreadRegistry()->Register(mAudioThreadId);
}
WebCore::DenormalDisabler disabler;
if (!mCallbacksStarted) {
mCallbacksStarted = true;
}
TRACE_AUDIO_CALLBACK_BUDGET(aFrames, mAudioClock.GetInputRate());
TRACE("AudioStream::DataCallback");

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

@ -297,6 +297,9 @@ class AudioStream final {
bool IsPlaybackCompleted() const;
// Returns true if at least one DataCallback has been called.
bool CallbackStarted() const { return mCallbacksStarted; }
protected:
friend class AudioClock;
@ -386,6 +389,7 @@ class AudioStream final {
std::atomic<bool> mPreservesPitch;
// Audio thread only
bool mAudioThreadChanged = false;
Atomic<bool> mCallbacksStarted;
};
} // namespace mozilla

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

@ -77,6 +77,12 @@ class AudioSink : private AudioStream::DataSource {
const RefPtr<AudioDeviceInfo>& AudioDevice() { return mAudioDevice; }
// This returns true if the audio callbacks are being called, and so the
// audio stream-based clock is moving forward.
bool AudioStreamCallbackStarted() {
return mAudioStream && mAudioStream->CallbackStarted();
}
private:
// Allocate and initialize mAudioStream. Returns NS_OK on success.
nsresult InitializeAudioStream(const PlaybackParams& aParams);

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

@ -77,8 +77,7 @@ TimeUnit AudioSinkWrapper::GetPosition(TimeStamp* aTimeStamp) {
TimeUnit pos;
TimeStamp t = TimeStamp::Now();
if (!mAudioEnded && !IsMuted()) {
MOZ_ASSERT(mAudioSink);
if (!mAudioEnded && !IsMuted() && mAudioSink && mAudioSink->AudioStreamCallbackStarted()) {
// Rely on the audio sink to report playback position when it is not ended.
pos = mAudioSink->GetPosition();
LOGV("%p: Getting position from the Audio Sink %lf", this, pos.ToSeconds());