Bug 1330284 - Use MediaContentType in OggDecoder - r?jya draft
authorGerald Squelart <gsquelart@mozilla.com>
Sun, 01 Jan 2017 12:08:36 +1100
changeset 460032 2ccdbb8e97074b55472b868246ada161a258244e
parent 460031 bef62c36b0436b5f66e86bd54ccfbf91dc61699b
child 460033 31f563a4c8880073eb34e52e92147e58d276f2b0
push id41348
push usergsquelart@mozilla.com
push dateThu, 12 Jan 2017 20:50:49 +0000
reviewersjya
bugs1330284
milestone53.0a1
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;
   }