FrameStatistics.h (6827B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef FrameStatistics_h_ 8 #define FrameStatistics_h_ 9 10 #include "mozilla/ReentrantMonitor.h" 11 12 namespace mozilla { 13 14 struct FrameStatisticsData { 15 // Number of frames parsed and demuxed from media. 16 // Access protected by mReentrantMonitor. 17 uint64_t mParsedFrames = 0; 18 19 // Number of parsed frames which were actually decoded. 20 // Access protected by mReentrantMonitor. 21 uint64_t mDecodedFrames = 0; 22 23 // Number of parsed frames which were dropped in the decoder. 24 // Access protected by mReentrantMonitor. 25 uint64_t mDroppedDecodedFrames = 0; 26 27 // Number of decoded frames which were dropped in the sink 28 // Access protected by mReentrantMonitor. 29 uint64_t mDroppedSinkFrames = 0; 30 31 // Number of sinked frames which were dropped in the compositor 32 // Access protected by mReentrantMonitor. 33 uint64_t mDroppedCompositorFrames = 0; 34 35 // Number of decoded frames which were actually sent down the rendering 36 // pipeline to be painted ("presented"). Access protected by 37 // mReentrantMonitor. 38 uint64_t mPresentedFrames = 0; 39 40 // Sum of all inter-keyframe segment durations, in microseconds. 41 // Dividing by count will give the average inter-keyframe time. 42 uint64_t mInterKeyframeSum_us = 0; 43 // Number of inter-keyframe segments summed so far. 44 size_t mInterKeyframeCount = 0; 45 46 // Maximum inter-keyframe segment duration, in microseconds. 47 uint64_t mInterKeyFrameMax_us = 0; 48 49 FrameStatisticsData() = default; 50 FrameStatisticsData(uint64_t aParsed, uint64_t aDecoded, uint64_t aPresented, 51 uint64_t aDroppedDecodedFrames, 52 uint64_t aDroppedSinkFrames, 53 uint64_t aDroppedCompositorFrames) 54 : mParsedFrames(aParsed), 55 mDecodedFrames(aDecoded), 56 mDroppedDecodedFrames(aDroppedDecodedFrames), 57 mDroppedSinkFrames(aDroppedSinkFrames), 58 mDroppedCompositorFrames(aDroppedCompositorFrames), 59 mPresentedFrames(aPresented) {} 60 61 void Accumulate(const FrameStatisticsData& aStats) { 62 mParsedFrames += aStats.mParsedFrames; 63 mDecodedFrames += aStats.mDecodedFrames; 64 mPresentedFrames += aStats.mPresentedFrames; 65 mDroppedDecodedFrames += aStats.mDroppedDecodedFrames; 66 mDroppedSinkFrames += aStats.mDroppedSinkFrames; 67 mDroppedCompositorFrames += aStats.mDroppedCompositorFrames; 68 mInterKeyframeSum_us += aStats.mInterKeyframeSum_us; 69 mInterKeyframeCount += aStats.mInterKeyframeCount; 70 // It doesn't make sense to add max numbers, instead keep the bigger one. 71 if (mInterKeyFrameMax_us < aStats.mInterKeyFrameMax_us) { 72 mInterKeyFrameMax_us = aStats.mInterKeyFrameMax_us; 73 } 74 } 75 }; 76 77 // Frame decoding/painting related performance counters. 78 // Threadsafe. 79 class FrameStatistics { 80 public: 81 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FrameStatistics); 82 83 FrameStatistics() : mReentrantMonitor("FrameStats") {} 84 85 // Returns a copy of all frame statistics data. 86 // Can be called on any thread. 87 FrameStatisticsData GetFrameStatisticsData() const { 88 ReentrantMonitorAutoEnter mon(mReentrantMonitor); 89 return mFrameStatisticsData; 90 } 91 92 // Returns number of frames which have been parsed from the media. 93 // Can be called on any thread. 94 uint64_t GetParsedFrames() const { 95 ReentrantMonitorAutoEnter mon(mReentrantMonitor); 96 return mFrameStatisticsData.mParsedFrames; 97 } 98 99 // Returns the number of parsed frames which have been decoded. 100 // Can be called on any thread. 101 uint64_t GetDecodedFrames() const { 102 ReentrantMonitorAutoEnter mon(mReentrantMonitor); 103 return mFrameStatisticsData.mDecodedFrames; 104 } 105 106 // Returns the number of decoded frames which have been sent to the rendering 107 // pipeline for painting ("presented"). 108 // Can be called on any thread. 109 uint64_t GetPresentedFrames() const { 110 ReentrantMonitorAutoEnter mon(mReentrantMonitor); 111 return mFrameStatisticsData.mPresentedFrames; 112 } 113 114 // Returns the number of presented and dropped frames 115 // Can be called on any thread. 116 uint64_t GetTotalFrames() const { 117 ReentrantMonitorAutoEnter mon(mReentrantMonitor); 118 return GetTotalFrames(mFrameStatisticsData); 119 } 120 121 static uint64_t GetTotalFrames(const FrameStatisticsData& aData) { 122 return aData.mPresentedFrames + GetDroppedFrames(aData); 123 } 124 125 // Returns the number of frames that have been skipped because they have 126 // missed their composition deadline. 127 uint64_t GetDroppedFrames() const { 128 ReentrantMonitorAutoEnter mon(mReentrantMonitor); 129 return GetDroppedFrames(mFrameStatisticsData); 130 } 131 132 static uint64_t GetDroppedFrames(const FrameStatisticsData& aData) { 133 return aData.mDroppedDecodedFrames + aData.mDroppedSinkFrames + 134 aData.mDroppedCompositorFrames; 135 } 136 137 uint64_t GetDroppedDecodedFrames() const { 138 ReentrantMonitorAutoEnter mon(mReentrantMonitor); 139 return mFrameStatisticsData.mDroppedDecodedFrames; 140 } 141 142 uint64_t GetDroppedSinkFrames() const { 143 ReentrantMonitorAutoEnter mon(mReentrantMonitor); 144 return mFrameStatisticsData.mDroppedSinkFrames; 145 } 146 147 uint64_t GetDroppedCompositorFrames() const { 148 ReentrantMonitorAutoEnter mon(mReentrantMonitor); 149 return mFrameStatisticsData.mDroppedCompositorFrames; 150 } 151 152 // Increments the parsed and decoded frame counters by the passed in counts. 153 // Can be called on any thread. 154 void Accumulate(const FrameStatisticsData& aStats) { 155 ReentrantMonitorAutoEnter mon(mReentrantMonitor); 156 mFrameStatisticsData.Accumulate(aStats); 157 } 158 159 // Increments the presented frame counters. 160 // Can be called on any thread. 161 void NotifyPresentedFrame() { 162 ReentrantMonitorAutoEnter mon(mReentrantMonitor); 163 ++mFrameStatisticsData.mPresentedFrames; 164 } 165 166 // Stack based class to assist in notifying the frame statistics of 167 // parsed and decoded frames. Use inside video demux & decode functions 168 // to ensure all parsed and decoded frames are reported on all return paths. 169 class AutoNotifyDecoded { 170 public: 171 explicit AutoNotifyDecoded(FrameStatistics* aFrameStats) 172 : mFrameStats(aFrameStats) {} 173 ~AutoNotifyDecoded() { 174 if (mFrameStats) { 175 mFrameStats->Accumulate(mStats); 176 } 177 } 178 179 FrameStatisticsData mStats; 180 181 private: 182 FrameStatistics* mFrameStats; 183 }; 184 185 private: 186 ~FrameStatistics() = default; 187 188 // ReentrantMonitor to protect access of playback statistics. 189 mutable ReentrantMonitor mReentrantMonitor MOZ_UNANNOTATED; 190 191 FrameStatisticsData mFrameStatisticsData; 192 }; 193 194 } // namespace mozilla 195 196 #endif // FrameStatistics_h_