Bug 1743834 - When no packet are in the queue when shutting down the AudioStream, try our best to provide timing data. r=alwu
authorPaul Adenot <paul@paul.cx>
Tue, 24 May 2022 13:09:08 +0000
changeset 618733 55b1957af2162f94d1dcfbf882da7d7b9499ca19
parent 618732 0daef4d3e9ece931791f1121e27d8530a277d422
child 618734 1f8a39ab7f1c10b1a267fb228cc9426f292bcc72
push id163385
push userpadenot@mozilla.com
push dateTue, 24 May 2022 13:12:53 +0000
treeherderautoland@3774e6ab3869 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersalwu
bugs1743834
milestone102.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1743834 - When no packet are in the queue when shutting down the AudioStream, try our best to provide timing data. r=alwu Differential Revision: https://phabricator.services.mozilla.com/D141992
dom/media/mediasink/AudioSink.cpp
--- a/dom/media/mediasink/AudioSink.cpp
+++ b/dom/media/mediasink/AudioSink.cpp
@@ -122,20 +122,32 @@ TimeUnit AudioSink::UnplayedDuration() c
 
 void AudioSink::ReenqueueUnplayedAudioDataIfNeeded() {
   // This is OK: the AudioStream has been shut down. Shutdown guarantees that
   // the audio callback thread won't call back again.
   mProcessedSPSCQueue->ResetThreadIds();
 
   // construct an AudioData
   int sampleCount = mProcessedSPSCQueue->AvailableRead();
-  uint32_t channelCount = mConverter->OutputConfig().Channels();
-  uint32_t rate = mConverter->OutputConfig().Rate();
+
+  if (!sampleCount) {
+    return;
+  }
+
+  uint32_t channelCount;
+  uint32_t rate;
+  if (mConverter) {
+    channelCount = mConverter->OutputConfig().Channels();
+    rate = mConverter->OutputConfig().Rate();
+  } else {
+    channelCount = mOutputChannels;
+    rate = mOutputRate;
+  }
+
   uint32_t frameCount = sampleCount / channelCount;
-
   auto duration = FramesToTimeUnit(frameCount, rate);
   if (!duration.IsValid()) {
     NS_WARNING("Int overflow in AudioSink");
     mErrored = true;
     return;
   }
 
   AlignedAudioBuffer queuedAudio(sampleCount);
@@ -143,19 +155,28 @@ void AudioSink::ReenqueueUnplayedAudioDa
       mProcessedSPSCQueue->Dequeue(queuedAudio.Data(), sampleCount);
   MOZ_ASSERT(samplesRead == sampleCount);
 
   // Extrapolate mOffset, mTime from the front of the queue
   // We can't really find a good value for `mOffset`, so we take what we have
   // at the front of the queue.
   // For `mTime`, assume there hasn't been a discontinuity recently.
   RefPtr<AudioData> frontPacket = mAudioQueue.PeekFront();
+  uint32_t offset;
+  TimeUnit time;
+  if (!frontPacket) {
+    // We do our best here, but it's not going to be perfect.
+    offset = 0;
+    time = std::max(GetPosition() - duration, TimeUnit::Zero());
+  } else {
+    offset = frontPacket->mOffset;
+    time = frontPacket->mTime - duration;
+  }
   RefPtr<AudioData> data =
-      new AudioData(frontPacket->mOffset, frontPacket->mTime - duration,
-                    std::move(queuedAudio), channelCount, rate);
+      new AudioData(offset, time, std::move(queuedAudio), channelCount, rate);
   MOZ_DIAGNOSTIC_ASSERT(duration == data->mDuration, "must be equal");
 
   SINK_LOG(
       "Muting: Pushing back %u frames (%lfms) from the ring buffer back into "
       "the audio queue",
       frameCount, static_cast<float>(frameCount) / rate);
 
   mAudioQueue.PushFront(data);