Bug 1340096: Remove MediaCodecDataDecoder. r=bwu,jolin
authorJean-Yves Avenard <jyavenard@mozilla.com>
Thu, 16 Feb 2017 12:26:53 +0100
changeset 343493 c4d9e53bfd6825c1b034fbeef97d07daf771ae31
parent 343492 d7bf5b3165ad2093b5c17698208a72c58f240489
child 343494 2b40f2c9ab8e82b89f8a6e183be80bb4d475e47a
push id31381
push userkwierso@gmail.com
push dateFri, 17 Feb 2017 20:45:51 +0000
treeherdermozilla-central@f302def88fe5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbwu, jolin
bugs1340096
milestone54.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 1340096: Remove MediaCodecDataDecoder. r=bwu,jolin We prefer the RemoteDataDecoder instead. MozReview-Commit-ID: SK0D3hycRh
dom/media/MediaPrefs.h
dom/media/eme/mediadrm/MediaDrmProxySupport.cpp
dom/media/platforms/android/AndroidDecoderModule.cpp
dom/media/platforms/android/MediaCodecDataDecoder.cpp
dom/media/platforms/android/MediaCodecDataDecoder.h
dom/media/platforms/moz.build
mobile/android/app/mobile.js
mobile/android/base/java/org/mozilla/gecko/media/LocalMediaDrmBridge.java
mobile/android/base/java/org/mozilla/gecko/media/MediaDrmProxy.java
mobile/android/base/moz.build
widget/android/fennec/FennecJNIWrappers.cpp
widget/android/fennec/FennecJNIWrappers.h
--- a/dom/media/MediaPrefs.h
+++ b/dom/media/MediaPrefs.h
@@ -108,17 +108,16 @@ private:
   DECL_MEDIA_PREF("media.use-blank-decoder",                  PDMUseBlankDecoder, bool, false);
   DECL_MEDIA_PREF("media.gpu-process-decoder",                PDMUseGPUDecoder, bool, false);
 #ifdef MOZ_GONK_MEDIACODEC
   DECL_MEDIA_PREF("media.gonk.enabled",                       PDMGonkDecoderEnabled, bool, true);
 #endif
 #ifdef MOZ_WIDGET_ANDROID
   DECL_MEDIA_PREF("media.android-media-codec.enabled",        PDMAndroidMediaCodecEnabled, bool, false);
   DECL_MEDIA_PREF("media.android-media-codec.preferred",      PDMAndroidMediaCodecPreferred, bool, false);
-  DECL_MEDIA_PREF("media.android-remote-codec.enabled",       PDMAndroidRemoteCodecEnabled, bool, false);
 #endif
 #ifdef MOZ_FFMPEG
   DECL_MEDIA_PREF("media.ffmpeg.enabled",                     PDMFFmpegEnabled, bool, true);
   DECL_MEDIA_PREF("media.libavcodec.allow-obsolete",          LibavcodecAllowObsolete, bool, false);
 #endif
 #ifdef MOZ_FFVPX
   DECL_MEDIA_PREF("media.ffvpx.enabled",                      PDMFFVPXEnabled, bool, true);
 #endif
--- a/dom/media/eme/mediadrm/MediaDrmProxySupport.cpp
+++ b/dom/media/eme/mediadrm/MediaDrmProxySupport.cpp
@@ -195,20 +195,17 @@ MediaDrmJavaCallbacksSupport::OnRejectPr
                                          reason);
 }
 
 MediaDrmProxySupport::MediaDrmProxySupport(const nsAString& aKeySystem)
   : mKeySystem(aKeySystem), mDestroyed(false)
 {
   mJavaCallbacks = MediaDrmProxy::NativeMediaDrmProxyCallbacks::New();
 
-  mBridgeProxy =
-    MediaDrmProxy::Create(mKeySystem,
-                          mJavaCallbacks,
-                          MediaPrefs::PDMAndroidRemoteCodecEnabled());
+  mBridgeProxy = MediaDrmProxy::Create(mKeySystem, mJavaCallbacks);
 
   MOZ_ASSERT(mBridgeProxy, "mBridgeProxy should not be null");
   mMediaDrmStubId = mBridgeProxy->GetStubId()->ToString();
 }
 
 MediaDrmProxySupport::~MediaDrmProxySupport()
 {
   MOZ_ASSERT(mDestroyed, "Shutdown() should be called before !!");
--- a/dom/media/platforms/android/AndroidDecoderModule.cpp
+++ b/dom/media/platforms/android/AndroidDecoderModule.cpp
@@ -1,16 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "AndroidDecoderModule.h"
 #include "AndroidBridge.h"
 
-#include "MediaCodecDataDecoder.h"
 #include "RemoteDataDecoder.h"
 
 #include "MediaInfo.h"
 #include "VPXDecoder.h"
 
 #include "MediaPrefs.h"
 #include "OpusDecoder.h"
 #include "VorbisDecoder.h"
@@ -189,22 +188,22 @@ AndroidDecoderModule::CreateVideoDecoder
       &format), nullptr);
 
   nsString drmStubId;
   if (mProxy) {
     drmStubId = mProxy->GetMediaDrmStubId();
   }
 
   RefPtr<MediaDataDecoder> decoder =
-    MediaPrefs::PDMAndroidRemoteCodecEnabled()
-    ? RemoteDataDecoder::CreateVideoDecoder(
-        config, format, aParams.mImageContainer, drmStubId, mProxy,
-        aParams.mTaskQueue)
-    : MediaCodecDataDecoder::CreateVideoDecoder(
-        config, format, aParams.mImageContainer, drmStubId, mProxy);
+    RemoteDataDecoder::CreateVideoDecoder(config,
+                                          format,
+                                          aParams.mImageContainer,
+                                          drmStubId,
+                                          mProxy,
+                                          aParams.mTaskQueue);
   return decoder.forget();
 }
 
 already_AddRefed<MediaDataDecoder>
 AndroidDecoderModule::CreateAudioDecoder(const CreateDecoderParams& aParams)
 {
   const AudioInfo& config = aParams.AudioConfig();
   if (config.mBitDepth != 16) {
@@ -222,22 +221,18 @@ AndroidDecoderModule::CreateAudioDecoder
       config.mRate,
       config.mChannels,
       &format), nullptr);
 
   nsString drmStubId;
   if (mProxy) {
     drmStubId = mProxy->GetMediaDrmStubId();
   }
-  RefPtr<MediaDataDecoder> decoder =
-    MediaPrefs::PDMAndroidRemoteCodecEnabled()
-    ? RemoteDataDecoder::CreateAudioDecoder(config, format, drmStubId, mProxy,
-                                            aParams.mTaskQueue)
-    : MediaCodecDataDecoder::CreateAudioDecoder(config, format, drmStubId,
-                                                mProxy);
+  RefPtr<MediaDataDecoder> decoder = RemoteDataDecoder::CreateAudioDecoder(
+    config, format, drmStubId, mProxy, aParams.mTaskQueue);
   return decoder.forget();
 }
 
 PlatformDecoderModule::ConversionRequired
 AndroidDecoderModule::DecoderNeedsConversion(const TrackInfo& aConfig) const
 {
   if (aConfig.IsVideo()) {
     return ConversionRequired::kNeedAnnexB;
deleted file mode 100644
--- a/dom/media/platforms/android/MediaCodecDataDecoder.cpp
+++ /dev/null
@@ -1,771 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "MediaCodecDataDecoder.h"
-
-#include "AndroidBridge.h"
-#include "AndroidSurfaceTexture.h"
-#include "GeneratedJNINatives.h"
-#include "GLImages.h"
-
-#include "MediaData.h"
-#include "MediaInfo.h"
-#include "VPXDecoder.h"
-
-#include "nsThreadUtils.h"
-#include "nsPromiseFlatString.h"
-#include "nsIGfxInfo.h"
-
-#include "prlog.h"
-
-#include <jni.h>
-
-#undef LOG
-#define LOG(arg, ...) MOZ_LOG(sAndroidDecoderModuleLog, \
-    mozilla::LogLevel::Debug, ("MediaCodecDataDecoder(%p)::%s: " arg, \
-      this, __func__, ##__VA_ARGS__))
-
-using namespace mozilla;
-using namespace mozilla::gl;
-using namespace mozilla::java;
-using namespace mozilla::java::sdk;
-using media::TimeUnit;
-
-namespace mozilla {
-
-static MediaCodec::LocalRef
-CreateDecoder(const nsACString& aMimeType)
-{
-  MediaCodec::LocalRef codec;
-  NS_ENSURE_SUCCESS(MediaCodec::CreateDecoderByType(TranslateMimeType(aMimeType),
-                    &codec), nullptr);
-  return codec;
-}
-
-class VideoDataDecoder : public MediaCodecDataDecoder
-{
-public:
-  VideoDataDecoder(const VideoInfo& aConfig,
-                   MediaFormat::Param aFormat,
-                   layers::ImageContainer* aImageContainer,
-                   const nsString& aDrmStubId)
-    : MediaCodecDataDecoder(MediaData::Type::VIDEO_DATA, aConfig.mMimeType,
-                            aFormat, aDrmStubId)
-    , mImageContainer(aImageContainer)
-    , mConfig(aConfig)
-  {
-
-  }
-
-  const char* GetDescriptionName() const override
-  {
-    return "Android MediaCodec video decoder";
-  }
-
-  RefPtr<InitPromise> Init() override
-  {
-    mSurfaceTexture = AndroidSurfaceTexture::Create();
-    if (!mSurfaceTexture) {
-      NS_WARNING("Failed to create SurfaceTexture for video decode\n");
-      return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
-    }
-
-    if (NS_FAILED(InitDecoder(mSurfaceTexture->JavaSurface()))) {
-      return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
-    }
-    return InitPromise::CreateAndResolve(TrackInfo::kVideoTrack, __func__);
-  }
-
-  void Cleanup() override
-  {
-  }
-
-  nsresult PostOutput(BufferInfo::Param aInfo, MediaFormat::Param aFormat,
-                      const TimeUnit& aDuration) override
-  {
-    RefPtr<layers::Image> img =
-      new SurfaceTextureImage(mSurfaceTexture.get(), mConfig.mDisplay,
-                              gl::OriginPos::BottomLeft);
-
-    nsresult rv;
-    int32_t flags;
-    NS_ENSURE_SUCCESS(rv = aInfo->Flags(&flags), rv);
-
-    bool isSync = !!(flags & MediaCodec::BUFFER_FLAG_SYNC_FRAME);
-
-    int32_t offset;
-    NS_ENSURE_SUCCESS(rv = aInfo->Offset(&offset), rv);
-
-    int64_t presentationTimeUs;
-    NS_ENSURE_SUCCESS(rv = aInfo->PresentationTimeUs(&presentationTimeUs), rv);
-
-    RefPtr<VideoData> v =
-      VideoData::CreateFromImage(mConfig,
-                                 offset,
-                                 presentationTimeUs,
-                                 aDuration.ToMicroseconds(),
-                                 img,
-                                 isSync,
-                                 presentationTimeUs,
-                                 gfx::IntRect(0, 0,
-                                              mConfig.mDisplay.width,
-                                              mConfig.mDisplay.height));
-    if (!v) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-    MonitorAutoLock mon(mMonitor);
-    mDecodedData.AppendElement(Move(v));
-    return NS_OK;
-  }
-
-  bool SupportDecoderRecycling() const override
-  {
-    return mIsCodecSupportAdaptivePlayback;
-  }
-
-protected:
-  layers::ImageContainer* mImageContainer;
-  const VideoInfo& mConfig;
-  RefPtr<AndroidSurfaceTexture> mSurfaceTexture;
-};
-
-class AudioDataDecoder : public MediaCodecDataDecoder
-{
-public:
-  AudioDataDecoder(const AudioInfo& aConfig, MediaFormat::Param aFormat,
-                   const nsString& aDrmStubId)
-    : MediaCodecDataDecoder(MediaData::Type::AUDIO_DATA, aConfig.mMimeType,
-                            aFormat, aDrmStubId)
-  {
-    JNIEnv* const env = jni::GetEnvForThread();
-
-    jni::ByteBuffer::LocalRef buffer(env);
-    NS_ENSURE_SUCCESS_VOID(aFormat->GetByteBuffer(NS_LITERAL_STRING("csd-0"),
-                                                  &buffer));
-
-    if (!buffer && aConfig.mCodecSpecificConfig->Length() >= 2) {
-      buffer = jni::ByteBuffer::New(
-          aConfig.mCodecSpecificConfig->Elements(),
-          aConfig.mCodecSpecificConfig->Length());
-      NS_ENSURE_SUCCESS_VOID(aFormat->SetByteBuffer(NS_LITERAL_STRING("csd-0"),
-                                                    buffer));
-    }
-  }
-
-  const char* GetDescriptionName() const override
-  {
-    return "android audio decoder";
-  }
-
-  nsresult Output(BufferInfo::Param aInfo, void* aBuffer,
-                  MediaFormat::Param aFormat, const TimeUnit& aDuration) override
-  {
-    // The output on Android is always 16-bit signed
-    nsresult rv;
-    int32_t numChannels;
-    NS_ENSURE_SUCCESS(rv =
-        aFormat->GetInteger(NS_LITERAL_STRING("channel-count"), &numChannels), rv);
-    AudioConfig::ChannelLayout layout(numChannels);
-    if (!layout.IsValid()) {
-      return NS_ERROR_FAILURE;
-    }
-
-    int32_t sampleRate;
-    NS_ENSURE_SUCCESS(rv =
-        aFormat->GetInteger(NS_LITERAL_STRING("sample-rate"), &sampleRate), rv);
-
-    int32_t size;
-    NS_ENSURE_SUCCESS(rv = aInfo->Size(&size), rv);
-
-    int32_t offset;
-    NS_ENSURE_SUCCESS(rv = aInfo->Offset(&offset), rv);
-
-#ifdef MOZ_SAMPLE_TYPE_S16
-    const int32_t numSamples = size / 2;
-#else
-#error We only support 16-bit integer PCM
-#endif
-
-    const int32_t numFrames = numSamples / numChannels;
-    AlignedAudioBuffer audio(numSamples);
-    if (!audio) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-
-    const uint8_t* bufferStart = static_cast<uint8_t*>(aBuffer) + offset;
-    PodCopy(audio.get(), reinterpret_cast<const AudioDataValue*>(bufferStart),
-            numSamples);
-
-    int64_t presentationTimeUs;
-    NS_ENSURE_SUCCESS(rv = aInfo->PresentationTimeUs(&presentationTimeUs), rv);
-
-    RefPtr<AudioData> data = new AudioData(0, presentationTimeUs,
-                                           aDuration.ToMicroseconds(),
-                                           numFrames,
-                                           Move(audio),
-                                           numChannels,
-                                           sampleRate);
-    MonitorAutoLock mon(mMonitor);
-    mDecodedData.AppendElement(Move(data));
-    return NS_OK;
-  }
-};
-
-already_AddRefed<MediaDataDecoder>
-MediaCodecDataDecoder::CreateAudioDecoder(const AudioInfo& aConfig,
-                                          java::sdk::MediaFormat::Param aFormat,
-                                          const nsString& aDrmStubId,
-                                          CDMProxy* aProxy)
-{
-  RefPtr<MediaDataDecoder> decoder;
-  if (!aProxy) {
-    decoder = new AudioDataDecoder(aConfig, aFormat, aDrmStubId);
-  } else {
-    // TODO in bug 1334061.
-  }
-  return decoder.forget();
-}
-
-already_AddRefed<MediaDataDecoder>
-MediaCodecDataDecoder::CreateVideoDecoder(const VideoInfo& aConfig,
-                                          java::sdk::MediaFormat::Param aFormat,
-                                          layers::ImageContainer* aImageContainer,
-                                          const nsString& aDrmStubId,
-                                          CDMProxy* aProxy)
-{
-  RefPtr<MediaDataDecoder> decoder;
-  if (!aProxy) {
-    decoder = new VideoDataDecoder(aConfig, aFormat, aImageContainer, aDrmStubId);
-  } else {
-    // TODO in bug 1334061.
-  }
-  return decoder.forget();
-}
-
-MediaCodecDataDecoder::MediaCodecDataDecoder(MediaData::Type aType,
-                                             const nsACString& aMimeType,
-                                             MediaFormat::Param aFormat,
-                                             const nsString& aDrmStubId)
-  : mType(aType)
-  , mMimeType(aMimeType)
-  , mFormat(aFormat)
-  , mInputBuffers(nullptr)
-  , mOutputBuffers(nullptr)
-  , mError(false)
-  , mMonitor("MediaCodecDataDecoder::mMonitor")
-  , mState(ModuleState::kDecoding)
-  , mDrmStubId(aDrmStubId)
-{
-  mDecodePromise.SetMonitor(&mMonitor);
-  mDrainPromise.SetMonitor(&mMonitor);
-}
-
-MediaCodecDataDecoder::~MediaCodecDataDecoder()
-{
-  Shutdown();
-}
-
-RefPtr<MediaDataDecoder::InitPromise>
-MediaCodecDataDecoder::Init()
-{
-  nsresult rv = InitDecoder(nullptr);
-
-  TrackInfo::TrackType type =
-    (mType == MediaData::AUDIO_DATA ? TrackInfo::TrackType::kAudioTrack
-                                    : TrackInfo::TrackType::kVideoTrack);
-
-  return NS_SUCCEEDED(rv) ? InitPromise::CreateAndResolve(type, __func__)
-                          : InitPromise::CreateAndReject(
-                              NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
-}
-
-nsresult
-MediaCodecDataDecoder::InitDecoder(Surface::Param aSurface)
-{
-  mDecoder = CreateDecoder(mMimeType);
-
-  if (!mDecoder) {
-    return NS_ERROR_FAILURE;
-  }
-
-  // Check if the video codec supports adaptive playback or not.
-  if (aSurface) {
-    mIsCodecSupportAdaptivePlayback =
-      java::HardwareCodecCapabilityUtils::CheckSupportsAdaptivePlayback(mDecoder,
-        nsCString(TranslateMimeType(mMimeType)));
-    if (mIsCodecSupportAdaptivePlayback) {
-        // TODO: may need to find a way to not use hard code to decide the max w/h.
-        mFormat->SetInteger(MediaFormat::KEY_MAX_WIDTH, 1920);
-        mFormat->SetInteger(MediaFormat::KEY_MAX_HEIGHT, 1080);
-    }
-  }
-
-  MediaCrypto::LocalRef crypto = MediaDrmProxy::GetMediaCrypto(mDrmStubId);
-  bool hascrypto = !!crypto;
-  LOG("Has(%d) MediaCrypto (%s)", hascrypto,
-      NS_ConvertUTF16toUTF8(mDrmStubId).get());
-  nsresult rv;
-  NS_ENSURE_SUCCESS(rv = mDecoder->Configure(mFormat, aSurface, crypto, 0), rv);
-  NS_ENSURE_SUCCESS(rv = mDecoder->Start(), rv);
-
-  NS_ENSURE_SUCCESS(rv = ResetInputBuffers(), rv);
-  NS_ENSURE_SUCCESS(rv = ResetOutputBuffers(), rv);
-
-  nsCOMPtr<nsIRunnable> r =
-    NewRunnableMethod(this, &MediaCodecDataDecoder::DecoderLoop);
-  rv = NS_NewNamedThread("MC Decoder", getter_AddRefs(mThread), r);
-
-  return rv;
-}
-
-// This is in usec, so that's 10ms.
-static const int64_t kDecoderTimeout = 10000;
-
-#define BREAK_ON_DECODER_ERROR_LOCKED()                                        \
-  if (NS_FAILED(res)) {                                                        \
-    mError = true;                                                             \
-    mMonitor.AssertCurrentThreadOwns();                                        \
-    NS_WARNING("Exiting decoder loop due to exception");                       \
-    if (mState == ModuleState::kDrainDecoder) {                                \
-      mDrainPromise.RejectIfExists(                                            \
-        MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__), __func__);        \
-      SetState(ModuleState::kDecoding);                                        \
-      break;                                                                   \
-    }                                                                          \
-    mDecodePromise.RejectIfExists(                                             \
-      MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__), __func__);          \
-    break;                                                                     \
-  }
-
-#define BREAK_ON_DECODER_ERROR()                                               \
-  if (NS_FAILED(res)) {                                                        \
-    mError = true;                                                             \
-    MonitorAutoLock mon(mMonitor);                                             \
-    NS_WARNING("Exiting decoder loop due to exception");                       \
-    if (mState == ModuleState::kDrainDecoder) {                                \
-      mDrainPromise.RejectIfExists(                                            \
-        MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__), __func__);        \
-      SetState(ModuleState::kDecoding);                                        \
-      break;                                                                   \
-    }                                                                          \
-    mDecodePromise.RejectIfExists(                                             \
-      MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__), __func__);          \
-    break;                                                                     \
-  }
-
-nsresult
-MediaCodecDataDecoder::GetInputBuffer(
-    JNIEnv* aEnv, int aIndex, jni::Object::LocalRef* aBuffer)
-{
-  MOZ_ASSERT(aEnv);
-  MOZ_ASSERT(!*aBuffer);
-
-  int numTries = 2;
-
-  while (numTries--) {
-    *aBuffer = jni::Object::LocalRef::Adopt(
-        aEnv->GetObjectArrayElement(mInputBuffers.Get(), aIndex));
-    if (*aBuffer) {
-      return NS_OK;
-    }
-    nsresult res = ResetInputBuffers();
-    if (NS_FAILED(res)) {
-      return res;
-    }
-  }
-  return NS_ERROR_FAILURE;
-}
-
-bool
-MediaCodecDataDecoder::WaitForInput()
-{
-  MonitorAutoLock lock(mMonitor);
-
-  while (mState == ModuleState::kDecoding && mQueue.empty()) {
-    // We're done processing the current sample.
-    mDecodePromise.ResolveIfExists(mDecodedData, __func__);
-    mDecodedData.Clear();
-    lock.Wait();
-  }
-
-  return mState != ModuleState::kStopping;
-}
-
-
-already_AddRefed<MediaRawData>
-MediaCodecDataDecoder::PeekNextSample()
-{
-  MonitorAutoLock lock(mMonitor);
-
-  if (mState == ModuleState::kFlushing) {
-    mDecoder->Flush();
-    ClearQueue();
-    SetState(ModuleState::kDecoding);
-    lock.Notify();
-    return nullptr;
-  }
-
-  if (mQueue.empty()) {
-    if (mState == ModuleState::kDrainQueue) {
-      SetState(ModuleState::kDrainDecoder);
-    }
-    return nullptr;
-  }
-
-  // We're not stopping or flushing, so try to get a sample.
-  return RefPtr<MediaRawData>(mQueue.front()).forget();
-}
-
-nsresult
-MediaCodecDataDecoder::QueueSample(const MediaRawData* aSample)
-{
-  MOZ_ASSERT(aSample);
-  AutoLocalJNIFrame frame(jni::GetEnvForThread(), 1);
-
-  // We have a sample, try to feed it to the decoder.
-  int32_t inputIndex = -1;
-  nsresult res = mDecoder->DequeueInputBuffer(kDecoderTimeout, &inputIndex);
-  if (NS_FAILED(res)) {
-    return res;
-  }
-
-  if (inputIndex < 0) {
-    // There is no valid input buffer available.
-    return NS_ERROR_FAILURE;
-  }
-
-  jni::Object::LocalRef buffer(frame.GetEnv());
-  res = GetInputBuffer(frame.GetEnv(), inputIndex, &buffer);
-  if (NS_FAILED(res)) {
-    return res;
-  }
-
-  void* directBuffer = frame.GetEnv()->GetDirectBufferAddress(buffer.Get());
-
-  MOZ_ASSERT(frame.GetEnv()->GetDirectBufferCapacity(buffer.Get()) >=
-             aSample->Size(),
-             "Decoder buffer is not large enough for sample");
-
-  PodCopy(static_cast<uint8_t*>(directBuffer), aSample->Data(), aSample->Size());
-
-  CryptoInfo::LocalRef cryptoInfo = GetCryptoInfoFromSample(aSample);
-  if (cryptoInfo) {
-    res = mDecoder->QueueSecureInputBuffer(inputIndex, 0, cryptoInfo,
-                                           aSample->mTime, 0);
-  } else {
-    res = mDecoder->QueueInputBuffer(inputIndex, 0, aSample->Size(),
-                                     aSample->mTime, 0);
-  }
-
-  if (NS_FAILED(res)) {
-    return res;
-  }
-
-  mDurations.push_back(TimeUnit::FromMicroseconds(aSample->mDuration));
-  return NS_OK;
-}
-
-nsresult
-MediaCodecDataDecoder::QueueEOS()
-{
-  mMonitor.AssertCurrentThreadOwns();
-
-  nsresult res = NS_OK;
-  int32_t inputIndex = -1;
-  res = mDecoder->DequeueInputBuffer(kDecoderTimeout, &inputIndex);
-  if (NS_FAILED(res) || inputIndex < 0) {
-    return res;
-  }
-
-  res = mDecoder->QueueInputBuffer(inputIndex, 0, 0, 0,
-                                   MediaCodec::BUFFER_FLAG_END_OF_STREAM);
-  if (NS_SUCCEEDED(res)) {
-    SetState(ModuleState::kDrainWaitEOS);
-    mMonitor.Notify();
-  }
-  return res;
-}
-
-void
-MediaCodecDataDecoder::HandleEOS(int32_t aOutputStatus)
-{
-  MonitorAutoLock lock(mMonitor);
-
-  if (mState ==  ModuleState::kDrainWaitEOS) {
-    SetState(ModuleState::kDecoding);
-
-    mDrainPromise.ResolveIfExists(mDecodedData, __func__);
-    mDecodedData.Clear();
-    mMonitor.Notify();
-  }
-
-  mDecoder->ReleaseOutputBuffer(aOutputStatus, false);
-}
-
-Maybe<TimeUnit>
-MediaCodecDataDecoder::GetOutputDuration()
-{
-  if (mDurations.empty()) {
-    return Nothing();
-  }
-  const Maybe<TimeUnit> duration = Some(mDurations.front());
-  mDurations.pop_front();
-  return duration;
-}
-
-nsresult
-MediaCodecDataDecoder::ProcessOutput(
-    BufferInfo::Param aInfo, MediaFormat::Param aFormat, int32_t aStatus)
-{
-  AutoLocalJNIFrame frame(jni::GetEnvForThread(), 1);
-
-  const Maybe<TimeUnit> duration = GetOutputDuration();
-  if (!duration) {
-    // Some devices report failure in QueueSample while actually succeeding at
-    // it, in which case we get an output buffer without having a cached duration
-    // (bug 1273523).
-    return NS_OK;
-  }
-
-  const auto buffer = jni::Object::LocalRef::Adopt(
-      frame.GetEnv()->GetObjectArrayElement(mOutputBuffers.Get(), aStatus));
-
-  if (buffer) {
-    // The buffer will be null on Android L if we are decoding to a Surface.
-    void* directBuffer = frame.GetEnv()->GetDirectBufferAddress(buffer.Get());
-    Output(aInfo, directBuffer, aFormat, duration.value());
-  }
-
-  // The Surface will be updated at this point (for video).
-  mDecoder->ReleaseOutputBuffer(aStatus, true);
-  return PostOutput(aInfo, aFormat, duration.value());
-}
-
-void
-MediaCodecDataDecoder::DecoderLoop()
-{
-  bool isOutputDone = false;
-  AutoLocalJNIFrame frame(jni::GetEnvForThread(), 1);
-  MediaFormat::LocalRef outputFormat(frame.GetEnv());
-  nsresult res = NS_OK;
-
-  while (WaitForInput()) {
-    RefPtr<MediaRawData> sample = PeekNextSample();
-
-    {
-      MonitorAutoLock lock(mMonitor);
-      if (mState == ModuleState::kDrainDecoder) {
-        MOZ_ASSERT(!sample, "Shouldn't have a sample when pushing EOF frame");
-        res = QueueEOS();
-        BREAK_ON_DECODER_ERROR_LOCKED();
-      }
-    }
-
-    if (sample) {
-      res = QueueSample(sample);
-      if (NS_SUCCEEDED(res)) {
-        // We've fed this into the decoder, so remove it from the queue.
-        MonitorAutoLock lock(mMonitor);
-        MOZ_RELEASE_ASSERT(mQueue.size(), "Queue may not be empty");
-        mQueue.pop_front();
-        isOutputDone = false;
-      }
-    }
-
-    if (isOutputDone) {
-      continue;
-    }
-
-    BufferInfo::LocalRef bufferInfo;
-    nsresult res = BufferInfo::New(&bufferInfo);
-    BREAK_ON_DECODER_ERROR();
-
-    int32_t outputStatus = -1;
-    res = mDecoder->DequeueOutputBuffer(bufferInfo, kDecoderTimeout,
-                                        &outputStatus);
-    BREAK_ON_DECODER_ERROR();
-
-    if (outputStatus == MediaCodec::INFO_TRY_AGAIN_LATER) {
-    } else if (outputStatus == MediaCodec::INFO_OUTPUT_BUFFERS_CHANGED) {
-      res = ResetOutputBuffers();
-      BREAK_ON_DECODER_ERROR();
-    } else if (outputStatus == MediaCodec::INFO_OUTPUT_FORMAT_CHANGED) {
-      res = mDecoder->GetOutputFormat(ReturnTo(&outputFormat));
-      BREAK_ON_DECODER_ERROR();
-    } else if (outputStatus < 0) {
-      NS_WARNING("Unknown error from decoder!");
-      {
-        const auto result =
-          MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, __func__);
-        MonitorAutoLock mon(mMonitor);
-        mDecodePromise.RejectIfExists(result, __func__);
-        mDrainPromise.RejectIfExists(result, __func__);
-      }
-      // Don't break here just in case it's recoverable. If it's not, other
-      // stuff will fail later and we'll bail out.
-    } else {
-      // We have a valid buffer index >= 0 here.
-      int32_t flags;
-      nsresult res = bufferInfo->Flags(&flags);
-      BREAK_ON_DECODER_ERROR();
-
-      if (flags & MediaCodec::BUFFER_FLAG_END_OF_STREAM) {
-        HandleEOS(outputStatus);
-        isOutputDone = true;
-        // We only queue empty EOF frames, so we're done for now.
-        continue;
-      }
-
-      res = ProcessOutput(bufferInfo, outputFormat, outputStatus);
-      BREAK_ON_DECODER_ERROR();
-    }
-  }
-
-  Cleanup();
-
-  // We're done.
-  MonitorAutoLock lock(mMonitor);
-  SetState(ModuleState::kShutdown);
-  mMonitor.Notify();
-}
-
-const char*
-MediaCodecDataDecoder::ModuleStateStr(ModuleState aState) {
-    switch (aState) {
-      case ModuleState::kDecoding:     return "Decoding";
-      case ModuleState::kFlushing:     return "Flushing";
-      case ModuleState::kDrainQueue:   return "DrainQueue";
-      case ModuleState::kDrainDecoder: return "DrainDecoder";
-      case ModuleState::kDrainWaitEOS: return "DrainWaitEOS";
-      case ModuleState::kStopping:     return "Stopping";
-      case ModuleState::kShutdown:     return "Shutdown";
-      default: MOZ_ASSERT_UNREACHABLE("Invalid state.");
-    }
-    return "Unknown";
-}
-
-bool
-MediaCodecDataDecoder::SetState(ModuleState aState)
-{
-  mMonitor.AssertCurrentThreadOwns();
-
-  bool ok = true;
-
-  if (mState == ModuleState::kShutdown) {
-    ok = false;
-  } else if (mState == ModuleState::kStopping) {
-    ok = aState == ModuleState::kShutdown;
-  } else if (aState == ModuleState::kDrainDecoder) {
-    ok = mState == ModuleState::kDrainQueue;
-  } else if (aState == ModuleState::kDrainWaitEOS) {
-    ok = mState == ModuleState::kDrainDecoder;
-  }
-
-  if (ok) {
-    LOG("%s -> %s", ModuleStateStr(mState), ModuleStateStr(aState));
-    mState = aState;
-  } else {
-    LOG("Fail to transit from %s to %s state", ModuleStateStr(mState), ModuleStateStr(aState));
-  }
-
-  return ok;
-}
-
-void
-MediaCodecDataDecoder::ClearQueue()
-{
-  mMonitor.AssertCurrentThreadOwns();
-
-  mQueue.clear();
-  mDurations.clear();
-  mDecodedData.Clear();
-}
-
-RefPtr<MediaDataDecoder::DecodePromise>
-MediaCodecDataDecoder::Decode(MediaRawData* aSample)
-{
-  if (mError) {
-    return DecodePromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR,
-                                          __func__);
-  }
-  MonitorAutoLock lock(mMonitor);
-  RefPtr<DecodePromise> p = mDecodePromise.Ensure(__func__);
-  mQueue.push_back(aSample);
-  lock.NotifyAll();
-  return p;
-}
-
-nsresult
-MediaCodecDataDecoder::ResetInputBuffers()
-{
-  return mDecoder->GetInputBuffers(ReturnTo(&mInputBuffers));
-}
-
-nsresult
-MediaCodecDataDecoder::ResetOutputBuffers()
-{
-  return mDecoder->GetOutputBuffers(ReturnTo(&mOutputBuffers));
-}
-
-RefPtr<MediaDataDecoder::FlushPromise>
-MediaCodecDataDecoder::Flush()
-{
-  MonitorAutoLock lock(mMonitor);
-  mDecodePromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
-  mDrainPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
-  if (!SetState(ModuleState::kFlushing)) {
-    return FlushPromise::CreateAndResolve(true, __func__);
-  }
-  lock.Notify();
-
-  while (mState == ModuleState::kFlushing) {
-    lock.Wait();
-  }
-  return FlushPromise::CreateAndResolve(true, __func__);
-}
-
-RefPtr<MediaDataDecoder::DecodePromise>
-MediaCodecDataDecoder::Drain()
-{
-  if (mError) {
-    return DecodePromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR,
-                                          __func__);
-  }
-  MonitorAutoLock lock(mMonitor);
-  RefPtr<DecodePromise> p = mDecodePromise.Ensure(__func__);
-  MOZ_ASSERT(mState != ModuleState::kDrainDecoder
-             && mState != ModuleState::kDrainQueue, "Already draining");
-
-  SetState(ModuleState::kDrainQueue);
-  lock.Notify();
-  return p;
-}
-
-RefPtr<ShutdownPromise>
-MediaCodecDataDecoder::Shutdown()
-{
-  MonitorAutoLock lock(mMonitor);
-
-  SetState(ModuleState::kStopping);
-  lock.Notify();
-
-  while (mThread && mState != ModuleState::kShutdown) {
-    lock.Wait();
-  }
-
-  if (mThread) {
-    mThread->Shutdown();
-    mThread = nullptr;
-  }
-
-  if (mDecoder) {
-    mDecoder->Stop();
-    mDecoder->Release();
-    mDecoder = nullptr;
-  }
-
-  return ShutdownPromise::CreateAndResolve(true, __func__);
-}
-
-} // mozilla
deleted file mode 100644
--- a/dom/media/platforms/android/MediaCodecDataDecoder.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef MediaCodecDataDecoder_h_
-#define MediaCodecDataDecoder_h_
-
-#include "AndroidDecoderModule.h"
-
-#include "MediaCodec.h"
-#include "SurfaceTexture.h"
-#include "TimeUnits.h"
-#include "mozilla/Atomics.h"
-#include "mozilla/Monitor.h"
-#include "mozilla/Maybe.h"
-
-#include <deque>
-
-namespace mozilla {
-
-typedef std::deque<RefPtr<MediaRawData>> SampleQueue;
-
-class MediaCodecDataDecoder : public MediaDataDecoder
-{
-public:
-  static already_AddRefed<MediaDataDecoder> CreateAudioDecoder(
-    const AudioInfo& aConfig, java::sdk::MediaFormat::Param aFormat,
-    const nsString& aDrmStubId, CDMProxy* aProxy);
-
-  static already_AddRefed<MediaDataDecoder> CreateVideoDecoder(
-    const VideoInfo& aConfig, java::sdk::MediaFormat::Param aFormat,
-    layers::ImageContainer* aImageContainer, const nsString& aDrmStubId,
-    CDMProxy* aProxy);
-
-  ~MediaCodecDataDecoder();
-
-  RefPtr<InitPromise> Init() override;
-  RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
-  RefPtr<DecodePromise> Drain() override;
-  RefPtr<FlushPromise> Flush() override;
-  RefPtr<ShutdownPromise> Shutdown() override;
-  const char* GetDescriptionName() const override
-  {
-    return "Android MediaCodec decoder";
-  }
-
-protected:
-  enum class ModuleState : uint8_t
-  {
-    kDecoding = 0,
-    kFlushing,
-    kDrainQueue,
-    kDrainDecoder,
-    kDrainWaitEOS,
-    kStopping,
-    kShutdown
-  };
-
-  friend class AndroidDecoderModule;
-
-  MediaCodecDataDecoder(MediaData::Type aType,
-                        const nsACString& aMimeType,
-                        java::sdk::MediaFormat::Param aFormat,
-                        const nsString& aDrmStubId);
-
-  static const char* ModuleStateStr(ModuleState aState);
-
-  virtual nsresult InitDecoder(java::sdk::Surface::Param aSurface);
-
-  virtual nsresult Output(java::sdk::BufferInfo::Param aInfo, void* aBuffer,
-      java::sdk::MediaFormat::Param aFormat, const media::TimeUnit& aDuration)
-  {
-    return NS_OK;
-  }
-
-  virtual nsresult PostOutput(java::sdk::BufferInfo::Param aInfo,
-      java::sdk::MediaFormat::Param aFormat, const media::TimeUnit& aDuration)
-  {
-    return NS_OK;
-  }
-
-  virtual void Cleanup() {};
-
-  nsresult ResetInputBuffers();
-  nsresult ResetOutputBuffers();
-
-  nsresult GetInputBuffer(JNIEnv* env, int index, jni::Object::LocalRef* buffer);
-  bool WaitForInput();
-  already_AddRefed<MediaRawData> PeekNextSample();
-  nsresult QueueSample(const MediaRawData* aSample);
-  nsresult QueueEOS();
-  void HandleEOS(int32_t aOutputStatus);
-  Maybe<media::TimeUnit> GetOutputDuration();
-  nsresult ProcessOutput(java::sdk::BufferInfo::Param aInfo,
-                         java::sdk::MediaFormat::Param aFormat,
-                         int32_t aStatus);
-  // Sets decoder state and returns whether the new state has become effective.
-  // Must hold the monitor.
-  bool SetState(ModuleState aState);
-  void DecoderLoop();
-
-  virtual void ClearQueue();
-
-  MediaData::Type mType;
-
-  nsAutoCString mMimeType;
-  java::sdk::MediaFormat::GlobalRef mFormat;
-
-  java::sdk::MediaCodec::GlobalRef mDecoder;
-
-  jni::ObjectArray::GlobalRef mInputBuffers;
-  jni::ObjectArray::GlobalRef mOutputBuffers;
-
-  nsCOMPtr<nsIThread> mThread;
-
-  Atomic<bool> mError;
-
-  // Only these members are protected by mMonitor.
-  Monitor mMonitor;
-
-  ModuleState mState;
-
-  SampleQueue mQueue;
-  // Durations are stored in microseconds.
-  std::deque<media::TimeUnit> mDurations;
-
-  nsString mDrmStubId;
-
-  bool mIsCodecSupportAdaptivePlayback = false;
-
-  MozPromiseHolder<DecodePromise> mDecodePromise;
-  MozPromiseHolder<DecodePromise> mDrainPromise;
-  DecodedData mDecodedData;
-};
-
-} // namespace mozilla
-
-#endif
--- a/dom/media/platforms/moz.build
+++ b/dom/media/platforms/moz.build
@@ -72,16 +72,15 @@ if CONFIG['MOZ_APPLEMEDIA']:
 include('/ipc/chromium/chromium-config.mozbuild')
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
     EXPORTS += [
         'android/AndroidDecoderModule.h',
     ]
     UNIFIED_SOURCES += [
         'android/AndroidDecoderModule.cpp',
-        'android/MediaCodecDataDecoder.cpp',
         'android/RemoteDataDecoder.cpp',
     ]
 
 FINAL_LIBRARY = 'xul'
 
 if CONFIG['GNU_CXX']:
     CXXFLAGS += ['-Wno-error=shadow']
--- a/mobile/android/app/mobile.js
+++ b/mobile/android/app/mobile.js
@@ -617,18 +617,16 @@ pref("media.video-queue.default-size", 3
 pref("media.video-queue.send-to-compositor-size", 1);
 
 // Allow to check if the decoder supports recycling only on Fennec nightly build.
 pref("media.decoder.recycle.enabled", true);
 
 // Enable the MediaCodec PlatformDecoderModule by default.
 pref("media.android-media-codec.enabled", true);
 pref("media.android-media-codec.preferred", true);
-// Run decoder in seperate process.
-pref("media.android-remote-codec.enabled", true);
 
 // Enable MSE
 pref("media.mediasource.enabled", true);
 
 pref("media.mediadrm-widevinecdm.visible", true);
 
 // Enable EME (Encrypted Media Extensions)
 pref("media.eme.enabled", true);
deleted file mode 100644
--- a/mobile/android/base/java/org/mozilla/gecko/media/LocalMediaDrmBridge.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.media;
-import org.mozilla.gecko.AppConstants;
-
-import android.media.MediaCrypto;
-import android.util.Log;
-
-final class LocalMediaDrmBridge implements GeckoMediaDrm {
-    private static final String LOGTAG = "GeckoLocalMediaDrmBridge";
-    private static final boolean DEBUG = false;
-    private GeckoMediaDrm mBridge = null;
-    private CallbacksForwarder mCallbacksFwd;
-
-    // Forward the callback calls from GeckoMediaDrmBridgeV{21,23}
-    // to the callback MediaDrmProxy.Callbacks.
-    private class CallbacksForwarder implements GeckoMediaDrm.Callbacks {
-        private final GeckoMediaDrm.Callbacks mProxyCallbacks;
-
-        CallbacksForwarder(GeckoMediaDrm.Callbacks callbacks) {
-            assertTrue(callbacks != null);
-            mProxyCallbacks = callbacks;
-        }
-
-        @Override
-        public void onSessionCreated(int createSessionToken,
-                                     int promiseId,
-                                     byte[] sessionId,
-                                     byte[] request) {
-            assertTrue(mProxyCallbacks != null);
-            mProxyCallbacks.onSessionCreated(createSessionToken,
-                                             promiseId,
-                                             sessionId,
-                                             request);
-        }
-
-        @Override
-        public void onSessionUpdated(int promiseId, byte[] sessionId) {
-            assertTrue(mProxyCallbacks != null);
-            mProxyCallbacks.onSessionUpdated(promiseId, sessionId);
-        }
-
-        @Override
-        public void onSessionClosed(int promiseId, byte[] sessionId) {
-            assertTrue(mProxyCallbacks != null);
-            mProxyCallbacks.onSessionClosed(promiseId, sessionId);
-        }
-
-        @Override
-        public void onSessionMessage(byte[] sessionId,
-                                     int sessionMessageType,
-                                     byte[] request) {
-            assertTrue(mProxyCallbacks != null);
-            mProxyCallbacks.onSessionMessage(sessionId, sessionMessageType, request);
-        }
-
-        @Override
-        public void onSessionError(byte[] sessionId,
-                                   String message) {
-            assertTrue(mProxyCallbacks != null);
-            mProxyCallbacks.onSessionError(sessionId, message);
-        }
-
-        @Override
-        public void onSessionBatchedKeyChanged(byte[] sessionId,
-                                               SessionKeyInfo[] keyInfos) {
-            assertTrue(mProxyCallbacks != null);
-            mProxyCallbacks.onSessionBatchedKeyChanged(sessionId, keyInfos);
-        }
-
-        @Override
-        public void onRejectPromise(int promiseId, String message) {
-            if (DEBUG) Log.d(LOGTAG, message);
-            assertTrue(mProxyCallbacks != null);
-            mProxyCallbacks.onRejectPromise(promiseId, message);
-        }
-    } // CallbacksForwarder
-
-    private static void assertTrue(boolean condition) {
-        if (DEBUG && !condition) {
-          throw new AssertionError("Expected condition to be true");
-        }
-      }
-
-    LocalMediaDrmBridge(String keySystem) throws Exception {
-        if (AppConstants.Versions.preLollipop) {
-            Log.e(LOGTAG, "Pre-Lollipop should never enter here!!");
-            mBridge = null;
-        } else if (AppConstants.Versions.preMarshmallow) {
-            mBridge = new GeckoMediaDrmBridgeV21(keySystem);
-        } else {
-            mBridge = new GeckoMediaDrmBridgeV23(keySystem);
-        }
-    }
-
-    @Override
-    public synchronized void setCallbacks(Callbacks callbacks) {
-        if (DEBUG) Log.d(LOGTAG, "setCallbacks()");
-        mCallbacksFwd = new CallbacksForwarder(callbacks);
-        assertTrue(mBridge != null);
-        mBridge.setCallbacks(mCallbacksFwd);
-    }
-
-    @Override
-    public synchronized void createSession(int createSessionToken,
-                                           int promiseId,
-                                           String initDataType,
-                                           byte[] initData) {
-        if (DEBUG) Log.d(LOGTAG, "createSession()");
-        assertTrue(mCallbacksFwd != null);
-        try {
-            mBridge.createSession(createSessionToken, promiseId, initDataType, initData);
-        } catch (Exception e) {
-            Log.e(LOGTAG, "Failed to createSession.", e);
-            mCallbacksFwd.onRejectPromise(promiseId, "Failed to createSession.");
-        }
-    }
-
-    @Override
-    public synchronized void updateSession(int promiseId, String sessionId, byte[] response) {
-        if (DEBUG) Log.d(LOGTAG, "updateSession()");
-        assertTrue(mCallbacksFwd != null);
-        try {
-            mBridge.updateSession(promiseId, sessionId, response);
-        } catch (Exception e) {
-            Log.e(LOGTAG, "Failed to updateSession.", e);
-            mCallbacksFwd.onRejectPromise(promiseId, "Failed to updateSession.");
-        }
-    }
-
-    @Override
-    public synchronized void closeSession(int promiseId, String sessionId) {
-        if (DEBUG) Log.d(LOGTAG, "closeSession()");
-        assertTrue(mCallbacksFwd != null);
-        try {
-            mBridge.closeSession(promiseId, sessionId);
-        } catch (Exception e) {
-            Log.e(LOGTAG, "Failed to closeSession.", e);
-            mCallbacksFwd.onRejectPromise(promiseId, "Failed to closeSession.");
-        }
-    }
-
-    @Override
-    public synchronized void release() {
-        if (DEBUG) Log.d(LOGTAG, "release()");
-        try {
-            mBridge.release();
-            mBridge = null;
-            mCallbacksFwd = null;
-        } catch (Exception e) {
-            Log.e(LOGTAG, "Failed to release", e);
-        }
-    }
-
-    @Override
-    public synchronized MediaCrypto getMediaCrypto() {
-        if (DEBUG) Log.d(LOGTAG, "getMediaCrypto()");
-        return mBridge != null ? mBridge.getMediaCrypto() : null;
-    }
-}
--- a/mobile/android/base/java/org/mozilla/gecko/media/MediaDrmProxy.java
+++ b/mobile/android/base/java/org/mozilla/gecko/media/MediaDrmProxy.java
@@ -245,33 +245,28 @@ public final class MediaDrmProxy {
     } // MediaDrmProxyCallbacks
 
     public boolean isDestroyed() {
         return mDestroyed;
     }
 
     @WrapForJNI(calledFrom = "gecko")
     public static MediaDrmProxy create(String keySystem,
-                                       Callbacks nativeCallbacks,
-                                       boolean isRemote) {
-        MediaDrmProxy proxy = new MediaDrmProxy(keySystem, nativeCallbacks, isRemote);
+                                       Callbacks nativeCallbacks) {
+        MediaDrmProxy proxy = new MediaDrmProxy(keySystem, nativeCallbacks);
         return proxy;
     }
 
-    MediaDrmProxy(String keySystem, Callbacks nativeCallbacks, boolean isRemote) {
+    MediaDrmProxy(String keySystem, Callbacks nativeCallbacks) {
         if (DEBUG) Log.d(LOGTAG, "Constructing MediaDrmProxy");
         try {
             mDrmStubId = UUID.randomUUID().toString();
-            if (isRemote) {
-                IMediaDrmBridge remoteBridge =
-                    RemoteManager.getInstance().createRemoteMediaDrmBridge(keySystem, mDrmStubId);
-                mImpl = new RemoteMediaDrmBridge(remoteBridge);
-            } else {
-                mImpl = new LocalMediaDrmBridge(keySystem);
-            }
+            IMediaDrmBridge remoteBridge =
+                RemoteManager.getInstance().createRemoteMediaDrmBridge(keySystem, mDrmStubId);
+            mImpl = new RemoteMediaDrmBridge(remoteBridge);
             mImpl.setCallbacks(new MediaDrmProxyCallbacks(this, nativeCallbacks));
             sProxyList.add(this);
         } catch (Exception e) {
             Log.e(LOGTAG, "Constructing MediaDrmProxy ... error", e);
         }
     }
 
     @WrapForJNI
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -590,17 +590,16 @@ gbjar.sources += ['java/org/mozilla/geck
     'media/AudioFocusAgent.java',
     'media/Codec.java',
     'media/CodecProxy.java',
     'media/FormatParam.java',
     'media/GeckoMediaDrm.java',
     'media/GeckoMediaDrmBridgeV21.java',
     'media/GeckoMediaDrmBridgeV23.java',
     'media/JellyBeanAsyncCodec.java',
-    'media/LocalMediaDrmBridge.java',
     'media/MediaControlService.java',
     'media/MediaDrmProxy.java',
     'media/MediaManager.java',
     'media/RemoteManager.java',
     'media/RemoteMediaDrmBridge.java',
     'media/RemoteMediaDrmBridgeStub.java',
     'media/Sample.java',
     'media/SamplePool.java',
--- a/widget/android/fennec/FennecJNIWrappers.cpp
+++ b/widget/android/fennec/FennecJNIWrappers.cpp
@@ -280,19 +280,19 @@ constexpr char MediaDrmProxy::CloseSessi
 auto MediaDrmProxy::CloseSession(int32_t a0, mozilla::jni::String::Param a1) const -> void
 {
     return mozilla::jni::Method<CloseSession_t>::Call(MediaDrmProxy::mCtx, nullptr, a0, a1);
 }
 
 constexpr char MediaDrmProxy::Create_t::name[];
 constexpr char MediaDrmProxy::Create_t::signature[];
 
-auto MediaDrmProxy::Create(mozilla::jni::String::Param a0, mozilla::jni::Object::Param a1, bool a2) -> MediaDrmProxy::LocalRef
+auto MediaDrmProxy::Create(mozilla::jni::String::Param a0, mozilla::jni::Object::Param a1) -> MediaDrmProxy::LocalRef
 {
-    return mozilla::jni::Method<Create_t>::Call(MediaDrmProxy::Context(), nullptr, a0, a1, a2);
+    return mozilla::jni::Method<Create_t>::Call(MediaDrmProxy::Context(), nullptr, a0, a1);
 }
 
 constexpr char MediaDrmProxy::CreateSession_t::name[];
 constexpr char MediaDrmProxy::CreateSession_t::signature[];
 
 auto MediaDrmProxy::CreateSession(int32_t a0, int32_t a1, mozilla::jni::String::Param a2, mozilla::jni::ByteArray::Param a3) const -> void
 {
     return mozilla::jni::Method<CreateSession_t>::Call(MediaDrmProxy::mCtx, nullptr, a0, a1, a2, a3);
--- a/widget/android/fennec/FennecJNIWrappers.h
+++ b/widget/android/fennec/FennecJNIWrappers.h
@@ -983,31 +983,30 @@ public:
     auto CloseSession(int32_t, mozilla::jni::String::Param) const -> void;
 
     struct Create_t {
         typedef MediaDrmProxy Owner;
         typedef MediaDrmProxy::LocalRef ReturnType;
         typedef MediaDrmProxy::Param SetterType;
         typedef mozilla::jni::Args<
                 mozilla::jni::String::Param,
-                mozilla::jni::Object::Param,
-                bool> Args;
+                mozilla::jni::Object::Param> Args;
         static constexpr char name[] = "create";
         static constexpr char signature[] =
-                "(Ljava/lang/String;Lorg/mozilla/gecko/media/MediaDrmProxy$Callbacks;Z)Lorg/mozilla/gecko/media/MediaDrmProxy;";
+                "(Ljava/lang/String;Lorg/mozilla/gecko/media/MediaDrmProxy$Callbacks;)Lorg/mozilla/gecko/media/MediaDrmProxy;";
         static const bool isStatic = true;
         static const mozilla::jni::ExceptionMode exceptionMode =
                 mozilla::jni::ExceptionMode::ABORT;
         static const mozilla::jni::CallingThread callingThread =
                 mozilla::jni::CallingThread::GECKO;
         static const mozilla::jni::DispatchTarget dispatchTarget =
                 mozilla::jni::DispatchTarget::CURRENT;
     };
 
-    static auto Create(mozilla::jni::String::Param, mozilla::jni::Object::Param, bool) -> MediaDrmProxy::LocalRef;
+    static auto Create(mozilla::jni::String::Param, mozilla::jni::Object::Param) -> MediaDrmProxy::LocalRef;
 
     struct CreateSession_t {
         typedef MediaDrmProxy Owner;
         typedef void ReturnType;
         typedef void SetterType;
         typedef mozilla::jni::Args<
                 int32_t,
                 int32_t,