Bug 1314863 - Correct data sample being fed twice to the decoder draft
authorJames Cheng <jacheng@mozilla.com>
Thu, 10 Nov 2016 17:52:39 +0800
changeset 437099 afab9788d97f58ab1342aa9f29f5e69bb86c7e5e
parent 435666 783356f1476eafd8e4d6fa5f3919cf6167e84f8d
child 536559 551252ddcb3195c0524899c66d90aacb9ba72754
push id35327
push userbmo:jacheng@mozilla.com
push dateThu, 10 Nov 2016 10:27:10 +0000
bugs1314863
milestone52.0a1
Bug 1314863 - Correct data sample being fed twice to the decoder MozReview-Commit-ID: 2TmHiLju0C4
dom/media/platforms/wrappers/H264Converter.cpp
--- a/dom/media/platforms/wrappers/H264Converter.cpp
+++ b/dom/media/platforms/wrappers/H264Converter.cpp
@@ -81,16 +81,21 @@ H264Converter::Input(MediaRawData* aSamp
     if (rv == NS_ERROR_NOT_INITIALIZED) {
       // We are missing the required SPS to create the decoder.
       // Ignore for the time being, the MediaRawData will be dropped.
       mCallback->InputExhausted();
       return;
     }
   } else {
     rv = CheckForSPSChange(aSample);
+    if (rv == NS_ERROR_NOT_INITIALIZED) {
+      // The decoder is pending initialization.
+      mCallback->InputExhausted();
+      return;
+    }
   }
   if (NS_FAILED(rv)) {
     mCallback->Error(
       MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
                   RESULT_DETAIL("Unable to create H264 decoder")));
     return;
   }
 
@@ -223,16 +228,17 @@ H264Converter::CreateDecoderAndInit(Medi
   if (NS_SUCCEEDED(rv)) {
     // Queue the incoming sample.
     mMediaRawSamples.AppendElement(aSample);
 
     mInitPromiseRequest.Begin(mDecoder->Init()
       ->Then(AbstractThread::GetCurrent()->AsTaskQueue(), __func__, this,
              &H264Converter::OnDecoderInitDone,
              &H264Converter::OnDecoderInitFailed));
+    return NS_ERROR_NOT_INITIALIZED;
   }
   return rv;
 }
 
 void
 H264Converter::OnDecoderInitDone(const TrackType aTrackType)
 {
   mInitPromiseRequest.Complete();
@@ -240,16 +246,23 @@ H264Converter::OnDecoderInitDone(const T
   for (uint32_t i = 0 ; i < mMediaRawSamples.Length(); i++) {
     const RefPtr<MediaRawData>& sample = mMediaRawSamples[i];
     if (mNeedKeyframe) {
       if (!sample->mKeyframe) {
         continue;
       }
       mNeedKeyframe = false;
     }
+    if (!mNeedAVCC &&
+        !mp4_demuxer::AnnexB::ConvertSampleToAnnexB(sample, mNeedKeyframe)) {
+      mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY,
+                                   RESULT_DETAIL("ConvertSampleToAnnexB")));
+      mMediaRawSamples.Clear();
+      return;
+    }
     mDecoder->Input(sample);
   }
   if (!gotInput) {
     mCallback->InputExhausted();
   }
   mMediaRawSamples.Clear();
 }