Bug 1176218 - p5. Use DecoderTraits::CanHandleContentType in MediaSource - r=jya draft
authorGerald Squelart <gsquelart@mozilla.com>
Thu, 29 Sep 2016 23:10:15 +1000
changeset 421997 b3d102b02fa671d0a42d70ae7fe66bdd51ac5d86
parent 421996 11bcd26aaf0fd74fb02416b1d0c9b4c2b5d73345
child 421998 1a62ac51fbb33c5cc19f58b34ede28e91fa96d0a
push id31653
push usergsquelart@mozilla.com
push dateFri, 07 Oct 2016 06:47:50 +0000
reviewersjya
bugs1176218
milestone52.0a1
Bug 1176218 - p5. Use DecoderTraits::CanHandleContentType in MediaSource - r=jya Replace both uses of nsContentTypeParser with MediaContentType. MozReview-Commit-ID: KV7ze3ASRf3
dom/media/mediasource/MediaSource.cpp
--- a/dom/media/mediasource/MediaSource.cpp
+++ b/dom/media/mediasource/MediaSource.cpp
@@ -5,27 +5,27 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "MediaSource.h"
 
 #include "AsyncEventRunner.h"
 #include "DecoderTraits.h"
 #include "Benchmark.h"
 #include "DecoderDoctorDiagnostics.h"
+#include "MediaContentType.h"
 #include "MediaResult.h"
 #include "MediaSourceUtils.h"
 #include "SourceBuffer.h"
 #include "SourceBufferList.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/BindingDeclarations.h"
 #include "mozilla/dom/HTMLMediaElement.h"
 #include "mozilla/mozalloc.h"
-#include "nsContentTypeParser.h"
 #include "nsDebug.h"
 #include "nsError.h"
 #include "nsIRunnable.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsPIDOMWindow.h"
 #include "nsString.h"
 #include "nsThreadUtils.h"
 #include "mozilla/Logging.h"
@@ -51,24 +51,16 @@ mozilla::LogModule* GetMediaSourceAPILog
 #define MSE_DEBUG(arg, ...) MOZ_LOG(GetMediaSourceLog(), mozilla::LogLevel::Debug, ("MediaSource(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
 #define MSE_API(arg, ...) MOZ_LOG(GetMediaSourceAPILog(), mozilla::LogLevel::Debug, ("MediaSource(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
 
 // Arbitrary limit.
 static const unsigned int MAX_SOURCE_BUFFERS = 16;
 
 namespace mozilla {
 
-static const char* const gMediaSourceTypes[6] = {
-  "video/mp4",
-  "audio/mp4",
-  "video/webm",
-  "audio/webm",
-  nullptr
-};
-
 // Returns true if we should enable MSE webm regardless of preferences.
 // 1. If MP4/H264 isn't supported:
 //   * Windows XP
 //   * Windows Vista and Server 2008 without the optional "Platform Update Supplement"
 //   * 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
@@ -86,56 +78,50 @@ namespace dom {
 
 /* static */
 nsresult
 MediaSource::IsTypeSupported(const nsAString& aType, DecoderDoctorDiagnostics* aDiagnostics)
 {
   if (aType.IsEmpty()) {
     return NS_ERROR_DOM_TYPE_ERR;
   }
-  nsContentTypeParser parser(aType);
-  nsAutoString mimeType;
-  nsresult rv = parser.GetType(mimeType);
-  if (NS_FAILED(rv)) {
+
+  MediaContentType contentType{aType};
+  if (!contentType.IsValid()) {
+    return NS_ERROR_DOM_TYPE_ERR;
+  }
+
+  if (DecoderTraits::CanHandleContentType(contentType, aDiagnostics)
+      == CANPLAY_NO) {
     return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
   }
-  NS_ConvertUTF16toUTF8 mimeTypeUTF8(mimeType);
 
-  nsAutoString codecs;
-  bool hasCodecs = NS_SUCCEEDED(parser.GetParameter("codecs", codecs));
-
-  for (uint32_t i = 0; gMediaSourceTypes[i]; ++i) {
-    if (mimeType.EqualsASCII(gMediaSourceTypes[i])) {
-      if (DecoderTraits::IsMP4TypeAndEnabled(mimeTypeUTF8, aDiagnostics)) {
-        if (!Preferences::GetBool("media.mediasource.mp4.enabled", false)) {
-          return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
-        }
-        if (hasCodecs &&
-            DecoderTraits::CanHandleCodecsType(mimeTypeUTF8.get(),
-                                               codecs,
-                                               aDiagnostics) == CANPLAY_NO) {
-          return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
-        }
-        return NS_OK;
-      } else if (DecoderTraits::IsWebMTypeAndEnabled(mimeTypeUTF8)) {
-        if (!(Preferences::GetBool("media.mediasource.webm.enabled", false) ||
-              (Preferences::GetBool("media.mediasource.webm.audio.enabled", true) &&
-               DecoderTraits::IsWebMAudioType(mimeTypeUTF8)) ||
-              IsWebMForced(aDiagnostics))) {
-          return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
-        }
-        if (hasCodecs &&
-            DecoderTraits::CanHandleCodecsType(mimeTypeUTF8.get(),
-                                               codecs,
-                                               aDiagnostics) == CANPLAY_NO) {
-          return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
-        }
-        return NS_OK;
-      }
+  // Now we know that this media type could be played.
+  // MediaSource imposes extra restrictions, and some prefs.
+  const nsACString& mimeType = contentType.GetMIMEType();
+  if (mimeType.EqualsASCII("video/mp4") || mimeType.EqualsASCII("audio/mp4")) {
+    if (!Preferences::GetBool("media.mediasource.mp4.enabled", false)) {
+      return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
     }
+    return NS_OK;
+  }
+  if (mimeType.EqualsASCII("video/webm")) {
+    if (!(Preferences::GetBool("media.mediasource.webm.enabled", false) ||
+          IsWebMForced(aDiagnostics))) {
+      return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
+    }
+    return NS_OK;
+  }
+  if (mimeType.EqualsASCII("audio/webm")) {
+    if (!(Preferences::GetBool("media.mediasource.webm.enabled", false) ||
+          Preferences::GetBool("media.mediasource.webm.audio.enabled", true) ||
+          IsWebMForced(aDiagnostics))) {
+      return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
+    }
+    return NS_OK;
   }
 
   return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
 }
 
 /* static */ already_AddRefed<MediaSource>
 MediaSource::Constructor(const GlobalObject& aGlobal,
                          ErrorResult& aRv)
@@ -238,24 +224,23 @@ MediaSource::AddSourceBuffer(const nsASt
   if (mSourceBuffers->Length() >= MAX_SOURCE_BUFFERS) {
     aRv.Throw(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR);
     return nullptr;
   }
   if (mReadyState != MediaSourceReadyState::Open) {
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return nullptr;
   }
-  nsContentTypeParser parser(aType);
-  nsAutoString mimeType;
-  rv = parser.GetType(mimeType);
-  if (NS_FAILED(rv)) {
+  MediaContentType contentType{aType};
+  if (!contentType.IsValid()) {
     aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
     return nullptr;
   }
-  RefPtr<SourceBuffer> sourceBuffer = new SourceBuffer(this, NS_ConvertUTF16toUTF8(mimeType));
+  const nsACString& mimeType = contentType.GetMIMEType();
+  RefPtr<SourceBuffer> sourceBuffer = new SourceBuffer(this, mimeType);
   if (!sourceBuffer) {
     aRv.Throw(NS_ERROR_FAILURE); // XXX need a better error here
     return nullptr;
   }
   mSourceBuffers->Append(sourceBuffer);
   MSE_DEBUG("sourceBuffer=%p", sourceBuffer.get());
   return sourceBuffer.forget();
 }