Bug 1344661 - capture input sample for CheckForSPSChange(). draft
authorAlastor Wu <alwu@mozilla.com>
Mon, 06 Mar 2017 18:16:04 +0800
changeset 493905 9c91aca0b091a5df12563491868c9d26db0f5042
parent 493498 0fdda5fe6d746c166c98230653899f8b61340f83
child 547973 afd7bae923cbfd09648b29d2309964f0c497573d
push id47894
push useralwu@mozilla.com
push dateMon, 06 Mar 2017 10:16:40 +0000
bugs1344661
milestone54.0a1
Bug 1344661 - capture input sample for CheckForSPSChange(). When the SPS changed, we save the input sample in |mPendingSample|, and then call CreateDecoderAndInit(mPendingSample) after calling shutdown(). However, the |mPendingSample| has been clear in shutdown(), so actually we send the nullptr to CreateDecoderAndInit(). MozReview-Commit-ID: JTRVdKxyEy6
dom/media/platforms/wrappers/H264Converter.cpp
--- a/dom/media/platforms/wrappers/H264Converter.cpp
+++ b/dom/media/platforms/wrappers/H264Converter.cpp
@@ -313,35 +313,34 @@ H264Converter::CheckForSPSChange(MediaRa
   RefPtr<MediaByteBuffer> extra_data =
     mp4_demuxer::AnnexB::ExtractExtraData(aSample);
   if (!mp4_demuxer::AnnexB::HasSPS(extra_data)
       || mp4_demuxer::AnnexB::CompareExtraData(extra_data,
                                                mCurrentConfig.mExtraData)) {
         return NS_OK;
       }
 
-  mPendingSample = aSample;
+  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;
     mDecoder->Flush()
       ->Then(AbstractThread::GetCurrent()->AsTaskQueue(),
              __func__,
-             [self, this]() {
+             [self, sample, this]() {
                mFlushRequest.Complete();
-               DecodeFirstSample(mPendingSample);
-               mPendingSample = nullptr;
+               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
@@ -350,27 +349,26 @@ H264Converter::CheckForSPSChange(MediaRa
   }
 
   // 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__,
-           [self, this]() {
+           [self, sample, this]() {
              mFlushRequest.Complete();
              mShutdownPromise = Shutdown();
              mShutdownPromise
                ->Then(AbstractThread::GetCurrent()->AsTaskQueue(),
                       __func__,
-                      [self, this]() {
+                      [self, sample, this]() {
                         mShutdownRequest.Complete();
                         mShutdownPromise = nullptr;
                         mNeedAVCC.reset();
-                        RefPtr<MediaRawData> sample = mPendingSample.forget();
                         nsresult rv = CreateDecoderAndInit(sample);
                         if (rv == NS_ERROR_DOM_MEDIA_INITIALIZING_DECODER) {
                           // All good so far, will continue later.
                           return;
                         }
                         MOZ_ASSERT(NS_FAILED(rv));
                         mDecodePromise.Reject(rv, __func__);
                         return;