LCOV - code coverage report
Current view: top level - dom/media/platforms/agnostic/eme - DecryptThroughputLimit.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 36 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 9 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 file,
       5             :  * You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef DecryptThroughputLimit_h
       8             : #define DecryptThroughputLimit_h
       9             : 
      10             : #include "PlatformDecoderModule.h"
      11             : #include "MediaTimer.h"
      12             : #include <deque>
      13             : 
      14             : namespace mozilla {
      15             : 
      16             : // We throttle our decrypt so that we don't decrypt more than a certain
      17             : // duration of samples per second. This is to work around bugs in the
      18             : // Widevine CDM. See bug 1338924 and bug 1342822.
      19           0 : class DecryptThroughputLimit
      20             : {
      21             : public:
      22             : 
      23           0 :   explicit DecryptThroughputLimit(AbstractThread* aTargetThread)
      24           0 :     : mThrottleScheduler(aTargetThread)
      25             :   {
      26           0 :   }
      27             : 
      28             :   typedef MozPromise<RefPtr<MediaRawData>, MediaResult, true> ThrottlePromise;
      29             : 
      30             :   // Resolves promise after a delay if necessary in order to reduce the
      31             :   // throughput of samples sent through the CDM for decryption.
      32             :   RefPtr<ThrottlePromise>
      33           0 :   Throttle(MediaRawData* aSample)
      34             :   {
      35             :     // We should only have one decrypt request being processed at once.
      36           0 :     MOZ_RELEASE_ASSERT(!mThrottleScheduler.IsScheduled());
      37             : 
      38           0 :     const TimeDuration WindowSize = TimeDuration::FromSeconds(1.0);
      39           0 :     const TimeDuration MaxThroughput = TimeDuration::FromSeconds(2.0);
      40             : 
      41             :     // Forget decrypts that happened before the start of our window.
      42           0 :     const TimeStamp now = TimeStamp::Now();
      43           0 :     while (!mDecrypts.empty() && mDecrypts.front().mTimestamp < now - WindowSize) {
      44           0 :       mDecrypts.pop_front();
      45             :     }
      46             : 
      47             :     // How much time duration of the media would we have decrypted inside the
      48             :     // time window if we did decrypt this block?
      49           0 :     TimeDuration sampleDuration = aSample->mDuration.ToTimeDuration();
      50           0 :     TimeDuration durationDecrypted = sampleDuration;
      51           0 :     for (const DecryptedJob& job : mDecrypts) {
      52           0 :       durationDecrypted += job.mSampleDuration;
      53             :     }
      54             : 
      55           0 :     if (durationDecrypted < MaxThroughput) {
      56             :       // If we decrypted a sample of this duration, we would *not* have
      57             :       // decrypted more than our threshold for max throughput, over the
      58             :       // preceding wall time window. So we're safe to proceed with this
      59             :       // decrypt.
      60           0 :       mDecrypts.push_back(DecryptedJob({ now, sampleDuration }));
      61           0 :       return ThrottlePromise::CreateAndResolve(aSample, __func__);
      62             :     }
      63             : 
      64             :     // Otherwise, we need to delay until decrypting won't exceed our
      65             :     // throughput threshold.
      66             : 
      67           0 :     RefPtr<ThrottlePromise> p = mPromiseHolder.Ensure(__func__);
      68             : 
      69           0 :     TimeDuration delay = durationDecrypted - MaxThroughput;
      70           0 :     TimeStamp target = now + delay;
      71           0 :     RefPtr<MediaRawData> sample(aSample);
      72           0 :     mThrottleScheduler.Ensure(target,
      73           0 :       [this, sample, sampleDuration]() {
      74           0 :         mThrottleScheduler.CompleteRequest();
      75           0 :         mDecrypts.push_back(DecryptedJob({ TimeStamp::Now(), sampleDuration }));
      76           0 :         mPromiseHolder.Resolve(sample, __func__);
      77           0 :       },
      78           0 :       [] () {
      79           0 :         MOZ_DIAGNOSTIC_ASSERT(false);
      80           0 :       });
      81             : 
      82           0 :     return p;
      83             :   }
      84             : 
      85             :   void
      86           0 :   Flush()
      87             :   {
      88           0 :     mThrottleScheduler.Reset();
      89           0 :     mPromiseHolder.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
      90           0 :   }
      91             : 
      92             : private:
      93             :   DelayedScheduler mThrottleScheduler;
      94             :   MozPromiseHolder<ThrottlePromise> mPromiseHolder;
      95             : 
      96             :   struct DecryptedJob
      97             :   {
      98             :     TimeStamp mTimestamp;
      99             :     TimeDuration mSampleDuration;
     100             :   };
     101             :   std::deque<DecryptedJob> mDecrypts;
     102             : };
     103             : 
     104             : }
     105             : 
     106             : #endif // DecryptThroughputLimit_h

Generated by: LCOV version 1.13