Bug 1330284 - Use MediaContentType in MP4Decoder - r=jya
authorGerald Squelart <gsquelart@mozilla.com>
Sun, 01 Jan 2017 12:27:45 +1100
changeset 374468 f65d9b2df6eedbca013adc4112b8ee3fb7e7a0b8
parent 374467 571b1d64748c01fe7c6b014bacc31187bd4b6f66
child 374469 e0dd6cd20db146d4cf59844f64abb32810827064
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya
bugs1330284
milestone53.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 1330284 - Use MediaContentType in MP4Decoder - r=jya MozReview-Commit-ID: 9Npl40Iicjc
dom/media/DecoderTraits.cpp
dom/media/DecoderTraits.h
dom/media/eme/MediaKeySystemAccess.cpp
dom/media/fmp4/MP4Decoder.cpp
dom/media/fmp4/MP4Decoder.h
dom/media/gtest/TestMediaDataDecoder.cpp
dom/media/mediasource/MediaSource.cpp
--- a/dom/media/DecoderTraits.cpp
+++ b/dom/media/DecoderTraits.cpp
@@ -96,41 +96,22 @@ IsAndroidMediaType(const nsACString& aTy
 #ifdef MOZ_DIRECTSHOW
 static bool
 IsDirectShowSupportedType(const nsACString& aType)
 {
   return DirectShowDecoder::GetSupportedCodecs(aType, nullptr);
 }
 #endif
 
-#ifdef MOZ_FMP4
-static bool
-IsMP4SupportedType(const MediaContentType& aParsedType,
-                   DecoderDoctorDiagnostics* aDiagnostics)
-{
-  return MP4Decoder::CanHandleMediaType(aParsedType, aDiagnostics);
-}
-static bool
-IsMP4SupportedType(const nsACString& aType,
-                   DecoderDoctorDiagnostics* aDiagnostics)
-{
-  Maybe<MediaContentType> contentType = MakeMediaContentType(aType);
-  if (!contentType) {
-    return false;
-  }
-  return IsMP4SupportedType(*contentType, aDiagnostics);
-}
-#endif
-
 /* static */ bool
-DecoderTraits::IsMP4TypeAndEnabled(const nsACString& aType,
-                                   DecoderDoctorDiagnostics* aDiagnostics)
+DecoderTraits::IsMP4SupportedType(const MediaContentType& aType,
+                                  DecoderDoctorDiagnostics* aDiagnostics)
 {
 #ifdef MOZ_FMP4
-  return IsMP4SupportedType(aType, aDiagnostics);
+  return MP4Decoder::IsSupportedType(aType, aDiagnostics);
 #else
   return false;
 #endif
 }
 
 static bool
 IsMP3SupportedType(const nsACString& aType,
                    const nsAString& aCodecs = EmptyString())
@@ -197,18 +178,19 @@ CanHandleCodecsType(const MediaContentTy
     } else {
       // We can only reach this position if a particular codec was requested,
       // webm is supported and working: the codec must be invalid.
       return CANPLAY_NO;
     }
   }
 #endif
 #ifdef MOZ_FMP4
-  if (DecoderTraits::IsMP4TypeAndEnabled(mimeType.Type().AsString(), aDiagnostics)) {
-    if (IsMP4SupportedType(aType, aDiagnostics)) {
+  if (MP4Decoder::IsSupportedType(mimeType,
+                                  /* DecoderDoctorDiagnostics* */ nullptr)) {
+    if (MP4Decoder::IsSupportedType(aType, aDiagnostics)) {
       return CANPLAY_YES;
     } else {
       // We can only reach this position if a particular codec was requested,
       // fmp4 is supported and working: the codec must be invalid.
       return CANPLAY_NO;
     }
   }
 #endif
@@ -281,19 +263,21 @@ CanHandleMediaType(const MediaContentTyp
   const MediaContentType mimeType(aType.Type());
 
   if (OggDecoder::IsSupportedType(mimeType)) {
     return CANPLAY_MAYBE;
   }
   if (IsWaveSupportedType(mimeType.Type().AsString())) {
     return CANPLAY_MAYBE;
   }
-  if (DecoderTraits::IsMP4TypeAndEnabled(mimeType.Type().AsString(), aDiagnostics)) {
+#ifdef MOZ_FMP4
+  if (MP4Decoder::IsSupportedType(mimeType, aDiagnostics)) {
     return CANPLAY_MAYBE;
   }
+#endif
 #if !defined(MOZ_OMX_WEBM_DECODER)
   if (WebMDecoder::IsSupportedType(mimeType)) {
     return CANPLAY_MAYBE;
   }
 #endif
   if (IsMP3SupportedType(mimeType.Type().AsString())) {
     return CANPLAY_MAYBE;
   }
@@ -363,17 +347,17 @@ already_AddRefed<MediaDecoder>
 InstantiateDecoder(const MediaContentType& aType,
                    MediaDecoderOwner* aOwner,
                    DecoderDoctorDiagnostics* aDiagnostics)
 {
   MOZ_ASSERT(NS_IsMainThread());
   RefPtr<MediaDecoder> decoder;
 
 #ifdef MOZ_FMP4
-  if (IsMP4SupportedType(aType.Type().AsString(), aDiagnostics)) {
+  if (MP4Decoder::IsSupportedType(aType, aDiagnostics)) {
     decoder = new MP4Decoder(aOwner);
     return decoder.forget();
   }
 #endif
   if (IsMP3SupportedType(aType.Type().AsString())) {
     decoder = new MP3Decoder(aOwner);
     return decoder.forget();
   }
@@ -448,17 +432,18 @@ MediaDecoderReader* DecoderTraits::Creat
     return decoderReader;
   }
   Maybe<MediaContentType> type = MakeMediaContentType(aType);
   if (!type) {
     return decoderReader;
   }
 
 #ifdef MOZ_FMP4
-  if (IsMP4SupportedType(aType, /* DecoderDoctorDiagnostics* */ nullptr)) {
+  if (MP4Decoder::IsSupportedType(*type,
+                                  /* DecoderDoctorDiagnostics* */ nullptr)) {
     decoderReader = new MediaFormatReader(aDecoder, new MP4Demuxer(aDecoder->GetResource()));
   } else
 #endif
   if (IsMP3SupportedType(aType)) {
     decoderReader = new MediaFormatReader(aDecoder, new mp3::MP3Demuxer(aDecoder->GetResource()));
   } else
   if (IsAACSupportedType(aType)) {
     decoderReader = new MediaFormatReader(aDecoder, new ADTSDemuxer(aDecoder->GetResource()));
@@ -510,17 +495,17 @@ bool DecoderTraits::IsSupportedInVideoDo
 
   return
     OggDecoder::IsSupportedType(*type) ||
     WebMDecoder::IsSupportedType(*type) ||
 #ifdef MOZ_ANDROID_OMX
     (MediaDecoder::IsAndroidMediaPluginEnabled() && IsAndroidMediaType(aType)) ||
 #endif
 #ifdef MOZ_FMP4
-    IsMP4SupportedType(aType, /* DecoderDoctorDiagnostics* */ nullptr) ||
+    MP4Decoder::IsSupportedType(*type, /* DecoderDoctorDiagnostics* */ nullptr) ||
 #endif
     IsMP3SupportedType(aType) ||
     IsAACSupportedType(aType) ||
     IsFlacSupportedType(aType) ||
 #ifdef MOZ_DIRECTSHOW
     IsDirectShowSupportedType(aType) ||
 #endif
     false;
--- a/dom/media/DecoderTraits.h
+++ b/dom/media/DecoderTraits.h
@@ -51,16 +51,18 @@ public:
   static MediaDecoderReader* CreateReader(const nsACString& aType,
                                           AbstractMediaDecoder* aDecoder);
 
   // Returns true if MIME type aType is supported in video documents,
   // or false otherwise. Not all platforms support all MIME types, and
   // vice versa.
   static bool IsSupportedInVideoDocument(const nsACString& aType);
 
-  static bool IsMP4TypeAndEnabled(const nsACString& aType,
-                                  DecoderDoctorDiagnostics* aDiagnostics);
+  // Convenience function that returns false if MOZ_FMP4 is not defined,
+  // otherwise defers to MP4Decoder::IsSupportedType().
+  static bool IsMP4SupportedType(const MediaContentType& aType,
+                                 DecoderDoctorDiagnostics* aDiagnostics);
 };
 
 } // namespace mozilla
 
 #endif
 
--- a/dom/media/eme/MediaKeySystemAccess.cpp
+++ b/dom/media/eme/MediaKeySystemAccess.cpp
@@ -635,18 +635,17 @@ GetSupportedCapabilities(const CodecType
     }
 
     // If the user agent does not support container, continue to the next iteration.
     // The case-sensitivity of string comparisons is determined by the appropriate RFC.
     // (Note: Per RFC 6838 [RFC6838], "Both top-level type and subtype names are
     // case-insensitive."'. We're using nsContentTypeParser and that is
     // case-insensitive and converts all its parameter outputs to lower case.)
     const bool isMP4 =
-      DecoderTraits::IsMP4TypeAndEnabled(contentType.Type().AsString(),
-                                         aDiagnostics);
+      DecoderTraits::IsMP4SupportedType(contentType, aDiagnostics);
     if (isMP4 && !aKeySystem.mMP4.IsSupported()) {
       EME_LOG("MediaKeySystemConfiguration (label='%s') "
               "MediaKeySystemMediaCapability('%s','%s') unsupported; "
               "MP4 requested but unsupported.",
               NS_ConvertUTF16toUTF8(aPartialConfig.mLabel).get(),
               NS_ConvertUTF16toUTF8(contentTypeString).get(),
               NS_ConvertUTF16toUTF8(robustness).get());
       continue;
--- a/dom/media/fmp4/MP4Decoder.cpp
+++ b/dom/media/fmp4/MP4Decoder.cpp
@@ -62,61 +62,57 @@ IsWhitelistedH264Codec(const nsAString& 
          (profile == H264_PROFILE_BASE ||
           profile == H264_PROFILE_MAIN ||
           profile == H264_PROFILE_EXTENDED ||
           profile == H264_PROFILE_HIGH);
 }
 
 /* static */
 bool
-MP4Decoder::CanHandleMediaType(const MediaContentType& aType,
-                               DecoderDoctorDiagnostics* aDiagnostics)
+MP4Decoder::IsSupportedType(const MediaContentType& aType,
+                            DecoderDoctorDiagnostics* aDiagnostics)
 {
   if (!IsEnabled()) {
     return false;
   }
 
   // Whitelist MP4 types, so they explicitly match what we encounter on
   // the web, as opposed to what we use internally (i.e. what our demuxers
   // etc output).
-  const bool isMP4Audio = aType.Type() == MEDIAMIMETYPE("audio/mp4") ||
-                          aType.Type() == MEDIAMIMETYPE("audio/x-m4a");
-  const bool isMP4Video =
+  const bool isAudio = aType.Type() == MEDIAMIMETYPE("audio/mp4")
+                       || aType.Type() == MEDIAMIMETYPE("audio/x-m4a");
+  const bool isVideo = aType.Type() == MEDIAMIMETYPE("video/mp4")
+                       || aType.Type() == MEDIAMIMETYPE("video/quicktime")
   // On B2G, treat 3GPP as MP4 when Gonk PDM is available.
 #ifdef MOZ_GONK_MEDIACODEC
-      aType.Type() == MEDIAMIMETYPE(VIDEO_3GPP) ||
+                       || aType.Type() == MEDIAMIMETYPE(VIDEO_3GPP)
 #endif
-      aType.Type() == MEDIAMIMETYPE("video/mp4") ||
-      aType.Type() == MEDIAMIMETYPE("video/quicktime") ||
-      aType.Type() == MEDIAMIMETYPE("video/x-m4v");
-  if (!isMP4Audio && !isMP4Video) {
+                       || aType.Type() == MEDIAMIMETYPE("video/x-m4v");
+
+  if (!isAudio && !isVideo) {
     return false;
   }
 
   nsTArray<UniquePtr<TrackInfo>> trackInfos;
   if (aType.ExtendedType().Codecs().IsEmpty()) {
     // No codecs specified. Assume H.264
-    if (isMP4Audio) {
+    if (isAudio) {
       trackInfos.AppendElement(
         CreateTrackInfoWithMIMETypeAndContentTypeExtraParameters(
           NS_LITERAL_CSTRING("audio/mp4a-latm"), aType));
     } else {
-      MOZ_ASSERT(isMP4Video);
+      MOZ_ASSERT(isVideo);
       trackInfos.AppendElement(
         CreateTrackInfoWithMIMETypeAndContentTypeExtraParameters(
           NS_LITERAL_CSTRING("video/avc"), aType));
     }
   } else {
     // Verify that all the codecs specified are ones that we expect that
     // we can play.
-    nsTArray<nsString> codecs;
-    if (!ParseCodecsString(aType.ExtendedType().Codecs().AsString(), codecs)) {
-      return false;
-    }
-    for (const nsString& codec : codecs) {
+    for (const auto& codec : aType.ExtendedType().Codecs().Range()) {
       if (IsAACCodecString(codec)) {
         trackInfos.AppendElement(
           CreateTrackInfoWithMIMETypeAndContentTypeExtraParameters(
             NS_LITERAL_CSTRING("audio/mp4a-latm"), aType));
         continue;
       }
       if (codec.EqualsLiteral("mp3")) {
         trackInfos.AppendElement(
@@ -133,17 +129,17 @@ MP4Decoder::CanHandleMediaType(const Med
       if (codec.EqualsLiteral("flac")) {
         trackInfos.AppendElement(
           CreateTrackInfoWithMIMETypeAndContentTypeExtraParameters(
             NS_LITERAL_CSTRING("audio/flac"), aType));
         continue;
       }
       // Note: Only accept H.264 in a video content type, not in an audio
       // content type.
-      if (IsWhitelistedH264Codec(codec) && isMP4Video) {
+      if (IsWhitelistedH264Codec(codec) && isVideo) {
         trackInfos.AppendElement(
           CreateTrackInfoWithMIMETypeAndContentTypeExtraParameters(
             NS_LITERAL_CSTRING("video/avc"), aType));
         continue;
       }
       // Some unsupported codec.
       return false;
     }
--- a/dom/media/fmp4/MP4Decoder.h
+++ b/dom/media/fmp4/MP4Decoder.h
@@ -25,20 +25,21 @@ public:
     if (!IsEnabled()) {
       return nullptr;
     }
     return new MP4Decoder(aOwner);
   }
 
   MediaDecoderStateMachine* CreateStateMachine() override;
 
-  // Returns true if aType is a type that we think we can render with the
-  // a MP4 platform decoder backend.
-  static bool CanHandleMediaType(const MediaContentType& aType,
-                                 DecoderDoctorDiagnostics* aDiagnostics);
+  // Returns true if aContentType is an MP4 type that we think we can render
+  // with the a platform decoder backend.
+  // If provided, codecs are checked for support.
+  static bool IsSupportedType(const MediaContentType& aContentType,
+                              DecoderDoctorDiagnostics* aDiagnostics);
 
   // Return true if aMimeType is a one of the strings used by our demuxers to
   // identify H264. Does not parse general content type strings, i.e. white
   // space matters.
   static bool IsH264(const nsACString& aMimeType);
 
   // Return true if aMimeType is a one of the strings used by our demuxers to
   // identify AAC. Does not parse general content type strings, i.e. white
--- a/dom/media/gtest/TestMediaDataDecoder.cpp
+++ b/dom/media/gtest/TestMediaDataDecoder.cpp
@@ -3,16 +3,17 @@
  * 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 "gtest/gtest.h"
 #include "Benchmark.h"
 #include "MockMediaResource.h"
 #include "DecoderTraits.h"
 #include "MediaContentType.h"
+#include "MP4Decoder.h"
 #include "MP4Demuxer.h"
 #include "WebMDecoder.h"
 #include "WebMDemuxer.h"
 
 using namespace mozilla;
 
 class BenchmarkRunner
 {
@@ -39,18 +40,19 @@ public:
   }
 
 private:
   RefPtr<Benchmark> mBenchmark;
 };
 
 TEST(MediaDataDecoder, H264)
 {
-  if (!DecoderTraits::IsMP4TypeAndEnabled(NS_LITERAL_CSTRING("video/mp4")
-        , /* DecoderDoctorDiagnostics* */ nullptr)) {
+  if (!DecoderTraits::IsMP4SupportedType(
+         MediaContentType(MEDIAMIMETYPE("video/mp4")),
+         /* DecoderDoctorDiagnostics* */ nullptr)) {
     EXPECT_TRUE(true);
   } else {
     RefPtr<MediaResource> resource =
       new MockMediaResource("gizmo.mp4", NS_LITERAL_CSTRING("video/mp4"));
     nsresult rv = resource->Open(nullptr);
     EXPECT_TRUE(NS_SUCCEEDED(rv));
 
     BenchmarkRunner runner(new Benchmark(new MP4Demuxer(resource)));
--- a/dom/media/mediasource/MediaSource.cpp
+++ b/dom/media/mediasource/MediaSource.cpp
@@ -67,18 +67,18 @@ namespace mozilla {
 //   * N/KN editions (Europe and Korea) of Windows 7/8/8.1/10 without the
 //     optional "Windows Media Feature Pack"
 // 2. If H264 hardware acceleration is not available.
 // 3. The CPU is considered to be fast enough
 static bool
 IsWebMForced(DecoderDoctorDiagnostics* aDiagnostics)
 {
   bool mp4supported =
-    DecoderTraits::IsMP4TypeAndEnabled(NS_LITERAL_CSTRING("video/mp4"),
-                                       aDiagnostics);
+    DecoderTraits::IsMP4SupportedType(MediaContentType(MEDIAMIMETYPE("video/mp4")),
+                                      aDiagnostics);
   bool hwsupported = gfx::gfxVars::CanUseHardwareVideoDecoding();
 #ifdef MOZ_WIDGET_ANDROID
   return !mp4supported || !hwsupported || VP9Benchmark::IsVP9DecodeFast() ||
          java::HardwareCodecCapabilityUtils::HasHWVP9();
 #else
   return !mp4supported || !hwsupported || VP9Benchmark::IsVP9DecodeFast();
 #endif
 }