tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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_