Bug 1318965 - Adds a dummy WidevineDecoder so the CDM doesn't crash if the Decryptor has been destroyed r?cpearce draft
authorJay Harris <jharris@mozilla.com>
Tue, 17 Jan 2017 14:10:11 +1300
changeset 462318 ad40c4b48d6cf6ce03d4592048902f37c39718fd
parent 462317 1975ebdf7a1020c7e178e181559bdc1d9f9456d5
child 462843 e088a6ce09842c5c4e1c636e3fdc23e6079b6715
child 462852 5b8765b7070d659501cb97df2dd157b51e6c14f3
push id41697
push userbmo:jharris@mozilla.com
push dateTue, 17 Jan 2017 02:03:50 +0000
reviewerscpearce
bugs1318965
milestone53.0a1
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'