Bug 1345898: P3. Flush decoder on Android. r?jolin draft
authorJean-Yves Avenard <jyavenard@mozilla.com>
Tue, 30 May 2017 00:31:11 +0200
changeset 586186 e16509ff11a44db136e82fc6068a28f4a55e4a6e
parent 586185 1a06cd051fc6544868d9d5980c13b327756e9afb
child 630915 11ba34d369af1064d48cdf88a65891acccbff77c
push id61324
push userbmo:jyavenard@mozilla.com
push dateMon, 29 May 2017 22:31:56 +0000
reviewersjolin
bugs1345898
milestone55.0a1
Bug 1345898: P3. Flush decoder on Android. r?jolin In the situation described in P2, on android where the decoder is recycled rather than shut down, we would have potentially returned multiple frames with the same timestamp. It is necessary to flush the decoder. MozReview-Commit-ID: 6ovaD9PEdOG
dom/media/MediaFormatReader.cpp
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -2041,16 +2041,18 @@ MediaFormatReader::HandleDemuxedSamples(
         LOG("Decoder does not support recycling, recreate decoder.");
         // If flushing is required, it will clear our array of queued samples.
         // So make a copy now.
         nsTArray<RefPtr<MediaRawData>> samples{ Move(decoder.mQueuedSamples) };
         ShutdownDecoder(aTrack);
         if (sample->mKeyframe) {
           decoder.mQueuedSamples.AppendElements(Move(samples));
         }
+      } else if (decoder.HasWaitingPromise()) {
+        decoder.Flush();
       }
 
       decoder.mInfo = info;
 
       if (sample->mKeyframe) {
         ScheduleUpdate(aTrack);
       } else {
         auto time = TimeInterval(sample->mTime, sample->GetEndTime());
@@ -3061,17 +3063,17 @@ MediaFormatReader::GetMozDebugReaderData
 
   result += nsPrintfCString("Audio Decoder: %s\n", audioName);
   result += nsPrintfCString("Audio Frames Decoded: %" PRIu64 "\n",
                             mAudio.mNumSamplesOutputTotal);
   if (HasAudio()) {
     result += nsPrintfCString(
       "Audio State: ni=%d no=%d wp=%d demuxr=%d demuxq=%u decoder=%d tt=%.1f "
       "tths=%d in=%" PRIu64 " out=%" PRIu64
-      " qs=%u pending=%u wfd=%d eos=%d ds=%d wfk=%d sid=%u\n",
+      " qs=%u pending=%u wfd=%d eos=%d ds=%d wfk=%d sid=%u nsid=%d\n",
       NeedInput(mAudio),
       mAudio.HasPromise(),
       !mAudio.mWaitingPromise.IsEmpty(),
       mAudio.mDemuxRequest.Exists(),
       uint32_t(mAudio.mQueuedSamples.Length()),
       mAudio.mDecodeRequest.Exists(),
       mAudio.mTimeThreshold ? mAudio.mTimeThreshold.ref().Time().ToSeconds()
                             : -1.0,
@@ -3079,31 +3081,33 @@ MediaFormatReader::GetMozDebugReaderData
       mAudio.mNumSamplesInput,
       mAudio.mNumSamplesOutput,
       unsigned(size_t(mAudio.mSizeOfQueue)),
       unsigned(mAudio.mOutput.Length()),
       mAudio.mWaitingForData,
       mAudio.mDemuxEOS,
       int32_t(mAudio.mDrainState),
       mAudio.mWaitingForKey,
-      mAudio.mLastStreamSourceID);
+      mAudio.mLastStreamSourceID,
+      int32_t(mAudio.mNextStreamSourceID.refOr(-1)));
   }
   result += nsPrintfCString("Video Decoder: %s\n", videoName);
   result +=
     nsPrintfCString("Hardware Video Decoding: %s\n",
                     VideoIsHardwareAccelerated() ? "enabled" : "disabled");
   result +=
     nsPrintfCString("Video Frames Decoded: %" PRIu64 " (skipped=%" PRIu64 ")\n",
                     mVideo.mNumSamplesOutputTotal,
                     mVideo.mNumSamplesSkippedTotal);
   if (HasVideo()) {
     result += nsPrintfCString(
       "Video State: ni=%d no=%d wp=%d demuxr=%d demuxq=%u decoder=%d tt=%.1f "
       "tths=%d in=%" PRIu64 " out=%" PRIu64
-      " qs=%u pending:%u wfd=%d eos=%d ds=%d wfk=%d sid=%u\n",
+      " qs=%u pending:%u wfd=%d eos=%d ds=%d wfk=%d sid=%u nsid=%d lts=%" PRId64
+      "pt=%" PRId64 "\n",
       NeedInput(mVideo),
       mVideo.HasPromise(),
       !mVideo.mWaitingPromise.IsEmpty(),
       mVideo.mDemuxRequest.Exists(),
       uint32_t(mVideo.mQueuedSamples.Length()),
       mVideo.mDecodeRequest.Exists(),
       mVideo.mTimeThreshold ? mVideo.mTimeThreshold.ref().Time().ToSeconds()
                             : -1.0,
@@ -3111,17 +3115,20 @@ MediaFormatReader::GetMozDebugReaderData
       mVideo.mNumSamplesInput,
       mVideo.mNumSamplesOutput,
       unsigned(size_t(mVideo.mSizeOfQueue)),
       unsigned(mVideo.mOutput.Length()),
       mVideo.mWaitingForData,
       mVideo.mDemuxEOS,
       int32_t(mVideo.mDrainState),
       mVideo.mWaitingForKey,
-      mVideo.mLastStreamSourceID);
+      mVideo.mLastStreamSourceID,
+      int32_t(mVideo.mNextStreamSourceID.refOr(-1)),
+      mVideo.mLastTimeThreshold.ToMicroseconds(),
+      mVideo.mOutput.Length() ? mVideo.mOutput[0]->mTime.ToMicroseconds() : -1);
   }
   aString += result;
 }
 
 void
 MediaFormatReader::SetVideoNullDecode(bool aIsNullDecode)
 {
   MOZ_ASSERT(OnTaskQueue());