Backed out changeset 0b8bf5cb743f (bug 1358373) for build bustage. a=backout
authorIris Hsiao <ihsiao@mozilla.com>
Thu, 27 Apr 2017 10:10:47 +0800
changeset 355253 68532b7b6ca56db4250ebca9f979398ef47a9b78
parent 355252 6208b116de638c1466bc5fd381f20117e6fce77b
child 355254 5ab8cf2eca5f858f43af05653f1bda2278c816d2
push id31724
push userkwierso@gmail.com
push dateThu, 27 Apr 2017 19:44:12 +0000
treeherdermozilla-central@ffdedb9c5aad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1358373
milestone55.0a1
backs out0b8bf5cb743f4b6da71aa03b456aa551d6b96d4f
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
Backed out changeset 0b8bf5cb743f (bug 1358373) for build bustage. a=backout CLOSED TREE
dom/media/gmp/ChromiumCDMChild.cpp
dom/media/gmp/ChromiumCDMParent.cpp
dom/media/gmp/ChromiumCDMParent.h
dom/media/gmp/GMPTypes.ipdlh
dom/media/gmp/PChromiumCDM.ipdl
dom/media/gmp/widevine-adapter/WidevineUtils.h
modules/libpref/init/all.js
testing/profiles/prefs_general.js
--- a/dom/media/gmp/ChromiumCDMChild.cpp
+++ b/dom/media/gmp/ChromiumCDMChild.cpp
@@ -40,39 +40,28 @@ ChromiumCDMChild::TimerExpired(void* aCo
 {
   MOZ_ASSERT(IsOnMessageLoopThread());
   GMP_LOG("ChromiumCDMChild::TimerExpired(context=0x%p)", aContext);
   if (mCDM) {
     mCDM->TimerExpired(aContext);
   }
 }
 
-class CDMShmemBuffer : public CDMBuffer
+class CDMShmemBuffer : public cdm::Buffer
 {
 public:
   CDMShmemBuffer(ChromiumCDMChild* aProtocol, ipc::Shmem aShmem)
     : mProtocol(aProtocol)
     , mSize(aShmem.Size<uint8_t>())
     , mShmem(aShmem)
   {
     CDM_LOG("CDMShmemBuffer(size=%" PRIu32 ") created", Size());
     // Note: Chrome initializes the size of a buffer to it capacity. We do the same.
   }
 
-  CDMShmemBuffer(ChromiumCDMChild* aProtocol,
-                 ipc::Shmem aShmem,
-                 WidevineBuffer* aLocalBuffer)
-    : CDMShmemBuffer(aProtocol, aShmem)
-  {
-    MOZ_ASSERT(aLocalBuffer->Size() == Size());
-    memcpy(Data(),
-           aLocalBuffer->Data(),
-           std::min<uint32_t>(aLocalBuffer->Size(), Size()));
-  }
-
   ~CDMShmemBuffer() override
   {
     CDM_LOG("CDMShmemBuffer(size=%" PRIu32 ") destructed writable=%d",
             Size(),
             mShmem.IsWritable());
     if (mShmem.IsWritable()) {
       // The shmem wasn't extracted to send its data back up to the parent process,
       // so we can reuse the shmem.
@@ -103,18 +92,16 @@ public:
 
   ipc::Shmem ExtractShmem()
   {
     ipc::Shmem shmem = mShmem;
     mShmem = ipc::Shmem();
     return shmem;
   }
 
-  CDMShmemBuffer* AsShmemBuffer() override { return this; }
-
 private:
   RefPtr<ChromiumCDMChild> mProtocol;
   uint32_t mSize;
   mozilla::ipc::Shmem mShmem;
   CDMShmemBuffer(const CDMShmemBuffer&);
   void operator=(const CDMShmemBuffer&);
 };
 
@@ -151,20 +138,19 @@ ChromiumCDMChild::Allocate(uint32_t aCap
   for (size_t i = 0; i < mBuffers.Length(); i++) {
     if (mBuffers[i].Size<uint8_t>() >= aCapacity &&
         (best == invalid || wastedSpace(i) < wastedSpace(best))) {
       best = i;
     }
   }
   if (best == invalid) {
     // The parent process should have bestowed upon us a shmem of appropriate
-    // size, but did not! Do a "dive and catch", and create an non-shared
-    // memory buffer. The parent will detect this and send us an extra shmem
-    // so future frames can be in shmems, i.e. returned on the fast path.
-    return new WidevineBuffer(aCapacity);
+    // size, but did not!
+    MOZ_ASSERT(false);
+    return nullptr;
   }
   ipc::Shmem shmem = mBuffers[best];
   mBuffers.RemoveElementAt(best);
   return new CDMShmemBuffer(this, shmem);
 }
 
 void
 ChromiumCDMChild::SetTimer(int64_t aDelayMs, void* aContext)
@@ -580,19 +566,18 @@ ChromiumCDMChild::RecvDecrypt(const uint
   InitInputBuffer(aBuffer, subsamples, input);
 
   WidevineDecryptedBlock output;
   cdm::Status status = mCDM->Decrypt(input, &output);
 
   // CDM should have allocated a cdm::Buffer for output.
   CDMShmemBuffer* buffer =
     output.DecryptedBuffer()
-      ? static_cast<CDMShmemBuffer*>(output.DecryptedBuffer())
+      ? reinterpret_cast<CDMShmemBuffer*>(output.DecryptedBuffer())
       : nullptr;
-  MOZ_ASSERT(buffer->AsShmemBuffer());
   if (status != cdm::kSuccess || !buffer) {
     Unused << SendDecryptFailed(aId, status);
     return IPC_OK();
   }
 
   // Success! Return the decrypted sample to parent.
   MOZ_ASSERT(!HasShmemOfSize(outputShmemSize));
   ipc::Shmem shmem = buffer->ExtractShmem();
@@ -660,16 +645,17 @@ ChromiumCDMChild::RecvResetVideoDecoder(
 
 mozilla::ipc::IPCResult
 ChromiumCDMChild::RecvDecryptAndDecodeFrame(const CDMInputBuffer& aBuffer)
 {
   MOZ_ASSERT(IsOnMessageLoopThread());
   GMP_LOG("ChromiumCDMChild::RecvDecryptAndDecodeFrame() t=%" PRId64 ")",
           aBuffer.mTimestamp());
   MOZ_ASSERT(mDecoderInitialized);
+  MOZ_ASSERT(!mBuffers.IsEmpty());
 
   RefPtr<ChromiumCDMChild> self = this;
   auto autoDeallocateShmem = MakeScopeExit([&, self] {
     self->DeallocShmem(aBuffer.mData());
   });
 
   // The output frame may not have the same timestamp as the frame we put in.
   // We may need to input a number of frames before we receive output. The
@@ -685,80 +671,73 @@ ChromiumCDMChild::RecvDecryptAndDecodeFr
   WidevineVideoFrame frame;
   cdm::Status rv = mCDM->DecryptAndDecodeFrame(input, &frame);
   GMP_LOG("ChromiumCDMChild::RecvDecryptAndDecodeFrame() t=%" PRId64
           " CDM decoder rv=%d",
           aBuffer.mTimestamp(),
           rv);
 
   switch (rv) {
-    case cdm::kNeedMoreData:
-      Unused << SendDecodeFailed(rv);
-      break;
     case cdm::kNoKey:
       GMP_LOG("NoKey for sample at time=%" PRId64 "!", input.timestamp);
       // Somehow our key became unusable. Typically this would happen when
       // a stream requires output protection, and the configuration changed
       // such that output protection is no longer available. For example, a
       // non-compliant monitor was attached. The JS player should notice the
       // key status changing to "output-restricted", and is supposed to switch
       // to a stream that doesn't require OP. In order to keep the playback
       // pipeline rolling, just output a black frame. See bug 1343140.
       frame.InitToBlack(mCodedSize.width, mCodedSize.height, input.timestamp);
       MOZ_FALLTHROUGH;
     case cdm::kSuccess:
-      if (frame.FrameBuffer()) {
-        ReturnOutput(frame);
-        break;
-      }
-      // CDM didn't set a frame buffer on the sample, report it as an error.
-      MOZ_FALLTHROUGH;
+      ReturnOutput(frame);
+      break;
+    case cdm::kNeedMoreData:
+      Unused << SendDecodeFailed(rv);
+      break;
     default:
       Unused << SendDecodeFailed(rv);
       break;
   }
 
   return IPC_OK();
 }
 
 void
 ChromiumCDMChild::ReturnOutput(WidevineVideoFrame& aFrame)
 {
   MOZ_ASSERT(IsOnMessageLoopThread());
-  MOZ_ASSERT(aFrame.FrameBuffer());
   gmp::CDMVideoFrame output;
   output.mFormat() = static_cast<cdm::VideoFormat>(aFrame.Format());
   output.mImageWidth() = aFrame.Size().width;
   output.mImageHeight() = aFrame.Size().height;
+  CDMShmemBuffer* cdmSharedBuffer =
+    reinterpret_cast<CDMShmemBuffer*>(aFrame.FrameBuffer());
+  output.mData() = cdmSharedBuffer->ExtractShmem();
   output.mYPlane() = { aFrame.PlaneOffset(cdm::VideoFrame::kYPlane),
                        aFrame.Stride(cdm::VideoFrame::kYPlane) };
   output.mUPlane() = { aFrame.PlaneOffset(cdm::VideoFrame::kUPlane),
                        aFrame.Stride(cdm::VideoFrame::kUPlane) };
   output.mVPlane() = { aFrame.PlaneOffset(cdm::VideoFrame::kVPlane),
                        aFrame.Stride(cdm::VideoFrame::kVPlane) };
   output.mTimestamp() = aFrame.Timestamp();
 
   uint64_t duration = 0;
   if (mFrameDurations.Find(aFrame.Timestamp(), duration)) {
     output.mDuration() = duration;
   }
 
-  CDMBuffer* base = reinterpret_cast<CDMBuffer*>(aFrame.FrameBuffer());
-  if (base->AsShmemBuffer()) {
-    Unused << SendDecodedShmem(output, base->AsShmemBuffer()->ExtractShmem());
-  } else {
-    MOZ_ASSERT(base->AsArrayBuffer());
-    Unused << SendDecodedData(output, base->AsArrayBuffer()->ExtractBuffer());
-  }
+  Unused << SendDecoded(output);
 }
 
 mozilla::ipc::IPCResult
 ChromiumCDMChild::RecvDrain()
 {
   MOZ_ASSERT(IsOnMessageLoopThread());
+  MOZ_ASSERT(!mBuffers.IsEmpty());
   WidevineVideoFrame frame;
   cdm::InputBuffer sample;
   cdm::Status rv = mCDM->DecryptAndDecodeFrame(sample, &frame);
   CDM_LOG("ChromiumCDMChild::RecvDrain();  DecryptAndDecodeFrame() rv=%d", rv);
   if (rv == cdm::kSuccess) {
     MOZ_ASSERT(frame.Format() != cdm::kUnknownVideoFormat);
     ReturnOutput(frame);
   } else {
--- a/dom/media/gmp/ChromiumCDMParent.cpp
+++ b/dom/media/gmp/ChromiumCDMParent.cpp
@@ -17,17 +17,16 @@
 
 namespace mozilla {
 namespace gmp {
 
 ChromiumCDMParent::ChromiumCDMParent(GMPContentParent* aContentParent,
                                      uint32_t aPluginId)
   : mPluginId(aPluginId)
   , mContentParent(aContentParent)
-  , mVideoShmemCount(MediaPrefs::EMEChromiumAPIVideoShmemCount())
 {
   GMP_LOG(
     "ChromiumCDMParent::ChromiumCDMParent(this=%p, contentParent=%p, id=%u)",
     this,
     aContentParent,
     aPluginId);
 }
 
@@ -596,93 +595,45 @@ ChromiumCDMParent::RecvDecrypted(const u
       mDecrypts.RemoveElementAt(i);
       break;
     }
   }
   return IPC_OK();
 }
 
 ipc::IPCResult
-ChromiumCDMParent::RecvDecodedData(const CDMVideoFrame& aFrame,
-                                   nsTArray<uint8_t>&& aData)
+ChromiumCDMParent::RecvDecoded(const CDMVideoFrame& aFrame)
 {
-  GMP_LOG("ChromiumCDMParent::RecvDecodedData(this=%p) "
-          "mVideoShmemCount=%" PRIu32,
-          this,
-          mVideoShmemCount);
-  // We'd expect CDMs to not have video frames larger than 1280x720 (due to
-  // DRM robustness requirements), which is about 1.5MB per frame. So put an
-  // upper limit on the number of shmems we tolerate the CDM asking for. In
-  // practice, we expect the CDM to need less than 5, but some encodings
-  // require more.
-  Shmem shmem;
-  if (mVideoShmemCount >= 50 || !AllocShmem(mVideoFrameBufferSize,
-                                            Shmem::SharedMemory::TYPE_BASIC,
-                                            &shmem)) {
-    GMP_LOG("ChromiumCDMParent::RecvDecodedData(this=%p) "
-            "failed to allocate shmem for CDM.",
-            this);
-    mVideoDecoderInitialized = false;
-    mDecodePromise.RejectIfExists(
-      MediaResult(
-        NS_ERROR_DOM_MEDIA_FATAL_ERR,
-        RESULT_DETAIL("Failled to send shmems to CDM after decode init.")),
-      __func__);
+  // On failure we need to deallocate the shmem used to store the decrypted
+  // sample. On success we return it to the CDM to be reused.
+  auto autoDeallocateShmem =
+    MakeScopeExit([&, this] { this->DeallocShmem(aFrame.mData()); });
+
+  if (mIsShutdown || mDecodePromise.IsEmpty()) {
     return IPC_OK();
   }
-  mVideoShmemCount++;
-
-  ProcessDecoded(aFrame, aData, Move(shmem));
-
-  return IPC_OK();
-}
-
-ipc::IPCResult
-ChromiumCDMParent::RecvDecodedShmem(const CDMVideoFrame& aFrame,
-                                    ipc::Shmem&& aShmem)
-{
-  ProcessDecoded(
-    aFrame,
-    MakeSpan<uint8_t>(aShmem.get<uint8_t>(), aShmem.Size<uint8_t>()),
-    Move(aShmem));
-  return IPC_OK();
-}
+  VideoData::YCbCrBuffer b;
+  uint8_t* data = aFrame.mData().get<uint8_t>();
+  MOZ_ASSERT(aFrame.mData().Size<uint8_t>() > 0);
 
-void
-ChromiumCDMParent::ProcessDecoded(const CDMVideoFrame& aFrame,
-                                  Span<uint8_t> aData,
-                                  ipc::Shmem&& aGiftShmem)
-{
-  // On failure we need to deallocate the shmem we're to return to the
-  // CDM. On success we return it to the CDM to be reused.
-  auto autoDeallocateShmem =
-    MakeScopeExit([&, this] { this->DeallocShmem(aGiftShmem); });
-
-  if (mIsShutdown || mDecodePromise.IsEmpty()) {
-    return;
-  }
-  VideoData::YCbCrBuffer b;
-  uint8_t* data = aData.Elements();
-  MOZ_ASSERT(aData.Length() > 0);
-
-  b.mPlanes[0].mData = aData.Elements();
+  b.mPlanes[0].mData = data;
   b.mPlanes[0].mWidth = aFrame.mImageWidth();
   b.mPlanes[0].mHeight = aFrame.mImageHeight();
   b.mPlanes[0].mStride = aFrame.mYPlane().mStride();
   b.mPlanes[0].mOffset = aFrame.mYPlane().mPlaneOffset();
   b.mPlanes[0].mSkip = 0;
 
-  b.mPlanes[1].mData = aData.Elements();
+  b.mPlanes[1].mData = data;
   b.mPlanes[1].mWidth = (aFrame.mImageWidth() + 1) / 2;
   b.mPlanes[1].mHeight = (aFrame.mImageHeight() + 1) / 2;
   b.mPlanes[1].mStride = aFrame.mUPlane().mStride();
   b.mPlanes[1].mOffset = aFrame.mUPlane().mPlaneOffset();
   b.mPlanes[1].mSkip = 0;
 
-  b.mPlanes[2].mData = aData.Elements();
+  b.mPlanes[2].mData = data;
   b.mPlanes[2].mWidth = (aFrame.mImageWidth() + 1) / 2;
   b.mPlanes[2].mHeight = (aFrame.mImageHeight() + 1) / 2;
   b.mPlanes[2].mStride = aFrame.mVPlane().mStride();
   b.mPlanes[2].mOffset = aFrame.mVPlane().mPlaneOffset();
   b.mPlanes[2].mSkip = 0;
 
   gfx::IntRect pictureRegion(0, 0, aFrame.mImageWidth(), aFrame.mImageHeight());
   RefPtr<VideoData> v = VideoData::CreateAndCopyData(
@@ -693,35 +644,37 @@ ChromiumCDMParent::ProcessDecoded(const 
     media::TimeUnit::FromMicroseconds(aFrame.mDuration()),
     b,
     false,
     media::TimeUnit::FromMicroseconds(-1),
     pictureRegion);
 
   // Return the shmem to the CDM so the shmem can be reused to send us
   // another frame.
-  if (!SendGiveBuffer(aGiftShmem)) {
+  if (!SendGiveBuffer(aFrame.mData())) {
     mDecodePromise.RejectIfExists(
       MediaResult(NS_ERROR_OUT_OF_MEMORY,
                   RESULT_DETAIL("Can't return shmem to CDM process")),
       __func__);
-    return;
+    return IPC_OK();
   }
   // Don't need to deallocate the shmem since the CDM process is responsible
   // for it again.
   autoDeallocateShmem.release();
 
   if (v) {
     mDecodePromise.ResolveIfExists({ Move(v) }, __func__);
   } else {
     mDecodePromise.RejectIfExists(
       MediaResult(NS_ERROR_OUT_OF_MEMORY,
                   RESULT_DETAIL("CallBack::CreateAndCopyData")),
       __func__);
   }
+
+  return IPC_OK();
 }
 
 ipc::IPCResult
 ChromiumCDMParent::RecvDecodeFailed(const uint32_t& aStatus)
 {
   if (mIsShutdown) {
     MOZ_ASSERT(mDecodePromise.IsEmpty());
     return IPC_OK();
@@ -838,29 +791,22 @@ ChromiumCDMParent::RecvOnDecoderInitDone
     // GPU surface for video frames), and send the shmem back to the CDM
     // process so it can reuse it.
     //
     // We predict the size of buffer the CDM will allocate, and prepopulate
     // the CDM's list of shmems with shmems of at least that size, plus a bit
     // of padding for safety.
     //
     // Normally the CDM won't allocate more than one buffer at once, but
-    // we've seen cases where it allocates multiple buffers, returns one and
-    // holds onto the rest. So we need to ensure we have a minimum number of
-    // shmems pre-allocated for the CDM. This minimum is set by the pref
-    // media.eme.chromium-api.video-shmems.
-    //
-    // We also have a failure recovery mechanism; if the CDM asks for more
-    // buffers than we have shmem's available, ChromiumCDMChild gives the
-    // CDM a non-shared memory buffer, and returns the frame to the parent
-    // in an nsTArray<uint8_t> instead of a shmem. Every time this happens,
-    // the parent sends an extra shmem to the CDM process for it to add to the
-    // set of shmems with which to return output. Via this mechanism we should
-    // recover from incorrectly predicting how many shmems to pre-allocate.
-    for (uint32_t i = 0; i < mVideoShmemCount; i++) {
+    // we've seen cases where it allocates two buffers, returns one and holds
+    // onto the other. So the minimum number of shmems we give to the CDM
+    // must be at least two, and the default is three for safety.
+    const uint32_t count =
+      std::max<uint32_t>(2u, MediaPrefs::EMEChromiumAPIVideoShmemCount());
+    for (uint32_t i = 0; i < count; i++) {
       if (!SendBufferToCDM(mVideoFrameBufferSize)) {
         mVideoDecoderInitialized = false;
         mInitVideoDecoderPromise.RejectIfExists(
           MediaResult(
             NS_ERROR_DOM_MEDIA_FATAL_ERR,
             RESULT_DETAIL("Failled to send shmems to CDM after decode init.")),
           __func__);
         return IPC_OK();
--- a/dom/media/gmp/ChromiumCDMParent.h
+++ b/dom/media/gmp/ChromiumCDMParent.h
@@ -10,17 +10,16 @@
 #include "GMPCrashHelper.h"
 #include "GMPCrashHelperHolder.h"
 #include "GMPMessageUtils.h"
 #include "mozilla/gmp/PChromiumCDMParent.h"
 #include "mozilla/RefPtr.h"
 #include "nsDataHashtable.h"
 #include "PlatformDecoderModule.h"
 #include "ImageContainer.h"
-#include "mozilla/Span.h"
 
 namespace mozilla {
 
 class MediaRawData;
 class ChromiumCDMProxy;
 
 namespace gmp {
 
@@ -112,25 +111,17 @@ protected:
                                           const uint32_t& aSystemCode,
                                           const nsCString& aMessage) override;
   ipc::IPCResult RecvDecrypted(const uint32_t& aId,
                                const uint32_t& aStatus,
                                ipc::Shmem&& aData) override;
   ipc::IPCResult RecvDecryptFailed(const uint32_t& aId,
                                    const uint32_t& aStatus) override;
   ipc::IPCResult RecvOnDecoderInitDone(const uint32_t& aStatus) override;
-  ipc::IPCResult RecvDecodedShmem(const CDMVideoFrame& aFrame,
-                                  ipc::Shmem&& aShmem) override;
-  ipc::IPCResult RecvDecodedData(const CDMVideoFrame& aFrame,
-                                 nsTArray<uint8_t>&& aData) override;
-
-  void ProcessDecoded(const CDMVideoFrame& aFrame,
-                      Span<uint8_t> aData,
-                      ipc::Shmem&& aGiftShmem);
-
+  ipc::IPCResult RecvDecoded(const CDMVideoFrame& aFrame) override;
   ipc::IPCResult RecvDecodeFailed(const uint32_t& aStatus) override;
   ipc::IPCResult RecvShutdown() override;
   ipc::IPCResult RecvResetVideoDecoderComplete() override;
   ipc::IPCResult RecvDrainComplete() override;
   void ActorDestroy(ActorDestroyReason aWhy) override;
   bool SendBufferToCDM(uint32_t aSizeInBytes);
 
   void RejectPromise(uint32_t aPromiseId,
@@ -156,20 +147,16 @@ protected:
   RefPtr<layers::ImageContainer> mImageContainer;
   VideoInfo mVideoInfo;
   uint64_t mLastStreamOffset = 0;
 
   MozPromiseHolder<MediaDataDecoder::FlushPromise> mFlushDecoderPromise;
 
   int32_t mVideoFrameBufferSize = 0;
 
-  // Count of the number of shmems in the set used to return decoded video
-  // frames from the CDM to Gecko.
-  uint32_t mVideoShmemCount;
-
   bool mIsShutdown = false;
   bool mVideoDecoderInitialized = false;
   bool mActorDestroyed = false;
 };
 
 } // namespace gmp
 } // namespace mozilla
 
--- a/dom/media/gmp/GMPTypes.ipdlh
+++ b/dom/media/gmp/GMPTypes.ipdlh
@@ -90,16 +90,17 @@ struct CDMVideoPlane {
   uint32_t mPlaneOffset;
   uint32_t mStride;
 };
 
 struct CDMVideoFrame {
   uint32_t mFormat;
   int32_t mImageWidth;
   int32_t mImageHeight;
+  Shmem mData;
   CDMVideoPlane mYPlane;
   CDMVideoPlane mUPlane;
   CDMVideoPlane mVPlane;
   int64_t mTimestamp;
   int64_t mDuration;
 };
 
 }
--- a/dom/media/gmp/PChromiumCDM.ipdl
+++ b/dom/media/gmp/PChromiumCDM.ipdl
@@ -90,18 +90,17 @@ parent:
 
   // Return values of cdm::ContentDecryptionModule8::Decrypt
   async Decrypted(uint32_t aId, uint32_t aStatus, Shmem aDecryptedData);
   async DecryptFailed(uint32_t aId, uint32_t aStatus);
 
   async OnDecoderInitDone(uint32_t aStatus);
 
   // Return values of cdm::ContentDecryptionModule8::DecryptAndDecodeFrame
-  async DecodedShmem(CDMVideoFrame aFrame, Shmem aData);
-  async DecodedData(CDMVideoFrame aFrame, uint8_t[] aData);
+  async Decoded(CDMVideoFrame aFrame);
   async DecodeFailed(uint32_t aStatus);
 
   async ResetVideoDecoderComplete();
 
   async DrainComplete();
 
   async Shutdown();
 };
--- a/dom/media/gmp/widevine-adapter/WidevineUtils.h
+++ b/dom/media/gmp/widevine-adapter/WidevineUtils.h
@@ -56,47 +56,31 @@ private:
 
 void InitInputBuffer(const GMPEncryptedBufferMetadata* aCrypto,
                      int64_t aTimestamp,
                      const uint8_t* aData,
                      size_t aDataSize,
                      cdm::InputBuffer &aInputBuffer,
                      nsTArray<cdm::SubsampleEntry> &aSubsamples);
 
-namespace gmp {
-class CDMShmemBuffer;
-}
-class WidevineBuffer;
-
-// Base class for our cdm::Buffer implementations, so we can tell at runtime
-// whether the buffer is a Shmem or non-Shmem buffer.
-class CDMBuffer : public cdm::Buffer
-{
-public:
-  virtual WidevineBuffer* AsArrayBuffer() { return nullptr; }
-  virtual gmp::CDMShmemBuffer* AsShmemBuffer() { return nullptr; }
-};
-
-class WidevineBuffer : public CDMBuffer
+class WidevineBuffer : public cdm::Buffer
 {
 public:
   explicit WidevineBuffer(size_t aSize);
   ~WidevineBuffer() override;
   void Destroy() override;
   uint32_t Capacity() const override;
   uint8_t* Data() override;
   void SetSize(uint32_t aSize) override;
   uint32_t Size() const override;
 
   // Moves contents of buffer out into temporary.
   // Note: This empties the buffer.
   nsTArray<uint8_t> ExtractBuffer();
 
-  WidevineBuffer* AsArrayBuffer() override { return this; }
-
 private:
   nsTArray<uint8_t> mBuffer;
   WidevineBuffer(const WidevineBuffer&);
   void operator=(const WidevineBuffer&);
 };
 
 class WidevineDecryptedBlock : public cdm::DecryptedBlock
 {
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -361,17 +361,17 @@ pref("media.gmp.decoder.h264", 0);
 pref("media.raw.enabled", true);
 #endif
 pref("media.ogg.enabled", true);
 pref("media.opus.enabled", true);
 pref("media.wave.enabled", true);
 pref("media.webm.enabled", true);
 
 pref("media.eme.chromium-api.enabled", true);
-pref("media.eme.chromium-api.video-shmems", 4);
+pref("media.eme.chromium-api.video-shmems", 3);
 
 #ifdef MOZ_APPLEMEDIA
 #ifdef MOZ_WIDGET_UIKIT
 pref("media.mp3.enabled", true);
 #endif
 pref("media.apple.mp3.enabled", true);
 pref("media.apple.mp4.enabled", true);
 #endif
--- a/testing/profiles/prefs_general.js
+++ b/testing/profiles/prefs_general.js
@@ -305,21 +305,16 @@ user_pref("browser.search.countryCode", 
 user_pref("browser.search.geoSpecificDefaults", false);
 
 // Make sure self support doesn't hit the network.
 user_pref("browser.selfsupport.url", "https://example.com/selfsupport-dummy/");
 user_pref("extensions.shield-recipe-client.api_url", "https://example.com/selfsupport-dummy/");
 
 user_pref("media.eme.enabled", true);
 
-// Set the number of shmems the PChromiumCDM protocol pre-allocates to 0,
-// so that we test the case where we under-estimate how many shmems we need
-// to send decoded video frames from the CDM to Gecko.
-user_pref("media.eme.chromium-api.video-shmems", 0);
-
 user_pref("media.autoplay.enabled", true);
 
 // Don't use auto-enabled e10s
 user_pref("browser.tabs.remote.autostart.1", false);
 user_pref("browser.tabs.remote.autostart.2", false);
 // Don't show a delay when hiding the audio indicator during tests
 user_pref("browser.tabs.delayHidingAudioPlayingIconMS", 0);
 // Don't forceably kill content processes after a timeout