From d7ef88efff0b1639d8bf2a4d7bb38b73e1f0458e Mon Sep 17 00:00:00 2001 From: Paul Adenot Date: Thu, 7 Oct 2021 15:44:51 +0000 Subject: [PATCH] Bug 1678373 - Add a way to specify the type of content (audio/video/both) in the TelemetryProbesReporter, change a bit visibility event handling. r=alwu Differential Revision: https://phabricator.services.mozilla.com/D125078 --- dom/media/MediaDecoder.cpp | 9 +- dom/media/utils/TelemetryProbesReporter.cpp | 114 +++++++++++++++----- dom/media/utils/TelemetryProbesReporter.h | 24 ++++- 3 files changed, 118 insertions(+), 29 deletions(-) diff --git a/dom/media/MediaDecoder.cpp b/dom/media/MediaDecoder.cpp index 9ef0c72ea26d..7d297d41fd37 100644 --- a/dom/media/MediaDecoder.cpp +++ b/dom/media/MediaDecoder.cpp @@ -672,6 +672,9 @@ void MediaDecoder::MetadataLoaded( aInfo->mMediaSeekableOnlyInBufferedRanges; mInfo = std::move(aInfo); + mTelemetryProbesReporter->OnMediaContentChanged( + TelemetryProbesReporter::MediaInfoToMediaContent(*mInfo)); + // Make sure the element and the frame (if any) are told about // our new size. if (aEventVisibility != MediaDecoderEventVisibility::Suppressed) { @@ -735,6 +738,8 @@ void MediaDecoder::FirstFrameLoaded( aInfo->HasVideo(), PlayStateStr(), IsTransportSeekable()); mInfo = std::move(aInfo); + mTelemetryProbesReporter->OnMediaContentChanged( + TelemetryProbesReporter::MediaInfoToMediaContent(*mInfo)); Invalidate(); @@ -868,7 +873,9 @@ TelemetryProbesReporter::Visibility MediaDecoder::OwnerVisibility() const { void MediaDecoder::UpdateTelemetryHelperBasedOnPlayState( PlayState aState) const { if (aState == PlayState::PLAY_STATE_PLAYING) { - mTelemetryProbesReporter->OnPlay(OwnerVisibility()); + mTelemetryProbesReporter->OnPlay( + OwnerVisibility(), + TelemetryProbesReporter::MediaInfoToMediaContent(*mInfo)); } else if (aState == PlayState::PLAY_STATE_PAUSED || aState == PlayState::PLAY_STATE_ENDED) { mTelemetryProbesReporter->OnPause(OwnerVisibility()); diff --git a/dom/media/utils/TelemetryProbesReporter.cpp b/dom/media/utils/TelemetryProbesReporter.cpp index 4f452511aa53..a4aab6879a90 100644 --- a/dom/media/utils/TelemetryProbesReporter.cpp +++ b/dom/media/utils/TelemetryProbesReporter.cpp @@ -28,59 +28,122 @@ static const char* ToVisibilityStr( return "visible"; case TelemetryProbesReporter::Visibility::eInvisible: return "invisible"; + case TelemetryProbesReporter::Visibility::eInitial: + return "initial"; default: MOZ_ASSERT_UNREACHABLE("invalid visibility"); return "unknown"; } } +MediaContent TelemetryProbesReporter::MediaInfoToMediaContent( + const MediaInfo& aInfo) { + if (aInfo.HasAudio() && aInfo.HasVideo()) { + return MediaContent::MEDIA_HAS_VIDEO | MediaContent::MEDIA_HAS_AUDIO; + } + if (aInfo.HasAudio()) { + return MediaContent::MEDIA_HAS_AUDIO; + } + if (aInfo.HasVideo()) { + return MediaContent::MEDIA_HAS_VIDEO; + } + return MediaContent::MEDIA_HAS_NOTHING; +} + TelemetryProbesReporter::TelemetryProbesReporter( TelemetryProbesReporterOwner* aOwner) : mOwner(aOwner) { MOZ_ASSERT(mOwner); } -void TelemetryProbesReporter::OnPlay(Visibility aVisibility) { - AssertOnMainThreadAndNotShutdown(); - if (mTotalVideoPlayTime.IsStarted()) { - return; - } +void TelemetryProbesReporter::OnPlay(Visibility aVisibility, + MediaContent aMediaContent) { LOG("Start time accumulation for total play time"); - mTotalPlayTime.Start(); - mOwner->DispatchAsyncTestingEvent(u"moztotalplaytimestarted"_ns); - if (aVisibility == Visibility::eInvisible) { - StartInvisibleVideoTimeAcculator(); + + AssertOnMainThreadAndNotShutdown(); + MOZ_ASSERT_IF(mMediaContent & MediaContent::MEDIA_HAS_VIDEO, + !mTotalVideoPlayTime.IsStarted()); + + if (aMediaContent & MediaContent::MEDIA_HAS_VIDEO) { + mTotalVideoPlayTime.Start(); } + + OnMediaContentChanged(aMediaContent); + OnVisibilityChanged(aVisibility); + + mOwner->DispatchAsyncTestingEvent(u"moztotalplaytimestarted"_ns); + + mIsPlaying = true; } void TelemetryProbesReporter::OnPause(Visibility aVisibility) { - AssertOnMainThreadAndNotShutdown(); - if (!mTotalVideoPlayTime.IsStarted()) { + if (!mIsPlaying) { + // Not started return; } - if (aVisibility == Visibility::eInvisible) { - PauseInvisibleVideoTimeAcculator(); - } + LOG("Pause time accumulation for total play time"); - mTotalVideoPlayTime.Pause(); + + AssertOnMainThreadAndNotShutdown(); + MOZ_ASSERT_IF(mMediaContent & MediaContent::MEDIA_HAS_VIDEO, + mTotalVideoPlayTime.IsStarted()); + + if (mMediaContent & MediaContent::MEDIA_HAS_VIDEO) { + LOG("Pause video time accumulation for total play time"); + if (mInvisibleVideoPlayTime.IsStarted()) { + LOG("Pause invisible video time accumulation for total play time"); + PauseInvisibleVideoTimeAcculator(); + } + mTotalVideoPlayTime.Pause(); + } mOwner->DispatchAsyncTestingEvent(u"moztotalplaytimepaused"_ns); ReportTelemetry(); + + mIsPlaying = false; } void TelemetryProbesReporter::OnVisibilityChanged(Visibility aVisibility) { AssertOnMainThreadAndNotShutdown(); - if (mMediaElementVisibility == aVisibility) { - return; - } - - mMediaElementVisibility = aVisibility; - LOG("Corresponding media element visibility change=%s", - ToVisibilityStr(aVisibility)); - if (mMediaElementVisibility == Visibility::eInvisible) { + LOG("Corresponding media element visibility change=%s -> %s", + ToVisibilityStr(mMediaElementVisibility), ToVisibilityStr(aVisibility)); + if (aVisibility == Visibility::eInvisible) { StartInvisibleVideoTimeAcculator(); } else { - PauseInvisibleVideoTimeAcculator(); + if (aVisibility != Visibility::eInitial) { + PauseInvisibleVideoTimeAcculator(); + } else { + LOG("Visibility was initial, not pausing."); + } } + mMediaElementVisibility = aVisibility; +} +void TelemetryProbesReporter::OnMediaContentChanged(MediaContent aContent) { + AssertOnMainThreadAndNotShutdown(); + if (aContent == mMediaContent) { + return; + } + if (mMediaContent & MediaContent::MEDIA_HAS_VIDEO && + !(aContent & MediaContent::MEDIA_HAS_VIDEO)) { + LOG("Video track removed from media."); + if (mInvisibleVideoPlayTime.IsStarted()) { + PauseInvisibleVideoTimeAcculator(); + } + if (mTotalVideoPlayTime.IsStarted()) { + mTotalVideoPlayTime.Pause(); + } + } + if (!(mMediaContent & MediaContent::MEDIA_HAS_VIDEO) && + aContent & MediaContent::MEDIA_HAS_VIDEO) { + LOG("Video track added to media."); + if (mIsPlaying) { + mTotalVideoPlayTime.Start(); + if (mMediaElementVisibility == Visibility::eInvisible) { + StartInvisibleVideoTimeAccumulator(); + } + } + } + + mMediaContent = aContent; } void TelemetryProbesReporter::OnDecodeSuspended() { @@ -312,7 +375,8 @@ double TelemetryProbesReporter::GetTotalVideoPlayTimeInSeconds() const { } double TelemetryProbesReporter::GetVisibleVideoPlayTimeInSeconds() const { - return GetTotalVideoPlayTimeInSeconds() - GetInvisibleVideoPlayTimeInSeconds(); + return GetTotalVideoPlayTimeInSeconds() - + GetInvisibleVideoPlayTimeInSeconds(); } double TelemetryProbesReporter::GetInvisibleVideoPlayTimeInSeconds() const { diff --git a/dom/media/utils/TelemetryProbesReporter.h b/dom/media/utils/TelemetryProbesReporter.h index d669af411e7d..bb8426097c51 100644 --- a/dom/media/utils/TelemetryProbesReporter.h +++ b/dom/media/utils/TelemetryProbesReporter.h @@ -22,6 +22,14 @@ class TelemetryProbesReporterOwner { virtual void DispatchAsyncTestingEvent(const nsAString& aName) = 0; }; +enum class MediaContent : uint8_t { + MEDIA_HAS_NOTHING = (0 << 0), + MEDIA_HAS_VIDEO = (1 << 0), + MEDIA_HAS_AUDIO = (1 << 1) +}; + +MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(MediaContent) + /** * This class is used for collecting and reporting telemetry probes for * its owner which should inherit from TelemetryProbesReporterOwner. We use it @@ -33,16 +41,22 @@ class TelemetryProbesReporter final { ~TelemetryProbesReporter() = default; enum class Visibility { + eInitial, eVisible, eInvisible, }; - void OnPlay(Visibility aVisibility); + static MediaContent MediaInfoToMediaContent(const MediaInfo& aInfo); + + // State transitions + void OnPlay(Visibility aVisibility, MediaContent aContent); void OnPause(Visibility aVisibility); + void OnShutdown(); + void OnVisibilityChanged(Visibility aVisibility); + void OnMediaContentChanged(MediaContent aContent); void OnDecodeSuspended(); void OnDecodeResumed(); - void OnShutdown(); double GetTotalVideoPlayTimeInSeconds() const; double GetVisibleVideoPlayTimeInSeconds() const; @@ -113,7 +127,11 @@ class TelemetryProbesReporter final { // Total time a VIDEO has spent in video-decode-suspend mode. TimeDurationAccumulator mVideoDecodeSuspendedTime; - Visibility mMediaElementVisibility = Visibility::eInvisible; + Visibility mMediaElementVisibility = Visibility::eInitial; + + MediaContent mMediaContent = MediaContent::MEDIA_HAS_NOTHING; + + bool mIsPlaying = false; }; } // namespace mozilla