Bug 1175396 - Handle mismatched sample formats. r=jwwang, a=2.0+
☠☠ backed out by 2b69da6a768e ☠ ☠
authorMatthew Gregan <kinetik@flim.org>
Fri, 17 Jul 2015 11:29:11 +1200
changeset 204933 19dca15f418576bd6d7853b3de59e1fa6498e549
parent 204932 aaff5124ea11d442d8f275c58734ed16eab49887
child 204934 2b69da6a768e15b19e6a20a8745dab3583f31446
push id855
push userryanvm@gmail.com
push dateThu, 16 Jul 2015 23:48:26 +0000
treeherdermozilla-b2g32_v2_0@19dca15f4185 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwwang, 2
bugs1175396
milestone32.0
Bug 1175396 - Handle mismatched sample formats. r=jwwang, a=2.0+
content/media/MediaDecoderStateMachine.cpp
content/media/MediaDecoderStateMachine.h
--- a/content/media/MediaDecoderStateMachine.cpp
+++ b/content/media/MediaDecoderStateMachine.cpp
@@ -897,17 +897,17 @@ void MediaDecoderStateMachine::AudioLoop
       // we pushed to the audio hardware. We must push silence into the audio
       // hardware so that the next audio chunk begins playback at the correct
       // time.
       missingFrames = std::min<int64_t>(UINT32_MAX, missingFrames.value());
       VERBOSE_LOG("playing %d frames of silence", int32_t(missingFrames.value()));
       framesWritten = PlaySilence(static_cast<uint32_t>(missingFrames.value()),
                                   channels, playedFrames.value());
     } else {
-      framesWritten = PlayFromAudioQueue(sampleTime.value(), channels);
+      framesWritten = PlayFromAudioQueue(sampleTime.value(), channels, rate);
     }
     audioDuration += framesWritten;
     {
       ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
       CheckedInt64 playedUsecs = FramesToUsecs(audioDuration, rate) + audioStartTime;
       if (!playedUsecs.isValid()) {
         NS_WARNING("Int overflow calculating audio end time");
         break;
@@ -978,34 +978,40 @@ uint32_t MediaDecoderStateMachine::PlayS
   NS_ASSERTION(!mAudioStream->IsPaused(), "Don't play when paused");
   uint32_t maxFrames = SILENCE_BYTES_CHUNK / aChannels / sizeof(AudioDataValue);
   uint32_t frames = std::min(aFrames, maxFrames);
   WriteSilence(mAudioStream, frames);
   return frames;
 }
 
 uint32_t MediaDecoderStateMachine::PlayFromAudioQueue(uint64_t aFrameOffset,
-                                                      uint32_t aChannels)
+                                                      uint32_t aChannels,
+                                                      uint32_t aRate)
 {
   NS_ASSERTION(OnAudioThread(), "Only call on audio thread.");
   NS_ASSERTION(!mAudioStream->IsPaused(), "Don't play when paused");
   nsAutoPtr<AudioData> audio(AudioQueue().PopFront());
   {
     ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
     NS_WARN_IF_FALSE(IsPlaying(), "Should be playing");
     // Awaken the decode loop if it's waiting for space to free up in the
     // audio queue.
     mDecoder->GetReentrantMonitor().NotifyAll();
   }
   int64_t offset = -1;
   uint32_t frames = 0;
   VERBOSE_LOG("playing %d frames of data to stream for AudioData at %lld",
               audio->mFrames, audio->mTime);
-  mAudioStream->Write(audio->mAudioData,
-                      audio->mFrames);
+  if (audio->mRate == aRate && audio->mChannels == aChannels) {
+    mAudioStream->Write(audio->mAudioData, audio->mFrames);
+  } else {
+    VERBOSE_LOG("mismatched sample format mInfo=[%uHz/%u channels] audio=[%uHz/%u channels]",
+                 aRate, aChannels, audio->mRate, audio->mChannels);
+    PlaySilence(audio->mFrames, aChannels, 0);
+  }
 
   aChannels = mAudioStream->GetOutChannels();
 
   StartAudioStreamPlaybackIfNeeded(mAudioStream);
 
   offset = audio->mOffset;
   frames = audio->mFrames;
 
--- a/content/media/MediaDecoderStateMachine.h
+++ b/content/media/MediaDecoderStateMachine.h
@@ -499,17 +499,17 @@ protected:
   // impossibly large chunk of memory in order to play back silence. Called
   // on the audio thread.
   uint32_t PlaySilence(uint32_t aFrames,
                        uint32_t aChannels,
                        uint64_t aFrameOffset);
 
   // Pops an audio chunk from the front of the audio queue, and pushes its
   // audio data to the audio hardware.
-  uint32_t PlayFromAudioQueue(uint64_t aFrameOffset, uint32_t aChannels);
+  uint32_t PlayFromAudioQueue(uint64_t aFrameOffset, uint32_t aChannels, uint32_t aRate);
 
   // Stops the audio thread. The decoder monitor must be held with exactly
   // one lock count. Called on the state machine thread.
   void StopAudioThread();
 
   // Starts the audio thread. The decoder monitor must be held with exactly
   // one lock count. Called on the state machine thread.
   nsresult StartAudioThread();