1
0
MozillaFirefox/mozilla-gstreamer-760140.patch
Wolfgang Rosenauer 10b98266f1 - update to Firefox 20.0 (bnc#813026)
* requires NSPR 4.9.5 and NSS 3.14.3
  * MFSA 2013-30/CVE-2013-0788/CVE-2013-0789
    Miscellaneous memory safety hazards
  * MFSA 2013-31/CVE-2013-0800 (bmo#825721)
    Out-of-bounds write in Cairo library
  * MFSA 2013-35/CVE-2013-0796 (bmo#827106)
    WebGL crash with Mesa graphics driver on Linux
  * MFSA 2013-36/CVE-2013-0795 (bmo#825697)
    Bypass of SOW protections allows cloning of protected nodes
  * MFSA 2013-37/CVE-2013-0794 (bmo#626775)
    Bypass of tab-modal dialog origin disclosure
  * MFSA 2013-38/CVE-2013-0793 (bmo#803870)
    Cross-site scripting (XSS) using timed history navigations
  * MFSA 2013-39/CVE-2013-0792 (bmo#722831)
    Memory corruption while rendering grayscale PNG images
- use GStreamer 1.0 starting with 12.3 (mozilla-gstreamer-1.patch)

OBS-URL: https://build.opensuse.org/package/show/mozilla:Factory/MozillaFirefox?expand=0&rev=326
2013-04-02 19:00:31 +00:00

543 lines
15 KiB
Diff

# HG changeset patch
# Parent 9fe99f8a584f2369a88bfb5281fd6bc95eb2593c
Bug 760140 - Query the GstRegistry for the required demuxers/decoders from canPlayType
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 @@
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 @@
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 @@
#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 @@
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
@@ -49,17 +49,16 @@
#endif
#ifdef MOZ_WEBM
static bool IsWebMType(const nsACString& aType);
#endif
#ifdef MOZ_GSTREAMER
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 @@
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