Bug 1413480 - Check mCDM in ChromiumCDMChild::RecvXXX before dereferencing it.
MozReview-Commit-ID: Dp4FOtZ8Yok
--- a/dom/media/gmp/ChromiumCDMChild.cpp
+++ b/dom/media/gmp/ChromiumCDMChild.cpp
@@ -555,16 +555,17 @@ ChromiumCDMChild::RecvCreateSessionAndGe
return IPC_OK();
}
mozilla::ipc::IPCResult
ChromiumCDMChild::RecvLoadSession(const uint32_t& aPromiseId,
const uint32_t& aSessionType,
const nsCString& aSessionId)
{
+ MOZ_ASSERT(IsOnMessageLoopThread());
GMP_LOG("ChromiumCDMChild::RecvLoadSession(pid=%u, type=%u, sessionId=%s)",
aPromiseId,
aSessionType,
aSessionId.get());
if (mCDM) {
mLoadSessionPromiseIds.AppendElement(aPromiseId);
mCDM->LoadSession(aPromiseId,
static_cast<cdm::SessionType>(aSessionType),
@@ -732,16 +733,21 @@ ChromiumCDMChild::RecvDecrypt(const uint
}
mozilla::ipc::IPCResult
ChromiumCDMChild::RecvInitializeVideoDecoder(
const CDMVideoDecoderConfig& aConfig)
{
MOZ_ASSERT(IsOnMessageLoopThread());
MOZ_ASSERT(!mDecoderInitialized);
+ if (!mCDM) {
+ GMP_LOG("ChromiumCDMChild::RecvInitializeVideoDecoder() no CDM");
+ Unused << SendOnDecoderInitDone(cdm::kInitializationError);
+ return IPC_OK();
+ }
cdm::VideoDecoderConfig config;
config.codec =
static_cast<cdm::VideoDecoderConfig::VideoCodec>(aConfig.mCodec());
config.profile =
static_cast<cdm::VideoDecoderConfig::VideoCodecProfile>(aConfig.mProfile());
config.format = static_cast<cdm::VideoFormat>(aConfig.mFormat());
config.coded_size =
mCodedSize = { aConfig.mImageWidth(), aConfig.mImageHeight() };
@@ -756,44 +762,50 @@ ChromiumCDMChild::RecvInitializeVideoDec
}
mozilla::ipc::IPCResult
ChromiumCDMChild::RecvDeinitializeVideoDecoder()
{
MOZ_ASSERT(IsOnMessageLoopThread());
GMP_LOG("ChromiumCDMChild::RecvDeinitializeVideoDecoder()");
MOZ_ASSERT(mDecoderInitialized);
- if (mDecoderInitialized) {
- mDecoderInitialized = false;
+ if (mDecoderInitialized && mCDM) {
mCDM->DeinitializeDecoder(cdm::kStreamTypeVideo);
}
+ mDecoderInitialized = false;
PurgeShmems();
return IPC_OK();
}
mozilla::ipc::IPCResult
ChromiumCDMChild::RecvResetVideoDecoder()
{
MOZ_ASSERT(IsOnMessageLoopThread());
GMP_LOG("ChromiumCDMChild::RecvResetVideoDecoder()");
- if (mDecoderInitialized) {
+ if (mDecoderInitialized && mCDM) {
mCDM->ResetDecoder(cdm::kStreamTypeVideo);
}
Unused << SendResetVideoDecoderComplete();
return IPC_OK();
}
mozilla::ipc::IPCResult
ChromiumCDMChild::RecvDecryptAndDecodeFrame(const CDMInputBuffer& aBuffer)
{
MOZ_ASSERT(IsOnMessageLoopThread());
GMP_LOG("ChromiumCDMChild::RecvDecryptAndDecodeFrame() t=%" PRId64 ")",
aBuffer.mTimestamp());
MOZ_ASSERT(mDecoderInitialized);
+ if (!mCDM) {
+ GMP_LOG("ChromiumCDMChild::RecvDecryptAndDecodeFrame() no CDM");
+ Unused << SendDecodeFailed(cdm::kDecodeError);
+ return IPC_OK();
+ }
+
RefPtr<ChromiumCDMChild> self = this;
auto autoDeallocateShmem = MakeScopeExit([&, self] {
self->DeallocShmem(aBuffer.mData());
});
// The output frame may not have the same timestamp as the frame we put in.
// We may need to input a number of frames before we receive output. The
// CDM's decoder reorders to ensure frames output are in presentation order.
@@ -877,16 +889,21 @@ ChromiumCDMChild::ReturnOutput(WidevineV
Unused << SendDecodedData(output, base->AsArrayBuffer()->ExtractBuffer());
}
}
mozilla::ipc::IPCResult
ChromiumCDMChild::RecvDrain()
{
MOZ_ASSERT(IsOnMessageLoopThread());
+ if (!mCDM) {
+ GMP_LOG("ChromiumCDMChild::RecvDrain() no CDM");
+ Unused << SendDrainComplete();
+ return IPC_OK();
+ }
WidevineVideoFrame frame;
cdm::InputBuffer sample;
cdm::Status rv = mCDM->DecryptAndDecodeFrame(sample, &frame);
GMP_LOG("ChromiumCDMChild::RecvDrain(); DecryptAndDecodeFrame() rv=%d", rv);
if (rv == cdm::kSuccess) {
MOZ_ASSERT(frame.Format() != cdm::kUnknownVideoFormat);
ReturnOutput(frame);
} else {