Bug 1330284 - Use MediaContentType in OggDecoder - r=jya
authorGerald Squelart <gsquelart@mozilla.com>
Sun, 01 Jan 2017 12:08:36 +1100
changeset 374466 45673c5c9e207343e9cb41a93350665c38261d04
parent 374465 93c96992037764a3d8dcec38dda60ab941e8f204
child 374467 571b1d64748c01fe7c6b014bacc31187bd4b6f66
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 OggDecoder - r=jya MozReview-Commit-ID: 5sjoy8Gwm4K
dom/media/DecoderTraits.cpp
dom/media/ogg/OggDecoder.cpp
dom/media/ogg/OggDecoder.h
--- a/dom/media/DecoderTraits.cpp
+++ b/dom/media/DecoderTraits.cpp
@@ -58,29 +58,16 @@ CodecListContains(char const *const * aC
   for (int32_t i = 0; aCodecs[i]; ++i) {
     if (aCodec.EqualsASCII(aCodecs[i]))
       return true;
   }
   return false;
 }
 
 static bool
-IsOggSupportedType(const nsACString& aType,
-                   const nsAString& aCodecs = EmptyString())
-{
-  return OggDecoder::CanHandleMediaType(aType, aCodecs);
-}
-
-static bool
-IsOggTypeAndEnabled(const nsACString& aType)
-{
-  return IsOggSupportedType(aType);
-}
-
-static bool
 IsWebMSupportedType(const nsACString& aType,
                     const nsAString& aCodecs = EmptyString())
 {
   return WebMDecoder::CanHandleMediaType(aType, aCodecs);
 }
 
 /* static */ bool
 DecoderTraits::IsWebMTypeAndEnabled(const nsACString& aType)
@@ -198,19 +185,18 @@ CanHandleCodecsType(const MediaContentTy
 {
   // We should have been given a codecs string, though it may be empty.
   MOZ_ASSERT(aType.ExtendedType().HaveCodecs());
 
   // Content type with the the MIME type, no codecs.
   const MediaContentType mimeType(aType.Type());
 
   char const* const* codecList = nullptr;
-  if (IsOggTypeAndEnabled(mimeType.Type().AsString())) {
-    if (IsOggSupportedType(aType.Type().AsString(),
-                           aType.ExtendedType().Codecs().AsString())) {
+  if (OggDecoder::IsSupportedType(mimeType)) {
+    if (OggDecoder::IsSupportedType(aType)) {
       return CANPLAY_YES;
     } else {
       // We can only reach this position if a particular codec was requested,
       // ogg is supported and working: the codec must be invalid.
       return CANPLAY_NO;
     }
   }
   if (IsWaveSupportedType(mimeType.Type().AsString())) {
@@ -309,17 +295,17 @@ CanHandleMediaType(const MediaContentTyp
     if (result == CANPLAY_NO || result == CANPLAY_YES) {
       return result;
     }
   }
 
   // Content type with just the MIME type/subtype, no codecs.
   const MediaContentType mimeType(aType.Type());
 
-  if (IsOggTypeAndEnabled(mimeType.Type().AsString())) {
+  if (OggDecoder::IsSupportedType(mimeType)) {
     return CANPLAY_MAYBE;
   }
   if (IsWaveSupportedType(mimeType.Type().AsString())) {
     return CANPLAY_MAYBE;
   }
   if (DecoderTraits::IsMP4TypeAndEnabled(mimeType.Type().AsString(), aDiagnostics)) {
     return CANPLAY_MAYBE;
   }
@@ -410,17 +396,17 @@ InstantiateDecoder(const MediaContentTyp
   if (IsMP3SupportedType(aType.Type().AsString())) {
     decoder = new MP3Decoder(aOwner);
     return decoder.forget();
   }
   if (IsAACSupportedType(aType.Type().AsString())) {
     decoder = new ADTSDecoder(aOwner);
     return decoder.forget();
   }
-  if (IsOggSupportedType(aType.Type().AsString())) {
+  if (OggDecoder::IsSupportedType(aType)) {
     decoder = new OggDecoder(aOwner);
     return decoder.forget();
   }
   if (IsWaveSupportedType(aType.Type().AsString())) {
     decoder = new WaveDecoder(aOwner);
     return decoder.forget();
   }
   if (IsFlacSupportedType(aType.Type().AsString())) {
@@ -476,16 +462,21 @@ DecoderTraits::CreateDecoder(const nsACS
 MediaDecoderReader* DecoderTraits::CreateReader(const nsACString& aType, AbstractMediaDecoder* aDecoder)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MediaDecoderReader* decoderReader = nullptr;
 
   if (!aDecoder) {
     return decoderReader;
   }
+  Maybe<MediaContentType> type = MakeMediaContentType(aType);
+  if (!type) {
+    return decoderReader;
+  }
+
 #ifdef MOZ_FMP4
   if (IsMP4SupportedType(aType, /* 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
@@ -493,17 +484,17 @@ MediaDecoderReader* DecoderTraits::Creat
     decoderReader = new MediaFormatReader(aDecoder, new ADTSDemuxer(aDecoder->GetResource()));
   } else
   if (IsWaveSupportedType(aType)) {
     decoderReader = new MediaFormatReader(aDecoder, new WAVDemuxer(aDecoder->GetResource()));
   } else
   if (IsFlacSupportedType(aType)) {
     decoderReader = new MediaFormatReader(aDecoder, new FlacDemuxer(aDecoder->GetResource()));
   } else
-  if (IsOggSupportedType(aType)) {
+  if (OggDecoder::IsSupportedType(*type)) {
     decoderReader = new MediaFormatReader(aDecoder, new OggDemuxer(aDecoder->GetResource()));
   } else
 #ifdef MOZ_ANDROID_OMX
   if (MediaDecoder::IsAndroidMediaPluginEnabled() &&
       EnsureAndroidMediaPluginHost()->FindDecoder(aType, nullptr)) {
     decoderReader = new AndroidMediaReader(aDecoder, aType);
   } else
 #endif
@@ -527,18 +518,23 @@ bool DecoderTraits::IsSupportedInVideoDo
   // Forbid playing media in video documents if the user has opted
   // not to, using either the legacy WMF specific pref, or the newer
   // catch-all pref.
   if (!Preferences::GetBool("media.windows-media-foundation.play-stand-alone", true) ||
       !Preferences::GetBool("media.play-stand-alone", true)) {
     return false;
   }
 
+  Maybe<MediaContentType> type = MakeMediaContentType(aType);
+  if (!type) {
+    return false;
+  }
+
   return
-    IsOggSupportedType(aType) ||
+    OggDecoder::IsSupportedType(*type) ||
     IsWebMSupportedType(aType) ||
 #ifdef MOZ_ANDROID_OMX
     (MediaDecoder::IsAndroidMediaPluginEnabled() && IsAndroidMediaType(aType)) ||
 #endif
 #ifdef MOZ_FMP4
     IsMP4SupportedType(aType, /* DecoderDoctorDiagnostics* */ nullptr) ||
 #endif
     IsMP3SupportedType(aType) ||
--- a/dom/media/ogg/OggDecoder.cpp
+++ b/dom/media/ogg/OggDecoder.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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 "MediaPrefs.h"
+#include "MediaContentType.h"
 #include "MediaDecoderStateMachine.h"
 #include "MediaFormatReader.h"
 #include "OggDemuxer.h"
 #include "OggDecoder.h"
 #include "nsContentTypeParser.h"
 
 namespace mozilla {
 
@@ -20,51 +21,38 @@ MediaDecoderStateMachine* OggDecoder::Cr
     new MediaFormatReader(this, demuxer, GetVideoFrameContainer());
   demuxer->SetChainingEvents(&reader->TimedMetadataProducer(),
                              &reader->MediaNotSeekableProducer());
   return new MediaDecoderStateMachine(this, reader);
 }
 
 /* static */
 bool
-OggDecoder::IsEnabled()
+OggDecoder::IsSupportedType(const MediaContentType& aContentType)
 {
-  return MediaPrefs::OggEnabled();
-}
-
-/* static */
-bool
-OggDecoder::CanHandleMediaType(const nsACString& aMIMETypeExcludingCodecs,
-                               const nsAString& aCodecs)
-{
-  if (!IsEnabled()) {
+  if (!MediaPrefs::OggEnabled()) {
     return false;
   }
 
-  const bool isOggAudio = aMIMETypeExcludingCodecs.EqualsASCII("audio/ogg");
-  const bool isOggVideo =
-    aMIMETypeExcludingCodecs.EqualsASCII("video/ogg") ||
-    aMIMETypeExcludingCodecs.EqualsASCII("application/ogg");
-
-  if (!isOggAudio && !isOggVideo) {
+  if (aContentType.Type() != MEDIAMIMETYPE("audio/ogg") &&
+      aContentType.Type() != MEDIAMIMETYPE("video/ogg") &&
+      aContentType.Type() != MEDIAMIMETYPE("application/ogg")) {
     return false;
   }
 
-  nsTArray<nsCString> codecMimes;
-  if (aCodecs.IsEmpty()) {
+  const bool isOggVideo = (aContentType.Type() != MEDIAMIMETYPE("audio/ogg"));
+
+  const MediaCodecs& codecs = aContentType.ExtendedType().Codecs();
+  if (codecs.IsEmpty()) {
     // WebM guarantees that the only codecs it contained are vp8, vp9, opus or vorbis.
     return true;
   }
   // Verify that all the codecs specified are ones that we expect that
   // we can play.
-  nsTArray<nsString> codecs;
-  if (!ParseCodecsString(aCodecs, codecs)) {
-    return false;
-  }
-  for (const nsString& codec : codecs) {
+  for (const auto& codec : codecs.Range()) {
     if ((IsOpusEnabled() && codec.EqualsLiteral("opus")) ||
         codec.EqualsLiteral("vorbis") ||
         (MediaPrefs::FlacInOgg() && codec.EqualsLiteral("flac"))) {
       continue;
     }
     // Note: Only accept Theora in a video content type, not in an audio
     // content type.
     if (isOggVideo && codec.EqualsLiteral("theora")) {
--- a/dom/media/ogg/OggDecoder.h
+++ b/dom/media/ogg/OggDecoder.h
@@ -5,16 +5,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #if !defined(OggDecoder_h_)
 #define OggDecoder_h_
 
 #include "MediaDecoder.h"
 
 namespace mozilla {
 
+class MediaContentType;
+
 class OggDecoder : public MediaDecoder
 {
 public:
   explicit OggDecoder(MediaDecoderOwner* aOwner)
     : MediaDecoder(aOwner)
     , mShutdownBitMonitor("mShutdownBitMonitor")
     , mShutdownBit(false)
   {}
@@ -32,23 +34,20 @@ public:
   // protect the general state with a lock, so we make a special copy and a
   // special-purpose lock. This method may be called on any thread.
   bool IsOggDecoderShutdown() override
   {
     MonitorAutoLock lock(mShutdownBitMonitor);
     return mShutdownBit;
   }
 
-  // Returns true if aMIMEType is a type that we think we can render with the
-  // a platform decoder backend. If aCodecs is non emtpy, it is filled
-  // with a comma-delimited list of codecs to check support for.
-  static bool CanHandleMediaType(const nsACString& aMIMETypeExcludingCodecs,
-                                 const nsAString& aCodecs);
-
-  static bool IsEnabled();
+  // Returns true if aContentType is an Ogg type that we think we can render
+  // with an enabled platform decoder backend.
+  // If provided, codecs are checked for support.
+  static bool IsSupportedType(const MediaContentType& aContentType);
 
 protected:
   void ShutdownBitChanged() override
   {
     MonitorAutoLock lock(mShutdownBitMonitor);
     mShutdownBit = mStateMachineIsShutdown;
   }