Bug 1342822 - Backed out changeset a379d64f8496 (Bug 1338924 patch 3). r=gerald

MozReview-Commit-ID: 4aFx52mwpQ6

--HG--
extra : rebase_source : 45cfb3aba27e93d49c5ebf64510d0143f1c57654
This commit is contained in:
Chris Pearce 2017-02-27 13:57:39 +13:00
Родитель 941b2b29b9
Коммит 892e18f12e
2 изменённых файлов: 5 добавлений и 137 удалений

Просмотреть файл

@ -8,9 +8,7 @@
#include "WidevineAdapter.h"
#include "WidevineUtils.h"
#include "WidevineFileIO.h"
#include "GMPPlatform.h"
#include <stdarg.h>
#include "TimeUnits.h"
using namespace cdm;
using namespace std;
@ -160,33 +158,6 @@ WidevineDecryptor::SetServerCertificate(uint32_t aPromiseId,
CDM()->SetServerCertificate(aPromiseId, aServerCert, aServerCertSize);
}
cdm::Time
WidevineDecryptor::ThrottleDecrypt(cdm::Time aWallTime, cdm::Time aSampleDuration)
{
const cdm::Time WindowSize = 1.0;
const cdm::Time MaxThroughput = 2.0;
// Forget decrypts that happened before the start of our window.
while (!mDecrypts.empty() && mDecrypts.front().mWallTime < aWallTime - WindowSize) {
mDecrypts.pop_front();
}
// How much time duration of the media would we have decrypted inside the
// time window if we did decrypt this block?
cdm::Time durationDecrypted = aSampleDuration;
for (const DecryptJob& job : mDecrypts) {
durationDecrypted += job.mSampleDuration;
}
if (durationDecrypted > MaxThroughput) {
// If we decrypted a sample of this duration, we would have decrypted more than
// our threshold for max throughput, over the preceding wall time window.
return durationDecrypted - MaxThroughput;
}
return 0.0;
}
void
WidevineDecryptor::Decrypt(GMPBuffer* aBuffer,
GMPEncryptedBufferMetadata* aMetadata,
@ -196,72 +167,21 @@ WidevineDecryptor::Decrypt(GMPBuffer* aBuffer,
CDM_LOG("WidevineDecryptor::Decrypt() this=%p FAIL; !mCallback", this);
return;
}
cdm::Time duration = double(aDurationUsecs) / USECS_PER_S;
mPendingDecrypts.push({aBuffer, aMetadata, duration});
ProcessDecrypts();
}
void
WidevineDecryptor::ProcessDecryptsFromTimer()
{
MOZ_ASSERT(mPendingDecryptTimerSet);
mPendingDecryptTimerSet = false;
ProcessDecrypts();
}
void
WidevineDecryptor::ProcessDecrypts()
{
while (!mPendingDecrypts.empty()) {
PendingDecrypt job = mPendingDecrypts.front();
// We throttle our decrypt so that we don't decrypt more than a certain
// duration of samples per second. This is to work around bugs in the
// Widevine CDM. See bug 1338924.
cdm::Time now = GetCurrentWallTime();
cdm::Time delay = ThrottleDecrypt(now, job.mSampleDuration);
if (delay > 0.0) {
// If we decrypted this sample now, we'd decrypt more than our threshold
// per second of samples. Enqueue the sample, and wait until we'd be able
// to decrypt it without breaking our throughput threshold.
if (!mPendingDecryptTimerSet) {
mPendingDecryptTimerSet = true;
RefPtr<WidevineDecryptor> self = this;
GMPTask* task = gmp::NewGMPTask(
[self]() {
self->ProcessDecryptsFromTimer();
});
gmp::SetTimerOnMainThread(task, delay * 1000);
}
return;
}
DecryptBuffer(job);
mDecrypts.push_back(DecryptJob(now, job.mSampleDuration));
mPendingDecrypts.pop();
}
}
void
WidevineDecryptor::DecryptBuffer(const PendingDecrypt& aJob)
{
GMPBuffer* buffer = aJob.mBuffer;
const GMPEncryptedBufferMetadata* crypto = aJob.mMetadata;
const GMPEncryptedBufferMetadata* crypto = aMetadata;
InputBuffer sample;
nsTArray<SubsampleEntry> subsamples;
InitInputBuffer(crypto, buffer->Id(), buffer->Data(), buffer->Size(), sample, subsamples);
InitInputBuffer(crypto, aBuffer->Id(), aBuffer->Data(), aBuffer->Size(), sample, subsamples);
WidevineDecryptedBlock decrypted;
Status rv = CDM()->Decrypt(sample, &decrypted);
CDM_LOG("Decryptor::Decrypt(timestamp=%" PRId64 ") rv=%d sz=%d",
sample.timestamp, rv, decrypted.DecryptedBuffer()->Size());
if (rv == kSuccess) {
buffer->Resize(decrypted.DecryptedBuffer()->Size());
memcpy(buffer->Data(),
aBuffer->Resize(decrypted.DecryptedBuffer()->Size());
memcpy(aBuffer->Data(),
decrypted.DecryptedBuffer()->Data(),
decrypted.DecryptedBuffer()->Size());
}
mCallback->Decrypted(buffer, ToGMPErr(rv));
mCallback->Decrypted(aBuffer, ToGMPErr(rv));
}
void
@ -269,16 +189,6 @@ WidevineDecryptor::DecryptingComplete()
{
CDM_LOG("WidevineDecryptor::DecryptingComplete() this=%p, instanceId=%u",
this, mInstanceId);
// Ensure buffers are freed.
while (!mPendingDecrypts.empty()) {
PendingDecrypt& job = mPendingDecrypts.front();
if (mCallback) {
mCallback->Decrypted(job.mBuffer, GMPAbortedErr);
}
mPendingDecrypts.pop();
}
// Drop our references to the CDMWrapper. When any other references
// held elsewhere are dropped (for example references held by a
// WidevineVideoDecoder, or a runnable), the CDMWrapper destroys

Просмотреть файл

@ -12,8 +12,6 @@
#include "mozilla/RefPtr.h"
#include "WidevineUtils.h"
#include <map>
#include <deque>
#include <queue>
namespace mozilla {
@ -121,45 +119,6 @@ public:
GMPDecryptorCallback* Callback() const { return mCallback; }
RefPtr<CDMWrapper> GetCDMWrapper() const { return mCDM; }
private:
struct PendingDecrypt
{
PendingDecrypt(GMPBuffer* aBuffer,
GMPEncryptedBufferMetadata* aMetadata,
cdm::Time aSampleDuration)
: mBuffer(aBuffer)
, mMetadata(aMetadata)
, mSampleDuration(aSampleDuration)
{
}
GMPBuffer* mBuffer;
GMPEncryptedBufferMetadata* mMetadata;
cdm::Time mSampleDuration;
};
// Queue of buffers waiting to be decrypted.
std::queue<PendingDecrypt> mPendingDecrypts;
void DecryptBuffer(const PendingDecrypt& aJob);
cdm::Time ThrottleDecrypt(cdm::Time aWallClock, cdm::Time aSampleDuration);
void ProcessDecrypts();
void ProcessDecryptsFromTimer();
struct DecryptJob
{
DecryptJob(cdm::Time aWallTime, cdm::Time aSampleDuration)
: mWallTime(aWallTime)
, mSampleDuration(aSampleDuration)
{}
cdm::Time mWallTime;
cdm::Time mSampleDuration;
};
// Queue of durations of buffers that have been decrypted, along with the
// wall-clock timestamp when they were decrypted. This enables us to
// throttle the throughput against the wall-clock.
std::deque<DecryptJob> mDecrypts;
~WidevineDecryptor();
RefPtr<CDMWrapper> mCDM;
cdm::ContentDecryptionModule_8* CDM() { return mCDM->GetCDM(); }
@ -169,7 +128,6 @@ private:
bool mDistinctiveIdentifierRequired = false;
bool mPersistentStateRequired = false;
uint32_t mInstanceId = 0;
bool mPendingDecryptTimerSet = false;
};
} // namespace mozilla