Bug 1318965 - Adds a dummy WidevineDecoder so the CDM doesn't crash if the Decryptor has been destroyed r?cpearce
MozReview-Commit-ID: D8tCJRKF1vn
--- 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'