Bug 1265978. Part 2 - add methods to MediaDecoder and MDSM to dump debugging info. r=jya.
authorJW Wang <jwwang@mozilla.com>
Fri, 22 Apr 2016 14:18:26 +0800
changeset 334328 8dc7d569b77089b8e1410a0eccc2c4f339ee89ca
parent 334327 b709b8c797569fd70589fe6866b6ac5f531b6456
child 334329 26fbf6f91bf9b2cdfc18fdd0c0c45df47d745c46
push id1146
push userCallek@gmail.com
push dateMon, 25 Jul 2016 16:35:44 +0000
treeherdermozilla-release@a55778f9cd5a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya
bugs1265978
milestone48.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1265978. Part 2 - add methods to MediaDecoder and MDSM to dump debugging info. r=jya. MozReview-Commit-ID: Dbc5FT627uL
dom/html/HTMLMediaElement.cpp
dom/media/MediaDecoder.cpp
dom/media/MediaDecoder.h
dom/media/MediaDecoderStateMachine.cpp
dom/media/MediaDecoderStateMachine.h
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -562,17 +562,19 @@ HTMLMediaElement::GetMozDebugReaderData(
   if (mDecoder && !mSrcStream) {
     mDecoder->GetMozDebugReaderData(aString);
   }
 }
 
 void
 HTMLMediaElement::MozDumpDebugInfo()
 {
-  // Tell mDecoder to dump debugging info.
+  if (mDecoder) {
+    mDecoder->DumpDebugInfo();
+  }
 }
 
 already_AddRefed<DOMMediaStream>
 HTMLMediaElement::GetSrcObject() const
 {
   NS_ASSERTION(!mSrcAttrStream || mSrcAttrStream->GetPlaybackStream(),
                "MediaStream should have been set up properly");
   RefPtr<DOMMediaStream> stream = mSrcAttrStream;
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -46,21 +46,25 @@ namespace mozilla {
 // The amount of instability we tollerate in calls to
 // MediaDecoder::UpdateEstimatedMediaDuration(); changes of duration
 // less than this are ignored, as they're assumed to be the result of
 // instability in the duration estimation.
 static const uint64_t ESTIMATED_DURATION_FUZZ_FACTOR_USECS = USECS_PER_S / 2;
 
 // avoid redefined macro in unified build
 #undef DECODER_LOG
+#undef DUMP_LOG
 
 LazyLogModule gMediaDecoderLog("MediaDecoder");
 #define DECODER_LOG(x, ...) \
   MOZ_LOG(gMediaDecoderLog, LogLevel::Debug, ("Decoder=%p " x, this, ##__VA_ARGS__))
 
+#define DUMP_LOG(x, ...) \
+  NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString("Decoder=%p " x, this, ##__VA_ARGS__).get(), nullptr, nullptr, -1)
+
 static const char*
 ToPlayStateStr(MediaDecoder::PlayState aState)
 {
   switch (aState) {
     case MediaDecoder::PLAY_STATE_START:    return "START";
     case MediaDecoder::PLAY_STATE_LOADING:  return "LOADING";
     case MediaDecoder::PLAY_STATE_PAUSED:   return "PAUSED";
     case MediaDecoder::PLAY_STATE_PLAYING:  return "PLAYING";
@@ -1868,16 +1872,28 @@ MediaDecoder::NextFrameBufferedStatus()
   media::TimeInterval interval(currentPosition,
                                currentPosition + media::TimeUnit::FromMicroseconds(DEFAULT_NEXT_FRAME_AVAILABLE_BUFFERED));
   return GetBuffered().Contains(interval)
     ? MediaDecoderOwner::NEXT_FRAME_AVAILABLE
     : MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE;
 }
 
 void
+MediaDecoder::DumpDebugInfo()
+{
+  DUMP_LOG("metadata: channels=%u rate=%u hasAudio=%d hasVideo=%d, "
+           "state: mPlayState=%s mIsDormant=%d, mShuttingDown=%d",
+           mInfo->mAudio.mChannels, mInfo->mAudio.mRate, mInfo->HasAudio(), mInfo->HasVideo(),
+           PlayStateStr(), mIsDormant, mShuttingDown);
+  if (!mShuttingDown && GetStateMachine()) {
+    GetStateMachine()->DumpDebugInfo();
+  }
+}
+
+void
 MediaDecoder::NotifyAudibleStateChanged()
 {
   MOZ_ASSERT(!mShuttingDown);
   mOwner->NotifyAudibleStateChanged(mIsAudioDataAudible);
 }
 
 MediaMemoryTracker::MediaMemoryTracker()
 {
--- a/dom/media/MediaDecoder.h
+++ b/dom/media/MediaDecoder.h
@@ -494,16 +494,18 @@ private:
 
   virtual MediaDecoderOwner::NextFrameStatus NextFrameStatus() { return mNextFrameStatus; }
   virtual MediaDecoderOwner::NextFrameStatus NextFrameBufferedStatus();
 
   // Returns a string describing the state of the media player internal
   // data. Used for debugging purposes.
   virtual void GetMozDebugReaderData(nsAString& aString) {}
 
+  virtual void DumpDebugInfo();
+
 protected:
   virtual ~MediaDecoder();
 
   // Called when the first audio and/or video from the media file has been loaded
   // by the state machine. Call on the main thread only.
   virtual void FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo,
                                 MediaDecoderEventVisibility aEventVisibility);
 
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -58,32 +58,36 @@ using namespace mozilla::layers;
 using namespace mozilla::media;
 
 #define NS_DispatchToMainThread(...) CompileError_UseAbstractThreadDispatchInstead
 
 // avoid redefined macro in unified build
 #undef LOG
 #undef DECODER_LOG
 #undef VERBOSE_LOG
+#undef DUMP_LOG
 
 #define LOG(m, l, x, ...) \
   MOZ_LOG(m, l, ("Decoder=%p " x, mDecoderID, ##__VA_ARGS__))
 #define DECODER_LOG(x, ...) \
   LOG(gMediaDecoderLog, LogLevel::Debug, x, ##__VA_ARGS__)
 #define VERBOSE_LOG(x, ...) \
   LOG(gMediaDecoderLog, LogLevel::Verbose, x, ##__VA_ARGS__)
 #define SAMPLE_LOG(x, ...) \
   LOG(gMediaSampleLog, LogLevel::Debug, x, ##__VA_ARGS__)
 
 // Somehow MSVC doesn't correctly delete the comma before ##__VA_ARGS__
 // when __VA_ARGS__ expands to nothing. This is a workaround for it.
 #define DECODER_WARN_HELPER(a, b) NS_WARNING b
 #define DECODER_WARN(x, ...) \
   DECODER_WARN_HELPER(0, (nsPrintfCString("Decoder=%p " x, mDecoderID, ##__VA_ARGS__).get()))
 
+#define DUMP_LOG(x, ...) \
+  NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString("Decoder=%p " x, mDecoderID, ##__VA_ARGS__).get(), nullptr, nullptr, -1)
+
 // Certain constants get stored as member variables and then adjusted by various
 // scale factors on a per-decoder basis. We want to make sure to avoid using these
 // constants directly, so we put them in a namespace.
 namespace detail {
 
 // If audio queue has less than this many usecs of decoded audio, we won't risk
 // trying to decode the video, we'll skip decoding video up to the next
 // keyframe. We may increase this value for an individual decoder if we
@@ -2659,16 +2663,38 @@ MediaDecoderStateMachine::SetAudioCaptur
 uint32_t MediaDecoderStateMachine::GetAmpleVideoFrames() const
 {
   MOZ_ASSERT(OnTaskQueue());
   return (mReader->IsAsync() && mReader->VideoIsHardwareAccelerated())
     ? std::max<uint32_t>(sVideoQueueHWAccelSize, MIN_VIDEO_QUEUE_SIZE)
     : std::max<uint32_t>(sVideoQueueDefaultSize, MIN_VIDEO_QUEUE_SIZE);
 }
 
+void
+MediaDecoderStateMachine::DumpDebugInfo()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  // It is fine to capture a raw pointer here because MediaDecoder only call
+  // this function before shutdown begins.
+  nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([this] () {
+    DUMP_LOG(
+      "GetMediaTime=%lld GetClock=%lld "
+      "mState=%s mPlayState=%d mDecodingFirstFrame=%d IsPlaying=%d "
+      "mAudioStatus=%s mVideoStatus=%s mDecodedAudioEndTime=%lld mDecodedVideoEndTime=%lld "
+      "mIsAudioPrerolling=%d mIsVideoPrerolling=%d",
+      GetMediaTime(), mMediaSink->IsStarted() ? GetClock() : -1,
+      gMachineStateStr[mState], mPlayState.Ref(), mDecodingFirstFrame, IsPlaying(),
+      AudioRequestStatus(), VideoRequestStatus(), mDecodedAudioEndTime, mDecodedVideoEndTime,
+      mIsAudioPrerolling, mIsVideoPrerolling);
+  });
+
+  OwnerThread()->DispatchStateChange(r.forget());
+}
+
 void MediaDecoderStateMachine::AddOutputStream(ProcessedMediaStream* aStream,
                                                bool aFinishWhenEnded)
 {
   MOZ_ASSERT(NS_IsMainThread());
   DECODER_LOG("AddOutputStream aStream=%p!", aStream);
   mOutputStreamManager->Add(aStream, aFinishWhenEnded);
   nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethodWithArg<bool>(
     this, &MediaDecoderStateMachine::SetAudioCaptured, true);
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -151,16 +151,18 @@ public:
     DECODER_STATE_DECODING,
     DECODER_STATE_SEEKING,
     DECODER_STATE_BUFFERING,
     DECODER_STATE_COMPLETED,
     DECODER_STATE_SHUTDOWN,
     DECODER_STATE_ERROR
   };
 
+  void DumpDebugInfo();
+
   void AddOutputStream(ProcessedMediaStream* aStream, bool aFinishWhenEnded);
   // Remove an output stream added with AddOutputStream.
   void RemoveOutputStream(MediaStream* aStream);
 
   // Seeks to the decoder to aTarget asynchronously.
   RefPtr<MediaDecoder::SeekPromise> InvokeSeek(SeekTarget aTarget);
 
   // Set/Unset dormant state.