Bug 1318965 - Adds a dummy WidevineDecoder so the CDM doesn't crash if the Decryptor has been destroyed r=cpearce
authorJay Harris <jharris@mozilla.com>
Tue, 17 Jan 2017 14:10:11 +1300
changeset 374930 bb8e9c8daa60b20b4f825482522e799e625b7224
parent 374929 3aa851369053cf869703c864230eaba2557132da
child 374931 019a392cb8dd7e77256c92e1cedd03ea3b480fb7
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce
bugs1318965
milestone53.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 1318965 - Adds a dummy WidevineDecoder so the CDM doesn't crash if the Decryptor has been destroyed r=cpearce MozReview-Commit-ID: D8tCJRKF1vn
dom/media/gmp/widevine-adapter/WidevineAdapter.cpp
dom/media/gmp/widevine-adapter/WidevineDummyDecoder.cpp
dom/media/gmp/widevine-adapter/WidevineDummyDecoder.h
dom/media/gmp/widevine-adapter/moz.build
--- a/dom/media/gmp/widevine-adapter/WidevineAdapter.cpp
+++ b/dom/media/gmp/widevine-adapter/WidevineAdapter.cpp
@@ -2,16 +2,17 @@
 /* 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 "WidevineAdapter.h"
 #include "content_decryption_module.h"
 #include "VideoUtils.h"
 #include "WidevineDecryptor.h"
+#include "WidevineDummyDecoder.h"
 #include "WidevineUtils.h"
 #include "WidevineVideoDecoder.h"
 #include "gmp-api/gmp-entrypoints.h"
 #include "gmp-api/gmp-decryption.h"
 #include "gmp-api/gmp-video-codec.h"
 #include "gmp-api/gmp-platform.h"
 
 static const GMPPlatformAPI* sPlatform = nullptr;
@@ -119,23 +120,29 @@ WidevineAdapter::GMPGetAPI(const char* a
     }
     Log("cdm: 0x%x", cdm);
     RefPtr<CDMWrapper> wrapper(new CDMWrapper(cdm, decryptor));
     decryptor->SetCDM(wrapper, aDecryptorId);
     *aPluginAPI = decryptor;
 
   } else if (!strcmp(aAPIName, GMP_API_VIDEO_DECODER)) {
     RefPtr<CDMWrapper> wrapper = WidevineDecryptor::GetInstance(aDecryptorId);
+
+    // There is a possible race condition, where the decryptor will be destroyed
+    // before we are able to create the video decoder, so we create a dummy
+    // decoder to avoid crashing.
     if (!wrapper) {
-      Log("WidevineAdapter::GMPGetAPI(%s, 0x%p, 0x%p, %u) this=0x%p No cdm for video decoder",
+      Log("WidevineAdapter::GMPGetAPI(%s, 0x%p, 0x%p, %u) this=0x%p No cdm for video decoder. Using a DummyDecoder",
           aAPIName, aHostAPI, aPluginAPI, aDecryptorId, this);
-      return GMPGenericErr;
+
+      *aPluginAPI = new WidevineDummyDecoder();
+    } else {
+      *aPluginAPI = new WidevineVideoDecoder(static_cast<GMPVideoHost*>(aHostAPI),
+                                             wrapper);
     }
-    *aPluginAPI = new WidevineVideoDecoder(static_cast<GMPVideoHost*>(aHostAPI),
-                                           wrapper);
   }
   return *aPluginAPI ? GMPNoErr : GMPNotImplementedErr;
 }
 
 void
 WidevineAdapter::GMPShutdown()
 {
   Log("WidevineAdapter::GMPShutdown()");
new file mode 100644
--- /dev/null
+++ b/dom/media/gmp/widevine-adapter/WidevineDummyDecoder.cpp
@@ -0,0 +1,57 @@
+#include "WidevineDummyDecoder.h"
+#include "WidevineUtils.h"
+
+using namespace cdm;
+
+namespace mozilla {
+WidevineDummyDecoder::WidevineDummyDecoder()
+{
+  Log("WidevineDummyDecoder created");
+}
+
+void WidevineDummyDecoder::InitDecode(const GMPVideoCodec & aCodecSettings,
+                                      const uint8_t * aCodecSpecific,
+                                      uint32_t aCodecSpecificLength,
+                                      GMPVideoDecoderCallback * aCallback,
+                                      int32_t aCoreCount)
+{
+  Log("WidevineDummyDecoder::InitDecode");
+
+  mCallback = aCallback;
+  mCallback->Error(GMPErr::GMPNotImplementedErr);
+}
+
+void WidevineDummyDecoder::Decode(GMPVideoEncodedFrame * aInputFrame,
+                                  bool aMissingFrames,
+                                  const uint8_t * aCodecSpecificInfo,
+                                  uint32_t aCodecSpecificInfoLength,
+                                  int64_t aRenderTimeMs)
+{
+  Log("WidevineDummyDecoder::Decode");
+  mCallback->Error(GMPErr::GMPNotImplementedErr);
+}
+
+void WidevineDummyDecoder::Reset()
+{
+  Log("WidevineDummyDecoder::Reset");
+  mCallback->Error(GMPErr::GMPNotImplementedErr);
+}
+
+void WidevineDummyDecoder::Drain()
+{
+  Log("WidevineDummyDecoder::Drain");
+  mCallback->Error(GMPErr::GMPNotImplementedErr);
+}
+
+void WidevineDummyDecoder::DecodingComplete()
+{
+  Log("WidevineDummyDecoder::DecodingComplete");
+
+  mCallback = nullptr;
+  delete this;
+}
+
+WidevineDummyDecoder::~WidevineDummyDecoder() {
+  Log("WidevineDummyDecoder destroyed");
+}
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/dom/media/gmp/widevine-adapter/WidevineDummyDecoder.h
@@ -0,0 +1,43 @@
+#ifndef WidevineDummyDecoder_h_
+#define WidevineDummyDecoder_h_
+
+#include "stddef.h"
+#include "content_decryption_module.h"
+#include "gmp-api/gmp-video-decode.h"
+#include "gmp-api/gmp-video-host.h"
+#include "WidevineDecryptor.h"
+#include "WidevineVideoFrame.h"
+
+
+namespace mozilla {
+
+class WidevineDummyDecoder : public GMPVideoDecoder {
+public:
+  WidevineDummyDecoder();
+
+  void InitDecode(const GMPVideoCodec& aCodecSettings,
+                  const uint8_t* aCodecSpecific,
+                  uint32_t aCodecSpecificLength,
+                  GMPVideoDecoderCallback* aCallback,
+                  int32_t aCoreCount) override;
+
+  void Decode(GMPVideoEncodedFrame* aInputFrame,
+              bool aMissingFrames,
+              const uint8_t* aCodecSpecificInfo,
+              uint32_t aCodecSpecificInfoLength,
+              int64_t aRenderTimeMs = -1) override;
+
+  void Reset() override;
+
+  void Drain() override;
+
+  void DecodingComplete() override;
+
+private:
+  ~WidevineDummyDecoder();
+
+  GMPVideoDecoderCallback* mCallback;
+};
+}
+
+#endif
\ No newline at end of file
--- a/dom/media/gmp/widevine-adapter/moz.build
+++ b/dom/media/gmp/widevine-adapter/moz.build
@@ -2,16 +2,17 @@
 # vim: set filetype=python:
 # 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/.
 
 SOURCES += [
     'WidevineAdapter.cpp',
     'WidevineDecryptor.cpp',
+    'WidevineDummyDecoder.cpp',
     'WidevineFileIO.cpp',
     'WidevineUtils.cpp',
     'WidevineVideoDecoder.cpp',
     'WidevineVideoFrame.cpp',
 ]
 
 FINAL_LIBRARY = 'xul'