Bug 1345599 - Part 3: For recyclable decoder, don't drain/flush when stream ID/SPS change. r=jya, a=gchang
authorJohn Lin <jolin@mozilla.com>
Tue, 14 Mar 2017 15:04:52 +0800
changeset 395507 d2727be705bd42e5888f3dfd5502d82509344697
parent 395506 d2d9582aca65c41d7eccfa91dd6cf5c73e4ca984
child 395508 e733c38a51474cc7a537dcd9193daf2566a2e1a7
push id1468
push userasasaki@mozilla.com
push dateMon, 05 Jun 2017 19:31:07 +0000
treeherdermozilla-release@0641fc6ee9d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya, gchang
bugs1345599
milestone54.0a2
Bug 1345599 - Part 3: For recyclable decoder, don't drain/flush when stream ID/SPS change. r=jya, a=gchang MozReview-Commit-ID: 4qtlbMWgfPo
dom/media/MediaFormatReader.cpp
dom/media/platforms/wrappers/H264Converter.cpp
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -1956,35 +1956,37 @@ MediaFormatReader::HandleDemuxedSamples(
   LOGV("Giving %s input to decoder", TrackTypeToStr(aTrack));
 
   // Decode all our demuxed frames.
   while (decoder.mQueuedSamples.Length()) {
     RefPtr<MediaRawData> sample = decoder.mQueuedSamples[0];
     RefPtr<TrackInfoSharedPtr> info = sample->mTrackInfo;
 
     if (info && decoder.mLastStreamSourceID != info->GetID()) {
-      if (decoder.mNextStreamSourceID.isNothing()
-          || decoder.mNextStreamSourceID.ref() != info->GetID()) {
+      bool recyclable = MediaPrefs::MediaDecoderCheckRecycling()
+                        && decoder.mDecoder->SupportDecoderRecycling();
+      if (!recyclable
+          && (decoder.mNextStreamSourceID.isNothing()
+              || decoder.mNextStreamSourceID.ref() != info->GetID())) {
         LOG("%s stream id has changed from:%d to:%d, draining decoder.",
           TrackTypeToStr(aTrack), decoder.mLastStreamSourceID,
           info->GetID());
         decoder.RequestDrain();
         decoder.mNextStreamSourceID = Some(info->GetID());
         ScheduleUpdate(aTrack);
         return;
       }
 
       LOG("%s stream id has changed from:%d to:%d.",
           TrackTypeToStr(aTrack), decoder.mLastStreamSourceID,
           info->GetID());
       decoder.mLastStreamSourceID = info->GetID();
       decoder.mNextStreamSourceID.reset();
 
-      if (!MediaPrefs::MediaDecoderCheckRecycling()
-          || !decoder.mDecoder->SupportDecoderRecycling()) {
+      if (!recyclable) {
         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));
         }
--- a/dom/media/platforms/wrappers/H264Converter.cpp
+++ b/dom/media/platforms/wrappers/H264Converter.cpp
@@ -317,42 +317,21 @@ H264Converter::CheckForSPSChange(MediaRa
         return NS_OK;
       }
 
   RefPtr<MediaRawData> sample = aSample;
 
   if (CanRecycleDecoder()) {
     // Do not recreate the decoder, reuse it.
     UpdateConfigFromExtraData(extra_data);
-    // Ideally we would want to drain the decoder instead of flushing it.
-    // However the draining operation requires calling Drain and looping several
-    // times which isn't possible from within the H264Converter. So instead we
-    // flush the decoder. In practice, this is a no-op as SPS change will only
-    // be used with MSE. And with MSE, the MediaFormatReader would have drained
-    // the decoder already.
-    RefPtr<H264Converter> self = this;
     if (!sample->mTrackInfo) {
       sample->mTrackInfo = new TrackInfoSharedPtr(mCurrentConfig, 0);
     }
-    mDecoder->Flush()
-      ->Then(AbstractThread::GetCurrent()->AsTaskQueue(),
-             __func__,
-             [self, sample, this]() {
-               mFlushRequest.Complete();
-               DecodeFirstSample(sample);
-             },
-             [self, this](const MediaResult& aError) {
-               mFlushRequest.Complete();
-               mDecodePromise.Reject(aError, __func__);
-             })
-      ->Track(mFlushRequest);
     mNeedKeyframe = true;
-    // This is not really initializing the decoder, but it will do as it
-    // indicates an operation is pending.
-    return NS_ERROR_DOM_MEDIA_INITIALIZING_DECODER;
+    return NS_OK;
   }
 
   // The SPS has changed, signal to flush the current decoder and create a
   // new one.
   RefPtr<H264Converter> self = this;
   mDecoder->Flush()
     ->Then(AbstractThread::GetCurrent()->AsTaskQueue(),
            __func__,