LCOV - code coverage report
Current view: top level - dom/media - Latency.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 14 92 15.2 %
Date: 2017-07-14 16:53:18 Functions: 4 28 14.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim:set ts=2 sw=2 sts=2 et cindent: */
       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             : #include "Latency.h"
       8             : #include "nsThreadUtils.h"
       9             : #include "mozilla/Logging.h"
      10             : #include <cmath>
      11             : #include <algorithm>
      12             : 
      13             : #include <mozilla/Services.h>
      14             : #include <mozilla/StaticPtr.h>
      15             : #include "nsContentUtils.h"
      16             : 
      17             : using namespace mozilla;
      18             : 
      19             : const char* LatencyLogIndex2Strings[] = {
      20             :   "Audio MediaStreamTrack",
      21             :   "Video MediaStreamTrack",
      22             :   "Cubeb",
      23             :   "AudioStream",
      24             :   "NetEQ",
      25             :   "AudioCapture Base",
      26             :   "AudioCapture Samples",
      27             :   "AudioTrackInsertion",
      28             :   "MediaPipeline Audio Insertion",
      29             :   "AudioTransmit",
      30             :   "AudioReceive",
      31             :   "MediaPipelineAudioPlayout",
      32             :   "MediaStream Create",
      33             :   "AudioStream Create",
      34             :   "AudioSendRTP",
      35             :   "AudioRecvRTP"
      36             : };
      37             : 
      38           3 : static StaticRefPtr<AsyncLatencyLogger> gAsyncLogger;
      39             : 
      40             : LogModule*
      41           3 : GetLatencyLog()
      42             : {
      43             :   static LazyLogModule sLog("MediaLatency");
      44           3 :   return sLog;
      45             : }
      46             : 
      47             : class LogEvent : public Runnable
      48             : {
      49             : public:
      50           0 :   LogEvent(AsyncLatencyLogger::LatencyLogIndex aIndex,
      51             :            uint64_t aID,
      52             :            int64_t aValue,
      53             :            TimeStamp aTimeStamp)
      54           0 :     : mozilla::Runnable("LogEvent")
      55             :     , mIndex(aIndex)
      56             :     , mID(aID)
      57             :     , mValue(aValue)
      58           0 :     , mTimeStamp(aTimeStamp)
      59           0 :   {}
      60             :   LogEvent(AsyncLatencyLogger::LatencyLogIndex aIndex,
      61             :            uint64_t aID,
      62             :            int64_t aValue)
      63             :     : mozilla::Runnable("LogEvent")
      64             :     , mIndex(aIndex)
      65             :     , mID(aID)
      66             :     , mValue(aValue)
      67             :     , mTimeStamp(TimeStamp())
      68             :   {}
      69           0 :   ~LogEvent() {}
      70             : 
      71           0 :   NS_IMETHOD Run() override {
      72           0 :     AsyncLatencyLogger::Get(true)->WriteLog(mIndex, mID, mValue, mTimeStamp);
      73           0 :     return NS_OK;
      74             :   }
      75             : 
      76             : protected:
      77             :   AsyncLatencyLogger::LatencyLogIndex mIndex;
      78             :   uint64_t mID;
      79             :   int64_t mValue;
      80             :   TimeStamp mTimeStamp;
      81             : };
      82             : 
      83           0 : void LogLatency(AsyncLatencyLogger::LatencyLogIndex aIndex, uint64_t aID, int64_t aValue)
      84             : {
      85           0 :   AsyncLatencyLogger::Get()->Log(aIndex, aID, aValue);
      86           0 : }
      87             : 
      88           0 : void LogTime(AsyncLatencyLogger::LatencyLogIndex aIndex, uint64_t aID, int64_t aValue)
      89             : {
      90           0 :   TimeStamp now = TimeStamp::Now();
      91           0 :   AsyncLatencyLogger::Get()->Log(aIndex, aID, aValue, now);
      92           0 : }
      93             : 
      94           0 : void LogTime(AsyncLatencyLogger::LatencyLogIndex aIndex, uint64_t aID, int64_t aValue, TimeStamp &aTime)
      95             : {
      96           0 :   AsyncLatencyLogger::Get()->Log(aIndex, aID, aValue, aTime);
      97           0 : }
      98             : 
      99           0 : void LogTime(uint32_t aIndex, uint64_t aID, int64_t aValue)
     100             : {
     101           0 :   LogTime(static_cast<AsyncLatencyLogger::LatencyLogIndex>(aIndex), aID, aValue);
     102           0 : }
     103           0 : void LogTime(uint32_t aIndex, uint64_t aID, int64_t aValue, TimeStamp &aTime)
     104             : {
     105           0 :   LogTime(static_cast<AsyncLatencyLogger::LatencyLogIndex>(aIndex), aID, aValue, aTime);
     106           0 : }
     107           0 : void LogLatency(uint32_t aIndex, uint64_t aID, int64_t aValue)
     108             : {
     109           0 :   LogLatency(static_cast<AsyncLatencyLogger::LatencyLogIndex>(aIndex), aID, aValue);
     110           0 : }
     111             : 
     112             : /* static */
     113           3 : void AsyncLatencyLogger::InitializeStatics()
     114             : {
     115           3 :   NS_ASSERTION(NS_IsMainThread(), "Main thread only");
     116             : 
     117             :   //Make sure that the underlying logger is allocated.
     118           3 :   GetLatencyLog();
     119           3 :   gAsyncLogger = new AsyncLatencyLogger();
     120           3 : }
     121             : 
     122             : /* static */
     123           0 : void AsyncLatencyLogger::ShutdownLogger()
     124             : {
     125           0 :   gAsyncLogger = nullptr;
     126           0 : }
     127             : 
     128             : /* static */
     129           0 : AsyncLatencyLogger* AsyncLatencyLogger::Get(bool aStartTimer)
     130             : {
     131             :   // Users don't generally null-check the result since we should live longer than they
     132           0 :   MOZ_ASSERT(gAsyncLogger);
     133             : 
     134           0 :   if (aStartTimer) {
     135           0 :     gAsyncLogger->Init();
     136             :   }
     137           0 :   return gAsyncLogger;
     138             : }
     139             : 
     140           6 : NS_IMPL_ISUPPORTS(AsyncLatencyLogger, nsIObserver)
     141             : 
     142           3 : AsyncLatencyLogger::AsyncLatencyLogger()
     143             :   : mThread(nullptr),
     144           3 :     mMutex("AsyncLatencyLogger")
     145             : {
     146           3 :   NS_ASSERTION(NS_IsMainThread(), "Main thread only");
     147           3 :   nsContentUtils::RegisterShutdownObserver(this);
     148           3 : }
     149             : 
     150           0 : AsyncLatencyLogger::~AsyncLatencyLogger()
     151             : {
     152           0 :   AsyncLatencyLogger::Shutdown();
     153           0 : }
     154             : 
     155           0 : void AsyncLatencyLogger::Shutdown()
     156             : {
     157           0 :   nsContentUtils::UnregisterShutdownObserver(this);
     158             : 
     159           0 :   MutexAutoLock lock(mMutex);
     160           0 :   if (mThread) {
     161           0 :     mThread->Shutdown();
     162             :   }
     163           0 :   mStart = TimeStamp(); // make sure we don't try to restart it for any reason
     164           0 : }
     165             : 
     166           0 : void AsyncLatencyLogger::Init()
     167             : {
     168           0 :   MutexAutoLock lock(mMutex);
     169           0 :   if (mStart.IsNull()) {
     170           0 :     nsresult rv = NS_NewNamedThread("Latency Logger", getter_AddRefs(mThread));
     171           0 :     NS_ENSURE_SUCCESS_VOID(rv);
     172           0 :     mStart = TimeStamp::Now();
     173             :   }
     174             : }
     175             : 
     176           0 : void AsyncLatencyLogger::GetStartTime(TimeStamp &aStart)
     177             : {
     178           0 :   MutexAutoLock lock(mMutex);
     179           0 :   aStart = mStart;
     180           0 : }
     181             : 
     182             : nsresult
     183           0 : AsyncLatencyLogger::Observe(nsISupports* aSubject, const char* aTopic,
     184             :                             const char16_t* aData)
     185             : {
     186           0 :   MOZ_ASSERT(NS_IsMainThread());
     187           0 :   if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
     188           0 :     Shutdown();
     189             :   }
     190           0 :   return NS_OK;
     191             : }
     192             : 
     193             : // aID is a sub-identifier (in particular a specific MediaStramTrack)
     194           0 : void AsyncLatencyLogger::WriteLog(LatencyLogIndex aIndex, uint64_t aID, int64_t aValue,
     195             :                                   TimeStamp aTimeStamp)
     196             : {
     197           0 :   if (aTimeStamp.IsNull()) {
     198           0 :     MOZ_LOG(GetLatencyLog(), LogLevel::Debug,
     199             :       ("Latency: %s,%" PRIu64 ",%" PRId64 ",%" PRId64,
     200             :        LatencyLogIndex2Strings[aIndex], aID, GetTimeStamp(), aValue));
     201             :   } else {
     202           0 :     MOZ_LOG(GetLatencyLog(), LogLevel::Debug,
     203             :       ("Latency: %s,%" PRIu64 ",%" PRId64 ",%" PRId64 ",%" PRId64,
     204             :        LatencyLogIndex2Strings[aIndex], aID, GetTimeStamp(), aValue,
     205             :        static_cast<int64_t>((aTimeStamp - gAsyncLogger->mStart).ToMilliseconds())));
     206             :   }
     207           0 : }
     208             : 
     209           0 : int64_t AsyncLatencyLogger::GetTimeStamp()
     210             : {
     211           0 :   TimeDuration t = TimeStamp::Now() - mStart;
     212           0 :   return t.ToMilliseconds();
     213             : }
     214             : 
     215           0 : void AsyncLatencyLogger::Log(LatencyLogIndex aIndex, uint64_t aID, int64_t aValue)
     216             : {
     217           0 :   TimeStamp null;
     218           0 :   Log(aIndex, aID, aValue, null);
     219           0 : }
     220             : 
     221           0 : void AsyncLatencyLogger::Log(LatencyLogIndex aIndex, uint64_t aID, int64_t aValue, TimeStamp &aTime)
     222             : {
     223           0 :   if (MOZ_LOG_TEST(GetLatencyLog(), LogLevel::Debug)) {
     224           0 :     nsCOMPtr<nsIRunnable> event = new LogEvent(aIndex, aID, aValue, aTime);
     225           0 :     if (mThread) {
     226           0 :       mThread->Dispatch(event, NS_DISPATCH_NORMAL);
     227             :     }
     228             :   }
     229           0 : }

Generated by: LCOV version 1.13