TelemetryProbesReporter.h (6616B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifndef DOM_TelemetryProbesReporter_H_ 6 #define DOM_TelemetryProbesReporter_H_ 7 8 #include "AudioChannelService.h" 9 #include "MediaCodecsSupport.h" 10 #include "MediaInfo.h" 11 #include "mozilla/AwakeTimeStamp.h" 12 #include "mozilla/DefineEnum.h" 13 #include "mozilla/EnumSet.h" 14 #include "mozilla/Maybe.h" 15 #include "nsISupportsImpl.h" 16 17 namespace mozilla { 18 class FrameStatistics; 19 20 class TelemetryProbesReporterOwner { 21 public: 22 virtual Maybe<nsAutoString> GetKeySystem() const = 0; 23 virtual MediaInfo GetMediaInfo() const = 0; 24 virtual FrameStatistics* GetFrameStatistics() const = 0; 25 virtual bool IsEncrypted() const = 0; 26 virtual void DispatchAsyncTestingEvent(const nsAString& aName) = 0; 27 #ifdef MOZ_WMF_CDM 28 virtual bool IsUsingWMFCDM() const = 0; 29 #endif 30 }; 31 32 enum class MediaContent : uint8_t { 33 MEDIA_HAS_NOTHING = (0 << 0), 34 MEDIA_HAS_VIDEO = (1 << 0), 35 MEDIA_HAS_AUDIO = (1 << 1), 36 MEDIA_HAS_COLOR_DEPTH_ABOVE_8 = (1 << 2), 37 }; 38 39 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(MediaContent) 40 41 /** 42 * This class is used for collecting and reporting telemetry probes for 43 * its owner which should inherit from TelemetryProbesReporterOwner. We use it 44 * for HTMLMediaElement, and each element has one corresponding reporter. 45 */ 46 class TelemetryProbesReporter final { 47 public: 48 explicit TelemetryProbesReporter(TelemetryProbesReporterOwner* aOwner); 49 ~TelemetryProbesReporter() = default; 50 51 MOZ_DEFINE_ENUM_CLASS_WITH_TOSTRING_AT_CLASS_SCOPE(Visibility, 52 (eInitial, eVisible, 53 eInvisible)); 54 55 static MediaContent MediaInfoToMediaContent(const MediaInfo& aInfo); 56 57 using AudibleState = dom::AudioChannelService::AudibleState; 58 59 static void ReportDeviceMediaCodecSupported( 60 const media::MediaCodecsSupported& aSupported); 61 62 // State transitions 63 void OnPlay(Visibility aVisibility, MediaContent aContent, bool aIsMuted); 64 void OnPause(Visibility aVisibility); 65 void OnShutdown(); 66 67 void OnVisibilityChanged(Visibility aVisibility); 68 void OnAudibleChanged(AudibleState aAudible); 69 void OnMediaContentChanged(MediaContent aContent); 70 void OnMutedChanged(bool aMuted); 71 72 enum class FirstFrameLoadedFlag { 73 IsMSE, 74 IsExternalEngineStateMachine, 75 IsHLS, 76 IsHardwareDecoding, 77 }; 78 using FirstFrameLoadedFlagSet = EnumSet<FirstFrameLoadedFlag, uint8_t>; 79 void OnFirstFrameLoaded(const double aLoadedFirstFrameTime, 80 const double aLoadedMetadataTime, 81 const double aTotalWaitingDataTime, 82 const double aTotalBufferingTime, 83 const FirstFrameLoadedFlagSet aFlags, 84 const MediaInfo& aInfo, 85 const nsCString& aVideoDecoderName); 86 87 double GetTotalVideoPlayTimeInSeconds() const; 88 double GetTotalVideoHDRPlayTimeInSeconds() const; 89 double GetVisibleVideoPlayTimeInSeconds() const; 90 double GetInvisibleVideoPlayTimeInSeconds() const; 91 92 double GetTotalAudioPlayTimeInSeconds() const; 93 double GetInaudiblePlayTimeInSeconds() const; 94 double GetAudiblePlayTimeInSeconds() const; 95 double GetMutedPlayTimeInSeconds() const; 96 97 private: 98 void StartInvisibleVideoTimeAccumulator(); 99 void PauseInvisibleVideoTimeAccumulator(); 100 void StartInaudibleAudioTimeAccumulator(); 101 void PauseInaudibleAudioTimeAccumulator(); 102 void StartMutedAudioTimeAccumulator(); 103 void PauseMutedAudioTimeAccumulator(); 104 bool HasOwnerHadValidVideo() const; 105 bool HasOwnerHadValidMedia() const; 106 void AssertOnMainThreadAndNotShutdown() const; 107 108 void ReportTelemetry(); 109 void ReportResultForVideo(); 110 void ReportResultForAudio(); 111 void ReportResultForVideoFrameStatistics(double aTotalPlayTimeS, 112 const nsCString& key); 113 #ifdef MOZ_WMF_CDM 114 void ReportResultForMFCDMPlaybackIfNeeded(double aTotalPlayTimeS, 115 const nsCString& aResolution); 116 #endif 117 void ReportPlaytimeForKeySystem(const nsAString& aKeySystem, 118 const double aTotalPlayTimeS, 119 const nsCString& aCodec, 120 const nsCString& aResolution); 121 // Helper class to measure times for playback telemetry stats 122 class TimeDurationAccumulator { 123 public: 124 TimeDurationAccumulator() = default; 125 void Start() { 126 if (IsStarted()) { 127 return; 128 } 129 mStartTime = Some(AwakeTimeStamp::NowLoRes()); 130 } 131 void Pause() { 132 if (!IsStarted()) { 133 return; 134 } 135 mSum = (AwakeTimeStamp::NowLoRes() - mStartTime.value()); 136 mStartTime = Nothing(); 137 } 138 bool IsStarted() const { return mStartTime.isSome(); } 139 140 double GetAndClearTotal() { 141 MOZ_ASSERT(!IsStarted(), "only call this when accumulator is paused"); 142 double total = mSum.ToSeconds(); 143 mStartTime = Nothing(); 144 mSum = AwakeTimeDuration(); 145 return total; 146 } 147 148 double PeekTotal() const { 149 if (!IsStarted()) { 150 return mSum.ToSeconds(); 151 } 152 return (AwakeTimeStamp::NowLoRes() - mStartTime.value()).ToSeconds(); 153 } 154 155 private: 156 Maybe<AwakeTimeStamp> mStartTime; 157 AwakeTimeDuration mSum; 158 }; 159 160 // The owner is HTMLMediaElement that is guaranteed being always alive during 161 // our whole life cycle. 162 TelemetryProbesReporterOwner* mOwner; 163 164 // Total time an element has spent on playing video. 165 TimeDurationAccumulator mTotalVideoPlayTime; 166 167 // Total time an element has spent on playing video that has a color depth 168 // greater than 8, which is likely HDR video. 169 TimeDurationAccumulator mTotalVideoHDRPlayTime; 170 171 // Total time an element has spent on playing audio 172 TimeDurationAccumulator mTotalAudioPlayTime; 173 174 // Total time a VIDEO element has spent playing while the corresponding media 175 // element is invisible. 176 TimeDurationAccumulator mInvisibleVideoPlayTime; 177 178 // Total time an element has spent playing audio that was not audible 179 TimeDurationAccumulator mInaudibleAudioPlayTime; 180 181 // Total time an element with an audio track has spent muted 182 TimeDurationAccumulator mMutedAudioPlayTime; 183 184 Visibility mMediaElementVisibility = Visibility::eInitial; 185 186 MediaContent mMediaContent = MediaContent::MEDIA_HAS_NOTHING; 187 188 bool mIsPlaying = false; 189 190 bool mIsMuted = false; 191 }; 192 193 } // namespace mozilla 194 195 #endif // DOM_TelemetryProbesReporter_H_