Bug 1516660 - Add pattern encryption params to GMP IPDL and plumb to the CDM. r=cpearce
authorBryce Van Dyk <bvandyk@mozilla.com>
Mon, 14 Jan 2019 20:24:57 +0000
changeset 453808 36ec37a680354b2a1fb3b2232f24a65172d71962
parent 453807 1cf230625662499e8c2d0315cfa9d7cd161e1a48
child 453809 c036c740fbbc3e0fb8a4270ef029aaa160d30c9a
push id35374
push usercbrindusan@mozilla.com
push dateTue, 15 Jan 2019 04:37:11 +0000
treeherdermozilla-central@a01a559aa611 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce
bugs1516660
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1516660 - Add pattern encryption params to GMP IPDL and plumb to the CDM. r=cpearce Note, we only pass the relevant IV across the IPC boundry. I.e. if the crypto scheme is cenc we do not pass a constant IV (this is only used by cbcs), and only pass per sample IVs. For cbcs we do the converse. This means in the CDM child we're only receiving one IV, which should be appropriate for whatever scheme (this is similar to how Chromium handle IVs being passed to the CDM). The CDM child side now writes pattern information to samples it's preparing for CDM. With these changes we should be passing all the information required to handle cbcs to the CDM. Differential Revision: https://phabricator.services.mozilla.com/D16459
dom/media/gmp/ChromiumCDMChild.cpp
dom/media/gmp/ChromiumCDMParent.cpp
dom/media/gmp/GMPTypes.ipdlh
--- a/dom/media/gmp/ChromiumCDMChild.cpp
+++ b/dom/media/gmp/ChromiumCDMChild.cpp
@@ -570,36 +570,38 @@ static cdm::EncryptionScheme ConvertToCd
 
 static void InitInputBuffer(const CDMInputBuffer& aBuffer,
                             nsTArray<cdm::SubsampleEntry>& aSubSamples,
                             cdm::InputBuffer_2& aInputBuffer) {
   aInputBuffer.data = aBuffer.mData().get<uint8_t>();
   aInputBuffer.data_size = aBuffer.mData().Size<uint8_t>();
 
   if (aBuffer.mEncryptionScheme() > GMPEncryptionScheme::kGMPEncryptionNone) {
-    // Cbcs is not yet supported, so we expect only cenc if the buffer us
-    // encrypted
     MOZ_ASSERT(aBuffer.mEncryptionScheme() ==
-               GMPEncryptionScheme::kGMPEncryptionCenc);
+                   GMPEncryptionScheme::kGMPEncryptionCenc ||
+               aBuffer.mEncryptionScheme() ==
+                   GMPEncryptionScheme::kGMPEncryptionCbcs);
     aInputBuffer.key_id = aBuffer.mKeyId().Elements();
     aInputBuffer.key_id_size = aBuffer.mKeyId().Length();
 
     aInputBuffer.iv = aBuffer.mIV().Elements();
     aInputBuffer.iv_size = aBuffer.mIV().Length();
 
     aSubSamples.SetCapacity(aBuffer.mClearBytes().Length());
     for (size_t i = 0; i < aBuffer.mCipherBytes().Length(); i++) {
       aSubSamples.AppendElement(cdm::SubsampleEntry{aBuffer.mClearBytes()[i],
                                                     aBuffer.mCipherBytes()[i]});
     }
     aInputBuffer.subsamples = aSubSamples.Elements();
     aInputBuffer.num_subsamples = aSubSamples.Length();
     aInputBuffer.encryption_scheme =
         ConvertToCdmEncryptionScheme(aBuffer.mEncryptionScheme());
   }
+  aInputBuffer.pattern.crypt_byte_block = aBuffer.mCryptByteBlock();
+  aInputBuffer.pattern.skip_byte_block = aBuffer.mSkipByteBlock();
   aInputBuffer.timestamp = aBuffer.mTimestamp();
 }
 
 bool ChromiumCDMChild::HasShmemOfSize(size_t aSize) const {
   for (const ipc::Shmem& shmem : mBuffers) {
     if (shmem.Size<uint8_t>() == aSize) {
       return true;
     }
--- a/dom/media/gmp/ChromiumCDMParent.cpp
+++ b/dom/media/gmp/ChromiumCDMParent.cpp
@@ -259,25 +259,33 @@ bool ChromiumCDMParent::InitCDMInputBuff
     default:
       GMP_LOG(
           "InitCDMInputBuffer got unexpected encryption scheme with "
           "value of %" PRIu8 ". Treating as no encryption.",
           static_cast<uint8_t>(crypto.mCryptoScheme));
       MOZ_ASSERT_UNREACHABLE("Should not have unrecognized encryption type");
       break;
   }
+
+  const nsTArray<uint8_t>& iv =
+      encryptionScheme != GMPEncryptionScheme::kGMPEncryptionCbcs
+          ? crypto.mIV
+          : crypto.mConstantIV;
   aBuffer = gmp::CDMInputBuffer(
-      shmem, crypto.mKeyId, crypto.mIV, aSample->mTime.ToMicroseconds(),
+      shmem, crypto.mKeyId, iv, aSample->mTime.ToMicroseconds(),
       aSample->mDuration.ToMicroseconds(), crypto.mPlainSizes,
-      crypto.mEncryptedSizes, encryptionScheme);
+      crypto.mEncryptedSizes, crypto.mCryptByteBlock, crypto.mSkipByteBlock,
+      encryptionScheme);
   MOZ_ASSERT(
       aBuffer.mEncryptionScheme() == GMPEncryptionScheme::kGMPEncryptionNone ||
           aBuffer.mEncryptionScheme() ==
-              GMPEncryptionScheme::kGMPEncryptionCenc,
-      "aBuffer should use either no encryption or cenc, other kinds are not "
+              GMPEncryptionScheme::kGMPEncryptionCenc ||
+          aBuffer.mEncryptionScheme() ==
+              GMPEncryptionScheme::kGMPEncryptionCbcs,
+      "aBuffer should use no encryption, cenc, or cbcs, other kinds are not "
       "yet supported");
   return true;
 }
 
 bool ChromiumCDMParent::SendBufferToCDM(uint32_t aSizeInBytes) {
   GMP_LOG("ChromiumCDMParent::SendBufferToCDM() size=%" PRIu32, aSizeInBytes);
   Shmem shmem;
   if (!AllocShmem(aSizeInBytes, Shmem::SharedMemory::TYPE_BASIC, &shmem)) {
--- a/dom/media/gmp/GMPTypes.ipdlh
+++ b/dom/media/gmp/GMPTypes.ipdlh
@@ -51,16 +51,18 @@ struct GMPVideoi420FrameData
 struct CDMInputBuffer {
   Shmem mData;
   uint8_t[] mKeyId;
   uint8_t[] mIV;
   int64_t mTimestamp;
   int64_t mDuration;
   uint16_t[] mClearBytes;
   uint32_t[] mCipherBytes;
+  uint8_t mCryptByteBlock;
+  uint8_t mSkipByteBlock;
   GMPEncryptionScheme mEncryptionScheme;
 };
 
 struct CDMVideoDecoderConfig {
   uint32_t mCodec;
   uint32_t mProfile;
   uint32_t mFormat;
   int32_t mImageWidth;