diff -r bcb3d1af73f7 -r 3006d73ad2fa mozilla-gstreamer-760140.patch --- a/mozilla-gstreamer-760140.patch Sun Feb 03 16:47:11 2013 +0100 +++ b/mozilla-gstreamer-760140.patch Mon Feb 04 08:00:25 2013 +0100 @@ -1,87 +1,93 @@ -From: Alessandro Decina +# HG changeset patch +# Parent 9fe99f8a584f2369a88bfb5281fd6bc95eb2593c Bug 760140 - Query the GstRegistry for the required demuxers/decoders from canPlayType -diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp ---- a/content/base/src/nsContentUtils.cpp -+++ b/content/base/src/nsContentUtils.cpp -@@ -143,16 +143,19 @@ - #include "xpcprivate.h" // nsXPConnect - #include "nsScriptSecurityManager.h" - #include "nsIChannelPolicy.h" - #include "nsChannelPolicy.h" - #include "nsIContentSecurityPolicy.h" - #include "nsContentDLF.h" - #ifdef MOZ_MEDIA - #include "nsHTMLMediaElement.h" -+#ifdef MOZ_GSTREAMER -+#include "GStreamerDecoder.h" -+#endif + +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 - #include "nsDOMTouchEvent.h" - #include "nsIContentViewer.h" - #include "nsIObjectLoadingContent.h" - #include "nsCCUncollectableMarker.h" - #include "mozilla/Base64.h" + #ifdef MOZ_GSTREAMER #include "mozilla/Preferences.h" - #include "nsDOMMutationObserver.h" -diff --git a/content/html/content/public/nsHTMLMediaElement.h b/content/html/content/public/nsHTMLMediaElement.h ---- a/content/html/content/public/nsHTMLMediaElement.h -+++ b/content/html/content/public/nsHTMLMediaElement.h -@@ -259,17 +259,19 @@ public: - void UpdateMediaSize(nsIntSize size); ++#include "GStreamerDecoder.h" ++#include "nsXPCOMStrings.h" + #endif + #ifdef MOZ_WMF + #include "WMFDecoder.h" + #endif - // Returns the CanPlayStatus indicating if we can handle this - // MIME type. The MIME type should not include the codecs parameter. - // If it returns anything other than CANPLAY_NO then it also - // returns a null-terminated list of supported codecs - // in *aSupportedCodecs. This list should not be freed, it is static data. - static CanPlayStatus CanHandleMediaType(const char* aMIMEType, -- char const *const ** aSupportedCodecs); -+ const char* aCodecs, -+ char const *const ** aSupportedCodecs, -+ bool* aCheckSupportedCodecs); + namespace mozilla + { - // Returns the CanPlayStatus indicating if we can handle the - // full MIME type including the optional codecs parameter. - static CanPlayStatus GetCanPlay(const nsAString& aType); +@@ -137,48 +139,35 @@ + return false; + } - // Returns true if we should handle this MIME type when it appears - // as an or as a toplevel page. If, in practice, our support - // for the type is more limited than appears in the wild, we should return -@@ -292,18 +294,16 @@ public: - #ifdef MOZ_WEBM - static bool IsWebMType(const nsACString& aType); - static const char gWebMTypes[2][11]; - static char const *const gWebMCodecs[4]; + return CodecListContains(gWebMTypes, aType); + } #endif #ifdef MOZ_GSTREAMER - static bool IsGStreamerSupportedType(const nsACString& aType); -- static bool IsH264Type(const nsACString& aType); -- static const char gH264Types[3][16]; +-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 bool IsOmxSupportedType(const nsACString& aType); - static const char gOmxTypes[5][16]; - #endif - - #if defined(MOZ_GSTREAMER) || defined(MOZ_WIDGET_GONK) -diff --git a/content/html/content/src/nsHTMLMediaElement.cpp b/content/html/content/src/nsHTMLMediaElement.cpp ---- a/content/html/content/src/nsHTMLMediaElement.cpp -+++ b/content/html/content/src/nsHTMLMediaElement.cpp -@@ -2213,50 +2213,29 @@ nsHTMLMediaElement::IsWebMType(const nsA - return true; - } + static const char* const gOmxTypes[6] = { + "audio/mpeg", + "audio/mp4", + "video/mp4", + "video/3gpp", +@@ -190,19 +179,17 @@ + DecoderTraits::IsOmxSupportedType(const nsACString& aType) + { + if (!MediaDecoder::IsOmxEnabled()) { + return false; } - return false; + return CodecListContains(gOmxTypes, aType); } - #endif +-#endif -#if defined(MOZ_GSTREAMER) || defined(MOZ_WIDGET_GONK) -+#ifdef MOZ_WIDGET_GONK - char const *const nsHTMLMediaElement::gH264Codecs[9] = { + 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 @@ -89,233 +95,73 @@ "avc1.64001E", // H.264 High Profile Level 3.0 "avc1.64001F", // H.264 High Profile Level 3.1 "mp4v.20.3", // 3GPP - "mp4a.40.2", // AAC-LC - nullptr - }; --#endif -- --#ifdef MOZ_GSTREAMER --const char nsHTMLMediaElement::gH264Types[3][16] = { -- "video/mp4", -- "video/3gpp", -- "video/quicktime", --}; -- --bool --nsHTMLMediaElement::IsH264Type(const nsACString& aType) --{ -- for (uint32_t i = 0; i < ArrayLength(gH264Types); ++i) { -- if (aType.EqualsASCII(gH264Types[i])) { -- return true; -- } -- } -- return false; --} --#endif -- --#ifdef MOZ_WIDGET_GONK -+ - const char nsHTMLMediaElement::gOmxTypes[5][16] = { - "audio/mpeg", - "audio/mp4", - "video/mp4", - "video/3gpp", - "video/quicktime", - }; - -@@ -2319,18 +2298,22 @@ nsHTMLMediaElement::IsDASHMPDType(const - - return false; - } - #endif - - /* static */ - nsHTMLMediaElement::CanPlayStatus - nsHTMLMediaElement::CanHandleMediaType(const char* aMIMEType, -- char const *const ** aCodecList) -+ const char *aCodecs, -+ char const *const ** aCodecList, -+ bool* aCheckCodecList) - { -+ if (aCheckCodecList) -+ *aCheckCodecList = true; - #ifdef MOZ_RAW - if (IsRawType(nsDependentCString(aMIMEType))) { - *aCodecList = gRawCodecs; - return CANPLAY_MAYBE; +@@ -303,19 +290,19 @@ + #ifdef MOZ_DASH + if (IsDASHMPDType(nsDependentCString(aMIMEType))) { + // DASH manifest uses WebM codecs only. + codecList = gWebMCodecs; + result = CANPLAY_YES; } #endif - #ifdef MOZ_OGG - if (IsOggType(nsDependentCString(aMIMEType))) { -@@ -2354,20 +2337,22 @@ nsHTMLMediaElement::CanHandleMediaType(c - if (IsDASHMPDType(nsDependentCString(aMIMEType))) { - // DASH manifest uses WebM codecs only. - *aCodecList = gWebMCodecs; - return CANPLAY_YES; - } - #endif - #ifdef MOZ_GSTREAMER - if (IsH264Type(nsDependentCString(aMIMEType))) { -- *aCodecList = gH264Codecs; -- return CANPLAY_MAYBE; -- } -+ if (aCheckCodecList) -+ *aCheckCodecList = false; -+ if (aCodecList) -+ *aCodecList = nullptr; -+ if (GStreamerDecoder::CanHandleMediaType(aMIMEType, aCodecs)) +- 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))) { - *aCodecList = gH264Codecs; - return CANPLAY_MAYBE; + codecList = gH264Codecs; + result = CANPLAY_MAYBE; } #endif - #ifdef MOZ_MEDIA_PLUGINS -@@ -2388,17 +2373,17 @@ bool nsHTMLMediaElement::ShouldHandleMed - if (IsOggType(nsDependentCString(aMIMEType))) - return true; - #endif - #ifdef MOZ_WEBM - if (IsWebMType(nsDependentCString(aMIMEType))) - return true; - #endif - #ifdef MOZ_GSTREAMER -- if (IsH264Type(nsDependentCString(aMIMEType))) -+ if (GStreamerDecoder::CanHandleMediaType(aMIMEType, nullptr)) - return true; - #endif - #ifdef MOZ_WIDGET_GONK - if (IsOmxSupportedType(nsDependentCString(aMIMEType))) { - return true; +@@ -324,17 +311,17 @@ + result = CANPLAY_MAYBE; } #endif #ifdef MOZ_MEDIA_PLUGINS -@@ -2429,26 +2414,31 @@ nsHTMLMediaElement::GetCanPlay(const nsA - { - nsContentTypeParser parser(aType); - nsAutoString mimeType; - nsresult rv = parser.GetType(mimeType); - if (NS_FAILED(rv)) - return CANPLAY_NO; - - NS_ConvertUTF16toUTF8 mimeTypeUTF8(mimeType); -+ nsAutoString codecs; -+ rv = parser.GetParameter("codecs", codecs); -+ NS_ConvertUTF16toUTF8 codecsUTF8(codecs); - char const *const * supportedCodecs; -+ bool checkSupportedCodecs = true; - CanPlayStatus status = CanHandleMediaType(mimeTypeUTF8.get(), -- &supportedCodecs); -+ codecsUTF8.get(), -+ &supportedCodecs, -+ &checkSupportedCodecs); - if (status == CANPLAY_NO) - return CANPLAY_NO; - -- nsAutoString codecs; -- rv = parser.GetParameter("codecs", codecs); -- if (NS_FAILED(rv)) { -- // Parameter not found or whatever -+ if (codecs.IsEmpty() || !checkSupportedCodecs) { -+ /* no codecs to check for or they were already checked in CanHandleMediaType -+ * above */ - return status; + 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; } - CanPlayStatus result = CANPLAY_YES; // See http://www.rfc-editor.org/rfc/rfc4281.txt for the description // of the 'codecs' parameter - nsCharSeparatedTokenizer tokenizer(codecs, ','); + nsCharSeparatedTokenizer tokenizer(aRequestedCodecs, ','); bool expectMoreTokens = false; -@@ -2487,43 +2477,39 @@ nsHTMLMediaElement::CanPlayType(const ns - } + 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 +@@ -49,17 +49,16 @@ + #endif + + #ifdef MOZ_WEBM + static bool IsWebMType(const nsACString& aType); + #endif #ifdef MOZ_GSTREAMER - bool - nsHTMLMediaElement::IsGStreamerSupportedType(const nsACString& aMimeType) - { - if (!MediaDecoder::IsGStreamerEnabled()) - return false; -- if (IsH264Type(aMimeType)) -+ -+ const char *type; -+ NS_CStringGetData(aMimeType, &type, nullptr); -+ if (GStreamerDecoder::CanHandleMediaType(type, 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; - } + static bool IsGStreamerSupportedType(const nsACString& aType); +- static bool IsH264Type(const nsACString& aType); #endif - already_AddRefed - nsHTMLMediaElement::CreateDecoder(const nsACString& aType) - { - - #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. -- if (IsGStreamerSupportedType(aType)) { -- nsRefPtr decoder = new GStreamerDecoder(); -- if (decoder->Init(this)) { -- return decoder.forget(); -+ if (!Preferences::GetBool("media.prefer-gstreamer", false)) { -+ if (IsGStreamerSupportedType(aType)) { -+ nsRefPtr decoder = new GStreamerDecoder(); -+ if (decoder->Init(this)) { -+ return decoder.forget(); -+ } - } - } + #ifdef MOZ_WIDGET_GONK + static bool IsOmxSupportedType(const nsACString& aType); #endif - #ifdef MOZ_RAW - if (IsRawType(aType)) { - nsRefPtr decoder = new RawDecoder(); - if (decoder->Init(this)) { -@@ -2576,16 +2562,26 @@ nsHTMLMediaElement::CreateDecoder(const - if (IsDASHMPDType(aType)) { - nsRefPtr decoder = new DASHDecoder(); - if (decoder->Init(this)) { - return decoder.forget(); - } - } - #endif - -+#ifdef MOZ_GSTREAMER -+ // use GStreamer as fallback if not preferred -+ if (IsGStreamerSupportedType(aType)) { -+ nsRefPtr decoder = new GStreamerDecoder(); -+ if (decoder->Init(this)) { -+ return decoder.forget(); -+ } -+ } -+#endif -+ - return nullptr; - } - - nsresult nsHTMLMediaElement::InitializeDecoderAsClone(MediaDecoder* aOriginal) - { - NS_ASSERTION(mLoadingSrc, "mLoadingSrc must already be set"); - NS_ASSERTION(mDecoder == nullptr, "Shouldn't have a decoder"); - + #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,23 @@ +@@ -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, @@ -324,7 +170,7 @@ #include "MediaDecoderStateMachine.h" #include "GStreamerReader.h" #include "GStreamerDecoder.h" -+#include "nsGStreamerFormatHelper.h" ++#include "GStreamerFormatHelper.h" namespace mozilla { @@ -333,16 +179,28 @@ return new MediaDecoderStateMachine(this, new GStreamerReader(this)); } -+bool GStreamerDecoder::CanHandleMediaType(const char* aMIMEType, -+ const char* aCodecs) { ++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 -@@ -11,13 +11,14 @@ +@@ -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 { @@ -351,45 +209,24 @@ public: virtual MediaDecoder* Clone() { return new GStreamerDecoder(); } virtual MediaDecoderStateMachine* CreateStateMachine(); -+ static bool CanHandleMediaType(const char* aMIMEType, const char* aCodecs); ++ static bool CanHandleMediaType(const nsACString& aMIMEType, const nsAString* aCodecs); }; } // namespace mozilla #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 -@@ -17,16 +17,17 @@ LIBXUL_LIBRARY = 1 - - EXPORTS += \ - GStreamerDecoder.h \ - $(NULL) - - CPPSRCS = \ - GStreamerReader.cpp \ - GStreamerDecoder.cpp \ -+ nsGStreamerFormatHelper.cpp \ - $(NULL) - - FORCE_STATIC_LIB = 1 - - include $(topsrcdir)/config/rules.mk - - CFLAGS += $(GSTREAMER_CFLAGS) - CXXFLAGS += $(GSTREAMER_CFLAGS) -diff --git a/content/media/gstreamer/nsGStreamerFormatHelper.cpp b/content/media/gstreamer/nsGStreamerFormatHelper.cpp +diff --git a/content/media/gstreamer/GStreamerFormatHelper.cpp b/content/media/gstreamer/GStreamerFormatHelper.cpp new file mode 100644 --- /dev/null -+++ b/content/media/gstreamer/nsGStreamerFormatHelper.cpp -@@ -0,0 +1,149 @@ ++++ 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 "nsGStreamerFormatHelper.h" ++#include "GStreamerFormatHelper.h" +#include "nsCharSeparatedTokenizer.h" +#include "nsXPCOMStrings.h" + @@ -398,7 +235,7 @@ + +GStreamerFormatHelper* GStreamerFormatHelper::gInstance = nullptr; + -+GStreamerFormatHelper *GStreamerFormatHelper::Instance() { ++GStreamerFormatHelper* GStreamerFormatHelper::Instance() { + if (!gInstance) { + gst_init(nullptr, nullptr); + gInstance = new GStreamerFormatHelper(); @@ -407,27 +244,35 @@ + 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(0) ++ mCookie(static_cast(-1)) +{ -+ const char *containers[3][2] = { -+ {"video/mp4", "video/quicktime"}, -+ {"audio/mp4", "audio/mpeg, mpegversion=(int)4"}, -+ {"audio/mpeg", "audio/mpeg, mpegversion=(int)1"}, -+ }; -+ memcpy(mContainers, containers, sizeof(containers)); -+ -+ const char *codecs[7][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"}, -+ {"mp4a.40.2", "audio/mpeg, mpegversion=(int)4"}, -+ {"mp3", "audio/mpeg, mpegversion=(int)1"}, -+ }; -+ memcpy(mCodecs, codecs, sizeof(codecs)); +} + +GStreamerFormatHelper::~GStreamerFormatHelper() { @@ -435,9 +280,12 @@ + g_list_free(mFactories); +} + -+bool GStreamerFormatHelper::CanHandleMediaType(const char* aMIMEType, -+ const char *aCodecs) { -+ GstCaps *caps = ConvertFormatsToCaps(aMIMEType, aCodecs); ++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; + } @@ -448,12 +296,12 @@ + return ret; +} + -+GstCaps *GStreamerFormatHelper::ConvertFormatsToCaps(const char *aMIMEType, -+ const char *aCodecs) { ++GstCaps* GStreamerFormatHelper::ConvertFormatsToCaps(const char* aMIMEType, ++ const nsAString* aCodecs) { + unsigned int i; + + /* convert aMIMEType to gst container caps */ -+ const char *capsString = nullptr; ++ 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]); @@ -466,20 +314,19 @@ + return nullptr; + } + -+ GstCaps *caps = gst_caps_from_string(capsString); ++ GstCaps* caps = gst_caps_from_string(capsString); + /* container only */ + if (!aCodecs) { + return caps; + } + -+ nsDependentCSubstring codecs(aCodecs, strlen(aCodecs)); -+ nsCCharSeparatedTokenizer tokenizer(codecs, ','); ++ nsCharSeparatedTokenizer tokenizer(*aCodecs, ','); + while (tokenizer.hasMoreTokens()) { -+ const nsCSubstring& codec = tokenizer.nextToken(); ++ const nsSubstring& codec = tokenizer.nextToken(); + capsString = nullptr; + + for (i = 0; i < G_N_ELEMENTS(mCodecs); i++) { -+ if (codec.Equals(ENTRY_FORMAT(mCodecs[i]))) { ++ if (codec.EqualsASCII(ENTRY_FORMAT(mCodecs[i]))) { + capsString = ENTRY_CAPS(mCodecs[i]); + break; + } @@ -490,7 +337,7 @@ + return nullptr; + } + -+ GstCaps *tmp = gst_caps_from_string(capsString); ++ GstCaps* tmp = gst_caps_from_string(capsString); + /* appends and frees tmp */ + gst_caps_append(caps, tmp); + } @@ -498,17 +345,17 @@ + return caps; +} + -+bool GStreamerFormatHelper::HaveElementsToProcessCaps(GstCaps *aCaps) { ++bool GStreamerFormatHelper::HaveElementsToProcessCaps(GstCaps* aCaps) { + -+ GList *factories = GetFactories(); ++ GList* factories = GetFactories(); + -+ GList *list; ++ 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); ++ 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) { @@ -520,7 +367,7 @@ + return true; +} + -+GList * GStreamerFormatHelper::GetFactories() { ++GList* GStreamerFormatHelper::GetFactories() { + uint32_t cookie = gst_default_registry_get_feature_list_cookie (); + if (cookie != mCookie) { + g_list_free(mFactories); @@ -532,45 +379,164 @@ + + return mFactories; +} -diff --git a/content/media/gstreamer/nsGStreamerFormatHelper.h b/content/media/gstreamer/nsGStreamerFormatHelper.h +diff --git a/content/media/gstreamer/GStreamerFormatHelper.h b/content/media/gstreamer/GStreamerFormatHelper.h new file mode 100644 --- /dev/null -+++ b/content/media/gstreamer/nsGStreamerFormatHelper.h -@@ -0,0 +1,37 @@ ++++ 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(nsGStreamerFormatHelper_h_) -+#define nsGStreamerFormatHelper_h_ ++#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(); ++ static GStreamerFormatHelper* Instance(); + ~GStreamerFormatHelper(); + -+ bool CanHandleMediaType(const char *aMIMEType, -+ const char *aCodecs); ++ bool CanHandleMediaType(const nsACString& aMIMEType, ++ const nsAString* aCodecs); ++ ++ static void Shutdown(); + + private: + GStreamerFormatHelper(); -+ GstCaps *ConvertFormatsToCaps(const char *aMIMEType, -+ const char *aCodecs); -+ char * const *CodecListFromCaps(GstCaps *aCaps); -+ bool HaveElementsToProcessCaps(GstCaps *aCaps); -+ GList *GetFactories(); ++ 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]; + -+ static GStreamerFormatHelper *gInstance; ++ /* table to convert from codec MIME types to GStreamer elements */ ++ static char const *const mCodecs[8][2]; + -+ const char *mContainers[3][2]; -+ const char *mCodecs[7][2]; -+ GList *mFactories; ++ /* 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 @@ + 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 +@@ -316,16 +316,20 @@ + -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 +@@ -78,16 +78,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 + + #include "nsError.h" + + #include "nsCycleCollector.h" + #include "nsJSEnvironment.h" +@@ -336,16 +340,20 @@ + 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 +