diff -r de1740022f78 -r e8c83b144fd1 mozilla-gstreamer-760140.patch --- 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(-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 -+#include -+#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 -