mozilla-gstreamer-760140.patch
changeset 650 e8c83b144fd1
parent 649 de1740022f78
child 651 19262ba479c4
child 653 38c67b6b2f37
--- a/mozilla-gstreamer-760140.patch	Thu May 30 09:22:10 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,541 +0,0 @@
-# HG changeset patch
-# Parent 74ba8ebd0dc72be84280bd4806f84d9ec1f4e130
-Bug 760140 - Query the GstRegistry for the required demuxers/decoders from canPlayType (TM: 22)
-
-diff --git a/content/media/DecoderTraits.cpp b/content/media/DecoderTraits.cpp
---- a/content/media/DecoderTraits.cpp
-+++ b/content/media/DecoderTraits.cpp
-@@ -7,16 +7,18 @@
- #include "DecoderTraits.h"
- #include "MediaDecoder.h"
- #include "nsCharSeparatedTokenizer.h"
- #ifdef MOZ_MEDIA_PLUGINS
- #include "MediaPluginHost.h"
- #endif
- #ifdef MOZ_GSTREAMER
- #include "mozilla/Preferences.h"
-+#include "GStreamerDecoder.h"
-+#include "nsXPCOMStrings.h"
- #endif
- #ifdef MOZ_WMF
- #include "WMFDecoder.h"
- #endif
- 
- namespace mozilla
- {
- 
-@@ -137,48 +139,35 @@ DecoderTraits::IsWebMType(const nsACStri
-     return false;
-   }
- 
-   return CodecListContains(gWebMTypes, aType);
- }
- #endif
- 
- #ifdef MOZ_GSTREAMER
--static const char* const gH264Types[4] = {
--  "video/mp4",
--  "video/3gpp",
--  "video/quicktime",
--  nullptr
--};
--
- bool
- DecoderTraits::IsGStreamerSupportedType(const nsACString& aMimeType)
- {
-   if (!MediaDecoder::IsGStreamerEnabled())
-     return false;
--  if (IsH264Type(aMimeType))
-+  if (GStreamerDecoder::CanHandleMediaType(aMimeType, nullptr))
-     return true;
-   if (!Preferences::GetBool("media.prefer-gstreamer", false))
-     return false;
- #ifdef MOZ_WEBM
-   if (IsWebMType(aMimeType))
-     return true;
- #endif
- #ifdef MOZ_OGG
-   if (IsOggType(aMimeType))
-     return true;
- #endif
-   return false;
- }
--
--bool
--DecoderTraits::IsH264Type(const nsACString& aType)
--{
--  return CodecListContains(gH264Types, aType);
--}
- #endif
- 
- #ifdef MOZ_WIDGET_GONK
- static const char* const gOmxTypes[6] = {
-   "audio/mpeg",
-   "audio/mp4",
-   "video/mp4",
-   "video/3gpp",
-@@ -190,19 +179,17 @@ bool
- DecoderTraits::IsOmxSupportedType(const nsACString& aType)
- {
-   if (!MediaDecoder::IsOmxEnabled()) {
-     return false;
-   }
- 
-   return CodecListContains(gOmxTypes, aType);
- }
--#endif
- 
--#if defined(MOZ_GSTREAMER) || defined(MOZ_WIDGET_GONK)
- static char const *const gH264Codecs[9] = {
-   "avc1.42E01E",  // H.264 Constrained Baseline Profile Level 3.0
-   "avc1.42001E",  // H.264 Baseline Profile Level 3.0
-   "avc1.58A01E",  // H.264 Extended Profile Level 3.0
-   "avc1.4D401E",  // H.264 Main Profile Level 3.0
-   "avc1.64001E",  // H.264 High Profile Level 3.0
-   "avc1.64001F",  // H.264 High Profile Level 3.1
-   "mp4v.20.3",    // 3GPP
-@@ -303,19 +290,19 @@ DecoderTraits::CanHandleMediaType(const 
- #ifdef MOZ_DASH
-   if (IsDASHMPDType(nsDependentCString(aMIMEType))) {
-     // DASH manifest uses WebM codecs only.
-     codecList = gWebMCodecs;
-     result = CANPLAY_YES;
-   }
- #endif
- #ifdef MOZ_GSTREAMER
--  if (IsH264Type(nsDependentCString(aMIMEType))) {
--    codecList = gH264Codecs;
--    result = CANPLAY_MAYBE;
-+  if (GStreamerDecoder::CanHandleMediaType(nsDependentCString(aMIMEType),
-+                                           aHaveRequestedCodecs ? &aRequestedCodecs : nullptr)) {
-+    return CANPLAY_YES;
-   }
- #endif
- #ifdef MOZ_WIDGET_GONK
-   if (IsOmxSupportedType(nsDependentCString(aMIMEType))) {
-     codecList = gH264Codecs;
-     result = CANPLAY_MAYBE;
-   }
- #endif
-@@ -324,17 +311,17 @@ DecoderTraits::CanHandleMediaType(const 
-     result = CANPLAY_MAYBE;
-   }
- #endif
- #ifdef MOZ_MEDIA_PLUGINS
-   if (MediaDecoder::IsMediaPluginsEnabled() &&
-       GetMediaPluginHost()->FindDecoder(nsDependentCString(aMIMEType), &codecList))
-     result = CANPLAY_MAYBE;
- #endif
--  if (result == CANPLAY_NO || !aHaveRequestedCodecs) {
-+  if (result == CANPLAY_NO || !aHaveRequestedCodecs || !codecList) {
-     return result;
-   }
- 
-   // See http://www.rfc-editor.org/rfc/rfc4281.txt for the description
-   // of the 'codecs' parameter
-   nsCharSeparatedTokenizer tokenizer(aRequestedCodecs, ',');
-   bool expectMoreTokens = false;
-   while (tokenizer.hasMoreTokens()) {
-diff --git a/content/media/DecoderTraits.h b/content/media/DecoderTraits.h
---- a/content/media/DecoderTraits.h
-+++ b/content/media/DecoderTraits.h
-@@ -51,17 +51,16 @@ public:
- #ifdef MOZ_WEBM
-   static bool IsWebMType(const nsACString& aType);
- #endif
- 
- #ifdef MOZ_GSTREAMER
-   // When enabled, use GStreamer for H.264, but not for codecs handled by our
-   // bundled decoders, unless the "media.prefer-gstreamer" pref is set.
-   static bool IsGStreamerSupportedType(const nsACString& aType);
--  static bool IsH264Type(const nsACString& aType);
- #endif
- 
- #ifdef MOZ_WIDGET_GONK
-   static bool IsOmxSupportedType(const nsACString& aType);
- #endif
- 
- #ifdef MOZ_MEDIA_PLUGINS
-   static bool IsMediaPluginsType(const nsACString& aType);
-diff --git a/content/media/gstreamer/GStreamerDecoder.cpp b/content/media/gstreamer/GStreamerDecoder.cpp
---- a/content/media/gstreamer/GStreamerDecoder.cpp
-+++ b/content/media/gstreamer/GStreamerDecoder.cpp
-@@ -2,18 +2,26 @@
- /* 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 "MediaDecoderStateMachine.h"
- #include "GStreamerReader.h"
- #include "GStreamerDecoder.h"
-+#include "GStreamerFormatHelper.h"
- 
- namespace mozilla {
- 
- MediaDecoderStateMachine* GStreamerDecoder::CreateStateMachine()
- {
-   return new MediaDecoderStateMachine(this, new GStreamerReader(this));
- }
- 
-+bool
-+GStreamerDecoder::CanHandleMediaType(const nsACString& aMIMEType,
-+                                     const nsAString* aCodecs)
-+{
-+  return GStreamerFormatHelper::Instance()->CanHandleMediaType(aMIMEType, aCodecs);
-+}
-+
- } // namespace mozilla
- 
-diff --git a/content/media/gstreamer/GStreamerDecoder.h b/content/media/gstreamer/GStreamerDecoder.h
---- a/content/media/gstreamer/GStreamerDecoder.h
-+++ b/content/media/gstreamer/GStreamerDecoder.h
-@@ -3,21 +3,23 @@
- /* 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/. */
- 
- #if !defined(GStreamerDecoder_h_)
- #define GStreamerDecoder_h_
- 
- #include "MediaDecoder.h"
-+#include "nsXPCOMStrings.h"
- 
- namespace mozilla {
- 
- class GStreamerDecoder : public MediaDecoder
- {
- public:
-   virtual MediaDecoder* Clone() { return new GStreamerDecoder(); }
-   virtual MediaDecoderStateMachine* CreateStateMachine();
-+  static bool CanHandleMediaType(const nsACString& aMIMEType, const nsAString* aCodecs);
- };
- 
- } // namespace mozilla
- 
- #endif
-diff --git a/content/media/gstreamer/GStreamerFormatHelper.cpp b/content/media/gstreamer/GStreamerFormatHelper.cpp
-new file mode 100644
---- /dev/null
-+++ b/content/media/gstreamer/GStreamerFormatHelper.cpp
-@@ -0,0 +1,159 @@
-+/* -*- 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 "GStreamerFormatHelper.h"
-+#include "nsCharSeparatedTokenizer.h"
-+#include "nsXPCOMStrings.h"
-+
-+#define ENTRY_FORMAT(entry) entry[0]
-+#define ENTRY_CAPS(entry) entry[1]
-+
-+GStreamerFormatHelper* GStreamerFormatHelper::gInstance = nullptr;
-+
-+GStreamerFormatHelper* GStreamerFormatHelper::Instance() {
-+  if (!gInstance) {
-+    gst_init(nullptr, nullptr);
-+    gInstance = new GStreamerFormatHelper();
-+  }
-+
-+  return gInstance;
-+}
-+
-+void GStreamerFormatHelper::Shutdown() {
-+  if (gInstance) {
-+    delete gInstance;
-+    gInstance = nullptr;
-+  }
-+}
-+
-+char const *const GStreamerFormatHelper::mContainers[4][2] = {
-+  {"video/mp4", "video/quicktime"},
-+  {"video/quicktime", "video/quicktime"},
-+  {"audio/mp4", "audio/mpeg, mpegversion=(int)4"},
-+  {"audio/mpeg", "audio/mpeg, mpegversion=(int)1"},
-+};
-+
-+char const *const GStreamerFormatHelper::mCodecs[8][2] = {
-+  {"avc1.42E01E", "video/x-h264"},
-+  {"avc1.42001E", "video/x-h264"},
-+  {"avc1.58A01E", "video/x-h264"},
-+  {"avc1.4D401E", "video/x-h264"},
-+  {"avc1.64001E", "video/x-h264"},
-+  {"avc1.64001F", "video/x-h264"},
-+  {"mp4v.20.3", "video/3gpp"},
-+  {"mp4a.40.2", "audio/mpeg, mpegversion=(int)4"},
-+};
-+
-+GStreamerFormatHelper::GStreamerFormatHelper()
-+  : mFactories(nullptr),
-+    mCookie(static_cast<uint32_t>(-1))
-+{
-+}
-+
-+GStreamerFormatHelper::~GStreamerFormatHelper() {
-+  if (mFactories)
-+    g_list_free(mFactories);
-+}
-+
-+bool GStreamerFormatHelper::CanHandleMediaType(const nsACString& aMIMEType,
-+                                               const nsAString* aCodecs) {
-+  const char *type;
-+  NS_CStringGetData(aMIMEType, &type, NULL);
-+
-+  GstCaps* caps = ConvertFormatsToCaps(type, aCodecs);
-+  if (!caps) {
-+    return false;
-+  }
-+
-+  bool ret = HaveElementsToProcessCaps(caps);
-+  gst_caps_unref(caps);
-+
-+  return ret;
-+}
-+
-+GstCaps* GStreamerFormatHelper::ConvertFormatsToCaps(const char* aMIMEType,
-+                                                     const nsAString* aCodecs) {
-+  unsigned int i;
-+
-+  /* convert aMIMEType to gst container caps */
-+  const char* capsString = nullptr;
-+  for (i = 0; i < G_N_ELEMENTS(mContainers); i++) {
-+    if (!strcmp(ENTRY_FORMAT(mContainers[i]), aMIMEType)) {
-+      capsString = ENTRY_CAPS(mContainers[i]);
-+      break;
-+    }
-+  }
-+
-+  if (!capsString) {
-+    /* we couldn't find any matching caps */
-+    return nullptr;
-+  }
-+
-+  GstCaps* caps = gst_caps_from_string(capsString);
-+  /* container only */
-+  if (!aCodecs) {
-+    return caps;
-+  }
-+
-+  nsCharSeparatedTokenizer tokenizer(*aCodecs, ',');
-+  while (tokenizer.hasMoreTokens()) {
-+    const nsSubstring& codec = tokenizer.nextToken();
-+    capsString = nullptr;
-+
-+    for (i = 0; i < G_N_ELEMENTS(mCodecs); i++) {
-+      if (codec.EqualsASCII(ENTRY_FORMAT(mCodecs[i]))) {
-+        capsString = ENTRY_CAPS(mCodecs[i]);
-+        break;
-+      }
-+    }
-+
-+    if (!capsString) {
-+      gst_caps_unref(caps);
-+      return nullptr;
-+    }
-+
-+    GstCaps* tmp = gst_caps_from_string(capsString);
-+    /* appends and frees tmp */
-+    gst_caps_append(caps, tmp);
-+  }
-+
-+  return caps;
-+}
-+
-+bool GStreamerFormatHelper::HaveElementsToProcessCaps(GstCaps* aCaps) {
-+
-+  GList* factories = GetFactories();
-+
-+  GList* list;
-+  /* here aCaps contains [containerCaps, [codecCaps1, [codecCaps2, ...]]] so process
-+   * caps structures individually as we want one element for _each_
-+   * structure */
-+  for (unsigned int i = 0; i < gst_caps_get_size(aCaps); i++) {
-+    GstStructure* s = gst_caps_get_structure(aCaps, i);
-+    GstCaps* caps = gst_caps_new_full(gst_structure_copy(s), nullptr);
-+    list = gst_element_factory_list_filter (factories, caps, GST_PAD_SINK, FALSE);
-+    gst_caps_unref(caps);
-+    if (!list) {
-+      return false;
-+    }
-+    g_list_free(list);
-+  }
-+
-+  return true;
-+}
-+
-+GList* GStreamerFormatHelper::GetFactories() {
-+  uint32_t cookie = gst_default_registry_get_feature_list_cookie ();
-+  if (cookie != mCookie) {
-+    g_list_free(mFactories);
-+    mFactories = gst_element_factory_list_get_elements
-+        (GST_ELEMENT_FACTORY_TYPE_DEMUXER | GST_ELEMENT_FACTORY_TYPE_DECODER,
-+         GST_RANK_MARGINAL);
-+    mCookie = cookie;
-+  }
-+
-+  return mFactories;
-+}
-diff --git a/content/media/gstreamer/GStreamerFormatHelper.h b/content/media/gstreamer/GStreamerFormatHelper.h
-new file mode 100644
---- /dev/null
-+++ b/content/media/gstreamer/GStreamerFormatHelper.h
-@@ -0,0 +1,60 @@
-+/* -*- 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/. */
-+
-+#if !defined(GStreamerFormatHelper_h_)
-+#define GStreamerFormatHelper_h_
-+
-+#include <gst/gst.h>
-+#include <mozilla/Types.h>
-+#include "nsXPCOMStrings.h"
-+
-+class GStreamerFormatHelper {
-+  /* This class can be used to query the GStreamer registry for the required
-+   * demuxers/decoders from nsHTMLMediaElement::CanPlayType.
-+   * It implements looking at the GstRegistry to check if elements to
-+   * demux/decode the formats passed to CanPlayType() are actually installed.
-+   */
-+  public:
-+    static GStreamerFormatHelper* Instance();
-+    ~GStreamerFormatHelper();
-+
-+    bool CanHandleMediaType(const nsACString& aMIMEType,
-+                            const nsAString* aCodecs);
-+
-+   static void Shutdown();
-+
-+  private:
-+    GStreamerFormatHelper();
-+    GstCaps* ConvertFormatsToCaps(const char* aMIMEType,
-+                                  const nsAString* aCodecs);
-+    char* const *CodecListFromCaps(GstCaps* aCaps);
-+    bool HaveElementsToProcessCaps(GstCaps* aCaps);
-+    GList* GetFactories();
-+
-+    static GStreamerFormatHelper* gInstance;
-+
-+    /* table to convert from container MIME types to GStreamer elements */
-+    static char const *const mContainers[4][2];
-+
-+    /* table to convert from codec MIME types to GStreamer elements */
-+    static char const *const mCodecs[8][2];
-+
-+    /* list of GStreamer element factories
-+     * Element factories are the basic types retrieved from the GStreamer
-+     * registry, they describe all plugins and elements that GStreamer can
-+     * create.
-+     * This means that element factories are useful for automated element
-+     * instancing, such as what autopluggers do,
-+     * and for creating lists of available elements. */
-+    GList* mFactories;
-+
-+    /* Storage for the default registrys feature list cookie.
-+     * It changes every time a feature is added to or removed from the
-+     * GStreamer registry. */
-+    uint32_t mCookie;
-+};
-+
-+#endif
-diff --git a/content/media/gstreamer/Makefile.in b/content/media/gstreamer/Makefile.in
---- a/content/media/gstreamer/Makefile.in
-+++ b/content/media/gstreamer/Makefile.in
-@@ -13,21 +13,23 @@ include $(DEPTH)/config/autoconf.mk
- MODULE		= content
- LIBRARY_NAME	= gkcongstreamer_s
- LIBXUL_LIBRARY 	= 1
- 
- 
- EXPORTS		+= \
- 		GStreamerDecoder.h \
- 		GStreamerReader.h \
-+		GStreamerFormatHelper.h \
- 		$(NULL)
- 
- CPPSRCS		= \
- 		GStreamerReader.cpp \
- 		GStreamerDecoder.cpp \
-+		GStreamerFormatHelper.cpp \
- 		$(NULL)
- 
- FORCE_STATIC_LIB = 1
- 
- include $(topsrcdir)/config/rules.mk
- 
- CFLAGS		+= $(GSTREAMER_CFLAGS)
- CXXFLAGS	+= $(GSTREAMER_CFLAGS)
-diff --git a/layout/build/Makefile.in b/layout/build/Makefile.in
---- a/layout/build/Makefile.in
-+++ b/layout/build/Makefile.in
-@@ -318,16 +318,20 @@ LOCAL_INCLUDES	+= -I$(srcdir)/../base \
- 		   -I$(topsrcdir)/js/xpconnect/loader \
- 		   -I$(topsrcdir)/caps/include \
- 		   -I$(topsrcdir)/netwerk/base/src \
- 		   -I$(topsrcdir)/content/svg/content/src \
- 		   -I$(topsrcdir)/extensions/cookie \
- 		   -I$(topsrcdir)/netwerk/cookie \
- 		   $(NULL)
- 
-+ifdef MOZ_GSTREAMER
-+LOCAL_INCLUDES	+= $(GSTREAMER_CFLAGS)
-+endif
-+
- ifdef MOZ_B2G_RIL #{
- LOCAL_INCLUDES	+= -I$(topsrcdir)/dom/system/gonk
- endif #}
- 
- ifdef MOZ_B2G_FM #{
- LOCAL_INCLUDES	+= -I$(topsrcdir)/dom/fm
- endif #}
- 
-diff --git a/layout/build/nsLayoutStatics.cpp b/layout/build/nsLayoutStatics.cpp
---- a/layout/build/nsLayoutStatics.cpp
-+++ b/layout/build/nsLayoutStatics.cpp
-@@ -79,16 +79,20 @@
- #ifdef MOZ_MEDIA_PLUGINS
- #include "MediaPluginHost.h"
- #endif
- 
- #ifdef MOZ_WMF
- #include "WMFDecoder.h"
- #endif
- 
-+#ifdef MOZ_GSTREAMER
-+#include "GStreamerFormatHelper.h"
-+#endif
-+
- #ifdef MOZ_SYDNEYAUDIO
- #include "AudioStream.h"
- #endif
- 
- #ifdef MOZ_WIDGET_GONK
- #include "nsVolumeService.h"
- using namespace mozilla::system;
- #endif
-@@ -344,16 +348,20 @@ nsLayoutStatics::Shutdown()
-   nsXBLService::Shutdown();
-   nsAutoCopyListener::Shutdown();
-   FrameLayerBuilder::Shutdown();
- 
- #ifdef MOZ_MEDIA_PLUGINS
-   MediaPluginHost::Shutdown();
- #endif
- 
-+#ifdef MOZ_GSTREAMER
-+  GStreamerFormatHelper::Shutdown();
-+#endif
-+
- #ifdef MOZ_SYDNEYAUDIO
-   AudioStream::ShutdownLibrary();
- #endif
- 
- #ifdef MOZ_WMF
-   WMFDecoder::UnloadDLLs();
- #endif
-