Bug 1487416 - Handle cbcs data from mp4parse-rust. r=jya
authorBryce Van Dyk <bvandyk@mozilla.com>
Fri, 11 Jan 2019 15:13:41 +0000
changeset 453498 5686d29392e8aecb57c0f75414bedebf54631447
parent 453497 9851d4b03b567f9aba8645dc3560242266d0ffc6
child 453499 696de1cfcb5eab4e11a5234f5bcda72476010278
push id35357
push usernerli@mozilla.com
push dateFri, 11 Jan 2019 21:54:07 +0000
treeherdermozilla-central@0ce024c91511 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya
bugs1487416
milestone66.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 1487416 - Handle cbcs data from mp4parse-rust. r=jya Handle mp4parse-rust providing cbcs data in the track metadata. Explicitly check the crypto scheme we get in the metadata and error if we encounter something outside of cenc and cbcs -- catch unexpected data early. Differential Revision: https://phabricator.services.mozilla.com/D15878
dom/media/mp4/DecoderData.cpp
dom/media/mp4/MP4Metadata.cpp
--- a/dom/media/mp4/DecoderData.cpp
+++ b/dom/media/mp4/DecoderData.cpp
@@ -42,25 +42,39 @@ mozilla::Result<mozilla::Ok, nsresult> C
 
 bool MP4AudioInfo::IsValid() const {
   return mChannels > 0 && mRate > 0 &&
          // Accept any mime type here, but if it's aac, validate the profile.
          (!mMimeType.EqualsLiteral("audio/mp4a-latm") || mProfile > 0 ||
           mExtendedProfile > 0);
 }
 
-static void UpdateTrackProtectedInfo(mozilla::TrackInfo& aConfig,
-                                     const Mp4parseSinfInfo& aSinf) {
+static MediaResult UpdateTrackProtectedInfo(mozilla::TrackInfo& aConfig,
+                                            const Mp4parseSinfInfo& aSinf) {
   if (aSinf.is_encrypted != 0) {
-    // We currently only handle cenc, but this should be updated once we parse
-    // cbcs encryption data.
-    aConfig.mCrypto.mCryptoScheme = CryptoScheme::Cenc;
+    if (aSinf.scheme_type == MP4_PARSE_ENCRYPTION_SCHEME_TYPE_CENC) {
+      aConfig.mCrypto.mCryptoScheme = CryptoScheme::Cenc;
+    } else if (aSinf.scheme_type == MP4_PARSE_ENCRYPTION_SCHEME_TYPE_CBCS) {
+      aConfig.mCrypto.mCryptoScheme = CryptoScheme::Cbcs;
+    } else {
+      // Unsupported encryption type;
+      return MediaResult(
+          NS_ERROR_DOM_MEDIA_METADATA_ERR,
+          RESULT_DETAIL(
+              "Unsupported encryption scheme encountered aSinf.scheme_type=%d",
+              static_cast<int>(aSinf.scheme_type)));
+    }
     aConfig.mCrypto.mIVSize = aSinf.iv_size;
     aConfig.mCrypto.mKeyId.AppendElements(aSinf.kid.data, aSinf.kid.length);
+    aConfig.mCrypto.mCryptByteBlock = aSinf.crypt_byte_block;
+    aConfig.mCrypto.mSkipByteBlock = aSinf.skip_byte_block;
+    aConfig.mCrypto.mConstantIV.AppendElements(aSinf.constant_iv.data,
+                                               aSinf.constant_iv.length);
   }
+  return NS_OK;
 }
 
 MediaResult MP4AudioInfo::Update(const Mp4parseTrackInfo* track,
                                  const Mp4parseTrackAudioInfo* audio) {
   MOZ_DIAGNOSTIC_ASSERT(audio->sample_info_count > 0,
                         "Must have at least one audio sample info");
   if (audio->sample_info_count == 0) {
     return MediaResult(
@@ -83,17 +97,19 @@ MediaResult MP4AudioInfo::Update(const M
     if (audio->sample_info[i].protected_data.is_encrypted) {
       if (hasCrypto) {
         // Multiple crypto entries found. We don't handle this.
         return MediaResult(
             NS_ERROR_DOM_MEDIA_METADATA_ERR,
             RESULT_DETAIL(
                 "Multiple crypto info encountered while updating audio track"));
       }
-      UpdateTrackProtectedInfo(*this, audio->sample_info[i].protected_data);
+      auto rv =
+          UpdateTrackProtectedInfo(*this, audio->sample_info[i].protected_data);
+      NS_ENSURE_SUCCESS(rv, rv);
       hasCrypto = true;
     }
   }
 
   // We assume that the members of the first sample info are representative of
   // the entire track. This code will need to be updated should this assumption
   // ever not hold. E.g. if we need to handle different codecs in a single
   // track, or if we have different numbers or channels in a single track.
@@ -167,17 +183,19 @@ MediaResult MP4VideoInfo::Update(const M
     if (video->sample_info[i].protected_data.is_encrypted) {
       if (hasCrypto) {
         // Multiple crypto entries found. We don't handle this.
         return MediaResult(
             NS_ERROR_DOM_MEDIA_METADATA_ERR,
             RESULT_DETAIL(
                 "Multiple crypto info encountered while updating video track"));
       }
-      UpdateTrackProtectedInfo(*this, video->sample_info[i].protected_data);
+      auto rv =
+          UpdateTrackProtectedInfo(*this, video->sample_info[i].protected_data);
+      NS_ENSURE_SUCCESS(rv, rv);
       hasCrypto = true;
     }
   }
 
   // We assume that the members of the first sample info are representative of
   // the entire track. This code will need to be updated should this assumption
   // ever not hold. E.g. if we need to handle different codecs in a single
   // track, or if we have different numbers or channels in a single track.
--- a/dom/media/mp4/MP4Metadata.cpp
+++ b/dom/media/mp4/MP4Metadata.cpp
@@ -346,17 +346,17 @@ MP4Metadata::ResultAndTrackInfo MP4Metad
                 ("mp4parse_get_track_audio_info returned error %d", rv));
         return {MediaResult(NS_ERROR_DOM_MEDIA_METADATA_ERR,
                             RESULT_DETAIL("Cannot parse %s track #%zu",
                                           TrackTypeToStr(aType), aTrackNumber)),
                 nullptr};
       }
       auto track = mozilla::MakeUnique<MP4AudioInfo>();
       MediaResult updateStatus = track->Update(&info, &audio);
-      if (updateStatus != NS_OK) {
+      if (NS_FAILED(updateStatus)) {
         MOZ_LOG(gMP4MetadataLog, LogLevel::Warning,
                 ("Updating audio track failed with %s",
                  updateStatus.Message().get()));
         return {MediaResult(NS_ERROR_DOM_MEDIA_METADATA_ERR,
                             RESULT_DETAIL(
                                 "Failed to update %s track #%zu with error: %s",
                                 TrackTypeToStr(aType), aTrackNumber,
                                 updateStatus.Message().get())),
@@ -373,17 +373,17 @@ MP4Metadata::ResultAndTrackInfo MP4Metad
                 ("mp4parse_get_track_video_info returned error %d", rv));
         return {MediaResult(NS_ERROR_DOM_MEDIA_METADATA_ERR,
                             RESULT_DETAIL("Cannot parse %s track #%zu",
                                           TrackTypeToStr(aType), aTrackNumber)),
                 nullptr};
       }
       auto track = mozilla::MakeUnique<MP4VideoInfo>();
       MediaResult updateStatus = track->Update(&info, &video);
-      if (updateStatus != NS_OK) {
+      if (NS_FAILED(updateStatus)) {
         MOZ_LOG(gMP4MetadataLog, LogLevel::Warning,
                 ("Updating video track failed with %s",
                  updateStatus.Message().get()));
         return {MediaResult(NS_ERROR_DOM_MEDIA_METADATA_ERR,
                             RESULT_DETAIL(
                                 "Failed to update %s track #%zu with error: %s",
                                 TrackTypeToStr(aType), aTrackNumber,
                                 updateStatus.Message().get())),