Bug 1176989: Inform MediaSourceDecoder about new encryption keys inside TrackBuffersManager. r=cpearce
authorJean-Yves Avenard <jyavenard@mozilla.com>
Tue, 23 Jun 2015 17:19:05 -0700
changeset 250064 4cc713d3e7c063b3fc35dd0f1ff18b974a410198
parent 250063 92adb24e3f8ae2cc56c137c1baee41ba77b30405
child 250065 5b2d133bace37789601bcd52288f957d4e103486
push id28943
push usercbook@mozilla.com
push dateWed, 24 Jun 2015 14:02:00 +0000
treeherdermozilla-central@4cdc1a95a672 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce
bugs1176989
milestone41.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 1176989: Inform MediaSourceDecoder about new encryption keys inside TrackBuffersManager. r=cpearce
dom/media/MediaInfo.h
dom/media/mediasource/TrackBuffersManager.cpp
--- a/dom/media/MediaInfo.h
+++ b/dom/media/MediaInfo.h
@@ -281,16 +281,21 @@ public:
 
   nsRefPtr<MediaByteBuffer> mCodecSpecificConfig;
   nsRefPtr<MediaByteBuffer> mExtraData;
 
 };
 
 class EncryptionInfo {
 public:
+  EncryptionInfo()
+    : mEncrypted(false)
+  {
+  }
+
   struct InitData {
     template<typename AInitDatas>
     InitData(const nsAString& aType, AInitDatas&& aInitData)
       : mType(aType)
       , mInitData(Forward<AInitDatas>(aInitData))
     {
     }
 
@@ -300,32 +305,36 @@ public:
     // Encryption data.
     nsTArray<uint8_t> mInitData;
   };
   typedef nsTArray<InitData> InitDatas;
 
   // True if the stream has encryption metadata
   bool IsEncrypted() const
   {
-    return !mInitDatas.IsEmpty();
+    return mEncrypted;
   }
 
   template<typename AInitDatas>
   void AddInitData(const nsAString& aType, AInitDatas&& aInitData)
   {
     mInitDatas.AppendElement(InitData(aType, Forward<AInitDatas>(aInitData)));
+    mEncrypted = true;
   }
 
   void AddInitData(const EncryptionInfo& aInfo)
   {
     mInitDatas.AppendElements(aInfo.mInitDatas);
+    mEncrypted = !!mInitDatas.Length();
   }
 
   // One 'InitData' per encrypted buffer.
   InitDatas mInitDatas;
+private:
+  bool mEncrypted;
 };
 
 class MediaInfo {
 public:
   bool HasVideo() const
   {
     return mVideo.IsValid();
   }
--- a/dom/media/mediasource/TrackBuffersManager.cpp
+++ b/dom/media/mediasource/TrackBuffersManager.cpp
@@ -34,16 +34,44 @@ AppendStateToStr(TrackBuffersManager::Ap
       return "PARSING_MEDIA_SEGMENT";
     default:
       return "IMPOSSIBLE";
   }
 }
 
 static Atomic<uint32_t> sStreamSourceID(0u);
 
+#ifdef MOZ_EME
+class DispatchKeyNeededEvent : public nsRunnable {
+public:
+  DispatchKeyNeededEvent(AbstractMediaDecoder* aDecoder,
+                         nsTArray<uint8_t>& aInitData,
+                         const nsString& aInitDataType)
+    : mDecoder(aDecoder)
+    , mInitData(aInitData)
+    , mInitDataType(aInitDataType)
+  {
+  }
+  NS_IMETHOD Run() {
+    // Note: Null check the owner, as the decoder could have been shutdown
+    // since this event was dispatched.
+    MediaDecoderOwner* owner = mDecoder->GetOwner();
+    if (owner) {
+      owner->DispatchEncrypted(mInitData, mInitDataType);
+    }
+    mDecoder = nullptr;
+    return NS_OK;
+  }
+private:
+  nsRefPtr<AbstractMediaDecoder> mDecoder;
+  nsTArray<uint8_t> mInitData;
+  nsString mInitDataType;
+};
+#endif // MOZ_EME
+
 TrackBuffersManager::TrackBuffersManager(dom::SourceBuffer* aParent, MediaSourceDecoder* aParentDecoder, const nsACString& aType)
   : mInputBuffer(new MediaByteBuffer)
   , mAppendState(AppendState::WAITING_FOR_SEGMENT)
   , mBufferFull(false)
   , mFirstInitializationSegmentReceived(false)
   , mActiveTrack(false)
   , mType(aType)
   , mParser(ContainerParser::CreateForMIMEType(aType))
@@ -973,27 +1001,29 @@ TrackBuffersManager::OnDemuxerInitDone(n
 
     // 6. Set first initialization segment received flag to true.
     mFirstInitializationSegmentReceived = true;
   } else {
     mAudioTracks.mLastInfo = new SharedTrackInfo(info.mAudio, streamID);
     mVideoTracks.mLastInfo = new SharedTrackInfo(info.mVideo, streamID);
   }
 
-  // TODO CHECK ENCRYPTION
   UniquePtr<EncryptionInfo> crypto = mInputDemuxer->GetCrypto();
   if (crypto && crypto->IsEncrypted()) {
 #ifdef MOZ_EME
     // Try and dispatch 'encrypted'. Won't go if ready state still HAVE_NOTHING.
     for (uint32_t i = 0; i < crypto->mInitDatas.Length(); i++) {
-//      NS_DispatchToMainThread(
-//        new DispatchKeyNeededEvent(mParentDecoder, crypto->mInitDatas[i].mInitData, NS_LITERAL_STRING("cenc")));
+      NS_DispatchToMainThread(
+        new DispatchKeyNeededEvent(mParentDecoder, crypto->mInitDatas[i].mInitData, NS_LITERAL_STRING("cenc")));
     }
 #endif // MOZ_EME
     info.mCrypto = *crypto;
+    // We clear our crypto init data array, so the MediaFormatReader will
+    // not emit an encrypted event for the same init data again.
+    info.mCrypto.mInitDatas.Clear();
     mEncrypted = true;
   }
 
   {
     MonitorAutoLock mon(mMonitor);
     mInfo = info;
   }