Bug 1329891. Part 1 - default Handle{Audio,Video}Canceled() to crash. r=kikuo
authorJW Wang <jwwang@mozilla.com>
Mon, 09 Jan 2017 15:44:18 +0800
changeset 459223 3029299fcdcfd1dde73708248087aac34e39f34c
parent 459222 cefe354e0badff06dd3edad1a5a043eb5a97b0df
child 459224 8a74a651866e30a135d9266527765f378e47a257
push id41160
push userbmo:eoger@fastmail.com
push dateWed, 11 Jan 2017 16:28:31 +0000
reviewerskikuo
bugs1329891
milestone53.0a1
Bug 1329891. Part 1 - default Handle{Audio,Video}Canceled() to crash. r=kikuo 1. States (DecodeMetadataState and WaitForCDMState) happen before DecodingFirstFrameState should never receive this event because they don't decode at all. 2. DormantState and ShutdownState shouldn't receive this event because they call ResetDecode() in the entry action. 3. CompletedState should never receive this event because it happens after HandleEndOf{Audio,Video} which happens before Handle{Audio,Video}Canceled. MozReview-Commit-ID: LdwpWlFHtRp
dom/media/MediaDecoderStateMachine.cpp
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -201,32 +201,32 @@ public:
 
   virtual void HandleWaitingForAudio()
   {
     mMaster->WaitForData(MediaData::AUDIO_DATA);
   }
 
   virtual void HandleAudioCanceled()
   {
-    mMaster->EnsureAudioDecodeTaskQueued();
+    Crash("Unexpected event!", __func__);
   }
 
   virtual void HandleEndOfAudio()
   {
     AudioQueue().Finish();
   }
 
   virtual void HandleWaitingForVideo()
   {
     mMaster->WaitForData(MediaData::VIDEO_DATA);
   }
 
   virtual void HandleVideoCanceled()
   {
-    mMaster->EnsureVideoDecodeTaskQueued();
+    Crash("Unexpected event!", __func__);
   }
 
   virtual void HandleEndOfVideo()
   {
     VideoQueue().Finish();
   }
 
   virtual RefPtr<MediaDecoder::SeekPromise> HandleSeek(SeekTarget aTarget);
@@ -240,16 +240,24 @@ public:
   virtual void HandlePlayStateChanged(MediaDecoder::PlayState aPlayState) {}
 
   virtual void DumpDebugInfo() {}
 
 private:
   template <class S, typename R, typename... As>
   auto ReturnTypeHelper(R(S::*)(As...)) -> R;
 
+  void Crash(const char* aReason, const char* aSite)
+  {
+    char buf[1024];
+    SprintfLiteral(buf, "%s state=%s callsite=%s", aReason, ToStateStr(GetState()), aSite);
+    MOZ_ReportAssertionFailure(buf, __FILE__, __LINE__);
+    MOZ_CRASH();
+  }
+
 protected:
   enum class EventVisibility : int8_t
   {
     Observable,
     Suppressed
   };
 
   using Master = MediaDecoderStateMachine;
@@ -654,16 +662,26 @@ public:
   void HandleVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStart) override
   {
     mMaster->PushVideo(aVideo);
     DispatchDecodeTasksIfNeeded();
     MaybeStopPrerolling();
     CheckSlowDecoding(aDecodeStart);
   }
 
+  void HandleAudioCanceled() override
+  {
+    mMaster->EnsureAudioDecodeTaskQueued();
+  }
+
+  void HandleVideoCanceled() override
+  {
+    mMaster->EnsureVideoDecodeTaskQueued();
+  }
+
   void HandleEndOfAudio() override;
   void HandleEndOfVideo() override;
 
   void HandleWaitingForAudio() override
   {
     mMaster->WaitForData(MediaData::AUDIO_DATA);
     MaybeStopPrerolling();
   }
@@ -1639,16 +1657,26 @@ public:
   void HandleVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStart) override
   {
     // This might be the sample we need to exit buffering.
     // Schedule Step() to check it.
     mMaster->PushVideo(aVideo);
     mMaster->ScheduleStateMachine();
   }
 
+  void HandleAudioCanceled() override
+  {
+    mMaster->EnsureAudioDecodeTaskQueued();
+  }
+
+  void HandleVideoCanceled() override
+  {
+    mMaster->EnsureVideoDecodeTaskQueued();
+  }
+
   void HandleEndOfAudio() override;
   void HandleEndOfVideo() override;
 
   void HandleVideoSuspendTimeout() override
   {
     if (mMaster->HasVideo()) {
       mMaster->mVideoDecodeSuspended = true;
       mMaster->mOnPlaybackEvent.Notify(MediaEventType::EnterVideoSuspend);