Bug 1315850 - Port the work around from Bug 1343140 to the new CDM video decoder architecture. r=gerald draft
authorChris Pearce <cpearce@mozilla.com>
Tue, 14 Mar 2017 17:17:05 +1300
changeset 504181 404709f1aee80465a953fce1a1e715d49ebfbe35
parent 504180 ef6cab901d74b78f613660f263f5e453d6044536
child 504182 ed70c07bb74fc4db4c99223e5a948289ef93d569
child 504183 e507e48ee633cad8911287fb7296bbb1679a7bcb
push id50748
push userbmo:cpearce@mozilla.com
push dateFri, 24 Mar 2017 01:10:17 +0000
reviewersgerald
bugs1315850, 1343140
milestone55.0a1
Bug 1315850 - Port the work around from Bug 1343140 to the new CDM video decoder architecture. r=gerald MozReview-Commit-ID: EV0bieXIxYM
dom/media/gmp/ChromiumCDMChild.cpp
dom/media/gmp/ChromiumCDMChild.h
--- a/dom/media/gmp/ChromiumCDMChild.cpp
+++ b/dom/media/gmp/ChromiumCDMChild.cpp
@@ -463,17 +463,18 @@ ChromiumCDMChild::RecvInitializeVideoDec
   MOZ_ASSERT(IsOnMessageLoopThread());
   MOZ_ASSERT(!mDecoderInitialized);
   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 = { aConfig.mImageWidth(), aConfig.mImageHeight() };
+  config.coded_size =
+    mCodedSize = { aConfig.mImageWidth(), aConfig.mImageHeight() };
   nsTArray<uint8_t> extraData(aConfig.mExtraData());
   config.extra_data = extraData.Elements();
   config.extra_data_size = extraData.Length();
   cdm::Status status = mCDM->InitializeVideoDecoder(config);
   GMP_LOG("ChromiumCDMChild::RecvInitializeVideoDecoder() status=%u", status);
   Unused << SendOnDecoderInitDone(status);
   mDecoderInitialized = status == cdm::kSuccess;
   return IPC_OK();
@@ -523,22 +524,37 @@ ChromiumCDMChild::RecvDecryptAndDecodeFr
   InitInputBuffer(aBuffer, subsamples, input);
 
   WidevineVideoFrame frame;
   cdm::Status rv = mCDM->DecryptAndDecodeFrame(input, &frame);
   GMP_LOG("WidevineVideoDecoder::Decode(timestamp=%" PRId64 ") rv=%d",
           input.timestamp,
           rv);
 
-  if (rv == cdm::kSuccess) {
-    ReturnOutput(frame);
-  } else if (rv == cdm::kNeedMoreData) {
-    Unused << SendDecoded(gmp::CDMVideoFrame());
-  } else {
-    Unused << SendDecodeFailed(rv);
+  switch (rv) {
+    case cdm::kNoKey:
+      GMP_LOG("NoKey for sample at time=%" PRId64 "!", input.timestamp);
+      // Somehow our key became unusable. Typically this would happen when
+      // a stream requires output protection, and the configuration changed
+      // such that output protection is no longer available. For example, a
+      // non-compliant monitor was attached. The JS player should notice the
+      // key status changing to "output-restricted", and is supposed to switch
+      // to a stream that doesn't require OP. In order to keep the playback
+      // pipeline rolling, just output a black frame. See bug 1343140.
+      frame.InitToBlack(mCodedSize.width, mCodedSize.height, input.timestamp);
+      MOZ_FALLTHROUGH;
+    case cdm::kSuccess:
+      ReturnOutput(frame);
+      break;
+    case cdm::kNeedMoreData:
+      Unused << SendDecoded(gmp::CDMVideoFrame());
+      break;
+    default:
+      Unused << SendDecodeFailed(rv);
+      break;
   }
 
   return IPC_OK();
 }
 
 void
 ChromiumCDMChild::ReturnOutput(WidevineVideoFrame& aFrame)
 {
--- a/dom/media/gmp/ChromiumCDMChild.h
+++ b/dom/media/gmp/ChromiumCDMChild.h
@@ -114,16 +114,18 @@ protected:
 
   GMPContentChild* mPlugin = nullptr;
   cdm::ContentDecryptionModule_8* mCDM = nullptr;
 
   typedef SimpleMap<uint64_t> DurationMap;
   DurationMap mFrameDurations;
   nsTArray<uint32_t> mLoadSessionPromiseIds;
 
+  cdm::Size mCodedSize;
+
   bool mDecoderInitialized = false;
   bool mPersistentStateAllowed = false;
 };
 
 } // namespace gmp
 } // namespace mozilla
 
 #endif // ChromiumCDMChild_h_