Bug 1340096: Remove MediaCodecDataDecoder. r?bwu draft
authorJean-Yves Avenard <jyavenard@mozilla.com>
Thu, 16 Feb 2017 12:26:53 +0100
changeset 485532 bcfe7dac1162d1f34882f9889319b28af478532a
parent 485531 53a450fe6a6c1397a1640d174c9a87b7ae72fe41
child 485533 14fed98fd125a52e29d39ec7cbcc5dba12c7fc40
push id45757
push userbmo:jyavenard@mozilla.com
push dateThu, 16 Feb 2017 20:51:43 +0000
reviewersbwu
bugs1340096
milestone54.0a1
Bug 1340096: Remove MediaCodecDataDecoder. r?bwu 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/MediaDrmProxy.java
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);
--- 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/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,