Bug 1330284 - Use MediaCodecs in DirectShowDecoder and AndroidMediaPluginHost - r?jya draft
authorGerald Squelart <gsquelart@mozilla.com>
Fri, 23 Dec 2016 08:43:49 +1100
changeset 460045 388a82e668baf5ffe940f393b24fea53e8e9dc79
parent 460044 9c8e146cb88ce0e03cf2824120312c944e2ea90e
child 460046 044a1062f77b3b0b3494b887a341a27f458fb09c
push id41348
push usergsquelart@mozilla.com
push dateThu, 12 Jan 2017 20:50:49 +0000
reviewersjya
bugs1330284
milestone53.0a1
Bug 1330284 - Use MediaCodecs in DirectShowDecoder and AndroidMediaPluginHost - r?jya MozReview-Commit-ID: UJUk1OAAqG
dom/media/DecoderTraits.cpp
dom/media/android/AndroidMediaPluginHost.cpp
dom/media/android/AndroidMediaPluginHost.h
dom/media/directshow/DirectShowDecoder.cpp
dom/media/directshow/DirectShowDecoder.h
--- a/dom/media/DecoderTraits.cpp
+++ b/dom/media/DecoderTraits.cpp
@@ -109,17 +109,16 @@ CanHandleCodecsType(const MediaContentTy
                     DecoderDoctorDiagnostics* aDiagnostics)
 {
   // 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 (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;
     }
@@ -160,35 +159,33 @@ CanHandleCodecsType(const MediaContentTy
     return CANPLAY_YES;
   }
   if (ADTSDecoder::IsSupportedType(aType)) {
     return CANPLAY_YES;
   }
   if (FlacDecoder::IsSupportedType(aType)) {
     return CANPLAY_YES;
   }
+
+  MediaCodecs supportedCodecs;
 #ifdef MOZ_DIRECTSHOW
-  DirectShowDecoder::GetSupportedCodecs(aType, &codecList);
+  DirectShowDecoder::GetSupportedCodecs(aType, &supportedCodecs);
 #endif
 #ifdef MOZ_ANDROID_OMX
   if (MediaDecoder::IsAndroidMediaPluginEnabled()) {
-    EnsureAndroidMediaPluginHost()->FindDecoder(aType, &codecList);
+    EnsureAndroidMediaPluginHost()->FindDecoder(aType, &supportedCodecs);
   }
 #endif
-  if (!codecList) {
+  if (supportedCodecs.IsEmpty()) {
     return CANPLAY_MAYBE;
   }
 
-  // See http://www.rfc-editor.org/rfc/rfc4281.txt for the description
-  // of the 'codecs' parameter
-  for (const auto& token : aType.ExtendedType().Codecs().Range()) {
-    if (!CodecListContains(codecList, token)) {
-      // Totally unsupported codec
-      return CANPLAY_NO;
-    }
+  if (!supportedCodecs.ContainsAll(aType.ExtendedType().Codecs())) {
+    // At least one requested codec is not supported.
+    return CANPLAY_NO;
   }
 
   return CANPLAY_YES;
 }
 
 static
 CanPlayStatus
 CanHandleMediaType(const MediaContentType& aType,
@@ -408,17 +405,17 @@ DecoderTraits::CreateReader(const MediaC
     decoderReader = new AndroidMediaReader(aDecoder, aType);
   } else
 #endif
   if (WebMDecoder::IsSupportedType(aType)) {
     decoderReader =
       new MediaFormatReader(aDecoder, new WebMDemuxer(aDecoder->GetResource()));
   } else
 #ifdef MOZ_DIRECTSHOW
-  if (DirectShowDecoder::GetSupportedCodecs(*type, nullptr)) {
+  if (DirectShowDecoder::GetSupportedCodecs(aType, nullptr)) {
     decoderReader = new DirectShowReader(aDecoder);
   } else
 #endif
   if (false) {} // dummy if to take care of the dangling else
 
   return decoderReader;
 }
 
@@ -446,14 +443,14 @@ bool DecoderTraits::IsSupportedInVideoDo
 #endif
 #ifdef MOZ_FMP4
     MP4Decoder::IsSupportedType(*type, /* DecoderDoctorDiagnostics* */ nullptr) ||
 #endif
     MP3Decoder::IsSupportedType(*type) ||
     ADTSDecoder::IsSupportedType(*type) ||
     FlacDecoder::IsSupportedType(*type) ||
 #ifdef MOZ_DIRECTSHOW
-	  DirectShowDecoder::GetSupportedCodecs(*type, nullptr) ||
+    DirectShowDecoder::GetSupportedCodecs(*type, nullptr) ||
 #endif
     false;
 }
 
 } // namespace mozilla
--- a/dom/media/android/AndroidMediaPluginHost.cpp
+++ b/dom/media/android/AndroidMediaPluginHost.cpp
@@ -223,26 +223,34 @@ AndroidMediaPluginHost::AndroidMediaPlug
 }
 
 AndroidMediaPluginHost::~AndroidMediaPluginHost() {
   mResourceServer->Stop();
   MOZ_COUNT_DTOR(AndroidMediaPluginHost);
 }
 
 bool AndroidMediaPluginHost::FindDecoder(const MediaContentType& aMimeType,
-                                         const char* const** aCodecs)
+                                         MediaCodecs* aCodecs)
 {
   const char *chars;
   size_t len = NS_CStringGetData(aMimeType.Type().AsString(), &chars, nullptr);
   for (size_t n = 0; n < mPlugins.Length(); ++n) {
     Manifest *plugin = mPlugins[n];
     const char* const *codecs;
     if (plugin->CanDecode(chars, len, &codecs)) {
-      if (aCodecs)
-        *aCodecs = codecs;
+      if (aCodecs) {
+        nsString codecsString;
+        for (const char* const* codec = codecs; *codec; ++codec) {
+          if (codecsString.IsEmpty()) {
+            codecsString += ',';
+          }
+          codecsString.AppendASCII(*codec);
+        }
+        *aCodecs = MediaCodecs(codecsString);
+      }
       return true;
     }
   }
   return false;
 }
 
 MPAPI::Decoder *AndroidMediaPluginHost::CreateDecoder(MediaResource *aResource,
                                                       const MediaContentType& aMimeType)
--- a/dom/media/android/AndroidMediaPluginHost.h
+++ b/dom/media/android/AndroidMediaPluginHost.h
@@ -9,29 +9,30 @@
 #include "nsTArray.h"
 #include "MediaResource.h"
 #include "MPAPI.h"
 #include "AndroidMediaResourceServer.h"
 
 namespace mozilla {
 
 class MediaContentType;
+class MediaCodecs;
 
 class AndroidMediaPluginHost {
   RefPtr<AndroidMediaResourceServer> mResourceServer;
   nsTArray<MPAPI::Manifest *> mPlugins;
 
   MPAPI::Manifest *FindPlugin(const nsACString& aMimeType);
 public:
   AndroidMediaPluginHost();
   ~AndroidMediaPluginHost();
 
   static void Shutdown();
 
-  bool FindDecoder(const MediaContentType& aMimeType, const char* const** aCodecs);
+  bool FindDecoder(const MediaContentType& aMimeType, MediaCodecs* aCodecs);
   MPAPI::Decoder *CreateDecoder(mozilla::MediaResource *aResource, const MediaContentType& aMimeType);
   void DestroyDecoder(MPAPI::Decoder *aDecoder);
 };
 
 // Must be called on the main thread. Creates the plugin host if it doesn't
 // already exist.
 AndroidMediaPluginHost *EnsureAndroidMediaPluginHost();
 
--- a/dom/media/directshow/DirectShowDecoder.cpp
+++ b/dom/media/directshow/DirectShowDecoder.cpp
@@ -17,30 +17,26 @@ namespace mozilla {
 MediaDecoderStateMachine* DirectShowDecoder::CreateStateMachine()
 {
   return new MediaDecoderStateMachine(this, new DirectShowReader(this));
 }
 
 /* static */
 bool
 DirectShowDecoder::GetSupportedCodecs(const MediaContentType& aType,
-                                      char const *const ** aCodecList)
+                                      MediaCodecs* aOutCodecs)
 {
   if (!IsEnabled()) {
     return false;
   }
 
-  static char const *const mp3AudioCodecs[] = {
-    "mp3",
-    nullptr
-  };
   if (aType.Type() == MEDIAMIMETYPE("audio/mpeg")
       || aType.Type() == MEDIAMIMETYPE("audio/mp3")) {
-    if (aCodecList) {
-      *aCodecList = mp3AudioCodecs;
+    if (aOutCodecs) {
+      *aOutCodecs = MediaCodecs("mp3");
     }
     return true;
   }
 
   return false;
 }
 
 /* static */
--- a/dom/media/directshow/DirectShowDecoder.h
+++ b/dom/media/directshow/DirectShowDecoder.h
@@ -6,16 +6,17 @@
 
 #if !defined(DirectShowDecoder_h_)
 #define DirectShowDecoder_h_
 
 #include "MediaDecoder.h"
 
 namespace mozilla {
 
+class MediaCodecs;
 class MediaContentType;
 
 // Decoder that uses DirectShow to playback MP3 files only.
 class DirectShowDecoder : public MediaDecoder
 {
 public:
 
   explicit DirectShowDecoder(MediaDecoderOwner* aOwner);
@@ -31,17 +32,17 @@ public:
   MediaDecoderStateMachine* CreateStateMachine() override;
 
   // Returns true if aType is a MIME type that we render with the
   // DirectShow backend. If aCodecList is non null,
   // it is filled with a (static const) null-terminated list of strings
   // denoting the codecs we'll playback. Note that playback is strictly
   // limited to MP3 only.
   static bool GetSupportedCodecs(const MediaContentType& aType,
-                                 char const *const ** aCodecList);
+                                 MediaCodecs* aOutCodecs);
 
   // Returns true if the DirectShow backend is preffed on.
   static bool IsEnabled();
 };
 
 } // namespace mozilla
 
 #endif