summaryrefslogtreecommitdiff
path: root/www
diff options
context:
space:
mode:
authorryoon <ryoon@pkgsrc.org>2014-03-20 21:02:00 +0000
committerryoon <ryoon@pkgsrc.org>2014-03-20 21:02:00 +0000
commit278f6db5d50b1b9500a1a8d94b0a22ec846e1d4d (patch)
treece0e2ea91f9a3039c60cbb36bb260a45a3e1dba7 /www
parent5755901caf1363225c05025c2fb8baa246b80d49 (diff)
downloadpkgsrc-278f6db5d50b1b9500a1a8d94b0a22ec846e1d4d.tar.gz
Update to 28.0
Changelog: NEW VP9 video decoding implemented NEW Mac OS X: Notification Center support for web notifications NEW Horizontal HTML5 audio/video volume control NEW Support for Opus in WebM CHANGED Now that spdy/3 is implemented support for spdy/2 has been removed and servers without spdy/3 will negotiate to http/1 without any penalty DEVELOPER Support for MathML 2.0 'mathvariant' attribute DEVELOPER Background thread hang reporting DEVELOPER Support for multi-line flexbox in layout FIXED Various security fixes Fixed in Firefox 28 MFSA 2014-32 Out-of-bounds write through TypedArrayObject after neutering MFSA 2014-31 Out-of-bounds read/write through neutering ArrayBuffer objects MFSA 2014-30 Use-after-free in TypeObject MFSA 2014-29 Privilege escalation using WebIDL-implemented APIs MFSA 2014-28 SVG filters information disclosure through feDisplacementMap MFSA 2014-27 Memory corruption in Cairo during PDF font rendering MFSA 2014-26 Information disclosure through polygon rendering in MathML MFSA 2014-25 Firefox OS DeviceStorageFile object vulnerable to relative path escape MFSA 2014-24 Android Crash Reporter open to manipulation MFSA 2014-23 Content Security Policy for data: documents not preserved by session restore MFSA 2014-22 WebGL content injection from one domain to rendering in another MFSA 2014-21 Local file access via Open Link in new tab MFSA 2014-20 onbeforeunload and Javascript navigation DOS MFSA 2014-19 Spoofing attack on WebRTC permission prompt MFSA 2014-18 crypto.generateCRMFRequest does not validate type of key MFSA 2014-17 Out of bounds read during WAV file decoding MFSA 2014-16 Files extracted during updates are not always read only MFSA 2014-15 Miscellaneous memory safety hazards (rv:28.0 / rv:24.4)
Diffstat (limited to 'www')
-rw-r--r--www/firefox/Makefile7
-rw-r--r--www/firefox/PLIST77
-rw-r--r--www/firefox/distinfo90
-rw-r--r--www/firefox/patches/patch-aa421
-rw-r--r--www/firefox/patches/patch-ao14
-rw-r--r--www/firefox/patches/patch-as203
-rw-r--r--www/firefox/patches/patch-browser_app_nsBrowserApp.cpp12
-rw-r--r--www/firefox/patches/patch-browser_installer_package-manifest.in8
-rw-r--r--www/firefox/patches/patch-browser_themes_shared_devtools_common.css32
-rw-r--r--www/firefox/patches/patch-browser_themes_shared_devtools_highlighter.inc.css13
-rw-r--r--www/firefox/patches/patch-build_pgo_profileserver.py13
-rw-r--r--www/firefox/patches/patch-config_Makefile.in16
-rw-r--r--www/firefox/patches/patch-config_external_moz.build31
-rw-r--r--www/firefox/patches/patch-config_system-headers32
-rw-r--r--www/firefox/patches/patch-content_base_src_Makefile.in15
-rw-r--r--www/firefox/patches/patch-content_media_Makefile.in21
-rw-r--r--www/firefox/patches/patch-content_media_gstreamer_GStreamerAllocator.cpp203
-rw-r--r--www/firefox/patches/patch-content_media_gstreamer_GStreamerAllocator.h30
-rw-r--r--www/firefox/patches/patch-content_media_gstreamer_GStreamerFormatHelper.cpp29
-rw-r--r--www/firefox/patches/patch-content_media_gstreamer_GStreamerFunctionList.h168
-rw-r--r--www/firefox/patches/patch-content_media_gstreamer_GStreamerLoader.cpp97
-rw-r--r--www/firefox/patches/patch-content_media_gstreamer_GStreamerLoader.h24
-rw-r--r--www/firefox/patches/patch-content_media_gstreamer_GStreamerReader-0.10.cpp208
-rw-r--r--www/firefox/patches/patch-content_media_gstreamer_GStreamerReader.cpp969
-rw-r--r--www/firefox/patches/patch-content_media_gstreamer_GStreamerReader.h103
-rw-r--r--www/firefox/patches/patch-content_media_gstreamer_moz.build25
-rw-r--r--www/firefox/patches/patch-content_media_test_manifest.js17
-rw-r--r--www/firefox/patches/patch-extensions_auth_nsAuthGSSAPI.cpp14
-rw-r--r--www/firefox/patches/patch-gfx_moz.build26
-rw-r--r--www/firefox/patches/patch-gfx_skia_Makefile.in15
-rw-r--r--www/firefox/patches/patch-gfx_skia_moz.build8
-rw-r--r--www/firefox/patches/patch-gfx_thebes_Makefile.in19
-rw-r--r--www/firefox/patches/patch-intl_unicharutil_util_Makefile.in12
-rw-r--r--www/firefox/patches/patch-ipc_chromium_Makefile.in40
-rw-r--r--www/firefox/patches/patch-ipc_glue_GeckoChildProcessHost.cpp16
-rw-r--r--www/firefox/patches/patch-js_src_Makefile.in23
-rw-r--r--www/firefox/patches/patch-js_src_config_system-headers11
-rw-r--r--www/firefox/patches/patch-mb45
-rw-r--r--www/firefox/patches/patch-media_libtheora_Makefile.in14
-rw-r--r--www/firefox/patches/patch-media_libtremor_Makefile.in14
-rw-r--r--www/firefox/patches/patch-media_libvorbis_Makefile.in14
-rw-r--r--www/firefox/patches/patch-media_webrtc_signaling_test_Makefile.in21
-rw-r--r--www/firefox/patches/patch-media_webrtc_trunk_webrtc_modules_audio__coding_codecs_opus_opus.gypi17
-rw-r--r--www/firefox/patches/patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_device__info__linux.cc27
-rw-r--r--www/firefox/patches/patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_video__capture__linux.cc21
-rw-r--r--www/firefox/patches/patch-media_webrtc_trunk_webrtc_system__wrappers_source_spreadsortlib_spreadsort.hpp3402
-rw-r--r--www/firefox/patches/patch-memory_jemalloc_Makefile.in12
-rw-r--r--www/firefox/patches/patch-netwerk_dns_Makefile.in12
-rw-r--r--www/firefox/patches/patch-netwerk_wifi_moz.build12
-rw-r--r--www/firefox/patches/patch-netwerk_wifi_nsWifiScannerFreeBSD.cpp73
-rw-r--r--www/firefox/patches/patch-toolkit_components_osfile_modules_osfile__unix__allthreads.jsm13
-rw-r--r--www/firefox/patches/patch-toolkit_components_osfile_modules_osfile__unix__back.jsm66
-rw-r--r--www/firefox/patches/patch-toolkit_library_Makefile.in53
-rw-r--r--www/firefox/patches/patch-toolkit_xre_Makefile.in10
-rw-r--r--www/firefox/patches/patch-xpcom_base_nsMemoryInfoDumper.cpp31
-rw-r--r--www/firefox/patches/patch-xpcom_base_nsMemoryReporterManager.cpp106
-rw-r--r--www/firefox/patches/patch-xpcom_base_nsStackWalk.cpp29
-rw-r--r--www/firefox/patches/patch-xpcom_base_nscore.h13
-rw-r--r--www/firefox/patches/patch-xpcom_io_nsLocalFileUnix.cpp13
-rw-r--r--www/firefox/patches/patch-xpcom_reflect_xptcall_src_md_unix_moz.build10
-rw-r--r--www/firefox/patches/patch-xpcom_reflect_xptcall_src_md_unix_xptcinvoke__asm__mips.S (renamed from www/firefox/patches/patch-xn)6
-rw-r--r--www/firefox/patches/patch-xpcom_reflect_xptcall_src_md_unix_xptcstubs__asm__mips.S (renamed from www/firefox/patches/patch-xo)6
62 files changed, 3149 insertions, 3953 deletions
diff --git a/www/firefox/Makefile b/www/firefox/Makefile
index f9363f91b74..954335a1e9d 100644
--- a/www/firefox/Makefile
+++ b/www/firefox/Makefile
@@ -1,12 +1,11 @@
-# $NetBSD: Makefile,v 1.155 2014/03/12 23:41:33 ryoon Exp $
+# $NetBSD: Makefile,v 1.156 2014/03/20 21:02:00 ryoon Exp $
FIREFOX_VER= ${MOZ_BRANCH}${MOZ_BRANCH_MINOR}
-MOZ_BRANCH= 27.0
-MOZ_BRANCH_MINOR= .1
+MOZ_BRANCH= 28.0
+MOZ_BRANCH_MINOR=
DISTNAME= firefox-${FIREFOX_VER}.source
PKGNAME= firefox-${MOZ_BRANCH}${MOZ_BRANCH_MINOR:S/b/beta/:S/esr//}
-PKGREVISION= 1
CATEGORIES= www
MASTER_SITES= ${MASTER_SITE_MOZILLA:=firefox/releases/${FIREFOX_VER}/source/}
MASTER_SITES+= ${MASTER_SITE_MOZILLA_ALL:=firefox/releases/${FIREFOX_VER}/source/}
diff --git a/www/firefox/PLIST b/www/firefox/PLIST
index 5147e997605..81f2dd5d07b 100644
--- a/www/firefox/PLIST
+++ b/www/firefox/PLIST
@@ -1,4 +1,4 @@
-@comment $NetBSD: PLIST,v 1.77 2014/02/08 09:36:00 ryoon Exp $
+@comment $NetBSD: PLIST,v 1.78 2014/03/20 21:02:00 ryoon Exp $
bin/firefox
lib/firefox/application.ini
lib/firefox/browser/blocklist.xml
@@ -119,10 +119,12 @@ lib/firefox/browser/chrome/browser/content/browser/devtools/debugger.xul
lib/firefox/browser/chrome/browser/content/browser/devtools/fontinspector/font-inspector.css
lib/firefox/browser/chrome/browser/content/browser/devtools/fontinspector/font-inspector.js
lib/firefox/browser/chrome/browser/content/browser/devtools/fontinspector/font-inspector.xhtml
+lib/firefox/browser/chrome/browser/content/browser/devtools/framework/options-panel.css
lib/firefox/browser/chrome/browser/content/browser/devtools/framework/toolbox-options.js
lib/firefox/browser/chrome/browser/content/browser/devtools/framework/toolbox-options.xul
+lib/firefox/browser/chrome/browser/content/browser/devtools/framework/toolbox-process-window.js
+lib/firefox/browser/chrome/browser/content/browser/devtools/framework/toolbox-process-window.xul
lib/firefox/browser/chrome/browser/content/browser/devtools/framework/toolbox-window.xul
-lib/firefox/browser/chrome/browser/content/browser/devtools/framework/toolbox.css
lib/firefox/browser/chrome/browser/content/browser/devtools/framework/toolbox.xul
lib/firefox/browser/chrome/browser/content/browser/devtools/inspector/inspector.css
lib/firefox/browser/chrome/browser/content/browser/devtools/inspector/inspector.xul
@@ -135,7 +137,6 @@ lib/firefox/browser/chrome/browser/content/browser/devtools/netmonitor-controlle
lib/firefox/browser/chrome/browser/content/browser/devtools/netmonitor-view.js
lib/firefox/browser/chrome/browser/content/browser/devtools/netmonitor.css
lib/firefox/browser/chrome/browser/content/browser/devtools/netmonitor.xul
-lib/firefox/browser/chrome/browser/content/browser/devtools/orion.js
lib/firefox/browser/chrome/browser/content/browser/devtools/profiler.xul
lib/firefox/browser/chrome/browser/content/browser/devtools/profiler/cleopatra/css/devtools.css
lib/firefox/browser/chrome/browser/content/browser/devtools/profiler/cleopatra/css/tree.css
@@ -156,7 +157,8 @@ lib/firefox/browser/chrome/browser/content/browser/devtools/scratchpad.js
lib/firefox/browser/chrome/browser/content/browser/devtools/scratchpad.xul
lib/firefox/browser/chrome/browser/content/browser/devtools/shadereditor.js
lib/firefox/browser/chrome/browser/content/browser/devtools/shadereditor.xul
-lib/firefox/browser/chrome/browser/content/browser/devtools/source-editor-overlay.xul
+lib/firefox/browser/chrome/browser/content/browser/devtools/spectrum-frame.xhtml
+lib/firefox/browser/chrome/browser/content/browser/devtools/spectrum.css
lib/firefox/browser/chrome/browser/content/browser/devtools/splitview.css
lib/firefox/browser/chrome/browser/content/browser/devtools/styleeditor.css
lib/firefox/browser/chrome/browser/content/browser/devtools/styleeditor.xul
@@ -247,7 +249,6 @@ lib/firefox/browser/chrome/browser/content/browser/preferences/in-content/applic
lib/firefox/browser/chrome/browser/content/browser/preferences/in-content/applications.xul
lib/firefox/browser/chrome/browser/content/browser/preferences/in-content/content.js
lib/firefox/browser/chrome/browser/content/browser/preferences/in-content/content.xul
-lib/firefox/browser/chrome/browser/content/browser/preferences/in-content/landing.xul
lib/firefox/browser/chrome/browser/content/browser/preferences/in-content/main.js
lib/firefox/browser/chrome/browser/content/browser/preferences/in-content/main.xul
lib/firefox/browser/chrome/browser/content/browser/preferences/in-content/preferences.js
@@ -346,6 +347,7 @@ lib/firefox/browser/chrome/browser/skin/classic/browser/actionicon-tab.png
lib/firefox/browser/chrome/browser/skin/classic/browser/browser.css
lib/firefox/browser/chrome/browser/skin/classic/browser/click-to-play-warning-stripes.png
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/alerticon-warning.png
+lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/app-manager/add.svg
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/app-manager/connection-footer.css
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/app-manager/device.css
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/app-manager/error.svg
@@ -387,6 +389,7 @@ lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/breadcrumbs/rtl
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/breadcrumbs/rtl-start-selected.png
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/breadcrumbs/rtl-start.png
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/close.png
+lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/command-console.png
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/command-paintflashing.png
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/command-responsivemode.png
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/command-scratchpad.png
@@ -409,6 +412,9 @@ lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/debugger.css
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/dock-bottom.png
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/dock-side.png
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/dropmarker.png
+lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/editor-breakpoint.png
+lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/editor-debug-location.png
+lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/editor-error.png
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/floating-scrollbars-light.css
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/floating-scrollbars.css
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/font-inspector.css
@@ -425,12 +431,6 @@ lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/markup-view.css
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/netmonitor.css
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/noise.png
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/option-icon.png
-lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/orion-breakpoint.png
-lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/orion-container.css
-lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/orion-debug-location.png
-lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/orion-error.png
-lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/orion-task.png
-lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/orion.css
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/profiler-stopwatch.png
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/profiler.css
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/responsive-background.png
@@ -455,7 +455,14 @@ lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/tool-profiler.p
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/tool-scratchpad.png
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/tool-styleeditor.png
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/tool-webconsole.png
-lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/toolbox.css
+lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/tooltip/arrow-horizontal-dark.png
+lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/tooltip/arrow-horizontal-dark@2x.png
+lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/tooltip/arrow-horizontal-light.png
+lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/tooltip/arrow-horizontal-light@2x.png
+lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/tooltip/arrow-vertical-dark.png
+lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/tooltip/arrow-vertical-dark@2x.png
+lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/tooltip/arrow-vertical-light.png
+lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/tooltip/arrow-vertical-light@2x.png
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/undock.png
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/vview-delete.png
lib/firefox/browser/chrome/browser/skin/classic/browser/devtools/vview-edit.png
@@ -615,7 +622,6 @@ lib/firefox/browser/chrome/en-US/locale/browser/devtools/sourceeditor.properties
lib/firefox/browser/chrome/en-US/locale/browser/devtools/styleeditor.dtd
lib/firefox/browser/chrome/en-US/locale/browser/devtools/styleeditor.properties
lib/firefox/browser/chrome/en-US/locale/browser/devtools/styleinspector.dtd
-lib/firefox/browser/chrome/en-US/locale/browser/devtools/styleinspector.properties
lib/firefox/browser/chrome/en-US/locale/browser/devtools/tilt.properties
lib/firefox/browser/chrome/en-US/locale/browser/devtools/toolbox.dtd
lib/firefox/browser/chrome/en-US/locale/browser/devtools/toolbox.properties
@@ -698,6 +704,7 @@ lib/firefox/browser/chrome/pdfjs/content/PdfJs.jsm
lib/firefox/browser/chrome/pdfjs/content/PdfJsTelemetry.jsm
lib/firefox/browser/chrome/pdfjs/content/build/pdf.js
lib/firefox/browser/chrome/pdfjs/content/build/pdf.worker.js
+lib/firefox/browser/chrome/pdfjs/content/default_preferences.js
lib/firefox/browser/chrome/pdfjs/content/network.js
lib/firefox/browser/chrome/pdfjs/content/web/debugger.js
lib/firefox/browser/chrome/pdfjs/content/web/images/annotation-check.svg
@@ -806,7 +813,6 @@ lib/firefox/browser/modules/devtools/CmdScratchpad.jsm
lib/firefox/browser/modules/devtools/CmdTilt.jsm
lib/firefox/browser/modules/devtools/Commands.jsm
lib/firefox/browser/modules/devtools/DOMHelpers.jsm
-lib/firefox/browser/modules/devtools/DebuggerProcess.jsm
lib/firefox/browser/modules/devtools/DeveloperToolbar.jsm
lib/firefox/browser/modules/devtools/FloatingScrollbars.jsm
lib/firefox/browser/modules/devtools/Jsbeautify.jsm
@@ -818,6 +824,7 @@ lib/firefox/browser/modules/devtools/StyleEditorPanel.jsm
lib/firefox/browser/modules/devtools/StyleEditorUI.jsm
lib/firefox/browser/modules/devtools/StyleEditorUtil.jsm
lib/firefox/browser/modules/devtools/StyleSheetEditor.jsm
+lib/firefox/browser/modules/devtools/ToolboxProcess.jsm
lib/firefox/browser/modules/devtools/VariablesView.jsm
lib/firefox/browser/modules/devtools/VariablesViewController.jsm
lib/firefox/browser/modules/devtools/ViewHelpers.jsm
@@ -828,11 +835,12 @@ lib/firefox/browser/modules/devtools/app-manager/connection-store.js
lib/firefox/browser/modules/devtools/app-manager/device-store.js
lib/firefox/browser/modules/devtools/app-manager/simulators-store.js
lib/firefox/browser/modules/devtools/app-manager/webapps-store.js
-lib/firefox/browser/modules/devtools/debugger/debugger-panel.js
+lib/firefox/browser/modules/devtools/debugger/panel.js
lib/firefox/browser/modules/devtools/framework/sidebar.js
lib/firefox/browser/modules/devtools/framework/target.js
lib/firefox/browser/modules/devtools/framework/toolbox-hosts.js
lib/firefox/browser/modules/devtools/framework/toolbox-options.js
+lib/firefox/browser/modules/devtools/framework/toolbox-process-window.js
lib/firefox/browser/modules/devtools/framework/toolbox.js
lib/firefox/browser/modules/devtools/gDevTools.jsm
lib/firefox/browser/modules/devtools/gcli.jsm
@@ -844,7 +852,7 @@ lib/firefox/browser/modules/devtools/inspector/selector-search.js
lib/firefox/browser/modules/devtools/main.js
lib/firefox/browser/modules/devtools/markupview/html-editor.js
lib/firefox/browser/modules/devtools/markupview/markup-view.js
-lib/firefox/browser/modules/devtools/netmonitor/netmonitor-panel.js
+lib/firefox/browser/modules/devtools/netmonitor/panel.js
lib/firefox/browser/modules/devtools/profiler/cleopatra.js
lib/firefox/browser/modules/devtools/profiler/commands.js
lib/firefox/browser/modules/devtools/profiler/consts.js
@@ -862,12 +870,10 @@ lib/firefox/browser/modules/devtools/shared/observable-object.js
lib/firefox/browser/modules/devtools/shared/telemetry.js
lib/firefox/browser/modules/devtools/shared/theme-switching.js
lib/firefox/browser/modules/devtools/shared/undo.js
+lib/firefox/browser/modules/devtools/shared/widgets/Spectrum.js
lib/firefox/browser/modules/devtools/shared/widgets/Tooltip.js
lib/firefox/browser/modules/devtools/sourceeditor/debugger.js
lib/firefox/browser/modules/devtools/sourceeditor/editor.js
-lib/firefox/browser/modules/devtools/sourceeditor/source-editor-orion.jsm
-lib/firefox/browser/modules/devtools/sourceeditor/source-editor-ui.jsm
-lib/firefox/browser/modules/devtools/sourceeditor/source-editor.jsm
lib/firefox/browser/modules/devtools/styleinspector/computed-view.js
lib/firefox/browser/modules/devtools/styleinspector/rule-view.js
lib/firefox/browser/modules/devtools/styleinspector/style-inspector.js
@@ -894,16 +900,19 @@ lib/firefox/browser/modules/sessionstore/PageStyle.jsm
lib/firefox/browser/modules/sessionstore/PrivacyLevel.jsm
lib/firefox/browser/modules/sessionstore/RecentlyClosedTabsAndWindowsMenuUtils.jsm
lib/firefox/browser/modules/sessionstore/SessionCookies.jsm
+lib/firefox/browser/modules/sessionstore/SessionFile.jsm
lib/firefox/browser/modules/sessionstore/SessionHistory.jsm
lib/firefox/browser/modules/sessionstore/SessionMigration.jsm
lib/firefox/browser/modules/sessionstore/SessionSaver.jsm
lib/firefox/browser/modules/sessionstore/SessionStorage.jsm
lib/firefox/browser/modules/sessionstore/SessionStore.jsm
lib/firefox/browser/modules/sessionstore/SessionWorker.js
+lib/firefox/browser/modules/sessionstore/TabAttributes.jsm
+lib/firefox/browser/modules/sessionstore/TabState.jsm
lib/firefox/browser/modules/sessionstore/TabStateCache.jsm
lib/firefox/browser/modules/sessionstore/TextAndScrollData.jsm
+lib/firefox/browser/modules/sessionstore/Utils.jsm
lib/firefox/browser/modules/sessionstore/XPathGenerator.jsm
-lib/firefox/browser/modules/sessionstore/_SessionFile.jsm
lib/firefox/browser/modules/tabview/utils.jsm
lib/firefox/browser/modules/webappsUI.jsm
lib/firefox/browser/modules/webrtcUI.jsm
@@ -946,6 +955,8 @@ lib/firefox/chrome/en-US/locale/en-US/global/appPicker.dtd
lib/firefox/chrome/en-US/locale/en-US/global/appstrings.properties
lib/firefox/chrome/en-US/locale/en-US/global/brand.dtd
lib/firefox/chrome/en-US/locale/en-US/global/browser.properties
+lib/firefox/chrome/en-US/locale/en-US/global/charsetMenu.dtd
+lib/firefox/chrome/en-US/locale/en-US/global/charsetMenu.properties
lib/firefox/chrome/en-US/locale/en-US/global/charsetOverlay.dtd
lib/firefox/chrome/en-US/locale/en-US/global/charsetTitles.properties
lib/firefox/chrome/en-US/locale/en-US/global/commonDialog.dtd
@@ -964,6 +975,7 @@ lib/firefox/chrome/en-US/locale/en-US/global/customizeToolbar.properties
lib/firefox/chrome/en-US/locale/en-US/global/dateFormat.properties
lib/firefox/chrome/en-US/locale/en-US/global/datetimepicker.dtd
lib/firefox/chrome/en-US/locale/en-US/global/devtools/debugger.properties
+lib/firefox/chrome/en-US/locale/en-US/global/devtools/styleinspector.properties
lib/firefox/chrome/en-US/locale/en-US/global/dialog.properties
lib/firefox/chrome/en-US/locale/en-US/global/dialogOverlay.dtd
lib/firefox/chrome/en-US/locale/en-US/global/dom/dom.properties
@@ -1159,8 +1171,10 @@ lib/firefox/chrome/toolkit/content/global/aboutTelemetry.css
lib/firefox/chrome/toolkit/content/global/aboutTelemetry.js
lib/firefox/chrome/toolkit/content/global/aboutTelemetry.xhtml
lib/firefox/chrome/toolkit/content/global/accessibility/AccessFu.css
+lib/firefox/chrome/toolkit/content/global/accessibility/clicked.ogg
lib/firefox/chrome/toolkit/content/global/accessibility/content-script.js
-lib/firefox/chrome/toolkit/content/global/accessibility/tick.wav
+lib/firefox/chrome/toolkit/content/global/accessibility/virtual_cursor_key.ogg
+lib/firefox/chrome/toolkit/content/global/accessibility/virtual_cursor_move.ogg
lib/firefox/chrome/toolkit/content/global/alerts/alert.css
lib/firefox/chrome/toolkit/content/global/alerts/alert.js
lib/firefox/chrome/toolkit/content/global/alerts/alert.xul
@@ -1238,6 +1252,7 @@ lib/firefox/chrome/toolkit/content/global/filepicker.xul
lib/firefox/chrome/toolkit/content/global/findUtils.js
lib/firefox/chrome/toolkit/content/global/finddialog.js
lib/firefox/chrome/toolkit/content/global/finddialog.xul
+lib/firefox/chrome/toolkit/content/global/forms.js
lib/firefox/chrome/toolkit/content/global/globalOverlay.js
lib/firefox/chrome/toolkit/content/global/globalOverlay.xul
lib/firefox/chrome/toolkit/content/global/inlineSpellCheckUI.js
@@ -1519,7 +1534,8 @@ lib/firefox/chrome/toolkit/skin/classic/global/media/throbber.png
lib/firefox/chrome/toolkit/skin/classic/global/media/unmuteButton.png
lib/firefox/chrome/toolkit/skin/classic/global/media/videoClickToPlayButton.svg
lib/firefox/chrome/toolkit/skin/classic/global/media/videocontrols.css
-lib/firefox/chrome/toolkit/skin/classic/global/media/volumeThumb.png
+lib/firefox/chrome/toolkit/skin/classic/global/media/volume-empty.png
+lib/firefox/chrome/toolkit/skin/classic/global/media/volume-full.png
lib/firefox/chrome/toolkit/skin/classic/global/menu.css
lib/firefox/chrome/toolkit/skin/classic/global/menulist.css
lib/firefox/chrome/toolkit/skin/classic/global/netError.css
@@ -1641,8 +1657,12 @@ lib/firefox/chrome/toolkit/skin/classic/mozapps/update/updates.css
lib/firefox/chrome/toolkit/skin/classic/mozapps/viewsource/viewsource.css
lib/firefox/chrome/toolkit/skin/classic/mozapps/xpinstall/xpinstallConfirm.css
lib/firefox/chrome/toolkit/skin/classic/mozapps/xpinstall/xpinstallItemGeneric.png
+lib/firefox/components/ActivityMessageConfigurator.js
+lib/firefox/components/ActivityOptions.js
+lib/firefox/components/ActivityProxy.js
+lib/firefox/components/ActivityRequestHandler.js
+lib/firefox/components/ActivityWrapper.js
lib/firefox/components/AlarmsManager.js
-lib/firefox/components/AppProtocolHandler.js
lib/firefox/components/AppsService.js
lib/firefox/components/BrowserElementParent.js
lib/firefox/components/ColorAnalyzer.js
@@ -1667,8 +1687,9 @@ lib/firefox/components/PlacesCategoriesStarter.js
lib/firefox/components/Push.js
lib/firefox/components/PushServiceLauncher.js
lib/firefox/components/SettingsManager.js
-lib/firefox/components/SettingsService.js
lib/firefox/components/SiteSpecificUserAgent.js
+lib/firefox/components/SystemMessageInternal.js
+lib/firefox/components/SystemMessageManager.js
lib/firefox/components/TCPServerSocket.js
lib/firefox/components/TCPSocket.js
lib/firefox/components/TCPSocketParentIntermediary.js
@@ -1785,6 +1806,7 @@ lib/firefox/modules/AppsServiceChild.jsm
lib/firefox/modules/AppsUtils.jsm
lib/firefox/modules/AsyncShutdown.jsm
lib/firefox/modules/AsyncSpellCheckTestHelper.jsm
+lib/firefox/modules/AutoCompleteE10S.jsm
lib/firefox/modules/BackgroundPageThumbs.jsm
lib/firefox/modules/BookmarkHTMLUtils.jsm
lib/firefox/modules/BookmarkJSONUtils.jsm
@@ -1792,6 +1814,7 @@ lib/firefox/modules/BrowserElementParent.jsm
lib/firefox/modules/BrowserElementPromptService.jsm
lib/firefox/modules/CSPUtils.jsm
lib/firefox/modules/CertUtils.jsm
+lib/firefox/modules/CharsetMenu.jsm
lib/firefox/modules/ChromeManifestParser.jsm
lib/firefox/modules/ClusterLib.js
lib/firefox/modules/ColorAnalyzer_worker.js
@@ -1832,6 +1855,8 @@ lib/firefox/modules/FormHistory.jsm
lib/firefox/modules/FrameWorker.jsm
lib/firefox/modules/FrameWorkerContent.js
lib/firefox/modules/FreeSpaceWatcher.jsm
+lib/firefox/modules/FxAccounts.jsm
+lib/firefox/modules/FxAccountsClient.jsm
lib/firefox/modules/Geometry.jsm
lib/firefox/modules/HealthReport.jsm
lib/firefox/modules/Http.jsm
@@ -1919,19 +1944,19 @@ lib/firefox/modules/WebappOSUtils.jsm
lib/firefox/modules/Webapps.jsm
lib/firefox/modules/WebappsInstaller.jsm
lib/firefox/modules/WindowDraggingUtils.jsm
+lib/firefox/modules/WindowsPrefSync.jsm
lib/firefox/modules/WorkerAPI.jsm
lib/firefox/modules/XPCOMUtils.jsm
lib/firefox/modules/XPIProvider.jsm
lib/firefox/modules/XPIProviderUtils.js
lib/firefox/modules/accessibility/AccessFu.jsm
+lib/firefox/modules/accessibility/Constants.jsm
lib/firefox/modules/accessibility/EventManager.jsm
-lib/firefox/modules/accessibility/Makefile.in
lib/firefox/modules/accessibility/OutputGenerator.jsm
lib/firefox/modules/accessibility/Presentation.jsm
lib/firefox/modules/accessibility/TouchAdapter.jsm
lib/firefox/modules/accessibility/TraversalRules.jsm
lib/firefox/modules/accessibility/Utils.jsm
-lib/firefox/modules/accessibility/jar.mn
lib/firefox/modules/commonjs/method/History.md
lib/firefox/modules/commonjs/method/License.md
lib/firefox/modules/commonjs/method/Readme.md
diff --git a/www/firefox/distinfo b/www/firefox/distinfo
index 5f4875ca305..5db7c78bd76 100644
--- a/www/firefox/distinfo
+++ b/www/firefox/distinfo
@@ -1,38 +1,60 @@
-$NetBSD: distinfo,v 1.133 2014/02/21 16:17:47 ryoon Exp $
+$NetBSD: distinfo,v 1.134 2014/03/20 21:02:00 ryoon Exp $
-SHA1 (firefox-27.0.1.source.tar.bz2) = 29dc759e36f2b9381e80ac48ce59635ea25033dc
-RMD160 (firefox-27.0.1.source.tar.bz2) = c6849fd4af75d8e6cb559b22bb7e3d1a616e270c
-Size (firefox-27.0.1.source.tar.bz2) = 129249507 bytes
-SHA1 (patch-aa) = e510bfad9f4d2950e5751d2a8d15971dcad75fb0
+SHA1 (firefox-28.0.source.tar.bz2) = f78517836ceca0cd2a0d3db1f282985c616e3fae
+RMD160 (firefox-28.0.source.tar.bz2) = 71124b36dca319eaa0de268ce4f6133f0ceca4f9
+Size (firefox-28.0.source.tar.bz2) = 134968426 bytes
+SHA1 (patch-aa) = c50d30d8bf2f8dbba938e4f5542b9d8b6e395e4e
SHA1 (patch-ak) = 971ddb1f12b14bcee604c9d7e72da5e7bf47d9be
SHA1 (patch-al) = 553c6042a98e4b381a46eec50c02cff349d88bd2
-SHA1 (patch-ao) = 3c777c8caf7f951a711c79612c08cee2cd338a57
-SHA1 (patch-as) = 62be47c27d74dedf70f048b3ac3ce99a2b4f7b3c
+SHA1 (patch-ao) = ca7e6723a10b9f6e3306cd12557e1856727edee9
+SHA1 (patch-as) = 3ce6e71d638ac1b6dec6737c92246e2dc7ff5d84
SHA1 (patch-bf) = 75c971043e9f693203d6bd670b2c20c4952a7756
SHA1 (patch-bg) = d6c02294765265d9e85cf49c22320d88573c2e25
SHA1 (patch-bi) = 3dd927d93431afe000cd4a45b4d9920e63158a85
+SHA1 (patch-browser_app_nsBrowserApp.cpp) = 348227a30b25fda41b4f79235fc623f64ca8e8ba
SHA1 (patch-browser_app_profile_firefox.js) = 108efbe1ae65669912d2f76caec546753e1ac8f3
-SHA1 (patch-browser_installer_package-manifest.in) = a00ac3c6ddedd316c7350ad9867a1a68cce974e1
+SHA1 (patch-browser_installer_package-manifest.in) = d5792a3c5dd7498d24ac0426aacf7d0b9a842c67
SHA1 (patch-browser_locales_en-US_chrome_browser-region_region.properties) = 284d62596718d7f372c4e5214fd05adec043c93a
SHA1 (patch-browser_locales_en-US_searchplugins_duckduckgo.xml) = 69eca52185ac868e95041b5d87611ee32c2b6330
SHA1 (patch-browser_locales_en-US_searchplugins_list.txt) = a6677b3a195b6c956858326e4e7474441823a47f
+SHA1 (patch-browser_themes_shared_devtools_common.css) = 37947ab5b523af83b58fd2dce3ed13599e5da9ef
+SHA1 (patch-browser_themes_shared_devtools_highlighter.inc.css) = 7c2a81b9f62a34d6d93b142508771f90954a6080
SHA1 (patch-build_autoconf_nss.m4) = bf65db126705a3a1ba294418b9380683ea401fc7
+SHA1 (patch-build_pgo_profileserver.py) = 8666187258e47c037f2065a19a5b38946fdc0f6c
+SHA1 (patch-config_Makefile.in) = 5ceb934dfc4bb02c8b1968a7bf8d004348a7ced1
SHA1 (patch-config_baseconfig.mk) = 9056301a239b7a927ee06a8f53702aece9780dc4
+SHA1 (patch-config_external_moz.build) = 52de4e24f4aa7446554c5906f9b475dbe956be5c
SHA1 (patch-config_stl__wrappers_ios) = 00d723e2f2f252485350ede5833f0bb84c1235c1
SHA1 (patch-config_stl__wrappers_ostream) = 7be7fe36704ffbdc070a113b46b4f391a598206b
-SHA1 (patch-config_system-headers) = b091819a932f86a19f98ea71787447c9899138c6
+SHA1 (patch-config_system-headers) = d74398cc427ebd436f6c3871f123feec7afa5926
SHA1 (patch-config_system__wrappers_unwind.h) = b3bdac0710179b9c8f8eabd824216d0114504491
+SHA1 (patch-content_base_src_Makefile.in) = 44016467828b787343444ba62c12637988e0f903
+SHA1 (patch-content_media_Makefile.in) = 56ecae4124aad54cffeba63c6e094e7a305c5b4e
+SHA1 (patch-content_media_gstreamer_GStreamerAllocator.cpp) = 1659560ccc68ef5e3d1b41be98a489d53d9e359f
+SHA1 (patch-content_media_gstreamer_GStreamerAllocator.h) = c2dd30332b3a13aea81d0e60ae2da535973cdc57
+SHA1 (patch-content_media_gstreamer_GStreamerFormatHelper.cpp) = 5728aad1f00f8600dd5c512c727640883c2bf225
+SHA1 (patch-content_media_gstreamer_GStreamerFunctionList.h) = 6bbcf08a4f5c710bf08a0e94945fcbf1b3e8e6bf
+SHA1 (patch-content_media_gstreamer_GStreamerLoader.cpp) = a86bc37efb7012a9a360dd41b9f84d87c783bdda
+SHA1 (patch-content_media_gstreamer_GStreamerLoader.h) = 0458ab4ecab7f76133c31af2ed952e0eeff71164
+SHA1 (patch-content_media_gstreamer_GStreamerReader-0.10.cpp) = ed9853effc8ee2999bdad34a6d59eb9e2897c43a
+SHA1 (patch-content_media_gstreamer_GStreamerReader.cpp) = bf26c4e2bdf3cfa644470d0a0dc8ff48f1ad42a1
+SHA1 (patch-content_media_gstreamer_GStreamerReader.h) = 118f83ebdec7bcda4f0ced8064a9b3c6cad78172
+SHA1 (patch-content_media_gstreamer_moz.build) = c38bd0d432577b55429ae5466b1b02c7b6fd1901
+SHA1 (patch-content_media_test_manifest.js) = 5b98d9eb16f898211fc0e30d821303bf72e8aaeb
SHA1 (patch-dom_plugins_ipc_PluginModuleChild.cpp) = 69b0a51d733cd52e7d200052362e0faf4ec918f1
SHA1 (patch-dom_plugins_ipc_PluginModuleChild.h) = 0a7f3167e939822013ae6195406657453578453e
-SHA1 (patch-extensions_auth_nsAuthGSSAPI.cpp) = 548886fc4a86a988f3f91650061ddc04f37653a8
SHA1 (patch-extensions_spellcheck_hunspell_src_mozHunspell.cpp) = a2a0652d0eac018fda06e729bf5ba786dd8a3866
SHA1 (patch-gfx__skia__include__core__SkPreConfig.h) = 6f99cf0eb5d4617d529c378707f537bc1e5cb28f
SHA1 (patch-gfx_graphite2_src_Bidi.cpp) = 5e80b4a32a47ae44d237fec69ea87bdd612a76ce
-SHA1 (patch-gfx_skia_moz.build) = dd83548d5eb7c3495932dd7df94c699c8c82270e
+SHA1 (patch-gfx_moz.build) = a98bda4727538f4a0f09a20b84f9dd883edaf7d9
+SHA1 (patch-gfx_skia_Makefile.in) = df1592fcab275a13e7015c9d73283f4326898186
+SHA1 (patch-gfx_skia_moz.build) = 1eb1b2c8948f7faaab267cace79f179fb258523c
SHA1 (patch-gfx_skia_src_utils_SkThreadUtils__pthread__linux.cpp) = 916d61bd9613df0fe2b6cfd0d6b1e49ffc40da5f
+SHA1 (patch-gfx_thebes_Makefile.in) = 42c12be1c2064d448c88edb542cdea0451f8f372
SHA1 (patch-image_decoders_nsJPEGDecoder.cpp) = e5df11499b1ec14e1d4c9a1408c0611d1c4e0574
SHA1 (patch-intl_hyphenation_src_hnjalloc.h) = 7fcc7b0fcf5a33486214197e925fbc8e6e22e2ee
-SHA1 (patch-ipc_chromium_Makefile.in) = 61ada3484c1ec0c07ee537aa7dd32e2c8411c10f
+SHA1 (patch-intl_unicharutil_util_Makefile.in) = 6ea0831e6cdcae43f8253a97766e783ad7b84b55
+SHA1 (patch-ipc_chromium_Makefile.in) = 3a1f5b218217fc8e5e9a07195054618071c38059
SHA1 (patch-ipc_chromium_src_base_base__paths.h) = 7bc83577a9678542db4dff7dda19d751ff6d78c1
SHA1 (patch-ipc_chromium_src_base_debug__util__posix.cc) = 677f0b5ccdcde7a8551f2d07d2a472361a5da03f
SHA1 (patch-ipc_chromium_src_base_file__util.h) = 9d6d074b1692c6b4e722bfac8d67c66040a6fa76
@@ -47,50 +69,56 @@ SHA1 (patch-ipc_chromium_src_base_sys__info__posix.cc) = 30646e3cd2d010a75e2a385
SHA1 (patch-ipc_chromium_src_base_time__posix.cc) = 337a0b4a5d51d68c7699b79c7591b953ea23ca67
SHA1 (patch-ipc_chromium_src_build_build__config.h) = af5a10df7d8fe9715f0e43cd6be14f8f20c53517
SHA1 (patch-ipc_chromium_src_chrome_common_transport__dib.h) = 7af18973c005d7b144a225bacf41833e059cb400
-SHA1 (patch-ipc_glue_GeckoChildProcessHost.cpp) = fe9ac2d0af8dd4757c93f50e6f74a31697f7e23c
+SHA1 (patch-ipc_glue_GeckoChildProcessHost.cpp) = 0fccd3224433017c7214b2615aa2c6c2d8ed658f
SHA1 (patch-ipc_ipdl_ipdl_lower.py) = 4025c0a4e149d9b2087331e10b342734fa77a905
SHA1 (patch-js__src__vm__SPSProfiler.cpp) = ac6da8a477cd0a768a513462b7bc3b871fd280f1
-SHA1 (patch-js_src_Makefile.in) = 2a3a52ec33b37b9df2047bfb35537689cca3ebb2
-SHA1 (patch-js_src_config_system-headers) = 405921c2638f6bf37f33b7d6b162addbfb162dea
+SHA1 (patch-js_src_Makefile.in) = f6ce5f02a9292e3e524424c5e810850232efe524
+SHA1 (patch-js_src_config_system-headers) = db1389af40dc0386ed8c3491a377668f5d29b6a1
SHA1 (patch-js_src_ctypes_CTypes.h) = 768a084239f92a424c1c7dc9eaaf9be9456ca9f0
SHA1 (patch-js_src_frontend_ParseMaps.cpp) = c00117d79b78904bc50a1d664a8fc0e4e339bfbc
SHA1 (patch-js_src_jsmath.cpp) = 7d4993ae91e9b5e6820358165603819aefb586f9
-SHA1 (patch-mb) = 24daa34185852f4f865bcd42041fc1cb693d9fe7
+SHA1 (patch-mb) = b661abce429a88554fca6c930b4dbf71ba6bb5cb
SHA1 (patch-media_libcubeb_src_cubeb__alsa.c) = 5ef0de0ac875334e959ff0d4bfa43a2e5ab087b9
SHA1 (patch-media_libpng_pngpriv.h) = c9cefd1b5dd85fbd0c875c3f9bc108975398fe3a
SHA1 (patch-media_libsoundtouch_src_cpu__detect__x86.cpp) = 061b46d1ee33c055a5b39e6b20f47b80bcde0c86
+SHA1 (patch-media_libtheora_Makefile.in) = 80ac9cb20760fe4d94047f7cb1c6a16bbdd6b505
+SHA1 (patch-media_libtremor_Makefile.in) = 497d03646caa721bdd129de365aadea8466043af
+SHA1 (patch-media_libvorbis_Makefile.in) = fd1ce15268eed9c97dd0774398d559cdbed63e53
SHA1 (patch-media_mtransport_third__party_nrappkit_src_port_generic_include_sys_queue.h) = 056172e54652caa60b6fee26e3073a6da83e734c
SHA1 (patch-media_webrtc_signaling_signaling.gyp) = ed52bb96a7ba6d7126b09871fe5ac81983cefdc1
-SHA1 (patch-media_webrtc_signaling_test_Makefile.in) = 7b05fe304cde8adbaa46ff8960978f96848541b6
+SHA1 (patch-media_webrtc_signaling_test_Makefile.in) = 4a9f9d3e4be79d711aa1f44f2982ec660ce5b15a
SHA1 (patch-media_webrtc_trunk_webrtc_build_common.gypi) = ac7250e37f30353af0a7789b7234f3bc56a3ecd7
-SHA1 (patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_device__info__linux.cc) = a7dd28746ea1c839e03c00f40985d73dd89dfd72
-SHA1 (patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_video__capture__linux.cc) = 076cf414a1a2ee270105a043517bbbb341382f49
+SHA1 (patch-media_webrtc_trunk_webrtc_modules_audio__coding_codecs_opus_opus.gypi) = f67c537662a994101125d8a10d0432c68d28f2ea
+SHA1 (patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_device__info__linux.cc) = 3cb1d688a19a9c211cc79fcf1c6879d8a5565433
+SHA1 (patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_video__capture__linux.cc) = be78d8d723c0560e08476a8d60b909772da49579
SHA1 (patch-media_webrtc_trunk_webrtc_modules_video__capture_video__capture.gypi) = 4721f01a89ef353c9b743b3cfefda4877d5283d9
-SHA1 (patch-media_webrtc_trunk_webrtc_system__wrappers_source_spreadsortlib_spreadsort.hpp) = f5af60a298e9e22499f3c743b3e140dbf4a83951
+SHA1 (patch-media_webrtc_trunk_webrtc_system__wrappers_source_spreadsortlib_spreadsort.hpp) = 78a9522f0e37cfc3ec8267e6c15de9dba0ec7ff3
+SHA1 (patch-memory_jemalloc_Makefile.in) = 772e996c8da254f952d0f3a0c9325a177c838543
SHA1 (patch-memory_mozalloc_fallible.h) = 8a60151465a07570db9636313f504004d73941d5
SHA1 (patch-memory_mozalloc_mozalloc.cpp) = 802af1da05f60fcf8c206568c2adc396e3bb0e06
SHA1 (patch-memory_mozalloc_mozalloc.h) = f2d9fd333ec28c075dfde8a6ee414b67b7f2cd26
SHA1 (patch-memory_mozalloc_mozalloc__abort.cpp) = 9d9036ddd28c7b8ce37860e0120df2997a3a0c59
SHA1 (patch-mfbt_Poison.cpp) = b582943c02f57835451c9eecd004c9912d42ce84
SHA1 (patch-modules_libjar_nsZipArchive.cpp) = 6aff0f8ed42575d8ca36a524e12e9a1f7351004a
+SHA1 (patch-netwerk_dns_Makefile.in) = 64b7ba4ec4f984e07c8c911cfb2261b08ea6aa55
SHA1 (patch-netwerk_sctp_src_netinet6_sctp6__usrreq.c) = 31d49db31b1e130f1b455f883e5b7c606d438771
SHA1 (patch-netwerk_sctp_src_netinet_sctp__os__userspace.h) = b3f94ac0f2bd652371fef22c642b14bf30162998
SHA1 (patch-netwerk_sctp_src_netinet_sctp__usrreq.c) = 421b6e071a9934567ccba337033a42208e6e4bd5
SHA1 (patch-netwerk_sctp_src_user__recv__thread.c) = cf26945441f74c581aeb5a8d7435780f4a48a607
SHA1 (patch-netwerk_sctp_src_user__socket.c) = c0b32ed2888b5845ce2b7646b85af8f0728bc7c3
SHA1 (patch-netwerk_sctp_src_user__socketvar.h) = 1b6e2864916ced693b1ab6c1bbdd80a4ffc4f7e4
-SHA1 (patch-netwerk_wifi_moz.build) = acbe49623fe25726a327f49c2568e77fa4b82558
-SHA1 (patch-netwerk_wifi_nsWifiScannerFreeBSD.cpp) = 9c343bef282192e1ac4b0742f160137d394c21b6
+SHA1 (patch-netwerk_wifi_moz.build) = 8c88e5bab2a5e164e97ce568686bd280d4b90bec
+SHA1 (patch-netwerk_wifi_nsWifiScannerFreeBSD.cpp) = c5711adc111dc8413a7234e7d5814a0af9ceeecc
SHA1 (patch-pb) = 97c9b2e4cefd524dc6ba825f71c3da2a761aa1f4
SHA1 (patch-pc) = 8b2baa88f0983a2fef4f801cf6b1ae425f6c813a
SHA1 (patch-rc) = 2733724442a2cb49c5091146fd7e6001af686121
SHA1 (patch-security_manager_ssl_src_JARSignatureVerification.cpp) = e9749dfeb0d3fcb4637935322ffd1e0cad4f8ec3
SHA1 (patch-security_manager_ssl_src_nsNSSComponent.cpp) = c4c96b7d3cb0c5dbcfe3820fd52421eec2592452
-SHA1 (patch-toolkit_components_osfile_modules_osfile__unix__back.jsm) = c18cac4393fb3503b60717d6053e27d41c9f733c
-SHA1 (patch-toolkit_library_Makefile.in) = 282e30738328fd447a1ba74a344a22f7fe044b3a
+SHA1 (patch-toolkit_components_osfile_modules_osfile__unix__allthreads.jsm) = b809c17231d1d5eecaed6f6aa0ddb34685fb6800
+SHA1 (patch-toolkit_components_osfile_modules_osfile__unix__back.jsm) = 274b06bd4bfea5b6d7d67c0d39a484d179ed560c
+SHA1 (patch-toolkit_library_Makefile.in) = ccd62ca282cf41eeb6637672920083ab269e1c33
SHA1 (patch-toolkit_mozapps_update_updater_updater.cpp) = 6936e5408fc7f0110768f3fc8f27506c0e7879fa
SHA1 (patch-toolkit_toolkit.mozbuild) = 0993d50cc02c2b421e6de087dfb0a9cb30562c6b
-SHA1 (patch-toolkit_xre_Makefile.in) = 6ad65fa2fd026888cc8345e184daf2a070ea4885
SHA1 (patch-toolkit_xre_nsEmbedFunctions.cpp) = 6ee6fba04a3ecc6596f8aed67f752a1075901fa8
SHA1 (patch-xb) = 30eea880b40cee45d1235d3292fead4b5a54bbaa
SHA1 (patch-xc) = 8575fdac2b47966ccfb5e1cc7ca8505163e358c9
@@ -99,13 +127,13 @@ SHA1 (patch-xf) = 1720ae5cf3cf0df6f2e9519c83a332585bdd67bf
SHA1 (patch-xg) = b80e660e85b06e4f71146bd41bd4bc0d2e3b6488
SHA1 (patch-xl) = 9555b86c72b2e144e341d6af1dbfbc07cc8c94db
SHA1 (patch-xm) = 81e02e410c00175cbb98c646dda90c7adf199657
-SHA1 (patch-xn) = c042e39d93706934ec03c78be3dc6e224ac62c0e
-SHA1 (patch-xo) = aae6107dcfaf731bd3e9962d953fb8701fc5f163
-SHA1 (patch-xpcom_base_nsMemoryInfoDumper.cpp) = 245508dc7ad64eb1dc514caf6e85904d440742ca
-SHA1 (patch-xpcom_base_nsMemoryReporterManager.cpp) = f23cf57c59faf1b83d54a234e53aad61116da5ca
-SHA1 (patch-xpcom_base_nsStackWalk.cpp) = b763f5f3505efbedf51a9544a03d0501d86138b1
+SHA1 (patch-xpcom_base_nsStackWalk.cpp) = 330635b2b0ad1efec6f2296ac1dedd458c9248dc
+SHA1 (patch-xpcom_base_nscore.h) = b1a190d8ef4478b882daeceda51584f947555a28
SHA1 (patch-xpcom_ds_TimeStamp.h) = a1fb060f91720eb330f102b28d9373bbdbe96e30
-SHA1 (patch-xpcom_reflect_xptcall_src_md_unix_moz.build) = 67e97ae07ec180da8277371f4b6fa4c56c203ac8
+SHA1 (patch-xpcom_io_nsLocalFileUnix.cpp) = 3de3345eb98ffe78628d5bac672ce4ab5806270e
+SHA1 (patch-xpcom_reflect_xptcall_src_md_unix_moz.build) = ee1e09e0352adedf0c50d11db18c7e57238a3b02
+SHA1 (patch-xpcom_reflect_xptcall_src_md_unix_xptcinvoke__asm__mips.S) = b2b81fcdf6591089fcc5de4c8f820e96c0a50256
SHA1 (patch-xpcom_reflect_xptcall_src_md_unix_xptcinvoke__gcc__x86__unix.cpp) = 8cd42915cd32756b55894a773a1e6d7c012b4467
+SHA1 (patch-xpcom_reflect_xptcall_src_md_unix_xptcstubs__asm__mips.S) = 1bb4baf0baa223cd87a8cb85b16b37c368c45b94
SHA1 (patch-xpcom_reflect_xptcall_src_md_unix_xptcstubs__gcc__x86__unix.cpp) = e9e336817c172187f3e15ddf539a8a2176e3e952
SHA1 (patch-xulrunner_installer_Makefile.in) = 9d32ff87d0962c0406ed38de995c0350dd372e49
diff --git a/www/firefox/patches/patch-aa b/www/firefox/patches/patch-aa
index fe429fd67bb..1356e8e81f2 100644
--- a/www/firefox/patches/patch-aa
+++ b/www/firefox/patches/patch-aa
@@ -1,51 +1,134 @@
-$NetBSD: patch-aa,v 1.20 2014/02/20 13:19:03 ryoon Exp $
+$NetBSD: patch-aa,v 1.21 2014/03/20 21:02:00 ryoon Exp $
---- configure.in.orig 2013-12-05 16:07:23.000000000 +0000
+--- configure.in.orig 2014-03-15 05:19:10.000000000 +0000
+++ configure.in
-@@ -2752,6 +2752,7 @@ EOF
- #pragma GCC visibility push(hidden)
- #pragma GCC visibility push(default)
- #include <string.h>
-+#include <iterator>
- #pragma GCC visibility pop
-
- __attribute__ ((visibility ("default"))) void Func() {
-@@ -2760,7 +2761,7 @@ __attribute__ ((visibility ("default")))
- }
- EOF
- ac_cv_have_visibility_builtin_bug=no
+@@ -2544,118 +2544,15 @@ MOZ_CXX11
+
+ AC_LANG_C
+
+-dnl Check for .hidden assembler directive and visibility attribute.
+-dnl Borrowed from glibc configure.in
++dnl Setup default hidden visibility and wrapped system headers.
+ dnl ===============================================================
+ if test "$GNU_CC"; then
+- AC_CACHE_CHECK(for visibility(hidden) attribute,
+- ac_cv_visibility_hidden,
+- [cat > conftest.c <<EOF
+- int foo __attribute__ ((visibility ("hidden"))) = 1;
+-EOF
+- ac_cv_visibility_hidden=no
+- if ${CC-cc} -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then
+- if egrep '\.(hidden|private_extern).*foo' conftest.s >/dev/null; then
+- ac_cv_visibility_hidden=yes
+- fi
+- fi
+- rm -f conftest.[cs]
+- ])
+- if test "$ac_cv_visibility_hidden" = "yes"; then
+- AC_DEFINE(HAVE_VISIBILITY_HIDDEN_ATTRIBUTE)
+-
+- AC_CACHE_CHECK(for visibility(default) attribute,
+- ac_cv_visibility_default,
+- [cat > conftest.c <<EOF
+- int foo __attribute__ ((visibility ("default"))) = 1;
+-EOF
+- ac_cv_visibility_default=no
+- if ${CC-cc} -fvisibility=hidden -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then
+- if ! egrep '\.(hidden|private_extern).*foo' conftest.s >/dev/null; then
+- ac_cv_visibility_default=yes
+- fi
+- fi
+- rm -f conftest.[cs]
+- ])
+- if test "$ac_cv_visibility_default" = "yes"; then
+- AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE)
+-
+- AC_CACHE_CHECK(for visibility pragma support,
+- ac_cv_visibility_pragma,
+- [cat > conftest.c <<EOF
+-#pragma GCC visibility push(hidden)
+- int foo_hidden = 1;
+-#pragma GCC visibility push(default)
+- int foo_default = 1;
+-EOF
+- ac_cv_visibility_pragma=no
+- if ${CC-cc} -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then
+- if egrep '\.(hidden|private_extern).*foo_hidden' conftest.s >/dev/null; then
+- if ! egrep '\.(hidden|private_extern).*foo_default' conftest.s > /dev/null; then
+- ac_cv_visibility_pragma=yes
+- fi
+- fi
+- fi
+- rm -f conftest.[cs]
+- ])
+- if test "$ac_cv_visibility_pragma" = "yes"; then
+- AC_CACHE_CHECK(For gcc visibility bug with class-level attributes (GCC bug 26905),
+- ac_cv_have_visibility_class_bug,
+- [cat > conftest.c <<EOF
+-#pragma GCC visibility push(hidden)
+-struct __attribute__ ((visibility ("default"))) TestStruct {
+- static void Init();
+-};
+-__attribute__ ((visibility ("default"))) void TestFunc() {
+- TestStruct::Init();
+-}
+-EOF
+- ac_cv_have_visibility_class_bug=no
+- if ! ${CXX-g++} ${CXXFLAGS} ${DSO_PIC_CFLAGS} ${DSO_LDOPTS} -S -o conftest.S conftest.c > /dev/null 2>&1 ; then
+- ac_cv_have_visibility_class_bug=yes
+- else
+- if test `egrep -c '@PLT|\\$stub' conftest.S` = 0; then
+- ac_cv_have_visibility_class_bug=yes
+- fi
+- fi
+- rm -rf conftest.{c,S}
+- ])
+-
+- AC_CACHE_CHECK(For x86_64 gcc visibility bug with builtins (GCC bug 20297),
+- ac_cv_have_visibility_builtin_bug,
+- [cat > conftest.c <<EOF
+-#pragma GCC visibility push(hidden)
+-#pragma GCC visibility push(default)
+-#include <string.h>
+-#pragma GCC visibility pop
+-
+-__attribute__ ((visibility ("default"))) void Func() {
+- char c[[100]];
+- memset(c, 0, sizeof(c));
+-}
+-EOF
+- ac_cv_have_visibility_builtin_bug=no
- if ! ${CC-cc} ${CFLAGS} ${DSO_PIC_CFLAGS} ${DSO_LDOPTS} -O2 -S -o conftest.S conftest.c > /dev/null 2>&1 ; then
-+ if ! ${CXX-c++} ${CXXFLAGS} ${DSO_PIC_CFLAGS} ${DSO_LDOPTS} -O2 -S -o conftest.S conftest.c > /dev/null 2>&1 ; then
- ac_cv_have_visibility_builtin_bug=yes
- else
- if test `grep -c "@PLT" conftest.S` = 0; then
-@@ -3216,14 +3217,22 @@ fi
- AC_CACHE_CHECK(
- [for res_ninit()],
- ac_cv_func_res_ninit,
-- [AC_TRY_LINK([
-+ [AC_TRY_RUN([
- #ifdef linux
- #define _BSD_SOURCE 1
- #endif
-+ #ifdef __NetBSD__
-+ #error use of global _res variable in threaded programs is not portable
-+ #endif
-+ #include <sys/types.h>
-+ #include <netinet/in.h>
-+ #include <arpa/nameser.h>
- #include <resolv.h>
-- ],
-- [int foo = res_ninit(&_res);],
-+ int main(int argc, char **argv){
-+ int foo = res_ninit(&_res);
-+ }],
- [ac_cv_func_res_ninit=yes],
-+ [ac_cv_func_res_ninit=no],
- [ac_cv_func_res_ninit=no])
- ])
-
-@@ -3874,6 +3883,14 @@ if test -n "$YASM"; then
+- ac_cv_have_visibility_builtin_bug=yes
+- else
+- if test `grep -c "@PLT" conftest.S` = 0; then
+- ac_cv_visibility_builtin_bug=yes
+- fi
+- fi
+- rm -f conftest.{c,S}
+- ])
+- if test "$ac_cv_have_visibility_builtin_bug" = "no" -a \
+- "$ac_cv_have_visibility_class_bug" = "no"; then
+- VISIBILITY_FLAGS='-I$(DIST)/system_wrappers -include $(topsrcdir)/config/gcc_hidden.h'
+- WRAP_SYSTEM_INCLUDES=1
+- STL_FLAGS='-I$(DIST)/stl_wrappers'
+- WRAP_STL_INCLUDES=1
+- else
+- VISIBILITY_FLAGS='-fvisibility=hidden'
+- fi # have visibility pragma bug
+- fi # have visibility pragma
+- fi # have visibility(default) attribute
+- fi # have visibility(hidden) attribute
++ AC_DEFINE(HAVE_VISIBILITY_HIDDEN_ATTRIBUTE)
++ AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE)
++ VISIBILITY_FLAGS='-I$(DIST)/system_wrappers -include $(topsrcdir)/config/gcc_hidden.h'
++ WRAP_SYSTEM_INCLUDES=1
++ STL_FLAGS='-I$(DIST)/stl_wrappers'
++ WRAP_STL_INCLUDES=1
+ fi # GNU_CC
+
+ # visibility hidden flag for Sun Studio on Solaris
+@@ -3724,6 +3621,14 @@ if test -n "$YASM"; then
_YASM_BUILD=` echo ${YASM_VERSION} | $AWK -F\. '{ print $4 }'`
fi
@@ -60,7 +143,7 @@ $NetBSD: patch-aa,v 1.20 2014/02/20 13:19:03 ryoon Exp $
if test -z "$SKIP_LIBRARY_CHECKS"; then
dnl system JPEG support
dnl ========================================================
-@@ -3901,11 +3918,7 @@ if test "$MOZ_NATIVE_JPEG" = 1; then
+@@ -3751,11 +3656,7 @@ if test "$MOZ_NATIVE_JPEG" = 1; then
#include <jpeglib.h> ],
[ #if JPEG_LIB_VERSION < $MOZJPEG
#error "Insufficient JPEG library version ($MOZJPEG required)."
@@ -73,7 +156,7 @@ $NetBSD: patch-aa,v 1.20 2014/02/20 13:19:03 ryoon Exp $
MOZ_NATIVE_JPEG=1,
AC_MSG_ERROR([Insufficient JPEG library version for --with-system-jpeg]))
fi
-@@ -4062,6 +4075,22 @@ fi
+@@ -3921,6 +3822,22 @@ fi
AC_SUBST(MOZ_NATIVE_ICU)
dnl ========================================================
@@ -96,20 +179,25 @@ $NetBSD: patch-aa,v 1.20 2014/02/20 13:19:03 ryoon Exp $
dnl Java SDK support
dnl ========================================================
-@@ -5281,6 +5310,12 @@ if test -n "$MOZ_WEBRTC"; then
- MOZ_VP8_ENCODER=1
+@@ -3955,6 +3872,7 @@ MOZ_SAMPLE_TYPE_FLOAT32=
+ MOZ_SAMPLE_TYPE_S16=
+ MOZ_OPUS=1
+ MOZ_WEBM=1
++MOZ_GSTREAMER=
+ MOZ_DIRECTSHOW=
+ MOZ_WMF=
+ MOZ_FMP4=
+@@ -5136,6 +5054,9 @@ if test -n "$MOZ_WEBRTC"; then
+ MOZ_VP8=1
MOZ_VP8_ERROR_CONCEALMENT=1
+ dnl with libv4l2 we can support more cameras
+ PKG_CHECK_MODULES(MOZ_LIBV4L2, libv4l2)
+
-+ dnl with libv4l2 we can support more cameras
-+ PKG_CHECK_MODULES(MOZ_LIBV4L2, libv4l2)
-+
dnl enable once Signaling lands
MOZ_WEBRTC_SIGNALING=1
AC_DEFINE(MOZ_WEBRTC_SIGNALING)
-@@ -5307,15 +5342,18 @@ AC_SUBST(MOZ_SRTP)
+@@ -5158,15 +5079,18 @@ AC_SUBST(MOZ_SRTP)
dnl Use integers over floats for audio on B2G and Android, because audio
dnl backends for those platforms don't support floats.
@@ -131,7 +219,205 @@ $NetBSD: patch-aa,v 1.20 2014/02/20 13:19:03 ryoon Exp $
dnl ========================================================
dnl = Disable Speech API code
-@@ -8276,7 +8314,7 @@ case "$OS_TARGET" in
+@@ -5230,6 +5154,40 @@ if test -n "$MOZ_OGG"; then
+ fi
+
+ dnl ========================================================
++dnl Check for libogg
++dnl ========================================================
++
++MOZ_ARG_WITH_BOOL(system-ogg,
++[ --with-system-ogg Use system libogg (located with pkgconfig)],
++MOZ_NATIVE_OGG=1,
++MOZ_NATIVE_OGG= )
++
++if test -n "$MOZ_NATIVE_OGG"; then
++ PKG_CHECK_MODULES(MOZ_OGG, ogg >= 1.2.1)
++fi
++
++AC_SUBST(MOZ_NATIVE_OGG)
++AC_SUBST(MOZ_OGG_CFLAGS)
++AC_SUBST(MOZ_OGG_LIBS)
++
++dnl ========================================================
++dnl Check for libvorbis
++dnl ========================================================
++
++MOZ_ARG_WITH_BOOL(system-vorbis,
++[ --with-system-vorbis Use system libvorbis (located with pkgconfig)],
++MOZ_NATIVE_VORBIS=1,
++MOZ_NATIVE_VORBIS= )
++
++if test -n "$MOZ_NATIVE_VORBIS"; then
++ PKG_CHECK_MODULES(MOZ_VORBIS, vorbis vorbisenc >= 1.3.4)
++fi
++
++AC_SUBST(MOZ_NATIVE_VORBIS)
++AC_SUBST(MOZ_VORBIS_CFLAGS)
++AC_SUBST(MOZ_VORBIS_LIBS)
++
++dnl ========================================================
+ dnl = Disable Opus audio codec support
+ dnl ========================================================
+ MOZ_ARG_DISABLE_BOOL(opus,
+@@ -5238,6 +5196,25 @@ MOZ_ARG_DISABLE_BOOL(opus,
+ MOZ_OPUS=1)
+
+ dnl ========================================================
++dnl Check for libopus
++dnl ========================================================
++
++MOZ_ARG_WITH_BOOL(system-opus,
++[ --with-system-opus Use system libopus (located with pkgconfig)],
++MOZ_NATIVE_OPUS=1,
++MOZ_NATIVE_OPUS= )
++
++if test -n "$MOZ_NATIVE_OPUS"; then
++ PKG_CHECK_MODULES(MOZ_OPUS, opus >= 1.1)
++else
++ MOZ_OPUS_CFLAGS='-I$(topsrcdir)/media/libopus/include'
++fi
++
++AC_SUBST(MOZ_NATIVE_OPUS)
++AC_SUBST(MOZ_OPUS_CFLAGS)
++AC_SUBST(MOZ_OPUS_LIBS)
++
++dnl ========================================================
+ dnl = Disable VP8 decoder support
+ dnl ========================================================
+ MOZ_ARG_DISABLE_BOOL(webm,
+@@ -5606,43 +5583,60 @@ dnl = Enable GStreamer
+ dnl ========================================================
+ if test "$OS_TARGET" = "Linux"; then
+ MOZ_GSTREAMER=1
++ GST_API_VERSION=0.10
+ fi
+
+-MOZ_ARG_ENABLE_BOOL(gstreamer,
+-[ --enable-gstreamer Enable GStreamer support],
+-MOZ_GSTREAMER=1,
+-MOZ_GSTREAMER=)
+-
+-if test "$MOZ_GSTREAMER"; then
+- # API version, eg 0.10, 1.0 etc
++MOZ_ARG_ENABLE_STRING(gstreamer,
++[ --enable-gstreamer[=0.10] Enable GStreamer support],
++[ MOZ_GSTREAMER=1
++ # API version, eg 0.10, 1.0 etc
++ if test -z "$enableval" -o "$enableval" = "yes"; then
+ GST_API_VERSION=0.10
++ elif test "$enableval" = "no"; then
++ MOZ_GSTREAMER=
++ else
++ GST_API_VERSION=$enableval
++ fi],
++)
++
++if test -n "$MOZ_GSTREAMER"; then
+ # core/base release number
+- GST_VERSION=0.10.25
++ if test "$GST_API_VERSION" = "1.0"; then
++ GST_VERSION=1.0
++ else
++ GST_VERSION=0.10.25
++ fi
++
+ PKG_CHECK_MODULES(GSTREAMER,
+ gstreamer-$GST_API_VERSION >= $GST_VERSION
+ gstreamer-app-$GST_API_VERSION
+- gstreamer-plugins-base-$GST_API_VERSION, ,
+- AC_MSG_ERROR([gstreamer and gstreamer-plugins-base development packages are needed to build gstreamer backend. Install them or disable gstreamer support with --disable-gstreamer]))
+- if test -n "$GSTREAMER_LIBS"; then
+- _SAVE_LDFLAGS=$LDFLAGS
+- LDFLAGS="$LDFLAGS $GSTREAMER_LIBS -lgstvideo-$GST_API_VERSION"
+- AC_TRY_LINK(,[return 0;],_HAVE_LIBGSTVIDEO=1,_HAVE_LIBGSTVIDEO=)
+- if test -n "$_HAVE_LIBGSTVIDEO" ; then
+- GSTREAMER_LIBS="$GSTREAMER_LIBS -lgstvideo-$GST_API_VERSION"
+- else
+- AC_MSG_ERROR([gstreamer-plugins-base found, but no libgstvideo. Something has gone terribly wrong. Try reinstalling gstreamer-plugins-base; failing that, disable the gstreamer backend with --disable-gstreamer.])
+- fi
+- LDFLAGS=$_SAVE_LDFLAGS
++ gstreamer-plugins-base-$GST_API_VERSION,
++ [_HAVE_GSTREAMER=1],
++ [_HAVE_GSTREAMER=])
++ if test -z "$_HAVE_GSTREAMER"; then
++ AC_MSG_ERROR([gstreamer and gstreamer-plugins-base development packages are needed to build gstreamer backend. Install them or disable gstreamer support with --disable-gstreamer])
++ fi
++
++ _SAVE_LDFLAGS=$LDFLAGS
++ LDFLAGS="$LDFLAGS $GSTREAMER_LIBS -lgstvideo-$GST_API_VERSION"
++ AC_TRY_LINK(,[return 0;],_HAVE_LIBGSTVIDEO=1,_HAVE_LIBGSTVIDEO=)
++ if test -n "$_HAVE_LIBGSTVIDEO" ; then
++ GSTREAMER_LIBS="$GSTREAMER_LIBS -lgstvideo-$GST_API_VERSION"
+ else
+- AC_MSG_ERROR([gstreamer and gstreamer-plugins-base development packages are needed to build gstreamer backend. Install them or disable gstreamer support with --disable-gstreamer])
++ AC_MSG_ERROR([gstreamer-plugins-base found, but no libgstvideo. Something has gone terribly wrong. Try reinstalling gstreamer-plugins-base; failing that, disable the gstreamer backend with --disable-gstreamer.])
+ fi
++ LDFLAGS=$_SAVE_LDFLAGS
++
++ AC_SUBST(GSTREAMER_CFLAGS)
++ AC_SUBST(GSTREAMER_LIBS)
+ fi
+-AC_SUBST(GSTREAMER_CFLAGS)
+-AC_SUBST(GSTREAMER_LIBS)
++
+ AC_SUBST(MOZ_GSTREAMER)
++AC_SUBST(GST_API_VERSION)
+
+ if test -n "$MOZ_GSTREAMER"; then
+- AC_DEFINE(MOZ_GSTREAMER)
++ AC_DEFINE(MOZ_GSTREAMER)
++ AC_DEFINE_UNQUOTED(GST_API_VERSION, "$GST_API_VERSION")
+ fi
+
+
+@@ -7424,7 +7418,10 @@ dnl ====================================
+ dnl = Support for gcc stack unwinding (from gcc 3.3)
+ dnl ========================================================
+ if test -z "$SKIP_LIBRARY_CHECKS"; then
++ AC_LANG_SAVE
++ AC_LANG_CPLUSPLUS
+ MOZ_CHECK_HEADER(unwind.h, AC_CHECK_FUNCS(_Unwind_Backtrace))
++ AC_LANG_RESTORE
+ fi
+
+ dnl ========================================================
+@@ -7870,6 +7867,34 @@ if test "$USE_FC_FREETYPE"; then
+ fi
+
+ dnl ========================================================
++dnl Check for graphite2 and harfbuzz
++dnl ========================================================
++
++MOZ_ARG_WITH_BOOL(system-harfbuzz,
++[ --with-system-harfbuzz Use system harfbuzz (located with pkgconfig)],
++MOZ_NATIVE_HARFBUZZ=1,
++MOZ_NATIVE_HARFBUZZ= )
++
++if test -n "$MOZ_NATIVE_HARFBUZZ"; then
++ PKG_CHECK_MODULES(MOZ_HARFBUZZ, harfbuzz >= 0.9.25)
++fi
++AC_SUBST(MOZ_NATIVE_HARFBUZZ)
++AC_SUBST(MOZ_HARFBUZZ_CFLAGS)
++AC_SUBST(MOZ_HARFBUZZ_LIBS)
++
++MOZ_ARG_WITH_BOOL(system-graphite2,
++[ --with-system-graphite2 Use system graphite2 (located with pkgconfig)],
++MOZ_NATIVE_GRAPHITE2=1,
++MOZ_NATIVE_GRAPHITE2= )
++
++if test -n "$MOZ_NATIVE_GRAPHITE2"; then
++ PKG_CHECK_MODULES(MOZ_GRAPHITE2, graphite2 >= 1.2.4)
++fi
++AC_SUBST(MOZ_NATIVE_GRAPHITE2)
++AC_SUBST(MOZ_GRAPHITE2_CFLAGS)
++AC_SUBST(MOZ_GRAPHITE2_LIBS)
++
++dnl ========================================================
+ dnl Check for pixman and cairo
+ dnl ========================================================
+
+@@ -8118,7 +8143,7 @@ case "$OS_TARGET" in
NECKO_WIFI=1
fi
;;
@@ -140,14 +426,31 @@ $NetBSD: patch-aa,v 1.20 2014/02/20 13:19:03 ryoon Exp $
NECKO_WIFI=1
;;
Linux)
-@@ -9005,6 +9043,14 @@ if test -n "$INTEL_ARCHITECTURE"; then
- fi
- fi
+@@ -8665,6 +8690,20 @@ AC_SUBST(MOZ_ENABLE_SZIP)
+ AC_SUBST(MOZ_SZIP_FLAGS)
-+if test -n "$MOZ_LIBV4L2_LIBS"; then
-+ EXTRA_GYP_DEFINES="$EXTRA_GYP_DEFINES -D use_libv4l2=1"
+ if test -n "$COMPILE_ENVIRONMENT"; then
++AC_MSG_CHECKING([for posix_fadvise])
++AC_TRY_LINK([#define _XOPEN_SOURCE 600
++ #include <fcntl.h>],
++ [posix_fadvise(0, 0, 0, 0);],
++ [ac_cv___posix_fadvise=true],
++ [ac_cv___posix_fadvise=false])
++
++if test "$ac_cv___posix_fadvise" = true ; then
++ AC_DEFINE(HAVE_POSIX_FADVISE)
++ AC_MSG_RESULT(yes)
++else
++ AC_MSG_RESULT(no)
+fi
+
+ AC_MSG_CHECKING([for posix_fallocate])
+ AC_TRY_LINK([#define _XOPEN_SOURCE 600
+ #include <fcntl.h>],
+@@ -8918,6 +8957,10 @@ if test -n "$INTEL_ARCHITECTURE"; then
+ fi
+ fi
+
+if test -n "$MOZ_LIBV4L2_LIBS"; then
+ EXTRA_GYP_DEFINES="$EXTRA_GYP_DEFINES -D use_libv4l2=1"
+fi
diff --git a/www/firefox/patches/patch-ao b/www/firefox/patches/patch-ao
index 472f09c5760..f760db30271 100644
--- a/www/firefox/patches/patch-ao
+++ b/www/firefox/patches/patch-ao
@@ -1,16 +1,12 @@
-$NetBSD: patch-ao,v 1.12 2014/02/20 13:19:03 ryoon Exp $
+$NetBSD: patch-ao,v 1.13 2014/03/20 21:02:00 ryoon Exp $
---- toolkit/mozapps/installer/packager.mk.orig 2013-10-25 22:27:43.000000000 +0000
+--- toolkit/mozapps/installer/packager.mk.orig 2014-03-15 05:19:37.000000000 +0000
+++ toolkit/mozapps/installer/packager.mk
-@@ -680,9 +680,9 @@ endif
- (cd $(DIST)/$(MOZ_PKG_DIR) && $(TAR) --exclude=precomplete $(TAR_CREATE_FLAGS) - .) | \
- (cd $(DESTDIR)$(installdir) && tar -xf -)
+@@ -775,7 +775,7 @@ endif
$(NSINSTALL) -D $(DESTDIR)$(bindir)
-- $(RM) -f $(DESTDIR)$(bindir)/$(MOZ_APP_NAME)
-- ln -s $(installdir)/$(MOZ_APP_NAME) $(DESTDIR)$(bindir)
+ $(RM) -f $(DESTDIR)$(bindir)/$(MOZ_APP_NAME)
+ ln -s $(installdir)/$(MOZ_APP_NAME) $(DESTDIR)$(bindir)
-ifdef INSTALL_SDK # Here comes the hard part
-+ $(RM) -f $(DESTDIR)$(bindir)/$(MOZILLA_PKG_NAME)
-+ ln -s $(installdir)/$(MOZ_APP_NAME) $(DESTDIR)$(bindir)/$(MOZILLA_PKG_NAME)
+ifeq ($(MOZ_APP_NAME),xulrunner)
$(NSINSTALL) -D $(DESTDIR)$(includedir)
(cd $(DIST)/include && $(TAR) $(TAR_CREATE_FLAGS) - .) | \
diff --git a/www/firefox/patches/patch-as b/www/firefox/patches/patch-as
index 8d729285b4f..3da0733fcb3 100644
--- a/www/firefox/patches/patch-as
+++ b/www/firefox/patches/patch-as
@@ -1,27 +1,132 @@
-$NetBSD: patch-as,v 1.8 2014/02/20 13:19:03 ryoon Exp $
+$NetBSD: patch-as,v 1.9 2014/03/20 21:02:00 ryoon Exp $
Treat DragonFly like FreeBSD.
---- js/src/configure.in.orig 2013-12-05 16:07:35.000000000 +0000
+--- js/src/configure.in.orig 2014-03-15 05:19:19.000000000 +0000
+++ js/src/configure.in
-@@ -2290,6 +2290,7 @@ EOF
- #pragma GCC visibility push(hidden)
- #pragma GCC visibility push(default)
- #include <string.h>
-+#include <iterator>
- #pragma GCC visibility pop
+@@ -2148,116 +2148,13 @@ AC_LANG_CPLUSPLUS
- __attribute__ ((visibility ("default"))) void Func() {
-@@ -2298,7 +2299,7 @@ __attribute__ ((visibility ("default")))
- }
- EOF
- ac_cv_have_visibility_builtin_bug=no
+ MOZ_CXX11
+
+-dnl Check for .hidden assembler directive and visibility attribute.
+-dnl Borrowed from glibc configure.in
++dnl Setup default hidden visibility and wrapped system headers.
+ dnl ===============================================================
+ if test "$GNU_CC"; then
+- AC_CACHE_CHECK(for visibility(hidden) attribute,
+- ac_cv_visibility_hidden,
+- [cat > conftest.c <<EOF
+- int foo __attribute__ ((visibility ("hidden"))) = 1;
+-EOF
+- ac_cv_visibility_hidden=no
+- if ${CC-cc} -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then
+- if egrep '\.(hidden|private_extern).*foo' conftest.s >/dev/null; then
+- ac_cv_visibility_hidden=yes
+- fi
+- fi
+- rm -f conftest.[cs]
+- ])
+- if test "$ac_cv_visibility_hidden" = "yes"; then
+- AC_DEFINE(HAVE_VISIBILITY_HIDDEN_ATTRIBUTE)
+-
+- AC_CACHE_CHECK(for visibility(default) attribute,
+- ac_cv_visibility_default,
+- [cat > conftest.c <<EOF
+- int foo __attribute__ ((visibility ("default"))) = 1;
+-EOF
+- ac_cv_visibility_default=no
+- if ${CC-cc} -fvisibility=hidden -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then
+- if ! egrep '\.(hidden|private_extern).*foo' conftest.s >/dev/null; then
+- ac_cv_visibility_default=yes
+- fi
+- fi
+- rm -f conftest.[cs]
+- ])
+- if test "$ac_cv_visibility_default" = "yes"; then
+- AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE)
+-
+- AC_CACHE_CHECK(for visibility pragma support,
+- ac_cv_visibility_pragma,
+- [cat > conftest.c <<EOF
+-#pragma GCC visibility push(hidden)
+- int foo_hidden = 1;
+-#pragma GCC visibility push(default)
+- int foo_default = 1;
+-EOF
+- ac_cv_visibility_pragma=no
+- if ${CC-cc} -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then
+- if egrep '\.(hidden|private_extern).*foo_hidden' conftest.s >/dev/null; then
+- if ! egrep '\.(hidden|private_extern).*foo_default' conftest.s > /dev/null; then
+- ac_cv_visibility_pragma=yes
+- fi
+- fi
+- fi
+- rm -f conftest.[cs]
+- ])
+- if test "$ac_cv_visibility_pragma" = "yes"; then
+- AC_CACHE_CHECK(For gcc visibility bug with class-level attributes (GCC bug 26905),
+- ac_cv_have_visibility_class_bug,
+- [cat > conftest.c <<EOF
+-#pragma GCC visibility push(hidden)
+-struct __attribute__ ((visibility ("default"))) TestStruct {
+- static void Init();
+-};
+-__attribute__ ((visibility ("default"))) void TestFunc() {
+- TestStruct::Init();
+-}
+-EOF
+- ac_cv_have_visibility_class_bug=no
+- if ! ${CXX-g++} ${CXXFLAGS} ${DSO_PIC_CFLAGS} ${DSO_LDOPTS} -S -o conftest.S conftest.c > /dev/null 2>&1 ; then
+- ac_cv_have_visibility_class_bug=yes
+- else
+- if test `egrep -c '@PLT|\\$stub' conftest.S` = 0; then
+- ac_cv_have_visibility_class_bug=yes
+- fi
+- fi
+- rm -rf conftest.{c,S}
+- ])
+-
+- AC_CACHE_CHECK(For x86_64 gcc visibility bug with builtins (GCC bug 20297),
+- ac_cv_have_visibility_builtin_bug,
+- [cat > conftest.c <<EOF
+-#pragma GCC visibility push(hidden)
+-#pragma GCC visibility push(default)
+-#include <string.h>
+-#pragma GCC visibility pop
+-
+-__attribute__ ((visibility ("default"))) void Func() {
+- char c[[100]];
+- memset(c, 0, sizeof(c));
+-}
+-EOF
+- ac_cv_have_visibility_builtin_bug=no
- if ! ${CC-cc} ${CFLAGS} ${DSO_PIC_CFLAGS} ${DSO_LDOPTS} -O2 -S -o conftest.S conftest.c > /dev/null 2>&1 ; then
-+ if ! ${CXX-c++} ${CXXFLAGS} ${DSO_PIC_CFLAGS} ${DSO_LDOPTS} -O2 -S -o conftest.S conftest.c > /dev/null 2>&1 ; then
- ac_cv_have_visibility_builtin_bug=yes
- else
- if test `grep -c "@PLT" conftest.S` = 0; then
-@@ -2515,7 +2516,7 @@ then
+- ac_cv_have_visibility_builtin_bug=yes
+- else
+- if test `grep -c "@PLT" conftest.S` = 0; then
+- ac_cv_visibility_builtin_bug=yes
+- fi
+- fi
+- rm -f conftest.{c,S}
+- ])
+- if test "$ac_cv_have_visibility_builtin_bug" = "no" -a \
+- "$ac_cv_have_visibility_class_bug" = "no"; then
+- VISIBILITY_FLAGS='-I$(DIST)/system_wrappers_js -include $(topsrcdir)/config/gcc_hidden.h'
+- WRAP_SYSTEM_INCLUDES=1
+- else
+- VISIBILITY_FLAGS='-fvisibility=hidden'
+- fi # have visibility pragma bug
+- fi # have visibility pragma
+- fi # have visibility(default) attribute
+- fi # have visibility(hidden) attribute
++ AC_DEFINE(HAVE_VISIBILITY_HIDDEN_ATTRIBUTE)
++ AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE)
++ VISIBILITY_FLAGS='-I$(DIST)/system_wrappers_js -include $(topsrcdir)/config/gcc_hidden.h'
++ WRAP_SYSTEM_INCLUDES=1
+ fi # GNU_CC
+
+ # visibility hidden flag for Sun Studio on Solaris
+@@ -2456,7 +2353,7 @@ then
fi
case "$target" in
@@ -30,33 +135,7 @@ Treat DragonFly like FreeBSD.
AC_DEFINE(_REENTRANT)
AC_DEFINE(_THREAD_SAFE)
dnl -pthread links in -lpthread, so don't specify it explicitly.
-@@ -2600,14 +2601,22 @@ fi
- AC_CACHE_CHECK(
- [for res_ninit()],
- ac_cv_func_res_ninit,
-- [AC_TRY_LINK([
-+ [AC_TRY_RUN([
- #ifdef linux
- #define _BSD_SOURCE 1
- #endif
-+ #ifdef __NetBSD__
-+ #error use of global _res variable in threaded programs is not portable
-+ #endif
-+ #include <sys/types.h>
-+ #include <netinet/in.h>
-+ #include <arpa/nameser.h>
- #include <resolv.h>
-- ],
-- [int foo = res_ninit(&_res);],
-+ int main(int argc, char **argv){
-+ int foo = res_ninit(&_res);
-+ }],
- [ac_cv_func_res_ninit=yes],
-+ [ac_cv_func_res_ninit=no],
- [ac_cv_func_res_ninit=no])
- ])
-
-@@ -3316,7 +3325,7 @@ if test "$MOZ_MEMORY"; then
+@@ -3270,7 +3167,7 @@ if test "$MOZ_MEMORY"; then
*-darwin*)
AC_DEFINE(MOZ_MEMORY_DARWIN)
;;
@@ -65,7 +144,39 @@ Treat DragonFly like FreeBSD.
AC_DEFINE(MOZ_MEMORY_BSD)
;;
*-android*|*-linuxandroid*)
-@@ -4339,6 +4348,16 @@ fi
+@@ -3632,7 +3529,10 @@ dnl ====================================
+ dnl = Support for gcc stack unwinding (from gcc 3.3)
+ dnl ========================================================
+ if test -z "$SKIP_LIBRARY_CHECKS"; then
++ AC_LANG_SAVE
++ AC_LANG_CPLUSPLUS
+ MOZ_CHECK_HEADER(unwind.h, AC_CHECK_FUNCS(_Unwind_Backtrace))
++ AC_LANG_RESTORE
+ fi
+
+ dnl ========================================================
+@@ -4086,6 +3986,20 @@ AC_SUBST(CXX_VERSION)
+ AC_SUBST(MSMANIFEST_TOOL)
+ AC_SUBST(MOZ_LINKER)
+
++AC_MSG_CHECKING([for posix_fadvise])
++AC_TRY_LINK([#define _XOPEN_SOURCE 600
++ #include <fcntl.h>],
++ [posix_fadvise(0, 0, 0, 0);],
++ [ac_cv___posix_fadvise=true],
++ [ac_cv___posix_fadvise=false])
++
++if test "$ac_cv___posix_fadvise" = true ; then
++ AC_DEFINE(HAVE_POSIX_FADVISE)
++ AC_MSG_RESULT(yes)
++else
++ AC_MSG_RESULT(no)
++fi
++
+ AC_MSG_CHECKING([for posix_fallocate])
+ AC_TRY_LINK([#define _XOPEN_SOURCE 600
+ #include <fcntl.h>],
+@@ -4436,6 +4350,16 @@ fi
dnl ========================================================
dnl JavaScript shell
dnl ========================================================
diff --git a/www/firefox/patches/patch-browser_app_nsBrowserApp.cpp b/www/firefox/patches/patch-browser_app_nsBrowserApp.cpp
new file mode 100644
index 00000000000..cfe7efb6e03
--- /dev/null
+++ b/www/firefox/patches/patch-browser_app_nsBrowserApp.cpp
@@ -0,0 +1,12 @@
+$NetBSD: patch-browser_app_nsBrowserApp.cpp,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- browser/app/nsBrowserApp.cpp.orig 2014-03-15 05:19:07.000000000 +0000
++++ browser/app/nsBrowserApp.cpp
+@@ -586,6 +586,7 @@ int main(int argc, char* argv[])
+ TriggerQuirks();
+ #endif
+
++ setenv("MOZ_PLUGIN_PATH", "%%LOCALBASE%%/lib/browser_plugins/symlinks/gecko", 0);
+ int gotCounters;
+ #if defined(XP_UNIX)
+ struct rusage initialRUsage;
diff --git a/www/firefox/patches/patch-browser_installer_package-manifest.in b/www/firefox/patches/patch-browser_installer_package-manifest.in
index 3ece8451a17..666d95fab8d 100644
--- a/www/firefox/patches/patch-browser_installer_package-manifest.in
+++ b/www/firefox/patches/patch-browser_installer_package-manifest.in
@@ -1,11 +1,11 @@
-$NetBSD: patch-browser_installer_package-manifest.in,v 1.3 2014/02/20 13:19:03 ryoon Exp $
+$NetBSD: patch-browser_installer_package-manifest.in,v 1.4 2014/03/20 21:02:00 ryoon Exp $
Limit SPARC bits to just SPARC (untested, but fixes x86).
---- browser/installer/package-manifest.in.orig 2013-06-18 11:01:12.000000000 +0000
+--- browser/installer/package-manifest.in.orig 2014-03-15 05:19:09.000000000 +0000
+++ browser/installer/package-manifest.in
-@@ -690,7 +690,7 @@
- @BINPATH@/components/pippki.xpt
+@@ -732,7 +732,7 @@
+ #endif
; for Solaris SPARC
-#ifdef SOLARIS
diff --git a/www/firefox/patches/patch-browser_themes_shared_devtools_common.css b/www/firefox/patches/patch-browser_themes_shared_devtools_common.css
new file mode 100644
index 00000000000..7e1a7176526
--- /dev/null
+++ b/www/firefox/patches/patch-browser_themes_shared_devtools_common.css
@@ -0,0 +1,32 @@
+$NetBSD: patch-browser_themes_shared_devtools_common.css,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- browser/themes/shared/devtools/common.css.orig 2014-03-15 05:19:09.000000000 +0000
++++ browser/themes/shared/devtools/common.css
+@@ -11,13 +11,13 @@
+ .devtools-monospace {
+ %ifdef XP_MACOSX
+ font-family: Menlo, monospace;
+-%endif
+-%ifdef XP_LINUX
++%elifdef XP_WIN
++ font-family: Consolas, monospace;
++%else
+ font-family: monospace;
+- font-size: 80%;
+ %endif
+-%ifdef XP_WIN
+- font-family: Consolas, monospace;
++%if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT)
++ font-size: 80%;
+ %endif
+ }
+
+@@ -62,7 +62,7 @@
+ background-image: linear-gradient(to bottom, hsla(209,18%,18%,0.9), hsl(210,11%,16%));
+ border-radius: 3px;
+ overflow-x: hidden;
+-%ifdef XP_LINUX
++%if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT)
+ max-height: 32rem;
+ %else
+ max-height: 40rem;
diff --git a/www/firefox/patches/patch-browser_themes_shared_devtools_highlighter.inc.css b/www/firefox/patches/patch-browser_themes_shared_devtools_highlighter.inc.css
new file mode 100644
index 00000000000..bde96910327
--- /dev/null
+++ b/www/firefox/patches/patch-browser_themes_shared_devtools_highlighter.inc.css
@@ -0,0 +1,13 @@
+$NetBSD: patch-browser_themes_shared_devtools_highlighter.inc.css,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- browser/themes/shared/devtools/highlighter.inc.css.orig 2014-03-15 05:19:09.000000000 +0000
++++ browser/themes/shared/devtools/highlighter.inc.css
+@@ -54,7 +54,7 @@ html|*.highlighter-nodeinfobar-pseudo-cl
+ padding: 0;
+ width: 26px;
+ min-height: 26px;
+-%ifndef XP_LINUX
++%if !defined(MOZ_WIDGET_GTK) && !defined(MOZ_WIDGET_QT)
+ background-color: transparent;
+ %endif
+ }
diff --git a/www/firefox/patches/patch-build_pgo_profileserver.py b/www/firefox/patches/patch-build_pgo_profileserver.py
new file mode 100644
index 00000000000..389a0641bda
--- /dev/null
+++ b/www/firefox/patches/patch-build_pgo_profileserver.py
@@ -0,0 +1,13 @@
+$NetBSD: patch-build_pgo_profileserver.py,v 1.3 2014/03/20 21:02:00 ryoon Exp $
+
+--- build/pgo/profileserver.py.orig 2014-03-15 05:19:09.000000000 +0000
++++ build/pgo/profileserver.py
+@@ -59,7 +59,7 @@ if __name__ == '__main__':
+ env["MOZ_JAR_LOG_FILE"] = os.path.abspath(jarlog)
+ print "jarlog: %s" % env["MOZ_JAR_LOG_FILE"]
+
+- cmdargs = ["http://localhost:%d/index.html" % PORT]
++ cmdargs = ["http://127.0.0.1:%d/index.html" % PORT]
+ runner = FirefoxRunner(profile=profile,
+ binary=build.get_binary_path(where="staged-package"),
+ cmdargs=cmdargs,
diff --git a/www/firefox/patches/patch-config_Makefile.in b/www/firefox/patches/patch-config_Makefile.in
new file mode 100644
index 00000000000..b6fe6db4832
--- /dev/null
+++ b/www/firefox/patches/patch-config_Makefile.in
@@ -0,0 +1,16 @@
+$NetBSD: patch-config_Makefile.in,v 1.3 2014/03/20 21:02:00 ryoon Exp $
+
+--- config/Makefile.in.orig 2014-03-15 05:19:09.000000000 +0000
++++ config/Makefile.in
+@@ -73,6 +73,11 @@ export:: $(export-preqs)
+ -DMOZ_NATIVE_LIBEVENT=$(MOZ_NATIVE_LIBEVENT) \
+ -DMOZ_NATIVE_LIBVPX=$(MOZ_NATIVE_LIBVPX) \
+ -DMOZ_NATIVE_ICU=$(MOZ_NATIVE_ICU) \
++ -DMOZ_NATIVE_GRAPHITE2=$(MOZ_NATIVE_GRAPHITE2) \
++ -DMOZ_NATIVE_HARFBUZZ=$(MOZ_NATIVE_HARFBUZZ) \
++ -DMOZ_NATIVE_OGG=$(MOZ_NATIVE_OGG) \
++ -DMOZ_NATIVE_VORBIS=$(MOZ_NATIVE_VORBIS) \
++ -DMOZ_NATIVE_OPUS=$(MOZ_NATIVE_OPUS) \
+ $(srcdir)/system-headers | $(PERL) $(topsrcdir)/nsprpub/config/make-system-wrappers.pl system_wrappers
+ $(INSTALL) system_wrappers $(DIST)
+
diff --git a/www/firefox/patches/patch-config_external_moz.build b/www/firefox/patches/patch-config_external_moz.build
new file mode 100644
index 00000000000..4199ee392ce
--- /dev/null
+++ b/www/firefox/patches/patch-config_external_moz.build
@@ -0,0 +1,31 @@
+$NetBSD: patch-config_external_moz.build,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- config/external/moz.build.orig 2014-03-15 05:19:09.000000000 +0000
++++ config/external/moz.build
+@@ -15,13 +15,13 @@ if CONFIG['MOZ_UPDATER']:
+ if not CONFIG['MOZ_NATIVE_BZ2']:
+ external_dirs += ['modules/libbz2']
+
+-if CONFIG['MOZ_VORBIS']:
++if CONFIG['MOZ_VORBIS'] and not CONFIG['MOZ_NATIVE_VORBIS']:
+ external_dirs += ['media/libvorbis']
+
+ if CONFIG['MOZ_TREMOR']:
+ external_dirs += ['media/libtremor']
+
+-if CONFIG['MOZ_OPUS']:
++if CONFIG['MOZ_OPUS'] and not CONFIG['MOZ_NATIVE_OPUS']:
+ external_dirs += ['media/libopus']
+
+ if CONFIG['MOZ_WEBM']:
+@@ -31,7 +31,9 @@ if CONFIG['MOZ_VP8'] and not CONFIG['MOZ
+ external_dirs += ['media/libvpx']
+
+ if CONFIG['MOZ_OGG']:
+- external_dirs += ['media/libogg', 'media/libtheora']
++ if not CONFIG['MOZ_NATIVE_OGG']:
++ external_dirs += ['media/libogg']
++ external_dirs += ['media/libtheora']
+
+ if not CONFIG['MOZ_NATIVE_PNG']:
+ external_dirs += ['media/libpng']
diff --git a/www/firefox/patches/patch-config_system-headers b/www/firefox/patches/patch-config_system-headers
index baf1c19310d..be8339eb3a4 100644
--- a/www/firefox/patches/patch-config_system-headers
+++ b/www/firefox/patches/patch-config_system-headers
@@ -1,9 +1,33 @@
-$NetBSD: patch-config_system-headers,v 1.6 2014/02/20 13:19:03 ryoon Exp $
+$NetBSD: patch-config_system-headers,v 1.7 2014/03/20 21:02:00 ryoon Exp $
---- config/system-headers.orig 2013-12-05 16:07:23.000000000 +0000
+--- config/system-headers.orig 2014-03-15 05:19:09.000000000 +0000
+++ config/system-headers
-@@ -1144,3 +1144,4 @@ unicode/unum.h
+@@ -1144,4 +1144,28 @@ unicode/unum.h
unicode/ustring.h
unicode/utypes.h
#endif
-+libutil.h
++cairo-qt.h
++#if MOZ_NATIVE_GRAPHITE2==1
++unwind.h
++graphite2/Font.h
++graphite2/Segment.h
++#endif
++#if MOZ_NATIVE_HARFBUZZ==1
++harfbuzz/hb-ot.h
++harfbuzz/hb.h
++#endif
++#if MOZ_NATIVE_OGG==1
++ogg/ogg.h
++ogg/os_types.h
++#endif
++#if MOZ_NATIVE_VORBIS==1
++vorbis/codec.h
++vorbis/vorbisenc.h
++#endif
++#if MOZ_NATIVE_OPUS==1
++opus.h
++opus_multistream.h
++opus/opus.h
++opus/opus_multistream.h
++#endif
+ libutil.h
diff --git a/www/firefox/patches/patch-content_base_src_Makefile.in b/www/firefox/patches/patch-content_base_src_Makefile.in
new file mode 100644
index 00000000000..dee5f3485e6
--- /dev/null
+++ b/www/firefox/patches/patch-content_base_src_Makefile.in
@@ -0,0 +1,15 @@
+$NetBSD: patch-content_base_src_Makefile.in,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- content/base/src/Makefile.in.orig 2014-03-15 05:19:10.000000000 +0000
++++ content/base/src/Makefile.in
+@@ -5,6 +5,10 @@
+
+ include $(topsrcdir)/config/rules.mk
+
++ifdef MOZ_NATIVE_HARFBUZZ
++nsContentUtils.$(OBJ_SUFFIX): CXXFLAGS+=$(MOZ_HARFBUZZ_CFLAGS)
++endif
++
+ # gcc requires -msse2 for this file since it uses SSE2 intrinsics. (See bug
+ # 585538 comment 12.)
+ ifneq (,$(INTEL_ARCHITECTURE))
diff --git a/www/firefox/patches/patch-content_media_Makefile.in b/www/firefox/patches/patch-content_media_Makefile.in
new file mode 100644
index 00000000000..281c780283c
--- /dev/null
+++ b/www/firefox/patches/patch-content_media_Makefile.in
@@ -0,0 +1,21 @@
+$NetBSD: patch-content_media_Makefile.in,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- content/media/Makefile.in.orig 2014-03-15 05:19:11.000000000 +0000
++++ content/media/Makefile.in
+@@ -7,4 +7,16 @@ include $(topsrcdir)/config/rules.mk
+ CFLAGS += $(GSTREAMER_CFLAGS)
+ CXXFLAGS += $(GSTREAMER_CFLAGS)
+
++ifdef MOZ_NATIVE_OGG
++CXXFLAGS += $(MOZ_OGG_CFLAGS)
++endif
++
++ifdef MOZ_NATIVE_VORBIS
++CXXFLAGS += $(MOZ_VORBIS_CFLAGS)
++endif
++
++ifdef MOZ_NATIVE_OPUS
++CXXFLAGS += $(MOZ_OPUS_CFLAGS)
++endif
++
+ AudioNodeEngineNEON.$(OBJ_SUFFIX): CXXFLAGS += -mfpu=neon
diff --git a/www/firefox/patches/patch-content_media_gstreamer_GStreamerAllocator.cpp b/www/firefox/patches/patch-content_media_gstreamer_GStreamerAllocator.cpp
new file mode 100644
index 00000000000..ab175dc7d15
--- /dev/null
+++ b/www/firefox/patches/patch-content_media_gstreamer_GStreamerAllocator.cpp
@@ -0,0 +1,203 @@
+$NetBSD: patch-content_media_gstreamer_GStreamerAllocator.cpp,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- content/media/gstreamer/GStreamerAllocator.cpp.orig 2014-03-20 11:09:40.000000000 +0000
++++ content/media/gstreamer/GStreamerAllocator.cpp
+@@ -0,0 +1,198 @@
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++
++#include "GStreamerAllocator.h"
++
++#include <gst/video/video.h>
++#include <gst/video/gstvideometa.h>
++
++#include "GStreamerLoader.h"
++
++using namespace mozilla::layers;
++
++namespace mozilla {
++
++typedef struct
++{
++ GstAllocator parent;
++ GStreamerReader *reader;
++} MozGfxMemoryAllocator;
++
++typedef struct
++{
++ GstAllocatorClass parent;
++} MozGfxMemoryAllocatorClass;
++
++typedef struct
++{
++ GstMemory memory;
++ PlanarYCbCrImage* image;
++ guint8* data;
++} MozGfxMemory;
++
++typedef struct
++{
++ GstMeta meta;
++} MozGfxMeta;
++
++typedef struct
++{
++ GstVideoBufferPoolClass parent_class;
++} MozGfxBufferPoolClass;
++
++typedef struct
++{
++ GstVideoBufferPool pool;
++} MozGfxBufferPool;
++
++G_DEFINE_TYPE(MozGfxMemoryAllocator, moz_gfx_memory_allocator, GST_TYPE_ALLOCATOR);
++G_DEFINE_TYPE(MozGfxBufferPool, moz_gfx_buffer_pool, GST_TYPE_VIDEO_BUFFER_POOL);
++
++void
++moz_gfx_memory_reset(MozGfxMemory *mem)
++{
++ if (mem->image)
++ mem->image->Release();
++
++ ImageContainer* container = ((MozGfxMemoryAllocator*) mem->memory.allocator)->reader->GetImageContainer();
++ ImageFormat format = PLANAR_YCBCR;
++ mem->image = reinterpret_cast<PlanarYCbCrImage*>(container->CreateImage(&format, 1).get());
++ mem->data = mem->image->AllocateAndGetNewBuffer(mem->memory.size);
++}
++
++static GstMemory*
++moz_gfx_memory_allocator_alloc(GstAllocator* aAllocator, gsize aSize,
++ GstAllocationParams* aParams)
++{
++ MozGfxMemory* mem = g_slice_new (MozGfxMemory);
++ gsize maxsize = aSize + aParams->prefix + aParams->padding;
++ gst_memory_init(GST_MEMORY_CAST (mem),
++ (GstMemoryFlags)aParams->flags,
++ aAllocator, NULL, maxsize, aParams->align,
++ aParams->prefix, aSize);
++ mem->image = NULL;
++ moz_gfx_memory_reset(mem);
++
++ return (GstMemory *) mem;
++}
++
++static void
++moz_gfx_memory_allocator_free (GstAllocator * allocator, GstMemory * gmem)
++{
++ MozGfxMemory *mem = (MozGfxMemory *) gmem;
++
++ if (mem->memory.parent)
++ goto sub_mem;
++
++ if (mem->image)
++ mem->image->Release();
++
++sub_mem:
++ g_slice_free (MozGfxMemory, mem);
++}
++
++static gpointer
++moz_gfx_memory_map (MozGfxMemory * mem, gsize maxsize, GstMapFlags flags)
++{
++ // check that the allocation didn't fail
++ if (mem->data == nullptr)
++ return nullptr;
++
++ return mem->data + mem->memory.offset;
++}
++
++static gboolean
++moz_gfx_memory_unmap (MozGfxMemory * mem)
++{
++ return TRUE;
++}
++
++static MozGfxMemory *
++moz_gfx_memory_share (MozGfxMemory * mem, gssize offset, gsize size)
++{
++ MozGfxMemory *sub;
++ GstMemory *parent;
++
++ /* find the real parent */
++ if ((parent = mem->memory.parent) == NULL)
++ parent = (GstMemory *) mem;
++
++ if (size == (gsize) -1)
++ size = mem->memory.size - offset;
++
++ /* the shared memory is always readonly */
++ sub = g_slice_new (MozGfxMemory);
++
++ gst_memory_init (GST_MEMORY_CAST (sub),
++ (GstMemoryFlags) (GST_MINI_OBJECT_FLAGS (parent) | GST_MINI_OBJECT_FLAG_LOCK_READONLY),
++ mem->memory.allocator, &mem->memory, mem->memory.maxsize, mem->memory.align,
++ mem->memory.offset + offset, size);
++
++ sub->image = mem->image;
++ sub->data = mem->data;
++
++ return sub;
++}
++
++static void
++moz_gfx_memory_allocator_class_init (MozGfxMemoryAllocatorClass * klass)
++{
++ GstAllocatorClass *allocator_class;
++
++ allocator_class = (GstAllocatorClass *) klass;
++
++ allocator_class->alloc = moz_gfx_memory_allocator_alloc;
++ allocator_class->free = moz_gfx_memory_allocator_free;
++}
++
++static void
++moz_gfx_memory_allocator_init (MozGfxMemoryAllocator * allocator)
++{
++ GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);
++
++ alloc->mem_type = "moz-gfx-image";
++ alloc->mem_map = (GstMemoryMapFunction) moz_gfx_memory_map;
++ alloc->mem_unmap = (GstMemoryUnmapFunction) moz_gfx_memory_unmap;
++ alloc->mem_share = (GstMemoryShareFunction) moz_gfx_memory_share;
++ /* fallback copy and is_span */
++}
++
++void
++moz_gfx_memory_allocator_set_reader(GstAllocator* aAllocator, GStreamerReader* aReader)
++{
++ MozGfxMemoryAllocator *allocator = (MozGfxMemoryAllocator *) aAllocator;
++ allocator->reader = aReader;
++}
++
++nsRefPtr<PlanarYCbCrImage>
++moz_gfx_memory_get_image(GstMemory *aMemory)
++{
++ NS_ASSERTION(GST_IS_MOZ_GFX_MEMORY_ALLOCATOR(aMemory->allocator), "Should be a gfx image");
++
++ return ((MozGfxMemory *) aMemory)->image;
++}
++
++void
++moz_gfx_buffer_pool_reset_buffer (GstBufferPool* aPool, GstBuffer* aBuffer)
++{
++ GstMemory* mem = gst_buffer_peek_memory(aBuffer, 0);
++
++ NS_ASSERTION(GST_IS_MOZ_GFX_MEMORY_ALLOCATOR(mem->allocator), "Should be a gfx image");
++ moz_gfx_memory_reset((MozGfxMemory *) mem);
++ GST_BUFFER_POOL_CLASS(moz_gfx_buffer_pool_parent_class)->reset_buffer(aPool, aBuffer);
++}
++
++static void
++moz_gfx_buffer_pool_class_init (MozGfxBufferPoolClass * klass)
++{
++ GstBufferPoolClass *pool_class = (GstBufferPoolClass *) klass;
++ pool_class->reset_buffer = moz_gfx_buffer_pool_reset_buffer;
++}
++
++static void
++moz_gfx_buffer_pool_init (MozGfxBufferPool * pool)
++{
++}
++
++} // namespace mozilla
diff --git a/www/firefox/patches/patch-content_media_gstreamer_GStreamerAllocator.h b/www/firefox/patches/patch-content_media_gstreamer_GStreamerAllocator.h
new file mode 100644
index 00000000000..a8b15f3a754
--- /dev/null
+++ b/www/firefox/patches/patch-content_media_gstreamer_GStreamerAllocator.h
@@ -0,0 +1,30 @@
+$NetBSD: patch-content_media_gstreamer_GStreamerAllocator.h,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- content/media/gstreamer/GStreamerAllocator.h.orig 2014-03-20 11:09:40.000000000 +0000
++++ content/media/gstreamer/GStreamerAllocator.h
+@@ -0,0 +1,25 @@
++/* 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(GStreamerAllocator_h_)
++#define GStreamerAllocator_h_
++
++#include "GStreamerReader.h"
++
++#define GST_TYPE_MOZ_GFX_MEMORY_ALLOCATOR (moz_gfx_memory_allocator_get_type())
++#define GST_IS_MOZ_GFX_MEMORY_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MOZ_GFX_MEMORY_ALLOCATOR))
++#define GST_TYPE_MOZ_GFX_BUFFER_POOL (moz_gfx_buffer_pool_get_type())
++#define GST_IS_MOZ_GFX_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MOZ_GFX_BUFFER_POOL))
++
++namespace mozilla {
++
++GType moz_gfx_memory_allocator_get_type();
++void moz_gfx_memory_allocator_set_reader(GstAllocator *aAllocator, GStreamerReader* aReader);
++nsRefPtr<layers::PlanarYCbCrImage> moz_gfx_memory_get_image(GstMemory *aMemory);
++
++GType moz_gfx_buffer_pool_get_type();
++
++} // namespace mozilla
++
++#endif
diff --git a/www/firefox/patches/patch-content_media_gstreamer_GStreamerFormatHelper.cpp b/www/firefox/patches/patch-content_media_gstreamer_GStreamerFormatHelper.cpp
new file mode 100644
index 00000000000..2886bda65fa
--- /dev/null
+++ b/www/firefox/patches/patch-content_media_gstreamer_GStreamerFormatHelper.cpp
@@ -0,0 +1,29 @@
+$NetBSD: patch-content_media_gstreamer_GStreamerFormatHelper.cpp,v 1.3 2014/03/20 21:02:00 ryoon Exp $
+
+--- content/media/gstreamer/GStreamerFormatHelper.cpp.orig 2014-03-15 05:19:11.000000000 +0000
++++ content/media/gstreamer/GStreamerFormatHelper.cpp
+@@ -294,12 +294,23 @@ bool GStreamerFormatHelper::CanHandleCod
+ GList* GStreamerFormatHelper::GetFactories() {
+ NS_ASSERTION(sLoadOK, "GStreamer library not linked");
+
+- uint32_t cookie = gst_default_registry_get_feature_list_cookie ();
++#if GST_VERSION_MAJOR >= 1
++ uint32_t cookie = gst_registry_get_feature_list_cookie(gst_registry_get());
++#else
++ uint32_t cookie = gst_default_registry_get_feature_list_cookie();
++#endif
+ if (cookie != mCookie) {
+ g_list_free(mFactories);
++#if GST_VERSION_MAJOR >= 1
++ mFactories =
++ gst_registry_feature_filter(gst_registry_get(),
++ (GstPluginFeatureFilter)FactoryFilter,
++ false, nullptr);
++#else
+ mFactories =
+ gst_default_registry_feature_filter((GstPluginFeatureFilter)FactoryFilter,
+ false, nullptr);
++#endif
+ mCookie = cookie;
+ }
+
diff --git a/www/firefox/patches/patch-content_media_gstreamer_GStreamerFunctionList.h b/www/firefox/patches/patch-content_media_gstreamer_GStreamerFunctionList.h
new file mode 100644
index 00000000000..c697e0143a6
--- /dev/null
+++ b/www/firefox/patches/patch-content_media_gstreamer_GStreamerFunctionList.h
@@ -0,0 +1,168 @@
+$NetBSD: patch-content_media_gstreamer_GStreamerFunctionList.h,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- content/media/gstreamer/GStreamerFunctionList.h.orig 2014-03-15 05:19:11.000000000 +0000
++++ content/media/gstreamer/GStreamerFunctionList.h
+@@ -9,7 +9,6 @@
+ * List of symbol names we need to dlsym from the gstreamer library.
+ */
+ GST_FUNC(LIBGSTAPP, gst_app_sink_get_type)
+-GST_FUNC(LIBGSTAPP, gst_app_sink_pull_buffer)
+ GST_FUNC(LIBGSTAPP, gst_app_sink_set_callbacks)
+ GST_FUNC(LIBGSTAPP, gst_app_src_end_of_stream)
+ GST_FUNC(LIBGSTAPP, gst_app_src_get_size)
+@@ -22,10 +21,8 @@ GST_FUNC(LIBGSTAPP, gst_app_src_set_stre
+ GST_FUNC(LIBGSTREAMER, gst_bin_get_by_name)
+ GST_FUNC(LIBGSTREAMER, gst_bin_get_type)
+ GST_FUNC(LIBGSTREAMER, gst_bin_iterate_recurse)
+-GST_FUNC(LIBGSTREAMER, gst_buffer_copy_metadata)
+ GST_FUNC(LIBGSTREAMER, gst_buffer_get_type)
+ GST_FUNC(LIBGSTREAMER, gst_buffer_new)
+-GST_FUNC(LIBGSTREAMER, gst_buffer_new_and_alloc)
+ GST_FUNC(LIBGSTREAMER, gst_bus_set_sync_handler)
+ GST_FUNC(LIBGSTREAMER, gst_bus_timed_pop_filtered)
+ GST_FUNC(LIBGSTREAMER, gst_caps_append)
+@@ -37,47 +34,37 @@ GST_FUNC(LIBGSTREAMER, gst_caps_new_any)
+ GST_FUNC(LIBGSTREAMER, gst_caps_new_empty)
+ GST_FUNC(LIBGSTREAMER, gst_caps_new_full)
+ GST_FUNC(LIBGSTREAMER, gst_caps_new_simple)
+-GST_FUNC(LIBGSTREAMER, gst_caps_unref)
+-GST_FUNC(LIBGSTREAMER, gst_element_factory_get_klass)
++GST_FUNC(LIBGSTREAMER, gst_caps_set_simple)
+ GST_FUNC(LIBGSTREAMER, gst_element_factory_get_static_pad_templates)
+ GST_FUNC(LIBGSTREAMER, gst_element_factory_get_type)
+ GST_FUNC(LIBGSTREAMER, gst_element_factory_make)
+ GST_FUNC(LIBGSTREAMER, gst_element_get_factory)
+-GST_FUNC(LIBGSTREAMER, gst_element_get_pad)
++GST_FUNC(LIBGSTREAMER, gst_element_get_static_pad)
+ GST_FUNC(LIBGSTREAMER, gst_element_get_type)
+ GST_FUNC(LIBGSTREAMER, gst_element_query_convert)
+ GST_FUNC(LIBGSTREAMER, gst_element_query_duration)
+ GST_FUNC(LIBGSTREAMER, gst_element_seek_simple)
+ GST_FUNC(LIBGSTREAMER, gst_element_set_state)
+-GST_FUNC(LIBGSTREAMER, gst_event_parse_new_segment)
+ GST_FUNC(LIBGSTREAMER, gst_flow_get_name)
+ GST_FUNC(LIBGSTREAMER, gst_init)
+ GST_FUNC(LIBGSTREAMER, gst_init_check)
+ GST_FUNC(LIBGSTREAMER, gst_iterator_next)
+ GST_FUNC(LIBGSTREAMER, gst_message_parse_error)
+ GST_FUNC(LIBGSTREAMER, gst_message_type_get_name)
+-GST_FUNC(LIBGSTREAMER, gst_mini_object_get_type)
+-GST_FUNC(LIBGSTREAMER, gst_mini_object_new)
+ GST_FUNC(LIBGSTREAMER, gst_mini_object_ref)
+ GST_FUNC(LIBGSTREAMER, gst_mini_object_unref)
+ GST_FUNC(LIBGSTREAMER, gst_object_get_name)
+ GST_FUNC(LIBGSTREAMER, gst_object_get_parent)
+ GST_FUNC(LIBGSTREAMER, gst_object_unref)
+-GST_FUNC(LIBGSTREAMER, gst_pad_add_event_probe)
+-GST_FUNC(LIBGSTREAMER, gst_pad_alloc_buffer)
+ GST_FUNC(LIBGSTREAMER, gst_pad_get_element_private)
+-GST_FUNC(LIBGSTREAMER, gst_pad_get_negotiated_caps)
+-GST_FUNC(LIBGSTREAMER, gst_pad_set_bufferalloc_function)
+ GST_FUNC(LIBGSTREAMER, gst_pad_set_element_private)
+ GST_FUNC(LIBGSTREAMER, gst_parse_bin_from_description)
+ GST_FUNC(LIBGSTREAMER, gst_pipeline_get_bus)
+ GST_FUNC(LIBGSTREAMER, gst_pipeline_get_type)
+ GST_FUNC(LIBGSTREAMER, gst_plugin_feature_get_rank)
+ GST_FUNC(LIBGSTREAMER, gst_registry_feature_filter)
+-GST_FUNC(LIBGSTREAMER, gst_registry_get_default)
+ GST_FUNC(LIBGSTREAMER, gst_registry_get_feature_list_cookie)
+ GST_FUNC(LIBGSTREAMER, gst_segment_init)
+-GST_FUNC(LIBGSTREAMER, gst_segment_set_newsegment)
+ GST_FUNC(LIBGSTREAMER, gst_segment_to_stream_time)
+ GST_FUNC(LIBGSTREAMER, gst_static_caps_get)
+ GST_FUNC(LIBGSTREAMER, gst_structure_copy)
+@@ -86,11 +73,82 @@ GST_FUNC(LIBGSTREAMER, gst_structure_get
+ GST_FUNC(LIBGSTREAMER, gst_structure_get_value)
+ GST_FUNC(LIBGSTREAMER, gst_structure_new)
+ GST_FUNC(LIBGSTREAMER, gst_util_uint64_scale)
++
++#if GST_VERSION_MAJOR == 0
++GST_FUNC(LIBGSTAPP, gst_app_sink_pull_buffer)
++GST_FUNC(LIBGSTREAMER, gst_buffer_copy_metadata)
++GST_FUNC(LIBGSTREAMER, gst_buffer_new_and_alloc)
++GST_FUNC(LIBGSTREAMER, gst_caps_unref)
++GST_FUNC(LIBGSTREAMER, gst_element_factory_get_klass)
++GST_FUNC(LIBGSTREAMER, gst_element_get_pad)
++GST_FUNC(LIBGSTREAMER, gst_event_parse_new_segment)
++GST_FUNC(LIBGSTREAMER, gst_mini_object_get_type)
++GST_FUNC(LIBGSTREAMER, gst_mini_object_new)
++GST_FUNC(LIBGSTREAMER, gst_pad_add_event_probe)
++GST_FUNC(LIBGSTREAMER, gst_pad_alloc_buffer)
++GST_FUNC(LIBGSTREAMER, gst_pad_get_negotiated_caps)
++GST_FUNC(LIBGSTREAMER, gst_pad_set_bufferalloc_function)
++GST_FUNC(LIBGSTREAMER, gst_registry_get_default)
++GST_FUNC(LIBGSTREAMER, gst_segment_set_newsegment)
+ GST_FUNC(LIBGSTVIDEO, gst_video_format_get_component_height)
+ GST_FUNC(LIBGSTVIDEO, gst_video_format_get_component_offset)
+ GST_FUNC(LIBGSTVIDEO, gst_video_format_get_component_width)
++GST_FUNC(LIBGSTVIDEO, gst_video_format_get_pixel_stride)
+ GST_FUNC(LIBGSTVIDEO, gst_video_format_get_row_stride)
+ GST_FUNC(LIBGSTVIDEO, gst_video_format_parse_caps)
++#else
++
++GST_FUNC(LIBGSTAPP, gst_app_sink_pull_sample)
++GST_FUNC(LIBGSTREAMER, _gst_caps_any)
++GST_FUNC(LIBGSTREAMER, gst_allocator_get_type)
++GST_FUNC(LIBGSTREAMER, gst_buffer_copy_into)
++GST_FUNC(LIBGSTREAMER, gst_buffer_extract)
++GST_FUNC(LIBGSTREAMER, gst_buffer_get_meta)
++GST_FUNC(LIBGSTREAMER, gst_buffer_get_size)
++GST_FUNC(LIBGSTREAMER, gst_buffer_map)
++GST_FUNC(LIBGSTREAMER, gst_buffer_new_allocate)
++GST_FUNC(LIBGSTREAMER, gst_buffer_n_memory)
++GST_FUNC(LIBGSTREAMER, gst_buffer_peek_memory)
++GST_FUNC(LIBGSTREAMER, gst_buffer_pool_acquire_buffer)
++GST_FUNC(LIBGSTREAMER, gst_buffer_pool_config_set_allocator)
++GST_FUNC(LIBGSTREAMER, gst_buffer_pool_config_set_params)
++GST_FUNC(LIBGSTREAMER, gst_buffer_pool_get_config)
++GST_FUNC(LIBGSTREAMER, gst_buffer_pool_get_type)
++GST_FUNC(LIBGSTREAMER, gst_buffer_pool_is_active)
++GST_FUNC(LIBGSTREAMER, gst_buffer_pool_set_active)
++GST_FUNC(LIBGSTREAMER, gst_buffer_pool_set_config)
++GST_FUNC(LIBGSTREAMER, gst_buffer_set_size)
++GST_FUNC(LIBGSTREAMER, gst_buffer_unmap)
++GST_FUNC(LIBGSTREAMER, gst_element_factory_get_metadata)
++GST_FUNC(LIBGSTREAMER, gst_event_parse_segment)
++GST_FUNC(LIBGSTREAMER, gst_memory_init)
++GST_FUNC(LIBGSTREAMER, gst_memory_map)
++GST_FUNC(LIBGSTREAMER, gst_memory_unmap)
++GST_FUNC(LIBGSTREAMER, gst_object_get_type)
++GST_FUNC(LIBGSTREAMER, gst_pad_add_probe)
++GST_FUNC(LIBGSTREAMER, gst_pad_get_current_caps)
++GST_FUNC(LIBGSTREAMER, gst_pad_probe_info_get_query)
++GST_FUNC(LIBGSTREAMER, gst_query_add_allocation_meta)
++GST_FUNC(LIBGSTREAMER, gst_query_add_allocation_param)
++GST_FUNC(LIBGSTREAMER, gst_query_add_allocation_pool)
++GST_FUNC(LIBGSTREAMER, gst_query_parse_allocation)
++GST_FUNC(LIBGSTREAMER, gst_registry_get)
++GST_FUNC(LIBGSTREAMER, gst_sample_get_buffer)
++GST_FUNC(LIBGSTREAMER, gst_segment_copy_into)
++GST_FUNC(LIBGSTREAMER, gst_structure_free)
++GST_FUNC(LIBGSTVIDEO, gst_buffer_pool_config_get_video_alignment)
++GST_FUNC(LIBGSTVIDEO, gst_buffer_pool_has_option)
++GST_FUNC(LIBGSTVIDEO, gst_video_buffer_pool_get_type)
++GST_FUNC(LIBGSTVIDEO, gst_video_frame_map)
++GST_FUNC(LIBGSTVIDEO, gst_video_frame_unmap)
++GST_FUNC(LIBGSTVIDEO, gst_video_info_align)
++GST_FUNC(LIBGSTVIDEO, gst_video_info_from_caps)
++GST_FUNC(LIBGSTVIDEO, gst_video_info_init)
++GST_FUNC(LIBGSTVIDEO, gst_video_meta_api_get_type)
++GST_FUNC(LIBGSTVIDEO, gst_video_meta_map)
++GST_FUNC(LIBGSTVIDEO, gst_video_meta_unmap)
++
++#endif
+
+ /*
+ * Functions that have been defined in the header file. We replace them so that
+@@ -100,6 +158,11 @@ GST_FUNC(LIBGSTVIDEO, gst_video_format_p
+ REPLACE_FUNC(gst_buffer_ref);
+ REPLACE_FUNC(gst_buffer_unref);
+ REPLACE_FUNC(gst_message_unref);
++
++#if GST_VERSION_MAJOR == 1
++REPLACE_FUNC(gst_caps_unref);
++REPLACE_FUNC(gst_sample_unref);
++#endif
+ #endif
+
+ #endif // !defined(__APPLE__)
diff --git a/www/firefox/patches/patch-content_media_gstreamer_GStreamerLoader.cpp b/www/firefox/patches/patch-content_media_gstreamer_GStreamerLoader.cpp
new file mode 100644
index 00000000000..92451a214dc
--- /dev/null
+++ b/www/firefox/patches/patch-content_media_gstreamer_GStreamerLoader.cpp
@@ -0,0 +1,97 @@
+$NetBSD: patch-content_media_gstreamer_GStreamerLoader.cpp,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- content/media/gstreamer/GStreamerLoader.cpp.orig 2014-03-15 05:19:11.000000000 +0000
++++ content/media/gstreamer/GStreamerLoader.cpp
+@@ -6,13 +6,21 @@
+ #include <dlfcn.h>
+ #include <stdio.h>
+
+-#include "GStreamerLoader.h"
++#include "nsDebug.h"
+ #include "mozilla/NullPtr.h"
+
++#include "GStreamerLoader.h"
++
+ #define LIBGSTREAMER 0
+ #define LIBGSTAPP 1
+ #define LIBGSTVIDEO 2
+
++#ifdef __OpenBSD__
++#define LIB_GST_SUFFIX ".so"
++#else
++#define LIB_GST_SUFFIX ".so.0"
++#endif
++
+ namespace mozilla {
+
+ /*
+@@ -32,6 +40,11 @@ namespace mozilla {
+ GstBuffer * gst_buffer_ref_impl(GstBuffer *buf);
+ void gst_buffer_unref_impl(GstBuffer *buf);
+ void gst_message_unref_impl(GstMessage *msg);
++void gst_caps_unref_impl(GstCaps *caps);
++
++#if GST_VERSION_MAJOR == 1
++void gst_sample_unref_impl(GstSample *sample);
++#endif
+
+ bool
+ load_gstreamer()
+@@ -58,32 +71,25 @@ load_gstreamer()
+ if (major == GST_VERSION_MAJOR && minor == GST_VERSION_MINOR) {
+ gstreamerLib = RTLD_DEFAULT;
+ } else {
+-#ifdef __OpenBSD__
+- gstreamerLib = dlopen("libgstreamer-0.10.so", RTLD_NOW | RTLD_LOCAL);
+-#else
+- gstreamerLib = dlopen("libgstreamer-0.10.so.0", RTLD_NOW | RTLD_LOCAL);
+-#endif
++ gstreamerLib = dlopen("libgstreamer-" GST_API_VERSION LIB_GST_SUFFIX, RTLD_NOW | RTLD_LOCAL);
+ }
+
+- void *handles[] = {
++ void *handles[3] = {
+ gstreamerLib,
+-#ifdef __OpenBSD__
+- dlopen("libgstapp-0.10.so", RTLD_NOW | RTLD_LOCAL),
+- dlopen("libgstvideo-0.10.so", RTLD_NOW | RTLD_LOCAL)
+-#else
+- dlopen("libgstapp-0.10.so.0", RTLD_NOW | RTLD_LOCAL),
+- dlopen("libgstvideo-0.10.so.0", RTLD_NOW | RTLD_LOCAL)
+-#endif
++ dlopen("libgstapp-" GST_API_VERSION LIB_GST_SUFFIX, RTLD_NOW | RTLD_LOCAL),
++ dlopen("libgstvideo-" GST_API_VERSION LIB_GST_SUFFIX, RTLD_NOW | RTLD_LOCAL)
+ };
+
+ for (size_t i = 0; i < sizeof(handles) / sizeof(handles[0]); i++) {
+ if (!handles[i]) {
++ NS_WARNING("Couldn't link gstreamer libraries");
+ goto fail;
+ }
+ }
+
+ #define GST_FUNC(lib, symbol) \
+ if (!(symbol = (typeof(symbol))dlsym(handles[lib], #symbol))) { \
++ NS_WARNING("Couldn't link symbol " #symbol); \
+ goto fail; \
+ }
+ #define REPLACE_FUNC(symbol) symbol = symbol##_impl;
+@@ -123,4 +129,18 @@ gst_message_unref_impl(GstMessage *msg)
+ gst_mini_object_unref(GST_MINI_OBJECT_CAST(msg));
+ }
+
++#if GST_VERSION_MAJOR == 1
++void
++gst_sample_unref_impl(GstSample *sample)
++{
++ gst_mini_object_unref(GST_MINI_OBJECT_CAST(sample));
++}
++#endif
++
++void
++gst_caps_unref_impl(GstCaps *caps)
++{
++ gst_mini_object_unref(GST_MINI_OBJECT_CAST(caps));
++}
++
+ }
diff --git a/www/firefox/patches/patch-content_media_gstreamer_GStreamerLoader.h b/www/firefox/patches/patch-content_media_gstreamer_GStreamerLoader.h
new file mode 100644
index 00000000000..8a0d20a1be9
--- /dev/null
+++ b/www/firefox/patches/patch-content_media_gstreamer_GStreamerLoader.h
@@ -0,0 +1,24 @@
+$NetBSD: patch-content_media_gstreamer_GStreamerLoader.h,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- content/media/gstreamer/GStreamerLoader.h.orig 2014-03-15 05:19:11.000000000 +0000
++++ content/media/gstreamer/GStreamerLoader.h
+@@ -22,6 +22,11 @@
+ #include <gst/video/video.h>
+ #pragma GCC diagnostic pop
+
++#if GST_VERSION_MAJOR == 1
++#include <gst/video/gstvideometa.h>
++#include <gst/video/gstvideopool.h>
++#endif
++
+ namespace mozilla {
+
+ /*
+@@ -42,4 +47,7 @@ bool load_gstreamer();
+
+ }
+
++#undef GST_CAPS_ANY
++#define GST_CAPS_ANY (*_gst_caps_any)
++
+ #endif // GStreamerLoader_h_
diff --git a/www/firefox/patches/patch-content_media_gstreamer_GStreamerReader-0.10.cpp b/www/firefox/patches/patch-content_media_gstreamer_GStreamerReader-0.10.cpp
new file mode 100644
index 00000000000..b126ae850bf
--- /dev/null
+++ b/www/firefox/patches/patch-content_media_gstreamer_GStreamerReader-0.10.cpp
@@ -0,0 +1,208 @@
+$NetBSD: patch-content_media_gstreamer_GStreamerReader-0.10.cpp,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- content/media/gstreamer/GStreamerReader-0.10.cpp.orig 2014-03-20 11:09:40.000000000 +0000
++++ content/media/gstreamer/GStreamerReader-0.10.cpp
+@@ -0,0 +1,203 @@
++#include "nsError.h"
++#include "MediaDecoderStateMachine.h"
++#include "AbstractMediaDecoder.h"
++#include "MediaResource.h"
++#include "GStreamerReader.h"
++#include "GStreamerMozVideoBuffer.h"
++#include "GStreamerFormatHelper.h"
++#include "VideoUtils.h"
++#include "mozilla/dom/TimeRanges.h"
++#include "mozilla/Preferences.h"
++
++using namespace mozilla;
++using mozilla::layers::PlanarYCbCrImage;
++using mozilla::layers::ImageContainer;
++
++GstFlowReturn GStreamerReader::AllocateVideoBufferCb(GstPad* aPad,
++ guint64 aOffset,
++ guint aSize,
++ GstCaps* aCaps,
++ GstBuffer** aBuf)
++{
++ GStreamerReader* reader = reinterpret_cast<GStreamerReader*>(gst_pad_get_element_private(aPad));
++ return reader->AllocateVideoBuffer(aPad, aOffset, aSize, aCaps, aBuf);
++}
++
++GstFlowReturn GStreamerReader::AllocateVideoBuffer(GstPad* aPad,
++ guint64 aOffset,
++ guint aSize,
++ GstCaps* aCaps,
++ GstBuffer** aBuf)
++{
++ nsRefPtr<PlanarYCbCrImage> image;
++ return AllocateVideoBufferFull(aPad, aOffset, aSize, aCaps, aBuf, image);
++}
++
++GstFlowReturn GStreamerReader::AllocateVideoBufferFull(GstPad* aPad,
++ guint64 aOffset,
++ guint aSize,
++ GstCaps* aCaps,
++ GstBuffer** aBuf,
++ nsRefPtr<PlanarYCbCrImage>& aImage)
++{
++ /* allocate an image using the container */
++ ImageContainer* container = mDecoder->GetImageContainer();
++ if (!container) {
++ // We don't have an ImageContainer. We probably belong to an <audio>
++ // element.
++ return GST_FLOW_NOT_SUPPORTED;
++ }
++ ImageFormat format = PLANAR_YCBCR;
++ PlanarYCbCrImage* img = reinterpret_cast<PlanarYCbCrImage*>(container->CreateImage(&format, 1).get());
++ nsRefPtr<PlanarYCbCrImage> image = dont_AddRef(img);
++
++ /* prepare a GstBuffer pointing to the underlying PlanarYCbCrImage buffer */
++ GstBuffer* buf = GST_BUFFER(gst_moz_video_buffer_new());
++ GST_BUFFER_SIZE(buf) = aSize;
++ /* allocate the actual YUV buffer */
++ GST_BUFFER_DATA(buf) = image->AllocateAndGetNewBuffer(aSize);
++
++ aImage = image;
++
++ /* create a GstMozVideoBufferData to hold the image */
++ GstMozVideoBufferData* bufferdata = new GstMozVideoBufferData(image);
++
++ /* Attach bufferdata to our GstMozVideoBuffer, it will take care to free it */
++ gst_moz_video_buffer_set_data(GST_MOZ_VIDEO_BUFFER(buf), bufferdata);
++
++ *aBuf = buf;
++ return GST_FLOW_OK;
++}
++
++gboolean GStreamerReader::EventProbe(GstPad* aPad, GstEvent* aEvent)
++{
++ GstElement* parent = GST_ELEMENT(gst_pad_get_parent(aPad));
++ switch(GST_EVENT_TYPE(aEvent)) {
++ case GST_EVENT_NEWSEGMENT:
++ {
++ gboolean update;
++ gdouble rate;
++ GstFormat format;
++ gint64 start, stop, position;
++ GstSegment* segment;
++
++ /* Store the segments so we can convert timestamps to stream time, which
++ * is what the upper layers sync on.
++ */
++ ReentrantMonitorAutoEnter mon(mGstThreadsMonitor);
++ gst_event_parse_new_segment(aEvent, &update, &rate, &format,
++ &start, &stop, &position);
++ if (parent == GST_ELEMENT(mVideoAppSink))
++ segment = &mVideoSegment;
++ else
++ segment = &mAudioSegment;
++ gst_segment_set_newsegment(segment, update, rate, format,
++ start, stop, position);
++ break;
++ }
++ case GST_EVENT_FLUSH_STOP:
++ /* Reset on seeks */
++ ResetDecode();
++ break;
++ default:
++ break;
++ }
++ gst_object_unref(parent);
++
++ return TRUE;
++}
++
++gboolean GStreamerReader::EventProbeCb(GstPad* aPad,
++ GstEvent* aEvent,
++ gpointer aUserData)
++{
++ GStreamerReader* reader = reinterpret_cast<GStreamerReader*>(aUserData);
++ return reader->EventProbe(aPad, aEvent);
++}
++
++nsRefPtr<PlanarYCbCrImage> GStreamerReader::GetImageFromBuffer(GstBuffer* aBuffer)
++{
++ if (!GST_IS_MOZ_VIDEO_BUFFER (aBuffer))
++ return nullptr;
++
++ nsRefPtr<PlanarYCbCrImage> image;
++ GstMozVideoBufferData* bufferdata = reinterpret_cast<GstMozVideoBufferData*>(gst_moz_video_buffer_get_data(GST_MOZ_VIDEO_BUFFER(aBuffer)));
++ image = bufferdata->mImage;
++
++ PlanarYCbCrImage::Data data;
++ data.mPicX = data.mPicY = 0;
++ data.mPicSize = nsIntSize(mPicture.width, mPicture.height);
++ data.mStereoMode = STEREO_MODE_MONO;
++
++ data.mYChannel = GST_BUFFER_DATA(aBuffer);
++ data.mYStride = gst_video_format_get_row_stride(mFormat, 0, mPicture.width);
++ data.mYSize = nsIntSize(data.mYStride,
++ gst_video_format_get_component_height(mFormat, 0, mPicture.height));
++ data.mYSkip = 0;
++ data.mCbCrStride = gst_video_format_get_row_stride(mFormat, 1, mPicture.width);
++ data.mCbCrSize = nsIntSize(data.mCbCrStride,
++ gst_video_format_get_component_height(mFormat, 1, mPicture.height));
++ data.mCbChannel = data.mYChannel + gst_video_format_get_component_offset(mFormat, 1,
++ mPicture.width, mPicture.height);
++ data.mCrChannel = data.mYChannel + gst_video_format_get_component_offset(mFormat, 2,
++ mPicture.width, mPicture.height);
++ data.mCbSkip = 0;
++ data.mCrSkip = 0;
++
++ image->SetDataNoCopy(data);
++
++ return image;
++}
++
++void GStreamerReader::CopyIntoImageBuffer(GstBuffer* aBuffer,
++ GstBuffer** aOutBuffer,
++ nsRefPtr<PlanarYCbCrImage> &aImage)
++{
++ AllocateVideoBufferFull(nullptr, GST_BUFFER_OFFSET(aBuffer),
++ GST_BUFFER_SIZE(aBuffer), nullptr, aOutBuffer, aImage);
++
++ gst_buffer_copy_metadata(*aOutBuffer, aBuffer, (GstBufferCopyFlags)GST_BUFFER_COPY_ALL);
++ memcpy(GST_BUFFER_DATA(*aOutBuffer), GST_BUFFER_DATA(aBuffer), GST_BUFFER_SIZE(*aOutBuffer));
++
++ aImage = GetImageFromBuffer(*aOutBuffer);
++}
++
++GstCaps* GStreamerReader::BuildAudioSinkCaps()
++{
++ GstCaps* caps;
++#ifdef IS_LITTLE_ENDIAN
++ int endianness = 1234;
++#else
++ int endianness = 4321;
++#endif
++ gint width;
++#ifdef MOZ_SAMPLE_TYPE_FLOAT32
++ caps = gst_caps_from_string("audio/x-raw-float, channels={1,2}");
++ width = 32;
++#else /* !MOZ_SAMPLE_TYPE_FLOAT32 */
++ caps = gst_caps_from_string("audio/x-raw-int, channels={1,2}");
++ width = 16;
++#endif
++ gst_caps_set_simple(caps,
++ "width", G_TYPE_INT, width,
++ "endianness", G_TYPE_INT, endianness,
++ NULL);
++
++ return caps;
++}
++
++void GStreamerReader::InstallPadCallbacks()
++{
++ GstPad* sinkpad = gst_element_get_static_pad(GST_ELEMENT(mVideoAppSink), "sink");
++ gst_pad_add_event_probe(sinkpad,
++ G_CALLBACK(&GStreamerReader::EventProbeCb), this);
++
++ gst_pad_set_bufferalloc_function(sinkpad, GStreamerReader::AllocateVideoBufferCb);
++ gst_pad_set_element_private(sinkpad, this);
++ gst_object_unref(sinkpad);
++
++ sinkpad = gst_element_get_static_pad(GST_ELEMENT(mAudioAppSink), "sink");
++ gst_pad_add_event_probe(sinkpad,
++ G_CALLBACK(&GStreamerReader::EventProbeCb), this);
++ gst_object_unref(sinkpad);
++}
diff --git a/www/firefox/patches/patch-content_media_gstreamer_GStreamerReader.cpp b/www/firefox/patches/patch-content_media_gstreamer_GStreamerReader.cpp
new file mode 100644
index 00000000000..a0e8bd8567a
--- /dev/null
+++ b/www/firefox/patches/patch-content_media_gstreamer_GStreamerReader.cpp
@@ -0,0 +1,969 @@
+$NetBSD: patch-content_media_gstreamer_GStreamerReader.cpp,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- content/media/gstreamer/GStreamerReader.cpp.orig 2014-03-15 05:19:11.000000000 +0000
++++ content/media/gstreamer/GStreamerReader.cpp
+@@ -10,8 +10,10 @@
+ #include "AbstractMediaDecoder.h"
+ #include "MediaResource.h"
+ #include "GStreamerReader.h"
++#if GST_VERSION_MAJOR >= 1
++#include "GStreamerAllocator.h"
++#endif
+ #include "GStreamerFormatHelper.h"
+-#include "GStreamerMozVideoBuffer.h"
+ #include "VideoUtils.h"
+ #include "mozilla/dom/TimeRanges.h"
+ #include "mozilla/Preferences.h"
+@@ -33,14 +35,16 @@ extern PRLogModuleInfo* gMediaDecoderLog
+ #define LOG(type, msg, ...)
+ #endif
+
+-extern bool
+-IsYV12Format(const VideoData::YCbCrBuffer::Plane& aYPlane,
+- const VideoData::YCbCrBuffer::Plane& aCbPlane,
+- const VideoData::YCbCrBuffer::Plane& aCrPlane);
+-
++#if DEBUG
+ static const unsigned int MAX_CHANNELS = 4;
+-// Let the demuxer work in pull mode for short files
+-static const int SHORT_FILE_SIZE = 1024 * 1024;
++#endif
++// Let the demuxer work in pull mode for short files. This used to be a micro
++// optimization to have more accurate durations for ogg files in mochitests.
++// Since as of today we aren't using gstreamer to demux ogg, and having demuxers
++// work in pull mode over http makes them slower (since they really assume
++// near-zero latency in pull mode) set the constant to 0 for now, which
++// effectively disables it.
++static const int SHORT_FILE_SIZE = 0;
+ // The default resource->Read() size when working in push mode
+ static const int DEFAULT_SOURCE_READ_SIZE = 50 * 1024;
+
+@@ -62,6 +66,10 @@ GStreamerReader::GStreamerReader(Abstrac
+ : MediaDecoderReader(aDecoder),
+ mMP3FrameParser(aDecoder->GetResource()->GetLength()),
+ mUseParserDuration(false),
++#if GST_VERSION_MAJOR >= 1
++ mAllocator(nullptr),
++ mBufferPool(nullptr),
++#endif
+ mPlayBin(nullptr),
+ mBus(nullptr),
+ mSource(nullptr),
+@@ -74,6 +82,9 @@ GStreamerReader::GStreamerReader(Abstrac
+ mAudioSinkBufferCount(0),
+ mGstThreadsMonitor("media.gst.threads"),
+ mReachedEos(false),
++#if GST_VERSION_MAJOR >= 1
++ mConfigureAlignment(true),
++#endif
+ fpsNum(0),
+ fpsDen(0)
+ {
+@@ -85,8 +96,12 @@ GStreamerReader::GStreamerReader(Abstrac
+
+ mSinkCallbacks.eos = GStreamerReader::EosCb;
+ mSinkCallbacks.new_preroll = GStreamerReader::NewPrerollCb;
++#if GST_VERSION_MAJOR >= 1
++ mSinkCallbacks.new_sample = GStreamerReader::NewBufferCb;
++#else
+ mSinkCallbacks.new_buffer = GStreamerReader::NewBufferCb;
+ mSinkCallbacks.new_buffer_list = nullptr;
++#endif
+
+ gst_segment_init(&mVideoSegment, GST_FORMAT_UNDEFINED);
+ gst_segment_init(&mAudioSegment, GST_FORMAT_UNDEFINED);
+@@ -110,65 +125,59 @@ GStreamerReader::~GStreamerReader()
+ mAudioAppSink = nullptr;
+ gst_object_unref(mBus);
+ mBus = nullptr;
++#if GST_VERSION_MAJOR >= 1
++ g_object_unref(mAllocator);
++ g_object_unref(mBufferPool);
++#endif
+ }
+ }
+
+ nsresult GStreamerReader::Init(MediaDecoderReader* aCloneDonor)
+ {
+- GError* error = nullptr;
+- if (!gst_init_check(0, 0, &error)) {
+- LOG(PR_LOG_ERROR, "gst initialization failed: %s", error->message);
+- g_error_free(error);
+- return NS_ERROR_FAILURE;
+- }
++ GStreamerFormatHelper::Instance();
++
++#if GST_VERSION_MAJOR >= 1
++ mAllocator = static_cast<GstAllocator*>(g_object_new(GST_TYPE_MOZ_GFX_MEMORY_ALLOCATOR, nullptr));
++ moz_gfx_memory_allocator_set_reader(mAllocator, this);
++
++ mBufferPool = static_cast<GstBufferPool*>(g_object_new(GST_TYPE_MOZ_GFX_BUFFER_POOL, nullptr));
++#endif
+
++#if GST_VERSION_MAJOR >= 1
++ mPlayBin = gst_element_factory_make("playbin", nullptr);
++#else
+ mPlayBin = gst_element_factory_make("playbin2", nullptr);
++#endif
+ if (!mPlayBin) {
+- LOG(PR_LOG_ERROR, "couldn't create playbin2");
++ LOG(PR_LOG_ERROR, "couldn't create playbin");
+ return NS_ERROR_FAILURE;
+ }
+ g_object_set(mPlayBin, "buffer-size", 0, nullptr);
+ mBus = gst_pipeline_get_bus(GST_PIPELINE(mPlayBin));
+
+ mVideoSink = gst_parse_bin_from_description("capsfilter name=filter ! "
+- "appsink name=videosink sync=true max-buffers=1 "
++ "appsink name=videosink sync=false max-buffers=1 "
++#if GST_VERSION_MAJOR >= 1
++ "caps=video/x-raw,format=I420"
++#else
+ "caps=video/x-raw-yuv,format=(fourcc)I420"
++#endif
+ , TRUE, nullptr);
+ mVideoAppSink = GST_APP_SINK(gst_bin_get_by_name(GST_BIN(mVideoSink),
+ "videosink"));
+- gst_app_sink_set_callbacks(mVideoAppSink, &mSinkCallbacks,
+- (gpointer) this, nullptr);
+- GstPad* sinkpad = gst_element_get_pad(GST_ELEMENT(mVideoAppSink), "sink");
+- gst_pad_add_event_probe(sinkpad,
+- G_CALLBACK(&GStreamerReader::EventProbeCb), this);
+- gst_object_unref(sinkpad);
+- gst_pad_set_bufferalloc_function(sinkpad, GStreamerReader::AllocateVideoBufferCb);
+- gst_pad_set_element_private(sinkpad, this);
+-
+ mAudioSink = gst_parse_bin_from_description("capsfilter name=filter ! "
+-#ifdef MOZ_SAMPLE_TYPE_FLOAT32
+- "appsink name=audiosink max-buffers=2 sync=false caps=audio/x-raw-float,"
+-#ifdef IS_LITTLE_ENDIAN
+- "channels={1,2},width=32,endianness=1234", TRUE, nullptr);
+-#else
+- "channels={1,2},width=32,endianness=4321", TRUE, nullptr);
+-#endif
+-#else
+- "appsink name=audiosink max-buffers=2 sync=false caps=audio/x-raw-int,"
+-#ifdef IS_LITTLE_ENDIAN
+- "channels={1,2},width=16,endianness=1234", TRUE, nullptr);
+-#else
+- "channels={1,2},width=16,endianness=4321", TRUE, nullptr);
+-#endif
+-#endif
++ "appsink name=audiosink sync=false max-buffers=1", TRUE, nullptr);
+ mAudioAppSink = GST_APP_SINK(gst_bin_get_by_name(GST_BIN(mAudioSink),
+ "audiosink"));
++ GstCaps* caps = BuildAudioSinkCaps();
++ g_object_set(mAudioAppSink, "caps", caps, nullptr);
++ gst_caps_unref(caps);
++
++ gst_app_sink_set_callbacks(mVideoAppSink, &mSinkCallbacks,
++ (gpointer) this, nullptr);
+ gst_app_sink_set_callbacks(mAudioAppSink, &mSinkCallbacks,
+ (gpointer) this, nullptr);
+- sinkpad = gst_element_get_pad(GST_ELEMENT(mAudioAppSink), "sink");
+- gst_pad_add_event_probe(sinkpad,
+- G_CALLBACK(&GStreamerReader::EventProbeCb), this);
+- gst_object_unref(sinkpad);
++ InstallPadCallbacks();
+
+ g_object_set(mPlayBin, "uri", "appsrc://",
+ "video-sink", mVideoSink,
+@@ -331,7 +340,7 @@ nsresult GStreamerReader::ReadMetadata(M
+ /* Little trick: set the target caps to "skip" so that playbin2 fails to
+ * find a decoder for the stream we want to skip.
+ */
+- GstCaps* filterCaps = gst_caps_new_simple ("skip", nullptr);
++ GstCaps* filterCaps = gst_caps_new_simple ("skip", nullptr, nullptr);
+ g_object_set(filter, "caps", filterCaps, nullptr);
+ gst_caps_unref(filterCaps);
+ gst_object_unref(filter);
+@@ -358,6 +367,7 @@ nsresult GStreamerReader::ReadMetadata(M
+ gst_message_unref(message);
+ ret = NS_ERROR_FAILURE;
+ } else {
++ LOG(PR_LOG_DEBUG, "read metadata pipeline prerolled");
+ gst_message_unref(message);
+ ret = NS_OK;
+ break;
+@@ -371,23 +381,8 @@ nsresult GStreamerReader::ReadMetadata(M
+ /* we couldn't get this to play */
+ return ret;
+
+- /* FIXME: workaround for a bug in matroskademux. This seek makes matroskademux
+- * parse the index */
+- if (gst_element_seek_simple(mPlayBin, GST_FORMAT_TIME,
+- GST_SEEK_FLAG_FLUSH, 0)) {
+- /* after a seek we need to wait again for ASYNC_DONE */
+- message = gst_bus_timed_pop_filtered(mBus, GST_CLOCK_TIME_NONE,
+- (GstMessageType)(GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR));
+- if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_ERROR) {
+- gst_element_set_state(mPlayBin, GST_STATE_NULL);
+- gst_message_unref(message);
+- return NS_ERROR_FAILURE;
+- }
+- }
+-
+ /* report the duration */
+ gint64 duration;
+- GstFormat format = GST_FORMAT_TIME;
+
+ if (isMP3 && mMP3FrameParser.IsMP3()) {
+ // The MP3FrameParser has reported a duration; use that over the gstreamer
+@@ -396,17 +391,25 @@ nsresult GStreamerReader::ReadMetadata(M
+ mUseParserDuration = true;
+ mLastParserDuration = mMP3FrameParser.GetDuration();
+ mDecoder->SetMediaDuration(mLastParserDuration);
+-
+- } else if (gst_element_query_duration(GST_ELEMENT(mPlayBin),
+- &format, &duration) && format == GST_FORMAT_TIME) {
+- // Otherwise use the gstreamer duration.
+- ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
+- LOG(PR_LOG_DEBUG, "returning duration %" GST_TIME_FORMAT, GST_TIME_ARGS(duration));
+- duration = GST_TIME_AS_USECONDS (duration);
+- mDecoder->SetMediaDuration(duration);
+-
+ } else {
+- mDecoder->SetMediaSeekable(false);
++ LOG(PR_LOG_DEBUG, "querying duration");
++ // Otherwise use the gstreamer duration.
++#if GST_VERSION_MAJOR >= 1
++ if (gst_element_query_duration(GST_ELEMENT(mPlayBin),
++ GST_FORMAT_TIME, &duration)) {
++#else
++ GstFormat format = GST_FORMAT_TIME;
++ if (gst_element_query_duration(GST_ELEMENT(mPlayBin),
++ &format, &duration) && format == GST_FORMAT_TIME) {
++#endif
++ ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
++ LOG(PR_LOG_DEBUG, "have duration %" GST_TIME_FORMAT,
++ GST_TIME_ARGS (duration));
++ duration = GST_TIME_AS_USECONDS (duration);
++ mDecoder->SetMediaDuration(duration);
++ } else {
++ mDecoder->SetMediaSeekable(false);
++ }
+ }
+
+ int n_video = 0, n_audio = 0;
+@@ -419,7 +422,11 @@ nsresult GStreamerReader::ReadMetadata(M
+ *aTags = nullptr;
+
+ // Watch the pipeline for fatal errors
++#if GST_VERSION_MAJOR >= 1
++ gst_bus_set_sync_handler(mBus, GStreamerReader::ErrorCb, this, nullptr);
++#else
+ gst_bus_set_sync_handler(mBus, GStreamerReader::ErrorCb, this);
++#endif
+
+ /* set the pipeline to PLAYING so that it starts decoding and queueing data in
+ * the appsinks */
+@@ -433,19 +440,35 @@ nsresult GStreamerReader::CheckSupported
+ bool done = false;
+ bool unsupported = false;
+
+- GstIterator *it = gst_bin_iterate_recurse(GST_BIN(mPlayBin));
++ GstIterator* it = gst_bin_iterate_recurse(GST_BIN(mPlayBin));
+ while (!done) {
++ GstIteratorResult res;
+ GstElement* element;
+- GstIteratorResult res = gst_iterator_next(it, (void **)&element);
++
++#if GST_VERSION_MAJOR >= 1
++ GValue value = {0,};
++ res = gst_iterator_next(it, &value);
++#else
++ res = gst_iterator_next(it, (void **) &element);
++#endif
+ switch(res) {
+ case GST_ITERATOR_OK:
+ {
++#if GST_VERSION_MAJOR >= 1
++ element = GST_ELEMENT (g_value_get_object (&value));
++#endif
+ GstElementFactory* factory = gst_element_get_factory(element);
+ if (factory) {
+ const char* klass = gst_element_factory_get_klass(factory);
+- GstPad* pad = gst_element_get_pad(element, "sink");
++ GstPad* pad = gst_element_get_static_pad(element, "sink");
+ if (pad) {
+- GstCaps* caps = gst_pad_get_negotiated_caps(pad);
++ GstCaps* caps;
++
++#if GST_VERSION_MAJOR >= 1
++ caps = gst_pad_get_current_caps(pad);
++#else
++ caps = gst_pad_get_negotiated_caps(pad);
++#endif
+
+ if (caps) {
+ /* check for demuxers but ignore elements like id3demux */
+@@ -460,7 +483,11 @@ nsresult GStreamerReader::CheckSupported
+ }
+ }
+
++#if GST_VERSION_MAJOR >= 1
++ g_value_unset (&value);
++#else
+ gst_object_unref(element);
++#endif
+ done = unsupported;
+ break;
+ }
+@@ -484,6 +511,8 @@ nsresult GStreamerReader::ResetDecode()
+ {
+ nsresult res = NS_OK;
+
++ LOG(PR_LOG_DEBUG, "reset decode");
++
+ if (NS_FAILED(MediaDecoderReader::ResetDecode())) {
+ res = NS_ERROR_FAILURE;
+ }
+@@ -494,6 +523,11 @@ nsresult GStreamerReader::ResetDecode()
+ mVideoSinkBufferCount = 0;
+ mAudioSinkBufferCount = 0;
+ mReachedEos = false;
++#if GST_VERSION_MAJOR >= 1
++ mConfigureAlignment = true;
++#endif
++
++ LOG(PR_LOG_DEBUG, "reset decode done");
+
+ return res;
+ }
+@@ -517,11 +551,11 @@ bool GStreamerReader::DecodeAudioData()
+ /* We have nothing decoded so it makes no sense to return to the state machine
+ * as it will call us back immediately, we'll return again and so on, wasting
+ * CPU cycles for no job done. So, block here until there is either video or
+- * audio data available
++ * audio data available
+ */
+ mon.Wait();
+ if (!mAudioSinkBufferCount) {
+- /* There is still no audio data available, so either there is video data or
++ /* There is still no audio data available, so either there is video data or
+ * something else has happened (Eos, etc...). Return to the state machine
+ * to process it.
+ */
+@@ -533,24 +567,43 @@ bool GStreamerReader::DecodeAudioData()
+ }
+ }
+
++#if GST_VERSION_MAJOR >= 1
++ GstSample *sample = gst_app_sink_pull_sample(mAudioAppSink);
++ buffer = gst_buffer_ref(gst_sample_get_buffer(sample));
++ gst_sample_unref(sample);
++#else
+ buffer = gst_app_sink_pull_buffer(mAudioAppSink);
++#endif
++
+ mAudioSinkBufferCount--;
+ }
+
+ int64_t timestamp = GST_BUFFER_TIMESTAMP(buffer);
+ timestamp = gst_segment_to_stream_time(&mAudioSegment,
+ GST_FORMAT_TIME, timestamp);
++
+ timestamp = GST_TIME_AS_USECONDS(timestamp);
+ int64_t duration = 0;
+ if (GST_CLOCK_TIME_IS_VALID(GST_BUFFER_DURATION(buffer)))
+ duration = GST_TIME_AS_USECONDS(GST_BUFFER_DURATION(buffer));
+
+ int64_t offset = GST_BUFFER_OFFSET(buffer);
++#if GST_VERSION_MAJOR >= 1
++ GstMapInfo info;
++ gst_buffer_map(buffer, &info, GST_MAP_READ);
++ unsigned int size = info.size;
++#else
+ unsigned int size = GST_BUFFER_SIZE(buffer);
++#endif
+ int32_t frames = (size / sizeof(AudioDataValue)) / mInfo.mAudio.mChannels;
+ ssize_t outSize = static_cast<size_t>(size / sizeof(AudioDataValue));
+ nsAutoArrayPtr<AudioDataValue> data(new AudioDataValue[outSize]);
++#if GST_VERSION_MAJOR >= 1
++ memcpy(data, info.data, info.size);
++ gst_buffer_unmap(buffer, &info);
++#else
+ memcpy(data, GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE(buffer));
++#endif
+ AudioData* audio = new AudioData(offset, timestamp, duration,
+ frames, data.forget(), mInfo.mAudio.mChannels);
+
+@@ -561,7 +614,7 @@ bool GStreamerReader::DecodeAudioData()
+ }
+
+ bool GStreamerReader::DecodeVideoFrame(bool &aKeyFrameSkip,
+- int64_t aTimeThreshold)
++ int64_t aTimeThreshold)
+ {
+ NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
+
+@@ -580,11 +633,11 @@ bool GStreamerReader::DecodeVideoFrame(b
+ /* We have nothing decoded so it makes no sense to return to the state machine
+ * as it will call us back immediately, we'll return again and so on, wasting
+ * CPU cycles for no job done. So, block here until there is either video or
+- * audio data available
++ * audio data available
+ */
+ mon.Wait();
+ if (!mVideoSinkBufferCount) {
+- /* There is still no video data available, so either there is audio data or
++ /* There is still no video data available, so either there is audio data or
+ * something else has happened (Eos, etc...). Return to the state machine
+ * to process it
+ */
+@@ -598,11 +651,17 @@ bool GStreamerReader::DecodeVideoFrame(b
+
+ mDecoder->NotifyDecodedFrames(0, 1);
+
++#if GST_VERSION_MAJOR >= 1
++ GstSample *sample = gst_app_sink_pull_sample(mVideoAppSink);
++ buffer = gst_buffer_ref(gst_sample_get_buffer(sample));
++ gst_sample_unref(sample);
++#else
+ buffer = gst_app_sink_pull_buffer(mVideoAppSink);
++#endif
+ mVideoSinkBufferCount--;
+ }
+
+- bool isKeyframe = !GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DISCONT);
++ bool isKeyframe = !GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT);
+ if ((aKeyFrameSkip && !isKeyframe)) {
+ gst_buffer_unref(buffer);
+ return true;
+@@ -618,73 +677,55 @@ bool GStreamerReader::DecodeVideoFrame(b
+ "frame has invalid timestamp");
+
+ timestamp = GST_TIME_AS_USECONDS(timestamp);
++ int64_t duration;
++ if (GST_CLOCK_TIME_IS_VALID(GST_BUFFER_DURATION(buffer)))
++ duration = GST_TIME_AS_USECONDS(GST_BUFFER_DURATION(buffer));
++ else if (fpsNum && fpsDen)
++ /* add 1-frame duration */
++ duration = gst_util_uint64_scale(GST_USECOND, fpsDen, fpsNum);
++
+ if (timestamp < aTimeThreshold) {
+ LOG(PR_LOG_DEBUG, "skipping frame %" GST_TIME_FORMAT
+- " threshold %" GST_TIME_FORMAT,
+- GST_TIME_ARGS(timestamp), GST_TIME_ARGS(aTimeThreshold));
++ " threshold %" GST_TIME_FORMAT,
++ GST_TIME_ARGS(timestamp * 1000),
++ GST_TIME_ARGS(aTimeThreshold * 1000));
+ gst_buffer_unref(buffer);
+ return true;
+ }
+-
+ if (!buffer)
+ /* no more frames */
+ return false;
+
+- int64_t duration = 0;
+- if (GST_CLOCK_TIME_IS_VALID(GST_BUFFER_DURATION(buffer)))
+- duration = GST_TIME_AS_USECONDS(GST_BUFFER_DURATION(buffer));
+- else if (fpsNum && fpsDen)
+- /* 1-frame duration */
+- duration = gst_util_uint64_scale(GST_USECOND, fpsNum, fpsDen);
+-
+- nsRefPtr<PlanarYCbCrImage> image;
+- GstMozVideoBufferData* bufferdata = reinterpret_cast<GstMozVideoBufferData*>
+- GST_IS_MOZ_VIDEO_BUFFER(buffer)?gst_moz_video_buffer_get_data(GST_MOZ_VIDEO_BUFFER(buffer)):nullptr;
+-
+- if(bufferdata)
+- image = bufferdata->mImage;
++#if GST_VERSION_MAJOR >= 1
++ if (mConfigureAlignment && buffer->pool) {
++ GstStructure *config = gst_buffer_pool_get_config(buffer->pool);
++ GstVideoAlignment align;
++ if (gst_buffer_pool_config_get_video_alignment(config, &align))
++ gst_video_info_align(&mVideoInfo, &align);
++ gst_structure_free(config);
++ mConfigureAlignment = false;
++ }
++#endif
+
++ nsRefPtr<PlanarYCbCrImage> image = GetImageFromBuffer(buffer);
+ if (!image) {
+ /* Ugh, upstream is not calling gst_pad_alloc_buffer(). Fallback to
+ * allocating a PlanarYCbCrImage backed GstBuffer here and memcpy.
+ */
+ GstBuffer* tmp = nullptr;
+- AllocateVideoBufferFull(nullptr, GST_BUFFER_OFFSET(buffer),
+- GST_BUFFER_SIZE(buffer), nullptr, &tmp, image);
+-
+- /* copy */
+- gst_buffer_copy_metadata(tmp, buffer, (GstBufferCopyFlags)GST_BUFFER_COPY_ALL);
+- memcpy(GST_BUFFER_DATA(tmp), GST_BUFFER_DATA(buffer),
+- GST_BUFFER_SIZE(tmp));
++ CopyIntoImageBuffer(buffer, &tmp, image);
+ gst_buffer_unref(buffer);
+ buffer = tmp;
+ }
+
+- guint8* data = GST_BUFFER_DATA(buffer);
+-
+- int width = mPicture.width;
+- int height = mPicture.height;
+- GstVideoFormat format = mFormat;
+-
+- VideoData::YCbCrBuffer b;
+- for(int i = 0; i < 3; i++) {
+- b.mPlanes[i].mData = data + gst_video_format_get_component_offset(format, i,
+- width, height);
+- b.mPlanes[i].mStride = gst_video_format_get_row_stride(format, i, width);
+- b.mPlanes[i].mHeight = gst_video_format_get_component_height(format,
+- i, height);
+- b.mPlanes[i].mWidth = gst_video_format_get_component_width(format,
+- i, width);
+- b.mPlanes[i].mOffset = 0;
+- b.mPlanes[i].mSkip = 0;
+- }
+-
+- isKeyframe = !GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT);
+ int64_t offset = mDecoder->GetResource()->Tell(); // Estimate location in media.
+- VideoData* video = VideoData::Create(mInfo.mVideo, image, offset,
+- timestamp, duration, b,
+- isKeyframe, -1, mPicture);
++ VideoData* video = VideoData::CreateFromImage(mInfo.mVideo,
++ mDecoder->GetImageContainer(),
++ offset, timestamp, duration,
++ static_cast<Image*>(image.get()),
++ isKeyframe, -1, mPicture);
+ mVideoQueue.Push(video);
++
+ gst_buffer_unref(buffer);
+
+ return true;
+@@ -707,6 +748,10 @@ nsresult GStreamerReader::Seek(int64_t a
+ return NS_ERROR_FAILURE;
+ }
+ LOG(PR_LOG_DEBUG, "seek succeeded");
++ GstMessage* message = gst_bus_timed_pop_filtered(mBus, GST_CLOCK_TIME_NONE,
++ (GstMessageType)(GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR));
++ gst_message_unref(message);
++ LOG(PR_LOG_DEBUG, "seek completed");
+
+ return DecodeToTarget(aTarget);
+ }
+@@ -718,7 +763,9 @@ nsresult GStreamerReader::GetBuffered(do
+ return NS_OK;
+ }
+
++#if GST_VERSION_MAJOR == 0
+ GstFormat format = GST_FORMAT_TIME;
++#endif
+ MediaResource* resource = mDecoder->GetResource();
+ nsTArray<MediaByteRange> ranges;
+ resource->GetCachedRanges(ranges);
+@@ -740,12 +787,21 @@ nsresult GStreamerReader::GetBuffered(do
+ int64_t endOffset = ranges[index].mEnd;
+ gint64 startTime, endTime;
+
++#if GST_VERSION_MAJOR >= 1
++ if (!gst_element_query_convert(GST_ELEMENT(mPlayBin), GST_FORMAT_BYTES,
++ startOffset, GST_FORMAT_TIME, &startTime))
++ continue;
++ if (!gst_element_query_convert(GST_ELEMENT(mPlayBin), GST_FORMAT_BYTES,
++ endOffset, GST_FORMAT_TIME, &endTime))
++ continue;
++#else
+ if (!gst_element_query_convert(GST_ELEMENT(mPlayBin), GST_FORMAT_BYTES,
+ startOffset, &format, &startTime) || format != GST_FORMAT_TIME)
+ continue;
+ if (!gst_element_query_convert(GST_ELEMENT(mPlayBin), GST_FORMAT_BYTES,
+ endOffset, &format, &endTime) || format != GST_FORMAT_TIME)
+ continue;
++#endif
+
+ double start = (double) GST_TIME_AS_USECONDS (startTime) / GST_MSECOND;
+ double end = (double) GST_TIME_AS_USECONDS (endTime) / GST_MSECOND;
+@@ -766,7 +822,13 @@ void GStreamerReader::ReadAndPushData(gu
+ nsresult rv = NS_OK;
+
+ GstBuffer* buffer = gst_buffer_new_and_alloc(aLength);
++#if GST_VERSION_MAJOR >= 1
++ GstMapInfo info;
++ gst_buffer_map(buffer, &info, GST_MAP_WRITE);
++ guint8 *data = info.data;
++#else
+ guint8* data = GST_BUFFER_DATA(buffer);
++#endif
+ uint32_t size = 0, bytesRead = 0;
+ while(bytesRead < aLength) {
+ rv = resource->Read(reinterpret_cast<char*>(data + bytesRead),
+@@ -780,7 +842,12 @@ void GStreamerReader::ReadAndPushData(gu
+ int64_t offset2 = resource->Tell();
+ unused << offset2;
+
++#if GST_VERSION_MAJOR >= 1
++ gst_buffer_unmap(buffer, &info);
++ gst_buffer_set_size(buffer, bytesRead);
++#else
+ GST_BUFFER_SIZE(buffer) = bytesRead;
++#endif
+
+ GstFlowReturn ret = gst_app_src_push_buffer(mSource, gst_buffer_ref(buffer));
+ if (ret != GST_FLOW_OK) {
+@@ -813,8 +880,13 @@ int64_t GStreamerReader::QueryDuration()
+ gint64 duration = 0;
+ GstFormat format = GST_FORMAT_TIME;
+
++#if GST_VERSION_MAJOR >= 1
++ if (gst_element_query_duration(GST_ELEMENT(mPlayBin),
++ format, &duration)) {
++#else
+ if (gst_element_query_duration(GST_ELEMENT(mPlayBin),
+ &format, &duration)) {
++#endif
+ if (format == GST_FORMAT_TIME) {
+ LOG(PR_LOG_DEBUG, "pipeline duration %" GST_TIME_FORMAT,
+ GST_TIME_ARGS (duration));
+@@ -893,108 +965,6 @@ gboolean GStreamerReader::SeekData(GstAp
+ return NS_SUCCEEDED(rv);
+ }
+
+-gboolean GStreamerReader::EventProbeCb(GstPad* aPad,
+- GstEvent* aEvent,
+- gpointer aUserData)
+-{
+- GStreamerReader* reader = reinterpret_cast<GStreamerReader*>(aUserData);
+- return reader->EventProbe(aPad, aEvent);
+-}
+-
+-gboolean GStreamerReader::EventProbe(GstPad* aPad, GstEvent* aEvent)
+-{
+- GstElement* parent = GST_ELEMENT(gst_pad_get_parent(aPad));
+- switch(GST_EVENT_TYPE(aEvent)) {
+- case GST_EVENT_NEWSEGMENT:
+- {
+- gboolean update;
+- gdouble rate;
+- GstFormat format;
+- gint64 start, stop, position;
+- GstSegment* segment;
+-
+- /* Store the segments so we can convert timestamps to stream time, which
+- * is what the upper layers sync on.
+- */
+- ReentrantMonitorAutoEnter mon(mGstThreadsMonitor);
+- gst_event_parse_new_segment(aEvent, &update, &rate, &format,
+- &start, &stop, &position);
+- if (parent == GST_ELEMENT(mVideoAppSink))
+- segment = &mVideoSegment;
+- else
+- segment = &mAudioSegment;
+- gst_segment_set_newsegment(segment, update, rate, format,
+- start, stop, position);
+- break;
+- }
+- case GST_EVENT_FLUSH_STOP:
+- /* Reset on seeks */
+- ResetDecode();
+- break;
+- default:
+- break;
+- }
+- gst_object_unref(parent);
+-
+- return TRUE;
+-}
+-
+-GstFlowReturn GStreamerReader::AllocateVideoBufferFull(GstPad* aPad,
+- guint64 aOffset,
+- guint aSize,
+- GstCaps* aCaps,
+- GstBuffer** aBuf,
+- nsRefPtr<PlanarYCbCrImage>& aImage)
+-{
+- /* allocate an image using the container */
+- ImageContainer* container = mDecoder->GetImageContainer();
+- if (!container) {
+- // We don't have an ImageContainer. We probably belong to an <audio>
+- // element.
+- return GST_FLOW_NOT_SUPPORTED;
+- }
+- ImageFormat format = PLANAR_YCBCR;
+- PlanarYCbCrImage* img = reinterpret_cast<PlanarYCbCrImage*>(container->CreateImage(&format, 1).get());
+- nsRefPtr<PlanarYCbCrImage> image = dont_AddRef(img);
+-
+- /* prepare a GstBuffer pointing to the underlying PlanarYCbCrImage buffer */
+- GstBuffer* buf = GST_BUFFER(gst_moz_video_buffer_new());
+- GST_BUFFER_SIZE(buf) = aSize;
+- /* allocate the actual YUV buffer */
+- GST_BUFFER_DATA(buf) = image->AllocateAndGetNewBuffer(aSize);
+-
+- aImage = image;
+-
+- /* create a GstMozVideoBufferData to hold the image */
+- GstMozVideoBufferData* bufferdata = new GstMozVideoBufferData(image);
+-
+- /* Attach bufferdata to our GstMozVideoBuffer, it will take care to free it */
+- gst_moz_video_buffer_set_data(GST_MOZ_VIDEO_BUFFER(buf), bufferdata);
+-
+- *aBuf = buf;
+- return GST_FLOW_OK;
+-}
+-
+-GstFlowReturn GStreamerReader::AllocateVideoBufferCb(GstPad* aPad,
+- guint64 aOffset,
+- guint aSize,
+- GstCaps* aCaps,
+- GstBuffer** aBuf)
+-{
+- GStreamerReader* reader = reinterpret_cast<GStreamerReader*>(gst_pad_get_element_private(aPad));
+- return reader->AllocateVideoBuffer(aPad, aOffset, aSize, aCaps, aBuf);
+-}
+-
+-GstFlowReturn GStreamerReader::AllocateVideoBuffer(GstPad* aPad,
+- guint64 aOffset,
+- guint aSize,
+- GstCaps* aCaps,
+- GstBuffer** aBuf)
+-{
+- nsRefPtr<PlanarYCbCrImage> image;
+- return AllocateVideoBufferFull(aPad, aOffset, aSize, aCaps, aBuf, image);
+-}
+-
+ GstFlowReturn GStreamerReader::NewPrerollCb(GstAppSink* aSink,
+ gpointer aUserData)
+ {
+@@ -1011,8 +981,12 @@ void GStreamerReader::AudioPreroll()
+ {
+ /* The first audio buffer has reached the audio sink. Get rate and channels */
+ LOG(PR_LOG_DEBUG, "Audio preroll");
+- GstPad* sinkpad = gst_element_get_pad(GST_ELEMENT(mAudioAppSink), "sink");
++ GstPad* sinkpad = gst_element_get_static_pad(GST_ELEMENT(mAudioAppSink), "sink");
++#if GST_VERSION_MAJOR >= 1
++ GstCaps *caps = gst_pad_get_current_caps(sinkpad);
++#else
+ GstCaps* caps = gst_pad_get_negotiated_caps(sinkpad);
++#endif
+ GstStructure* s = gst_caps_get_structure(caps, 0);
+ mInfo.mAudio.mRate = mInfo.mAudio.mChannels = 0;
+ gst_structure_get_int(s, "rate", (gint*) &mInfo.mAudio.mRate);
+@@ -1030,9 +1004,18 @@ void GStreamerReader::VideoPreroll()
+ {
+ /* The first video buffer has reached the video sink. Get width and height */
+ LOG(PR_LOG_DEBUG, "Video preroll");
+- GstPad* sinkpad = gst_element_get_pad(GST_ELEMENT(mVideoAppSink), "sink");
++ GstPad* sinkpad = gst_element_get_static_pad(GST_ELEMENT(mVideoAppSink), "sink");
++#if GST_VERSION_MAJOR >= 1
++ GstCaps* caps = gst_pad_get_current_caps(sinkpad);
++ memset (&mVideoInfo, 0, sizeof (mVideoInfo));
++ gst_video_info_from_caps(&mVideoInfo, caps);
++ mFormat = mVideoInfo.finfo->format;
++ mPicture.width = mVideoInfo.width;
++ mPicture.height = mVideoInfo.height;
++#else
+ GstCaps* caps = gst_pad_get_negotiated_caps(sinkpad);
+ gst_video_format_parse_caps(caps, &mFormat, &mPicture.width, &mPicture.height);
++#endif
+ GstStructure* structure = gst_caps_get_structure(caps, 0);
+ gst_structure_get_fraction(structure, "framerate", &fpsNum, &fpsDen);
+ NS_ASSERTION(mPicture.width && mPicture.height, "invalid video resolution");
+@@ -1061,6 +1044,7 @@ void GStreamerReader::NewVideoBuffer()
+ /* We have a new video buffer queued in the video sink. Increment the counter
+ * and notify the decode thread potentially blocked in DecodeVideoFrame
+ */
++
+ mDecoder->NotifyDecodedFrames(1, 0);
+ mVideoSinkBufferCount++;
+ mon.NotifyAll();
+@@ -1197,5 +1181,199 @@ void GStreamerReader::NotifyDataArrived(
+ }
+ }
+
++#if GST_VERSION_MAJOR >= 1
++GstCaps* GStreamerReader::BuildAudioSinkCaps()
++{
++ GstCaps* caps = gst_caps_from_string("audio/x-raw, channels={1,2}");
++ const char* format;
++#ifdef MOZ_SAMPLE_TYPE_FLOAT32
++#ifdef IS_LITTLE_ENDIAN
++ format = "F32LE";
++#else
++ format = "F32BE";
++#endif
++#else /* !MOZ_SAMPLE_TYPE_FLOAT32 */
++#ifdef IS_LITTLE_ENDIAN
++ format = "S16LE";
++#else
++ format = "S16BE";
++#endif
++#endif
++ gst_caps_set_simple(caps, "format", G_TYPE_STRING, format, nullptr);
++
++ return caps;
++}
++
++void GStreamerReader::InstallPadCallbacks()
++{
++ GstPad* sinkpad = gst_element_get_static_pad(GST_ELEMENT(mVideoAppSink), "sink");
++
++ gst_pad_add_probe(sinkpad,
++ (GstPadProbeType) (GST_PAD_PROBE_TYPE_SCHEDULING |
++ GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM |
++ GST_PAD_PROBE_TYPE_EVENT_UPSTREAM |
++ GST_PAD_PROBE_TYPE_EVENT_FLUSH),
++ &GStreamerReader::EventProbeCb, this, nullptr);
++ gst_pad_add_probe(sinkpad, GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM,
++ GStreamerReader::QueryProbeCb, nullptr, nullptr);
++
++ gst_pad_set_element_private(sinkpad, this);
++ gst_object_unref(sinkpad);
++
++ sinkpad = gst_element_get_static_pad(GST_ELEMENT(mAudioAppSink), "sink");
++ gst_pad_add_probe(sinkpad,
++ (GstPadProbeType) (GST_PAD_PROBE_TYPE_SCHEDULING |
++ GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM |
++ GST_PAD_PROBE_TYPE_EVENT_UPSTREAM |
++ GST_PAD_PROBE_TYPE_EVENT_FLUSH),
++ &GStreamerReader::EventProbeCb, this, nullptr);
++ gst_object_unref(sinkpad);
++}
++
++GstPadProbeReturn GStreamerReader::EventProbeCb(GstPad *aPad,
++ GstPadProbeInfo *aInfo,
++ gpointer aUserData)
++{
++ GStreamerReader *reader = (GStreamerReader *) aUserData;
++ GstEvent *aEvent = (GstEvent *)aInfo->data;
++ return reader->EventProbe(aPad, aEvent);
++}
++
++GstPadProbeReturn GStreamerReader::EventProbe(GstPad *aPad, GstEvent *aEvent)
++{
++ GstElement* parent = GST_ELEMENT(gst_pad_get_parent(aPad));
++
++ LOG(PR_LOG_DEBUG, "event probe %s", GST_EVENT_TYPE_NAME (aEvent));
++
++ switch(GST_EVENT_TYPE(aEvent)) {
++ case GST_EVENT_SEGMENT:
++ {
++ const GstSegment *newSegment;
++ GstSegment* segment;
++
++ /* Store the segments so we can convert timestamps to stream time, which
++ * is what the upper layers sync on.
++ */
++ ReentrantMonitorAutoEnter mon(mGstThreadsMonitor);
++#if GST_VERSION_MINOR <= 1 && GST_VERSION_MICRO < 1
++ ResetDecode();
++#endif
++ gst_event_parse_segment(aEvent, &newSegment);
++ if (parent == GST_ELEMENT(mVideoAppSink))
++ segment = &mVideoSegment;
++ else
++ segment = &mAudioSegment;
++ gst_segment_copy_into (newSegment, segment);
++ break;
++ }
++ case GST_EVENT_FLUSH_STOP:
++ /* Reset on seeks */
++ ResetDecode();
++ break;
++ default:
++ break;
++ }
++ gst_object_unref(parent);
++
++ return GST_PAD_PROBE_OK;
++}
++
++GstPadProbeReturn GStreamerReader::QueryProbeCb(GstPad* aPad, GstPadProbeInfo* aInfo, gpointer aUserData)
++{
++ GStreamerReader* reader = reinterpret_cast<GStreamerReader*>(gst_pad_get_element_private(aPad));
++ return reader->QueryProbe(aPad, aInfo, aUserData);
++}
++
++GstPadProbeReturn GStreamerReader::QueryProbe(GstPad* aPad, GstPadProbeInfo* aInfo, gpointer aUserData)
++{
++ GstQuery *query = gst_pad_probe_info_get_query(aInfo);
++ GstPadProbeReturn ret = GST_PAD_PROBE_OK;
++
++ switch (GST_QUERY_TYPE (query)) {
++ case GST_QUERY_ALLOCATION:
++ GstCaps *caps;
++ GstVideoInfo info;
++ gboolean need_pool;
++
++ gst_query_parse_allocation(query, &caps, &need_pool);
++ gst_video_info_init(&info);
++ gst_video_info_from_caps(&info, caps);
++ gst_query_add_allocation_param(query, mAllocator, nullptr);
++ gst_query_add_allocation_pool(query, mBufferPool, info.size, 0, 0);
++ gst_query_add_allocation_meta(query, GST_VIDEO_META_API_TYPE, nullptr);
++ break;
++ default:
++ break;
++ }
++
++ return ret;
++}
++
++void GStreamerReader::ImageDataFromVideoFrame(GstVideoFrame *aFrame,
++ PlanarYCbCrImage::Data *aData)
++{
++ NS_ASSERTION(GST_VIDEO_INFO_IS_YUV(&mVideoInfo),
++ "Non-YUV video frame formats not supported");
++ NS_ASSERTION(GST_VIDEO_FRAME_N_COMPONENTS(aFrame) == 3,
++ "Unsupported number of components in video frame");
++
++ aData->mPicX = aData->mPicY = 0;
++ aData->mPicSize = nsIntSize(mPicture.width, mPicture.height);
++ aData->mStereoMode = STEREO_MODE_MONO;
++
++ aData->mYChannel = GST_VIDEO_FRAME_COMP_DATA(aFrame, 0);
++ aData->mYStride = GST_VIDEO_FRAME_COMP_STRIDE(aFrame, 0);
++ aData->mYSize = nsIntSize(GST_VIDEO_FRAME_COMP_WIDTH(aFrame, 0),
++ GST_VIDEO_FRAME_COMP_HEIGHT(aFrame, 0));
++ aData->mYSkip = GST_VIDEO_FRAME_COMP_PSTRIDE(aFrame, 0) - 1;
++ aData->mCbCrStride = GST_VIDEO_FRAME_COMP_STRIDE(aFrame, 1);
++ aData->mCbCrSize = nsIntSize(GST_VIDEO_FRAME_COMP_WIDTH(aFrame, 1),
++ GST_VIDEO_FRAME_COMP_HEIGHT(aFrame, 1));
++ aData->mCbChannel = GST_VIDEO_FRAME_COMP_DATA(aFrame, 1);
++ aData->mCrChannel = GST_VIDEO_FRAME_COMP_DATA(aFrame, 2);
++ aData->mCbSkip = GST_VIDEO_FRAME_COMP_PSTRIDE(aFrame, 1) - 1;
++ aData->mCrSkip = GST_VIDEO_FRAME_COMP_PSTRIDE(aFrame, 2) - 1;
++}
++
++nsRefPtr<PlanarYCbCrImage> GStreamerReader::GetImageFromBuffer(GstBuffer* aBuffer)
++{
++ nsRefPtr<PlanarYCbCrImage> image = nullptr;
++
++ if (gst_buffer_n_memory(aBuffer) == 1) {
++ GstMemory* mem = gst_buffer_peek_memory(aBuffer, 0);
++ if (GST_IS_MOZ_GFX_MEMORY_ALLOCATOR(mem->allocator)) {
++ image = moz_gfx_memory_get_image(mem);
++
++ GstVideoFrame frame;
++ gst_video_frame_map(&frame, &mVideoInfo, aBuffer, GST_MAP_READ);
++ PlanarYCbCrImage::Data data;
++ ImageDataFromVideoFrame(&frame, &data);
++ image->SetDataNoCopy(data);
++ gst_video_frame_unmap(&frame);
++ }
++ }
++
++ return image;
++}
++
++void GStreamerReader::CopyIntoImageBuffer(GstBuffer* aBuffer,
++ GstBuffer** aOutBuffer,
++ nsRefPtr<PlanarYCbCrImage> &image)
++{
++ *aOutBuffer = gst_buffer_new_allocate(mAllocator, gst_buffer_get_size(aBuffer), nullptr);
++ GstMemory *mem = gst_buffer_peek_memory(*aOutBuffer, 0);
++ GstMapInfo map_info;
++ gst_memory_map(mem, &map_info, GST_MAP_WRITE);
++ gst_buffer_extract(aBuffer, 0, map_info.data, gst_buffer_get_size(aBuffer));
++ gst_memory_unmap(mem, &map_info);
++
++ /* create a new gst buffer with the newly created memory and copy the
++ * metadata over from the incoming buffer */
++ gst_buffer_copy_into(*aOutBuffer, aBuffer,
++ (GstBufferCopyFlags)(GST_BUFFER_COPY_METADATA), 0, -1);
++ image = GetImageFromBuffer(*aOutBuffer);
++}
++#endif
++
+ } // namespace mozilla
+
diff --git a/www/firefox/patches/patch-content_media_gstreamer_GStreamerReader.h b/www/firefox/patches/patch-content_media_gstreamer_GStreamerReader.h
new file mode 100644
index 00000000000..cc6fa481bd2
--- /dev/null
+++ b/www/firefox/patches/patch-content_media_gstreamer_GStreamerReader.h
@@ -0,0 +1,103 @@
+$NetBSD: patch-content_media_gstreamer_GStreamerReader.h,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- content/media/gstreamer/GStreamerReader.h.orig 2014-03-15 05:19:11.000000000 +0000
++++ content/media/gstreamer/GStreamerReader.h
+@@ -22,6 +22,7 @@
+
+ #include "MediaDecoderReader.h"
+ #include "MP3FrameParser.h"
++#include "ImageContainer.h"
+ #include "nsRect.h"
+
+ namespace mozilla {
+@@ -30,10 +31,6 @@ namespace dom {
+ class TimeRanges;
+ }
+
+-namespace layers {
+-class PlanarYCbCrImage;
+-}
+-
+ class AbstractMediaDecoder;
+
+ class GStreamerReader : public MediaDecoderReader
+@@ -67,10 +64,20 @@ public:
+ return mInfo.HasVideo();
+ }
+
++ layers::ImageContainer* GetImageContainer() { return mDecoder->GetImageContainer(); }
++
+ private:
+
+ void ReadAndPushData(guint aLength);
+ int64_t QueryDuration();
++ nsRefPtr<layers::PlanarYCbCrImage> GetImageFromBuffer(GstBuffer* aBuffer);
++ void CopyIntoImageBuffer(GstBuffer *aBuffer, GstBuffer** aOutBuffer, nsRefPtr<layers::PlanarYCbCrImage> &image);
++ GstCaps* BuildAudioSinkCaps();
++ void InstallPadCallbacks();
++
++#if GST_VERSION_MAJOR >= 1
++ void ImageDataFromVideoFrame(GstVideoFrame *aFrame, layers::PlanarYCbCrImage::Data *aData);
++#endif
+
+ /* Called once the pipeline is setup to check that the stream only contains
+ * supported formats
+@@ -105,20 +112,31 @@ private:
+ gboolean SeekData(GstAppSrc* aSrc, guint64 aOffset);
+
+ /* Called when events reach the sinks. See inline comments */
++#if GST_VERSION_MAJOR == 1
++ static GstPadProbeReturn EventProbeCb(GstPad *aPad, GstPadProbeInfo *aInfo, gpointer aUserData);
++ GstPadProbeReturn EventProbe(GstPad *aPad, GstEvent *aEvent);
++#else
+ static gboolean EventProbeCb(GstPad* aPad, GstEvent* aEvent, gpointer aUserData);
+ gboolean EventProbe(GstPad* aPad, GstEvent* aEvent);
++#endif
+
+- /* Called when elements in the video branch of the pipeline call
+- * gst_pad_alloc_buffer(). Used to provide PlanarYCbCrImage backed GstBuffers
+- * to the pipeline so that a memory copy can be avoided when handling YUV
+- * buffers from the pipeline to the gfx side.
+- */
++ /* Called when the video part of the pipeline allocates buffers. Used to
++ * provide PlanarYCbCrImage backed GstBuffers to the pipeline so that a memory
++ * copy can be avoided when handling YUV buffers from the pipeline to the gfx
++ * side.
++ */
++#if GST_VERSION_MAJOR == 1
++ static GstPadProbeReturn QueryProbeCb(GstPad *aPad, GstPadProbeInfo *aInfo, gpointer aUserData);
++ GstPadProbeReturn QueryProbe(GstPad *aPad, GstPadProbeInfo *aInfo, gpointer aUserData);
++#else
+ static GstFlowReturn AllocateVideoBufferCb(GstPad* aPad, guint64 aOffset, guint aSize,
+ GstCaps* aCaps, GstBuffer** aBuf);
+ GstFlowReturn AllocateVideoBufferFull(GstPad* aPad, guint64 aOffset, guint aSize,
+ GstCaps* aCaps, GstBuffer** aBuf, nsRefPtr<layers::PlanarYCbCrImage>& aImage);
+ GstFlowReturn AllocateVideoBuffer(GstPad* aPad, guint64 aOffset, guint aSize,
+ GstCaps* aCaps, GstBuffer** aBuf);
++#endif
++
+
+ /* Called when the pipeline is prerolled, that is when at start or after a
+ * seek, the first audio and video buffers are queued in the sinks.
+@@ -167,6 +185,11 @@ private:
+ bool mUseParserDuration;
+ int64_t mLastParserDuration;
+
++#if GST_VERSION_MAJOR >= 1
++ GstAllocator *mAllocator;
++ GstBufferPool *mBufferPool;
++ GstVideoInfo mVideoInfo;
++#endif
+ GstElement* mPlayBin;
+ GstBus* mBus;
+ GstAppSrc* mSource;
+@@ -197,6 +220,9 @@ private:
+ * DecodeAudioData and DecodeVideoFrame should not expect any more data
+ */
+ bool mReachedEos;
++#if GST_VERSION_MAJOR >= 1
++ bool mConfigureAlignment;
++#endif
+ int fpsNum;
+ int fpsDen;
+ };
diff --git a/www/firefox/patches/patch-content_media_gstreamer_moz.build b/www/firefox/patches/patch-content_media_gstreamer_moz.build
new file mode 100644
index 00000000000..6badf82e80e
--- /dev/null
+++ b/www/firefox/patches/patch-content_media_gstreamer_moz.build
@@ -0,0 +1,25 @@
+$NetBSD: patch-content_media_gstreamer_moz.build,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- content/media/gstreamer/moz.build.orig 2014-03-15 05:19:11.000000000 +0000
++++ content/media/gstreamer/moz.build
+@@ -15,10 +15,19 @@ SOURCES += [
+ 'GStreamerDecoder.cpp',
+ 'GStreamerFormatHelper.cpp',
+ 'GStreamerLoader.cpp',
+- 'GStreamerMozVideoBuffer.cpp',
+ 'GStreamerReader.cpp',
+ ]
+
++if CONFIG['GST_API_VERSION'] == '1.0':
++ SOURCES += [
++ 'GStreamerAllocator.cpp',
++ ]
++else:
++ SOURCES += [
++ 'GStreamerMozVideoBuffer.cpp',
++ 'GStreamerReader-0.10.cpp',
++ ]
++
+ FAIL_ON_WARNINGS = True
+
+ FINAL_LIBRARY = 'gklayout'
diff --git a/www/firefox/patches/patch-content_media_test_manifest.js b/www/firefox/patches/patch-content_media_test_manifest.js
new file mode 100644
index 00000000000..a91d314d1e9
--- /dev/null
+++ b/www/firefox/patches/patch-content_media_test_manifest.js
@@ -0,0 +1,17 @@
+$NetBSD: patch-content_media_test_manifest.js,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- content/media/test/manifest.js.orig 2014-03-15 05:19:11.000000000 +0000
++++ content/media/test/manifest.js
+@@ -357,9 +357,9 @@ var gUnseekableTests = [
+ { name:"bogus.duh", type:"bogus/duh"}
+ ];
+ // Unfortunately big-buck-bunny-unseekable.mp4 is doesn't play on Windows 7, so
+-// only include it in the unseekable tests if we're on later versions of Windows.
+-if (navigator.userAgent.indexOf("Windows") == -1 ||
+- IsWindows8OrLater()) {
++// only include it in the unseekable tests if we're on later versions of Windows.
++// This test actually only passes on win8 at the moment.
++if (navigator.userAgent.indexOf("Windows") != -1 && IsWindows8OrLater()) {
+ gUnseekableTests = gUnseekableTests.concat([
+ { name:"big-buck-bunny-unseekable.mp4", type:"video/mp4" }
+ ]);
diff --git a/www/firefox/patches/patch-extensions_auth_nsAuthGSSAPI.cpp b/www/firefox/patches/patch-extensions_auth_nsAuthGSSAPI.cpp
deleted file mode 100644
index 94cecf8501e..00000000000
--- a/www/firefox/patches/patch-extensions_auth_nsAuthGSSAPI.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-$NetBSD: patch-extensions_auth_nsAuthGSSAPI.cpp,v 1.3 2014/02/20 13:19:03 ryoon Exp $
-
---- extensions/auth/nsAuthGSSAPI.cpp.orig 2013-05-11 19:19:29.000000000 +0000
-+++ extensions/auth/nsAuthGSSAPI.cpp
-@@ -39,6 +39,9 @@ typedef KLStatus (*KLCacheHasValidTicket
- #endif
-
- #if defined(HAVE_RES_NINIT)
-+#include <sys/types.h>
-+#include <netinet/in.h>
-+#include <arpa/nameser.h>
- #include <resolv.h>
- #endif
-
diff --git a/www/firefox/patches/patch-gfx_moz.build b/www/firefox/patches/patch-gfx_moz.build
new file mode 100644
index 00000000000..1ca5a603ba2
--- /dev/null
+++ b/www/firefox/patches/patch-gfx_moz.build
@@ -0,0 +1,26 @@
+$NetBSD: patch-gfx_moz.build,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- gfx/moz.build.orig 2014-03-15 05:19:16.000000000 +0000
++++ gfx/moz.build
+@@ -7,6 +7,12 @@
+ if CONFIG['MOZ_TREE_CAIRO']:
+ DIRS += ['cairo']
+
++if not CONFIG['MOZ_NATIVE_GRAPHITE2']:
++ DIRS += ['graphite2/src' ]
++
++if not CONFIG['MOZ_NATIVE_HARFBUZZ']:
++ DIRS += ['harfbuzz/src']
++
+ DIRS += [
+ '2d',
+ 'ycbcr',
+@@ -15,8 +21,6 @@ DIRS += [
+ 'qcms',
+ 'gl',
+ 'layers',
+- 'graphite2/src',
+- 'harfbuzz/src',
+ 'ots/src',
+ 'thebes',
+ 'ipc',
diff --git a/www/firefox/patches/patch-gfx_skia_Makefile.in b/www/firefox/patches/patch-gfx_skia_Makefile.in
new file mode 100644
index 00000000000..bbc919b294c
--- /dev/null
+++ b/www/firefox/patches/patch-gfx_skia_Makefile.in
@@ -0,0 +1,15 @@
+$NetBSD: patch-gfx_skia_Makefile.in,v 1.3 2014/03/20 21:02:00 ryoon Exp $
+
+--- gfx/skia/Makefile.in.orig 2014-03-15 05:19:16.000000000 +0000
++++ gfx/skia/Makefile.in
+@@ -34,6 +34,10 @@ ifeq (qt,$(MOZ_WIDGET_TOOLKIT))
+ OS_CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(MOZ_PANGO_CFLAGS) $(CAIRO_FT_CFLAGS)
+ endif
+
++ifdef MOZ_NATIVE_HARFBUZZ
++OS_CXXFLAGS += $(MOZ_HARFBUZZ_CFLAGS)
++endif
++
+ include $(topsrcdir)/config/rules.mk
+
+ ifneq (,$(INTEL_ARCHITECTURE))
diff --git a/www/firefox/patches/patch-gfx_skia_moz.build b/www/firefox/patches/patch-gfx_skia_moz.build
index f3c2e35731c..8d5012ca5a9 100644
--- a/www/firefox/patches/patch-gfx_skia_moz.build
+++ b/www/firefox/patches/patch-gfx_skia_moz.build
@@ -1,10 +1,10 @@
-$NetBSD: patch-gfx_skia_moz.build,v 1.5 2014/02/20 13:19:03 ryoon Exp $
+$NetBSD: patch-gfx_skia_moz.build,v 1.6 2014/03/20 21:02:00 ryoon Exp $
---- gfx/skia/moz.build.orig 2014-02-12 21:29:00.000000000 +0000
+--- gfx/skia/moz.build.orig 2014-03-15 05:19:16.000000000 +0000
+++ gfx/skia/moz.build
-@@ -197,7 +197,7 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt
+@@ -209,7 +209,7 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt
+ 'src/ports/SkFontHost_cairo.cpp',
'src/ports/SkFontHost_FreeType_common.cpp',
- 'src/utils/SkOSFile.cpp',
]
- if CONFIG['OS_TARGET'] == 'Linux':
+ if CONFIG['MOZ_X11'] == 1 or CONFIG['OS_TARGET'] == 'Linux':
diff --git a/www/firefox/patches/patch-gfx_thebes_Makefile.in b/www/firefox/patches/patch-gfx_thebes_Makefile.in
new file mode 100644
index 00000000000..f27dff74010
--- /dev/null
+++ b/www/firefox/patches/patch-gfx_thebes_Makefile.in
@@ -0,0 +1,19 @@
+$NetBSD: patch-gfx_thebes_Makefile.in,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- gfx/thebes/Makefile.in.orig 2014-03-15 05:19:16.000000000 +0000
++++ gfx/thebes/Makefile.in
+@@ -13,6 +13,14 @@ DEFINES := $(filter-out -DUNICODE,$(DEFI
+ CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS) $(TK_CFLAGS)
+ CFLAGS += $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS) $(TK_CFLAGS)
+
++ifdef MOZ_NATIVE_GRAPHITE2
++CXXFLAGS += $(MOZ_GRAPHITE2_CFLAGS)
++endif
++
++ifdef MOZ_NATIVE_HARFBUZZ
++CXXFLAGS += $(MOZ_HARFBUZZ_CFLAGS)
++endif
++
+ ifeq ($(MOZ_WIDGET_TOOLKIT),android)
+ CXXFLAGS += $(CAIRO_FT_CFLAGS)
+ endif
diff --git a/www/firefox/patches/patch-intl_unicharutil_util_Makefile.in b/www/firefox/patches/patch-intl_unicharutil_util_Makefile.in
new file mode 100644
index 00000000000..6bc3763cd28
--- /dev/null
+++ b/www/firefox/patches/patch-intl_unicharutil_util_Makefile.in
@@ -0,0 +1,12 @@
+$NetBSD: patch-intl_unicharutil_util_Makefile.in,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- intl/unicharutil/util/Makefile.in.orig 2014-03-15 05:19:19.000000000 +0000
++++ intl/unicharutil/util/Makefile.in
+@@ -19,3 +19,7 @@ ifdef _MSC_VER
+ OS_COMPILE_CXXFLAGS += -Zl
+ OS_COMPILE_CFLAGS += -Zl
+ endif
++
++ifdef MOZ_NATIVE_HARFBUZZ
++nsUnicodePropertyData.$(OBJ_SUFFIX): CXXFLAGS+=$(MOZ_HARFBUZZ_CFLAGS)
++endif
diff --git a/www/firefox/patches/patch-ipc_chromium_Makefile.in b/www/firefox/patches/patch-ipc_chromium_Makefile.in
index 20868feb346..b584dd7e743 100644
--- a/www/firefox/patches/patch-ipc_chromium_Makefile.in
+++ b/www/firefox/patches/patch-ipc_chromium_Makefile.in
@@ -1,8 +1,8 @@
-$NetBSD: patch-ipc_chromium_Makefile.in,v 1.5 2014/02/20 13:19:03 ryoon Exp $
+$NetBSD: patch-ipc_chromium_Makefile.in,v 1.6 2014/03/20 21:02:00 ryoon Exp $
---- ipc/chromium/Makefile.in.orig 2013-10-25 22:27:21.000000000 +0000
+--- ipc/chromium/Makefile.in.orig 2014-03-15 05:19:19.000000000 +0000
+++ ipc/chromium/Makefile.in
-@@ -22,9 +22,7 @@ vpath %.c \
+@@ -11,9 +11,7 @@ vpath %.c \
$(srcdir)/src/third_party/libevent \
$(NULL)
else # } else {
@@ -13,37 +13,3 @@ $NetBSD: patch-ipc_chromium_Makefile.in,v 1.5 2014/02/20 13:19:03 ryoon Exp $
endif # }
vpath %.cc \
-@@ -45,6 +43,33 @@ DEFINES += -DANDROID -D_POSIX_MONOTONIC_
- endif # Android
- endif # } Not WINNT (OS_POSIX)
-
-+ifdef OS_SOLARIS # {
-+
-+CPPSRCS += \
-+ atomicops_internals_x86_gcc.cc \
-+ process_util_linux.cc \
-+ time_posix.cc \
-+ $(NULL)
-+
-+ifdef MOZ_ENABLE_GTK2
-+CPPSRCS += \
-+ message_pump_glib.cc \
-+ $(NULL)
-+endif
-+
-+ifdef MOZ_ENABLE_QT
-+MOCSRCS = \
-+ moc_message_pump_qt.cc \
-+ $(NULL)
-+
-+CPPSRCS += \
-+ $(MOCSRCS) \
-+ message_pump_qt.cc \
-+ $(NULL)
-+endif
-+
-+endif # } OS_SOLARIS
-+
- # libevent
-
- ifndef MOZ_NATIVE_LIBEVENT # {
diff --git a/www/firefox/patches/patch-ipc_glue_GeckoChildProcessHost.cpp b/www/firefox/patches/patch-ipc_glue_GeckoChildProcessHost.cpp
index 19b83b8040f..3c0dbc624d9 100644
--- a/www/firefox/patches/patch-ipc_glue_GeckoChildProcessHost.cpp
+++ b/www/firefox/patches/patch-ipc_glue_GeckoChildProcessHost.cpp
@@ -1,6 +1,6 @@
-$NetBSD: patch-ipc_glue_GeckoChildProcessHost.cpp,v 1.5 2014/02/20 13:19:03 ryoon Exp $
+$NetBSD: patch-ipc_glue_GeckoChildProcessHost.cpp,v 1.6 2014/03/20 21:02:00 ryoon Exp $
---- ipc/glue/GeckoChildProcessHost.cpp.orig 2013-07-30 00:58:17.000000000 +0000
+--- ipc/glue/GeckoChildProcessHost.cpp.orig 2014-03-15 05:19:19.000000000 +0000
+++ ipc/glue/GeckoChildProcessHost.cpp
@@ -4,7 +4,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -14,9 +14,9 @@ $NetBSD: patch-ipc_glue_GeckoChildProcessHost.cpp,v 1.5 2014/02/20 13:19:03 ryoo
+_Pragma("GCC visibility pop")
+#endif
- #include "base/command_line.h"
- #include "base/path_service.h"
-@@ -490,7 +496,7 @@ GeckoChildProcessHost::PerformAsyncLaunc
+ #if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
+ #include "sandboxBroker.h"
+@@ -499,7 +505,7 @@ GeckoChildProcessHost::PerformAsyncLaunc
// and passing wstrings from one config to the other is unsafe. So
// we split the logic here.
@@ -25,7 +25,7 @@ $NetBSD: patch-ipc_glue_GeckoChildProcessHost.cpp,v 1.5 2014/02/20 13:19:03 ryoo
base::environment_map newEnvVars;
ChildPrivileges privs = mPrivileges;
if (privs == base::PRIVILEGES_DEFAULT) {
-@@ -509,7 +515,7 @@ GeckoChildProcessHost::PerformAsyncLaunc
+@@ -518,7 +524,7 @@ GeckoChildProcessHost::PerformAsyncLaunc
if (NS_SUCCEEDED(rv)) {
nsCString path;
greDir->GetNativePath(path);
@@ -34,7 +34,7 @@ $NetBSD: patch-ipc_glue_GeckoChildProcessHost.cpp,v 1.5 2014/02/20 13:19:03 ryoo
# if defined(MOZ_WIDGET_ANDROID)
path += "/lib";
# endif // MOZ_WIDGET_ANDROID
-@@ -618,7 +624,7 @@ GeckoChildProcessHost::PerformAsyncLaunc
+@@ -627,7 +633,7 @@ GeckoChildProcessHost::PerformAsyncLaunc
childArgv.push_back(pidstring);
#if defined(MOZ_CRASHREPORTER)
@@ -43,7 +43,7 @@ $NetBSD: patch-ipc_glue_GeckoChildProcessHost.cpp,v 1.5 2014/02/20 13:19:03 ryoo
int childCrashFd, childCrashRemapFd;
if (!CrashReporter::CreateNotificationPipeForChild(
&childCrashFd, &childCrashRemapFd))
-@@ -651,7 +657,7 @@ GeckoChildProcessHost::PerformAsyncLaunc
+@@ -660,7 +666,7 @@ GeckoChildProcessHost::PerformAsyncLaunc
childArgv.push_back(childProcessType);
base::LaunchApp(childArgv, mFileMap,
diff --git a/www/firefox/patches/patch-js_src_Makefile.in b/www/firefox/patches/patch-js_src_Makefile.in
index a6304978041..f3cd1fd2e8f 100644
--- a/www/firefox/patches/patch-js_src_Makefile.in
+++ b/www/firefox/patches/patch-js_src_Makefile.in
@@ -1,18 +1,13 @@
-$NetBSD: patch-js_src_Makefile.in,v 1.6 2014/02/20 13:19:03 ryoon Exp $
+$NetBSD: patch-js_src_Makefile.in,v 1.7 2014/03/20 21:02:00 ryoon Exp $
---- js/src/Makefile.in.orig 2013-12-05 16:07:35.000000000 +0000
+--- js/src/Makefile.in.orig 2014-03-15 05:19:19.000000000 +0000
+++ js/src/Makefile.in
-@@ -467,6 +467,13 @@ EXTRA_LIBS += -lposix4 -ldl -lnsl -lsock
- endif
+@@ -379,7 +379,7 @@ endif
+ ifdef MOZ_SHARED_ICU
+ EXTRA_DSO_LDOPTS += $(MOZ_ICU_LIBS)
+ else
+-SHARED_LIBRARY_LIBS += $(MOZ_ICU_LIBS)
++SHARED_LIBRARY_LIBS += $(filter-out -L% -l% -Wl%,$(MOZ_ICU_LIBS))
endif
-+# clang 3.3 + -O2 makes jaeger crash in FixupArity
-+ifdef CLANG_CXX
-+ifndef MOZ_DEBUG
-+Compiler.$(OBJ_SUFFIX): CXXFLAGS += -fno-inline-functions
-+endif
-+endif
-+
- # An AIX Optimization bug causes PR_dtoa() & JS_dtoa to produce wrong result.
- # This suppresses optimization for this single compilation unit.
- ifeq ($(OS_ARCH),AIX)
+ # Prevent floating point errors caused by VC++ optimizations
diff --git a/www/firefox/patches/patch-js_src_config_system-headers b/www/firefox/patches/patch-js_src_config_system-headers
index 62d27f92722..d6dd1050732 100644
--- a/www/firefox/patches/patch-js_src_config_system-headers
+++ b/www/firefox/patches/patch-js_src_config_system-headers
@@ -1,9 +1,10 @@
-$NetBSD: patch-js_src_config_system-headers,v 1.6 2014/02/20 13:19:03 ryoon Exp $
+$NetBSD: patch-js_src_config_system-headers,v 1.7 2014/03/20 21:02:00 ryoon Exp $
---- js/src/config/system-headers.orig 2013-12-05 16:07:35.000000000 +0000
+--- js/src/config/system-headers.orig 2014-03-15 05:19:19.000000000 +0000
+++ js/src/config/system-headers
-@@ -1144,3 +1144,4 @@ unicode/unum.h
- unicode/ustring.h
+@@ -1145,3 +1145,5 @@ unicode/ustring.h
unicode/utypes.h
#endif
-+libutil.h
+ libutil.h
++unwind.h
++cairo-qt.h
diff --git a/www/firefox/patches/patch-mb b/www/firefox/patches/patch-mb
index 827d20f5468..491839768ac 100644
--- a/www/firefox/patches/patch-mb
+++ b/www/firefox/patches/patch-mb
@@ -1,20 +1,37 @@
-$NetBSD: patch-mb,v 1.8 2014/02/20 13:19:03 ryoon Exp $
+$NetBSD: patch-mb,v 1.9 2014/03/20 21:02:00 ryoon Exp $
---- xpcom/reflect/xptcall/src/md/unix/Makefile.in.orig 2013-09-10 03:43:57.000000000 +0000
+--- xpcom/reflect/xptcall/src/md/unix/Makefile.in.orig 2014-03-15 05:19:39.000000000 +0000
+++ xpcom/reflect/xptcall/src/md/unix/Makefile.in
-@@ -183,7 +183,7 @@ endif
- #
- # NetBSD/PPC
- #
--ifneq (,$(filter NetBSDmacppc NetBSDbebox NetBSDofppc NetBSDprep NetBSDamigappc,$(OS_ARCH)$(OS_TEST)))
-+ifeq ($(OS_ARCH)$(OS_TEST),NetBSDpowerpc)
- ASFILES := xptcinvoke_asm_ppc_netbsd.s xptcstubs_asm_ppc_netbsd.s
- endif
-
-@@ -235,6 +235,13 @@ ifneq (,$(filter OpenBSDsparc64 FreeBSDs
- ASFILES := xptcinvoke_asm_sparc64_openbsd.s xptcstubs_asm_sparc64_openbsd.s
- endif
+@@ -83,6 +83,39 @@ endif
+ # SPARC
+ ######################################################################
#
++# Linux/SPARC
++#
++ifeq ($(OS_ARCH),Linux)
++ifneq (,$(findstring sparc,$(OS_TEST)))
++ASFILES := xptcinvoke_asm_sparc_linux_GCC3.s xptcstubs_asm_sparc_solaris.s
++endif
++endif
++#
++# NetBSD/SPARC
++#
++ifeq ($(OS_ARCH)$(OS_TEST),NetBSDsparc)
++ASFILES := xptcinvoke_asm_sparc_netbsd.s xptcstubs_asm_sparc_netbsd.s
++endif
++#
++# OpenBSD/SPARC
++#
++ifeq ($(OS_ARCH)$(OS_TEST),OpenBSDsparc)
++ASFILES := xptcinvoke_asm_sparc_openbsd.s xptcstubs_asm_sparc_openbsd.s
++endif
++#
++# OpenBSD/SPARC64
++#
++ifneq (,$(filter OpenBSDsparc64 FreeBSDsparc64,$(OS_ARCH)$(OS_TEST)))
++ASFILES := xptcinvoke_asm_sparc64_openbsd.s xptcstubs_asm_sparc64_openbsd.s
++endif
++#
+# NetBSD/SPARC64
+#
+ifeq ($(OS_ARCH)$(OS_TEST),NetBSDsparc64)
diff --git a/www/firefox/patches/patch-media_libtheora_Makefile.in b/www/firefox/patches/patch-media_libtheora_Makefile.in
new file mode 100644
index 00000000000..b1d74312fc3
--- /dev/null
+++ b/www/firefox/patches/patch-media_libtheora_Makefile.in
@@ -0,0 +1,14 @@
+$NetBSD: patch-media_libtheora_Makefile.in,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- media/libtheora/Makefile.in.orig 2014-03-20 11:09:40.000000000 +0000
++++ media/libtheora/Makefile.in
+@@ -0,0 +1,9 @@
++# 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 $(topsrcdir)/config/rules.mk
++
++ifdef MOZ_NATIVE_OGG
++CFLAGS += $(MOZ_OGG_CFLAGS)
++endif
diff --git a/www/firefox/patches/patch-media_libtremor_Makefile.in b/www/firefox/patches/patch-media_libtremor_Makefile.in
new file mode 100644
index 00000000000..fb15e008cb8
--- /dev/null
+++ b/www/firefox/patches/patch-media_libtremor_Makefile.in
@@ -0,0 +1,14 @@
+$NetBSD: patch-media_libtremor_Makefile.in,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- media/libtremor/Makefile.in.orig 2014-03-20 11:09:40.000000000 +0000
++++ media/libtremor/Makefile.in
+@@ -0,0 +1,9 @@
++# 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 $(topsrcdir)/config/rules.mk
++
++ifdef MOZ_NATIVE_OGG
++CFLAGS += $(MOZ_OGG_CFLAGS)
++endif
diff --git a/www/firefox/patches/patch-media_libvorbis_Makefile.in b/www/firefox/patches/patch-media_libvorbis_Makefile.in
new file mode 100644
index 00000000000..2ede42f9228
--- /dev/null
+++ b/www/firefox/patches/patch-media_libvorbis_Makefile.in
@@ -0,0 +1,14 @@
+$NetBSD: patch-media_libvorbis_Makefile.in,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- media/libvorbis/Makefile.in.orig 2014-03-20 11:09:40.000000000 +0000
++++ media/libvorbis/Makefile.in
+@@ -0,0 +1,9 @@
++# 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 $(topsrcdir)/config/rules.mk
++
++ifdef MOZ_NATIVE_OGG
++CFLAGS += $(MOZ_OGG_CFLAGS)
++endif
diff --git a/www/firefox/patches/patch-media_webrtc_signaling_test_Makefile.in b/www/firefox/patches/patch-media_webrtc_signaling_test_Makefile.in
index 46e6c571bd6..c7f51747815 100644
--- a/www/firefox/patches/patch-media_webrtc_signaling_test_Makefile.in
+++ b/www/firefox/patches/patch-media_webrtc_signaling_test_Makefile.in
@@ -1,12 +1,25 @@
-$NetBSD: patch-media_webrtc_signaling_test_Makefile.in,v 1.4 2014/02/20 13:19:03 ryoon Exp $
+$NetBSD: patch-media_webrtc_signaling_test_Makefile.in,v 1.5 2014/03/20 21:02:00 ryoon Exp $
---- media/webrtc/signaling/test/Makefile.in.orig 2013-12-05 16:07:48.000000000 +0000
+--- media/webrtc/signaling/test/Makefile.in.orig 2014-03-15 05:19:29.000000000 +0000
+++ media/webrtc/signaling/test/Makefile.in
-@@ -7,6 +7,7 @@ LIBS = \
- $(NSPR_LIBS) \
+@@ -8,6 +8,7 @@ LIBS = \
$(NSS_LIBS) \
$(REALTIME_LIBS) \
+ $(MOZ_JS_LIBS) \
+ $(MOZ_LIBV4L2_LIBS) \
$(DEPTH)/xpcom/glue/$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) \
$(DEPTH)/media/mtransport/standalone/$(LIB_PREFIX)mtransport_s.$(LIB_SUFFIX) \
$(DEPTH)/media/webrtc/signalingtest/signaling_ecc/$(LIB_PREFIX)ecc.$(LIB_SUFFIX) \
+@@ -40,6 +41,12 @@ LIBS += \
+ $(NULL)
+ endif
+
++ifdef MOZ_NATIVE_OPUS
++LIBS += \
++ $(MOZ_OPUS_LIBS) \
++ $(NULL)
++endif
++
+ ifdef MOZ_NATIVE_LIBVPX
+ LIBS += \
+ $(MOZ_LIBVPX_LIBS) \
diff --git a/www/firefox/patches/patch-media_webrtc_trunk_webrtc_modules_audio__coding_codecs_opus_opus.gypi b/www/firefox/patches/patch-media_webrtc_trunk_webrtc_modules_audio__coding_codecs_opus_opus.gypi
new file mode 100644
index 00000000000..da26accd9c3
--- /dev/null
+++ b/www/firefox/patches/patch-media_webrtc_trunk_webrtc_modules_audio__coding_codecs_opus_opus.gypi
@@ -0,0 +1,17 @@
+$NetBSD: patch-media_webrtc_trunk_webrtc_modules_audio__coding_codecs_opus_opus.gypi,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- media/webrtc/trunk/webrtc/modules/audio_coding/codecs/opus/opus.gypi.orig 2014-03-15 05:19:30.000000000 +0000
++++ media/webrtc/trunk/webrtc/modules/audio_coding/codecs/opus/opus.gypi
+@@ -14,9 +14,9 @@
+ 'conditions': [
+ ['build_with_mozilla==1', {
+ # Mozilla provides its own build of the opus library.
+- 'include_dirs': [
+- '$(DIST)/include/opus',
+- ]
++ 'cflags_mozilla': [
++ '$(MOZ_OPUS_CFLAGS)',
++ ],
+ }, {
+ 'dependencies': [
+ '<(DEPTH)/third_party/opus/opus.gyp:opus'
diff --git a/www/firefox/patches/patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_device__info__linux.cc b/www/firefox/patches/patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_device__info__linux.cc
index 529915187e6..231103c6ced 100644
--- a/www/firefox/patches/patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_device__info__linux.cc
+++ b/www/firefox/patches/patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_device__info__linux.cc
@@ -1,10 +1,10 @@
-$NetBSD: patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_device__info__linux.cc,v 1.5 2014/02/20 13:19:03 ryoon Exp $
+$NetBSD: patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_device__info__linux.cc,v 1.6 2014/03/20 21:02:00 ryoon Exp $
---- media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.cc.orig 2013-10-25 22:27:35.000000000 +0000
+--- media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.cc.orig 2014-03-15 05:19:30.000000000 +0000
+++ media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.cc
-@@ -19,18 +19,30 @@
- #include <stdlib.h>
-
+@@ -18,17 +18,37 @@
+ #include <sys/stat.h>
+ #include <unistd.h>
//v4l includes
-#if defined(__DragonFly__) || defined(__NetBSD__) || defined(__OpenBSD__)
+#if defined(__NetBSD__) || defined(__OpenBSD__)
@@ -18,9 +18,8 @@ $NetBSD: patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_device__in
+#include <libv4l2.h>
+#endif
- #include "ref_count.h"
- #include "trace.h"
-
+ #include "webrtc/system_wrappers/interface/ref_count.h"
+ #include "webrtc/system_wrappers/interface/trace.h"
+#ifdef HAVE_LIBV4L2
+#define open v4l2_open
@@ -31,10 +30,18 @@ $NetBSD: patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_device__in
+#define munmap v4l2_munmap
+#endif
+
++#ifdef HAVE_LIBV4L2
++#define open v4l2_open
++#define close v4l2_close
++#define dup v4l2_dup
++#define ioctl v4l2_ioctl
++#define mmap v4l2_mmap
++#define munmap v4l2_munmap
++#endif
+
namespace webrtc
{
- namespace videocapturemodule
-@@ -137,6 +149,11 @@ int32_t DeviceInfoLinux::GetDeviceName(
+@@ -136,6 +156,11 @@ int32_t DeviceInfoLinux::GetDeviceName(
memset(deviceNameUTF8, 0, deviceNameLength);
memcpy(cameraName, cap.card, sizeof(cap.card));
diff --git a/www/firefox/patches/patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_video__capture__linux.cc b/www/firefox/patches/patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_video__capture__linux.cc
index 56f25812e3a..10847fdf84f 100644
--- a/www/firefox/patches/patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_video__capture__linux.cc
+++ b/www/firefox/patches/patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_video__capture__linux.cc
@@ -1,9 +1,9 @@
-$NetBSD: patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_video__capture__linux.cc,v 1.5 2014/02/20 13:19:03 ryoon Exp $
+$NetBSD: patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_video__capture__linux.cc,v 1.6 2014/03/20 21:02:00 ryoon Exp $
---- media/webrtc/trunk/webrtc/modules/video_capture/linux/video_capture_linux.cc.orig 2013-10-25 22:27:35.000000000 +0000
+--- media/webrtc/trunk/webrtc/modules/video_capture/linux/video_capture_linux.cc.orig 2014-03-15 05:19:30.000000000 +0000
+++ media/webrtc/trunk/webrtc/modules/video_capture/linux/video_capture_linux.cc
@@ -18,13 +18,16 @@
- #include <string.h>
+ #include <unistd.h>
//v4l includes
-#if defined(__DragonFly__) || defined(__NetBSD__) || defined(__OpenBSD__)
@@ -20,9 +20,9 @@ $NetBSD: patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_video__cap
#include <new>
-@@ -34,6 +37,15 @@
- #include "critical_section_wrapper.h"
- #include "video_capture_linux.h"
+@@ -34,6 +37,24 @@
+ #include "webrtc/system_wrappers/interface/thread_wrapper.h"
+ #include "webrtc/system_wrappers/interface/trace.h"
+#ifdef HAVE_LIBV4L2
+#define open v4l2_open
@@ -33,6 +33,15 @@ $NetBSD: patch-media_webrtc_trunk_webrtc_modules_video__capture_linux_video__cap
+#define munmap v4l2_munmap
+#endif
+
++#ifdef HAVE_LIBV4L2
++#define open v4l2_open
++#define close v4l2_close
++#define dup v4l2_dup
++#define ioctl v4l2_ioctl
++#define mmap v4l2_mmap
++#define munmap v4l2_munmap
++#endif
++
namespace webrtc
{
namespace videocapturemodule
diff --git a/www/firefox/patches/patch-media_webrtc_trunk_webrtc_system__wrappers_source_spreadsortlib_spreadsort.hpp b/www/firefox/patches/patch-media_webrtc_trunk_webrtc_system__wrappers_source_spreadsortlib_spreadsort.hpp
index a7c56b47a58..a2b73cec93f 100644
--- a/www/firefox/patches/patch-media_webrtc_trunk_webrtc_system__wrappers_source_spreadsortlib_spreadsort.hpp
+++ b/www/firefox/patches/patch-media_webrtc_trunk_webrtc_system__wrappers_source_spreadsortlib_spreadsort.hpp
@@ -1,3388 +1,18 @@
-$NetBSD: patch-media_webrtc_trunk_webrtc_system__wrappers_source_spreadsortlib_spreadsort.hpp,v 1.4 2014/02/20 13:19:03 ryoon Exp $
+$NetBSD: patch-media_webrtc_trunk_webrtc_system__wrappers_source_spreadsortlib_spreadsort.hpp,v 1.5 2014/03/20 21:02:00 ryoon Exp $
---- media/webrtc/trunk/webrtc/system_wrappers/source/spreadsortlib/spreadsort.hpp.orig 2013-12-05 16:07:50.000000000 +0000
+--- media/webrtc/trunk/webrtc/system_wrappers/source/spreadsortlib/spreadsort.hpp.orig 2014-03-15 05:19:30.000000000 +0000
+++ media/webrtc/trunk/webrtc/system_wrappers/source/spreadsortlib/spreadsort.hpp
-@@ -1,1688 +1,1695 @@
--//Templated spread_sort library
--
--// Copyright Steven J. Ross 2001 - 2009.
--// Distributed under the Boost Software License, Version 1.0.
--// (See accompanying file LICENSE_1_0.txt or copy at
--// http://www.boost.org/LICENSE_1_0.txt)
--
--// See http://www.boost.org/ for updates, documentation, and revision history.
--
--/*
--Some improvements suggested by:
--Phil Endecott and Frank Gennari
--Cygwin fix provided by:
--Scott McMurray
--*/
--
--#ifndef BOOST_SPREAD_SORT_H
--#define BOOST_SPREAD_SORT_H
--#include <algorithm>
--#include <cstring>
--#include <vector>
--#include "webrtc/system_wrappers/source/spreadsortlib/constants.hpp"
--
--namespace boost {
-- namespace detail {
-- //This only works on unsigned data types
-- template <typename T>
-- inline unsigned
-- rough_log_2_size(const T& input)
-- {
-- unsigned result = 0;
-- //The && is necessary on some compilers to avoid infinite loops; it doesn't significantly impair performance
-- while((input >> result) && (result < (8*sizeof(T)))) ++result;
-- return result;
-- }
--
-- //Gets the maximum size which we'll call spread_sort on to control worst-case performance
-- //Maintains both a minimum size to recurse and a check of distribution size versus count
-- //This is called for a set of bins, instead of bin-by-bin, to avoid performance overhead
-- inline size_t
-- get_max_count(unsigned log_range, size_t count)
-- {
-- unsigned divisor = rough_log_2_size(count);
-- //Making sure the divisor is positive
-- if(divisor > LOG_MEAN_BIN_SIZE)
-- divisor -= LOG_MEAN_BIN_SIZE;
-- else
-- divisor = 1;
-- unsigned relative_width = (LOG_CONST * log_range)/((divisor > MAX_SPLITS) ? MAX_SPLITS : divisor);
-- //Don't try to bitshift more than the size of an element
-- if((8*sizeof(size_t)) <= relative_width)
-- relative_width = (8*sizeof(size_t)) - 1;
-- return (size_t)1 << ((relative_width < (LOG_MEAN_BIN_SIZE + LOG_MIN_SPLIT_COUNT)) ?
-- (LOG_MEAN_BIN_SIZE + LOG_MIN_SPLIT_COUNT) : relative_width);
-- }
--
-- //Find the minimum and maximum using <
-- template <class RandomAccessIter>
-- inline void
-- find_extremes(RandomAccessIter current, RandomAccessIter last, RandomAccessIter & max, RandomAccessIter & min)
-- {
-- min = max = current;
-- //Start from the second item, as max and min are initialized to the first
-- while(++current < last) {
-- if(*max < *current)
-- max = current;
-- else if(*current < *min)
-- min = current;
-- }
-- }
--
-- //Uses a user-defined comparison operator to find minimum and maximum
-- template <class RandomAccessIter, class compare>
-- inline void
-- find_extremes(RandomAccessIter current, RandomAccessIter last, RandomAccessIter & max, RandomAccessIter & min, compare comp)
-- {
-- min = max = current;
-- while(++current < last) {
-- if(comp(*max, *current))
-- max = current;
-- else if(comp(*current, *min))
-- min = current;
-- }
-- }
--
-- //Gets a non-negative right bit shift to operate as a logarithmic divisor
-- inline int
-- get_log_divisor(size_t count, unsigned log_range)
-- {
-- int log_divisor;
-- //If we can finish in one iteration without exceeding either (2 to the MAX_SPLITS) or n bins, do so
-- if((log_divisor = log_range - rough_log_2_size(count)) <= 0 && log_range < MAX_SPLITS)
-- log_divisor = 0;
-- else {
-- //otherwise divide the data into an optimized number of pieces
-- log_divisor += LOG_MEAN_BIN_SIZE;
-- if(log_divisor < 0)
-- log_divisor = 0;
-- //Cannot exceed MAX_SPLITS or cache misses slow down bin lookups dramatically
-- if((log_range - log_divisor) > MAX_SPLITS)
-- log_divisor = log_range - MAX_SPLITS;
-- }
-- return log_divisor;
-- }
--
-- template <class RandomAccessIter>
-- inline RandomAccessIter *
-- size_bins(std::vector<size_t> &bin_sizes, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset, unsigned &cache_end, unsigned bin_count)
-- {
-- //Assure space for the size of each bin, followed by initializing sizes
-- if(bin_count > bin_sizes.size())
-- bin_sizes.resize(bin_count);
-- for(size_t u = 0; u < bin_count; u++)
-- bin_sizes[u] = 0;
-- //Make sure there is space for the bins
-- cache_end = cache_offset + bin_count;
-- if(cache_end > bin_cache.size())
-- bin_cache.resize(cache_end);
-- return &(bin_cache[cache_offset]);
-- }
--
-- //Implementation for recursive integer sorting
-- template <class RandomAccessIter, class div_type, class data_type>
-- inline void
-- spread_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes)
-- {
-- //This step is roughly 10% of runtime, but it helps avoid worst-case behavior and improve behavior with real data
-- //If you know the maximum and minimum ahead of time, you can pass those values in and skip this step for the first iteration
-- RandomAccessIter max, min;
-- find_extremes(first, last, max, min);
-- //max and min will be the same (the first item) iff all values are equivalent
-- if(max == min)
-- return;
-- RandomAccessIter * target_bin;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(*max >> 0) - (*min >> 0)));
-- div_type div_min = *min >> log_divisor;
-- div_type div_max = *max >> log_divisor;
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin; this takes roughly 10% of runtime
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[(*(current++) >> log_divisor) - div_min]++;
-- //Assign the bin positions
-- bins[0] = first;
-- for(unsigned u = 0; u < bin_count - 1; u++)
-- bins[u + 1] = bins[u] + bin_sizes[u];
--
-- //Swap into place
-- //This dominates runtime, mostly in the swap and bin lookups
-- RandomAccessIter nextbinstart = first;
-- for(unsigned u = 0; u < bin_count - 1; ++u) {
-- RandomAccessIter * local_bin = bins + u;
-- nextbinstart += bin_sizes[u];
-- //Iterating over each element in this bin
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //Swapping elements in current into place until the correct element has been swapped in
-- for(target_bin = (bins + ((*current >> log_divisor) - div_min)); target_bin != local_bin;
-- target_bin = bins + ((*current >> log_divisor) - div_min)) {
-- //3-way swap; this is about 1% faster than a 2-way swap with integers
-- //The main advantage is less copies are involved per item put in the correct place
-- data_type tmp;
-- RandomAccessIter b = (*target_bin)++;
-- RandomAccessIter * b_bin = bins + ((*b >> log_divisor) - div_min);
-- if (b_bin != local_bin) {
-- RandomAccessIter c = (*b_bin)++;
-- tmp = *c;
-- *c = *b;
-- }
-- else
-- tmp = *b;
-- *b = *current;
-- *current = tmp;
-- }
-- }
-- *local_bin = nextbinstart;
-- }
-- bins[bin_count - 1] = last;
--
-- //If we've bucketsorted, the array is sorted and we should skip recursion
-- if(!log_divisor)
-- return;
--
-- //Recursing; log_divisor is the remaining range
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- //don't sort unless there are at least two items to compare
-- if(count < 2)
-- continue;
-- //using std::sort if its worst-case is better
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[u]);
-- else
-- spread_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes);
-- }
-- }
--
-- //Generic bitshift-based 3-way swapping code
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-- inline void inner_swap_loop(RandomAccessIter * bins, const RandomAccessIter & nextbinstart, unsigned ii, right_shift &shift
-- , const unsigned log_divisor, const div_type div_min)
-- {
-- RandomAccessIter * local_bin = bins + ii;
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- for(RandomAccessIter * target_bin = (bins + (shift(*current, log_divisor) - div_min)); target_bin != local_bin;
-- target_bin = bins + (shift(*current, log_divisor) - div_min)) {
-- data_type tmp;
-- RandomAccessIter b = (*target_bin)++;
-- RandomAccessIter * b_bin = bins + (shift(*b, log_divisor) - div_min);
-- //Three-way swap; if the item to be swapped doesn't belong in the current bin, swap it to where it belongs
-- if (b_bin != local_bin) {
-- RandomAccessIter c = (*b_bin)++;
-- tmp = *c;
-- *c = *b;
-- }
-- //Note: we could increment current once the swap is done in this case, but that seems to impair performance
-- else
-- tmp = *b;
-- *b = *current;
-- *current = tmp;
-- }
-- }
-- *local_bin = nextbinstart;
-- }
--
-- //Standard swapping wrapper for ascending values
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-- inline void swap_loop(RandomAccessIter * bins, RandomAccessIter & nextbinstart, unsigned ii, right_shift &shift
-- , const std::vector<size_t> &bin_sizes, const unsigned log_divisor, const div_type div_min)
-- {
-- nextbinstart += bin_sizes[ii];
-- inner_swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, log_divisor, div_min);
-- }
--
-- //Functor implementation for recursive sorting
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare>
-- inline void
-- spread_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes, right_shift shift, compare comp)
-- {
-- RandomAccessIter max, min;
-- find_extremes(first, last, max, min, comp);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(shift(*max, 0)) - (shift(*min, 0))));
-- div_type div_min = shift(*min, log_divisor);
-- div_type div_max = shift(*max, log_divisor);
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[shift(*(current++), log_divisor) - div_min]++;
-- bins[0] = first;
-- for(unsigned u = 0; u < bin_count - 1; u++)
-- bins[u + 1] = bins[u] + bin_sizes[u];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- for(unsigned u = 0; u < bin_count - 1; ++u)
-- swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, u, shift, bin_sizes, log_divisor, div_min);
-- bins[bin_count - 1] = last;
--
-- //If we've bucketsorted, the array is sorted and we should skip recursion
-- if(!log_divisor)
-- return;
--
-- //Recursing
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[u], comp);
-- else
-- spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift, compare>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift, comp);
-- }
-- }
--
-- //Functor implementation for recursive sorting with only Shift overridden
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-- inline void
-- spread_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes, right_shift shift)
-- {
-- RandomAccessIter max, min;
-- find_extremes(first, last, max, min);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(shift(*max, 0)) - (shift(*min, 0))));
-- div_type div_min = shift(*min, log_divisor);
-- div_type div_max = shift(*max, log_divisor);
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[shift(*(current++), log_divisor) - div_min]++;
-- bins[0] = first;
-- for(unsigned u = 0; u < bin_count - 1; u++)
-- bins[u + 1] = bins[u] + bin_sizes[u];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- for(unsigned ii = 0; ii < bin_count - 1; ++ii)
-- swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, bin_sizes, log_divisor, div_min);
-- bins[bin_count - 1] = last;
--
-- //If we've bucketsorted, the array is sorted and we should skip recursion
-- if(!log_divisor)
-- return;
--
-- //Recursing
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[u]);
-- else
-- spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift);
-- }
-- }
--
-- //Holds the bin vector and makes the initial recursive call
-- template <class RandomAccessIter, class div_type, class data_type>
-- inline void
-- spread_sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- spread_sort_rec<RandomAccessIter, div_type, data_type>(first, last, bin_cache, 0, bin_sizes);
-- }
--
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare>
-- inline void
-- spread_sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift, compare comp)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift, compare>(first, last, bin_cache, 0, bin_sizes, shift, comp);
-- }
--
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-- inline void
-- spread_sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(first, last, bin_cache, 0, bin_sizes, shift);
-- }
-- }
--
-- //Top-level sorting call for integers
-- template <class RandomAccessIter>
-- inline void integer_sort(RandomAccessIter first, RandomAccessIter last)
-- {
-- //Don't sort if it's too small to optimize
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last);
-- else
-- detail::spread_sort(first, last, *first >> 0, *first);
-- }
--
-- //integer_sort with functors
-- template <class RandomAccessIter, class right_shift, class compare>
-- inline void integer_sort(RandomAccessIter first, RandomAccessIter last,
-- right_shift shift, compare comp) {
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last, comp);
-- else
-- detail::spread_sort(first, last, shift(*first, 0), *first, shift, comp);
-- }
--
-- //integer_sort with right_shift functor
-- template <class RandomAccessIter, class right_shift>
-- inline void integer_sort(RandomAccessIter first, RandomAccessIter last,
-- right_shift shift) {
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last);
-- else
-- detail::spread_sort(first, last, shift(*first, 0), *first, shift);
-- }
--
-- //------------------------------------------------------ float_sort source --------------------------------------
-- //Casts a RandomAccessIter to the specified data type
-- template<class cast_type, class RandomAccessIter>
-- inline cast_type
-- cast_float_iter(const RandomAccessIter & floatiter)
-- {
-- cast_type result;
-- std::memcpy(&result, &(*floatiter), sizeof(cast_type));
-- return result;
-- }
--
-- //Casts a data element to the specified datinner_float_a type
-- template<class data_type, class cast_type>
-- inline cast_type
-- mem_cast(const data_type & data)
-- {
-- cast_type result;
-- std::memcpy(&result, &data, sizeof(cast_type));
-- return result;
-- }
--
-- namespace detail {
-- template <class RandomAccessIter, class div_type, class right_shift>
-- inline void
-- find_extremes(RandomAccessIter current, RandomAccessIter last, div_type & max, div_type & min, right_shift shift)
-- {
-- min = max = shift(*current, 0);
-- while(++current < last) {
-- div_type value = shift(*current, 0);
-- if(max < value)
-- max = value;
-- else if(value < min)
-- min = value;
-- }
-- }
--
-- //Specialized swap loops for floating-point casting
-- template <class RandomAccessIter, class div_type, class data_type>
-- inline void inner_float_swap_loop(RandomAccessIter * bins, const RandomAccessIter & nextbinstart, unsigned ii
-- , const unsigned log_divisor, const div_type div_min)
-- {
-- RandomAccessIter * local_bin = bins + ii;
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- for(RandomAccessIter * target_bin = (bins + ((cast_float_iter<div_type, RandomAccessIter>(current) >> log_divisor) - div_min)); target_bin != local_bin;
-- target_bin = bins + ((cast_float_iter<div_type, RandomAccessIter>(current) >> log_divisor) - div_min)) {
-- data_type tmp;
-- RandomAccessIter b = (*target_bin)++;
-- RandomAccessIter * b_bin = bins + ((cast_float_iter<div_type, RandomAccessIter>(b) >> log_divisor) - div_min);
-- //Three-way swap; if the item to be swapped doesn't belong in the current bin, swap it to where it belongs
-- if (b_bin != local_bin) {
-- RandomAccessIter c = (*b_bin)++;
-- tmp = *c;
-- *c = *b;
-- }
-- else
-- tmp = *b;
-- *b = *current;
-- *current = tmp;
-- }
-- }
-- *local_bin = nextbinstart;
-- }
--
-- template <class RandomAccessIter, class div_type, class data_type>
-- inline void float_swap_loop(RandomAccessIter * bins, RandomAccessIter & nextbinstart, unsigned ii
-- , const std::vector<size_t> &bin_sizes, const unsigned log_divisor, const div_type div_min)
-- {
-- nextbinstart += bin_sizes[ii];
-- inner_float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, ii, log_divisor, div_min);
-- }
--
-- template <class RandomAccessIter, class cast_type>
-- inline void
-- find_extremes(RandomAccessIter current, RandomAccessIter last, cast_type & max, cast_type & min)
-- {
-- min = max = cast_float_iter<cast_type, RandomAccessIter>(current);
-- while(++current < last) {
-- cast_type value = cast_float_iter<cast_type, RandomAccessIter>(current);
-- if(max < value)
-- max = value;
-- else if(value < min)
-- min = value;
-- }
-- }
--
-- //Special-case sorting of positive floats with casting instead of a right_shift
-- template <class RandomAccessIter, class div_type, class data_type>
-- inline void
-- positive_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes)
-- {
-- div_type max, min;
-- find_extremes(first, last, max, min);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-- div_type div_min = min >> log_divisor;
-- div_type div_max = max >> log_divisor;
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[(cast_float_iter<div_type, RandomAccessIter>(current++) >> log_divisor) - div_min]++;
-- bins[0] = first;
-- for(unsigned u = 0; u < bin_count - 1; u++)
-- bins[u + 1] = bins[u] + bin_sizes[u];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- for(unsigned u = 0; u < bin_count - 1; ++u)
-- float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, u, bin_sizes, log_divisor, div_min);
-- bins[bin_count - 1] = last;
--
-- //Return if we've completed bucketsorting
-- if(!log_divisor)
-- return;
--
-- //Recursing
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[u]);
-- else
-- positive_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes);
-- }
-- }
--
-- //Sorting negative_ float_s
-- //Note that bins are iterated in reverse order because max_neg_float = min_neg_int
-- template <class RandomAccessIter, class div_type, class data_type>
-- inline void
-- negative_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes)
-- {
-- div_type max, min;
-- find_extremes(first, last, max, min);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-- div_type div_min = min >> log_divisor;
-- div_type div_max = max >> log_divisor;
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[(cast_float_iter<div_type, RandomAccessIter>(current++) >> log_divisor) - div_min]++;
-- bins[bin_count - 1] = first;
-- for(int ii = bin_count - 2; ii >= 0; --ii)
-- bins[ii] = bins[ii + 1] + bin_sizes[ii + 1];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- //The last bin will always have the correct elements in it
-- for(int ii = bin_count - 1; ii > 0; --ii)
-- float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, ii, bin_sizes, log_divisor, div_min);
-- //Since we don't process the last bin, we need to update its end position
-- bin_cache[cache_offset] = last;
--
-- //Return if we've completed bucketsorting
-- if(!log_divisor)
-- return;
--
-- //Recursing
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(int ii = cache_end - 1; ii >= (int)cache_offset; lastPos = bin_cache[ii], --ii) {
-- size_t count = bin_cache[ii] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[ii]);
-- else
-- negative_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes);
-- }
-- }
--
-- //Sorting negative_ float_s
-- //Note that bins are iterated in reverse order because max_neg_float = min_neg_int
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-- inline void
-- negative_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes, right_shift shift)
-- {
-- div_type max, min;
-- find_extremes(first, last, max, min, shift);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-- div_type div_min = min >> log_divisor;
-- div_type div_max = max >> log_divisor;
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[shift(*(current++), log_divisor) - div_min]++;
-- bins[bin_count - 1] = first;
-- for(int ii = bin_count - 2; ii >= 0; --ii)
-- bins[ii] = bins[ii + 1] + bin_sizes[ii + 1];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- //The last bin will always have the correct elements in it
-- for(int ii = bin_count - 1; ii > 0; --ii)
-- swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, bin_sizes, log_divisor, div_min);
-- //Since we don't process the last bin, we need to update its end position
-- bin_cache[cache_offset] = last;
--
-- //Return if we've completed bucketsorting
-- if(!log_divisor)
-- return;
--
-- //Recursing
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(int ii = cache_end - 1; ii >= (int)cache_offset; lastPos = bin_cache[ii], --ii) {
-- size_t count = bin_cache[ii] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[ii]);
-- else
-- negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift);
-- }
-- }
--
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare>
-- inline void
-- negative_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes, right_shift shift, compare comp)
-- {
-- div_type max, min;
-- find_extremes(first, last, max, min, shift);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-- div_type div_min = min >> log_divisor;
-- div_type div_max = max >> log_divisor;
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[shift(*(current++), log_divisor) - div_min]++;
-- bins[bin_count - 1] = first;
-- for(int ii = bin_count - 2; ii >= 0; --ii)
-- bins[ii] = bins[ii + 1] + bin_sizes[ii + 1];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- //The last bin will always have the correct elements in it
-- for(int ii = bin_count - 1; ii > 0; --ii)
-- swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, bin_sizes, log_divisor, div_min);
-- //Since we don't process the last bin, we need to update its end position
-- bin_cache[cache_offset] = last;
--
-- //Return if we've completed bucketsorting
-- if(!log_divisor)
-- return;
--
-- //Recursing
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(int ii = cache_end - 1; ii >= (int)cache_offset; lastPos = bin_cache[ii], --ii) {
-- size_t count = bin_cache[ii] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[ii], comp);
-- else
-- negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift, compare>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift, comp);
-- }
-- }
--
-- //Casting special-case for floating-point sorting
-- template <class RandomAccessIter, class div_type, class data_type>
-- inline void
-- float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes)
-- {
-- div_type max, min;
-- find_extremes(first, last, max, min);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-- div_type div_min = min >> log_divisor;
-- div_type div_max = max >> log_divisor;
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[(cast_float_iter<div_type, RandomAccessIter>(current++) >> log_divisor) - div_min]++;
-- //The index of the first positive bin
-- div_type first_positive = (div_min < 0) ? -div_min : 0;
-- //Resetting if all bins are negative
-- if(cache_offset + first_positive > cache_end)
-- first_positive = cache_end - cache_offset;
-- //Reversing the order of the negative bins
-- //Note that because of the negative/positive ordering direction flip
-- //We can not depend upon bin order and positions matching up
-- //so bin_sizes must be reused to contain the end of the bin
-- if(first_positive > 0) {
-- bins[first_positive - 1] = first;
-- for(int ii = first_positive - 2; ii >= 0; --ii) {
-- bins[ii] = first + bin_sizes[ii + 1];
-- bin_sizes[ii] += bin_sizes[ii + 1];
-- }
-- //Handling positives following negatives
-- if((unsigned)first_positive < bin_count) {
-- bins[first_positive] = first + bin_sizes[0];
-- bin_sizes[first_positive] += bin_sizes[0];
-- }
-- }
-- else
-- bins[0] = first;
-- for(unsigned u = first_positive; u < bin_count - 1; u++) {
-- bins[u + 1] = first + bin_sizes[u];
-- bin_sizes[u + 1] += bin_sizes[u];
-- }
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- for(unsigned u = 0; u < bin_count; ++u) {
-- nextbinstart = first + bin_sizes[u];
-- inner_float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, u, log_divisor, div_min);
-- }
--
-- if(!log_divisor)
-- return;
--
-- //Handling negative values first
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(int ii = cache_offset + first_positive - 1; ii >= (int)cache_offset ; lastPos = bin_cache[ii--]) {
-- size_t count = bin_cache[ii] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[ii]);
-- //sort negative values using reversed-bin spread_sort
-- else
-- negative_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes);
-- }
--
-- for(unsigned u = cache_offset + first_positive; u < cache_end; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[u]);
-- //sort positive values using normal spread_sort
-- else
-- positive_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes);
-- }
-- }
--
-- //Functor implementation for recursive sorting
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-- inline void
-- float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes, right_shift shift)
-- {
-- div_type max, min;
-- find_extremes(first, last, max, min, shift);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-- div_type div_min = min >> log_divisor;
-- div_type div_max = max >> log_divisor;
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[shift(*(current++), log_divisor) - div_min]++;
-- //The index of the first positive bin
-- div_type first_positive = (div_min < 0) ? -div_min : 0;
-- //Resetting if all bins are negative
-- if(cache_offset + first_positive > cache_end)
-- first_positive = cache_end - cache_offset;
-- //Reversing the order of the negative bins
-- //Note that because of the negative/positive ordering direction flip
-- //We can not depend upon bin order and positions matching up
-- //so bin_sizes must be reused to contain the end of the bin
-- if(first_positive > 0) {
-- bins[first_positive - 1] = first;
-- for(int ii = first_positive - 2; ii >= 0; --ii) {
-- bins[ii] = first + bin_sizes[ii + 1];
-- bin_sizes[ii] += bin_sizes[ii + 1];
-- }
-- //Handling positives following negatives
-- if((unsigned)first_positive < bin_count) {
-- bins[first_positive] = first + bin_sizes[0];
-- bin_sizes[first_positive] += bin_sizes[0];
-- }
-- }
-- else
-- bins[0] = first;
-- for(unsigned u = first_positive; u < bin_count - 1; u++) {
-- bins[u + 1] = first + bin_sizes[u];
-- bin_sizes[u + 1] += bin_sizes[u];
-- }
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- for(unsigned u = 0; u < bin_count; ++u) {
-- nextbinstart = first + bin_sizes[u];
-- inner_swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, u, shift, log_divisor, div_min);
-- }
--
-- //Return if we've completed bucketsorting
-- if(!log_divisor)
-- return;
--
-- //Handling negative values first
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(int ii = cache_offset + first_positive - 1; ii >= (int)cache_offset ; lastPos = bin_cache[ii--]) {
-- size_t count = bin_cache[ii] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[ii]);
-- //sort negative values using reversed-bin spread_sort
-- else
-- negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift);
-- }
--
-- for(unsigned u = cache_offset + first_positive; u < cache_end; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[u]);
-- //sort positive values using normal spread_sort
-- else
-- spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift);
-- }
-- }
--
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare>
-- inline void
-- float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-- , std::vector<size_t> &bin_sizes, right_shift shift, compare comp)
-- {
-- div_type max, min;
-- find_extremes(first, last, max, min, shift);
-- if(max == min)
-- return;
-- unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-- div_type div_min = min >> log_divisor;
-- div_type div_max = max >> log_divisor;
-- unsigned bin_count = div_max - div_min + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
--
-- //Calculating the size of each bin
-- for (RandomAccessIter current = first; current != last;)
-- bin_sizes[shift(*(current++), log_divisor) - div_min]++;
-- //The index of the first positive bin
-- div_type first_positive = (div_min < 0) ? -div_min : 0;
-- //Resetting if all bins are negative
-- if(cache_offset + first_positive > cache_end)
-- first_positive = cache_end - cache_offset;
-- //Reversing the order of the negative bins
-- //Note that because of the negative/positive ordering direction flip
-- //We can not depend upon bin order and positions matching up
-- //so bin_sizes must be reused to contain the end of the bin
-- if(first_positive > 0) {
-- bins[first_positive - 1] = first;
-- for(int ii = first_positive - 2; ii >= 0; --ii) {
-- bins[ii] = first + bin_sizes[ii + 1];
-- bin_sizes[ii] += bin_sizes[ii + 1];
-- }
-- //Handling positives following negatives
-- if((unsigned)first_positive < bin_count) {
-- bins[first_positive] = first + bin_sizes[0];
-- bin_sizes[first_positive] += bin_sizes[0];
-- }
-- }
-- else
-- bins[0] = first;
-- for(unsigned u = first_positive; u < bin_count - 1; u++) {
-- bins[u + 1] = first + bin_sizes[u];
-- bin_sizes[u + 1] += bin_sizes[u];
-- }
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- for(unsigned u = 0; u < bin_count; ++u) {
-- nextbinstart = first + bin_sizes[u];
-- inner_swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, u, shift, log_divisor, div_min);
-- }
--
-- //Return if we've completed bucketsorting
-- if(!log_divisor)
-- return;
--
-- //Handling negative values first
-- size_t max_count = get_max_count(log_divisor, last - first);
-- RandomAccessIter lastPos = first;
-- for(int ii = cache_offset + first_positive - 1; ii >= (int)cache_offset ; lastPos = bin_cache[ii--]) {
-- size_t count = bin_cache[ii] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[ii]);
-- //sort negative values using reversed-bin spread_sort
-- else
-- negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift, comp);
-- }
--
-- for(unsigned u = cache_offset + first_positive; u < cache_end; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- if(count < 2)
-- continue;
-- if(count < max_count)
-- std::sort(lastPos, bin_cache[u]);
-- //sort positive values using normal spread_sort
-- else
-- spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift, comp);
-- }
-- }
--
-- template <class RandomAccessIter, class cast_type, class data_type>
-- inline void
-- float_Sort(RandomAccessIter first, RandomAccessIter last, cast_type, data_type)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- float_sort_rec<RandomAccessIter, cast_type, data_type>(first, last, bin_cache, 0, bin_sizes);
-- }
--
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-- inline void
-- float_Sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(first, last, bin_cache, 0, bin_sizes, shift);
-- }
--
-- template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare>
-- inline void
-- float_Sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift, compare comp)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(first, last, bin_cache, 0, bin_sizes, shift, comp);
-- }
-- }
--
-- //float_sort with casting
-- //The cast_type must be equal in size to the data type, and must be a signed integer
-- template <class RandomAccessIter, class cast_type>
-- inline void float_sort_cast(RandomAccessIter first, RandomAccessIter last, cast_type cVal)
-- {
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last);
-- else
-- detail::float_Sort(first, last, cVal, *first);
-- }
--
-- //float_sort with casting to an int
-- //Only use this with IEEE floating-point numbers
-- template <class RandomAccessIter>
-- inline void float_sort_cast_to_int(RandomAccessIter first, RandomAccessIter last)
-- {
-- int cVal = 0;
-- float_sort_cast(first, last, cVal);
-- }
--
-- //float_sort with functors
-- template <class RandomAccessIter, class right_shift>
-- inline void float_sort(RandomAccessIter first, RandomAccessIter last, right_shift shift)
-- {
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last);
-- else
-- detail::float_Sort(first, last, shift(*first, 0), *first, shift);
-- }
--
-- template <class RandomAccessIter, class right_shift, class compare>
-- inline void float_sort(RandomAccessIter first, RandomAccessIter last, right_shift shift, compare comp)
-- {
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last, comp);
-- else
-- detail::float_Sort(first, last, shift(*first, 0), *first, shift, comp);
-- }
--
-- //------------------------------------------------- string_sort source ---------------------------------------------
-- namespace detail {
-- //Offsetting on identical characters. This function works a character at a time for optimal worst-case performance.
-- template<class RandomAccessIter>
-- inline void
-- update_offset(RandomAccessIter first, RandomAccessIter finish, unsigned &char_offset)
-- {
-- unsigned nextOffset = char_offset;
-- bool done = false;
-- while(!done) {
-- RandomAccessIter curr = first;
-- do {
-- //ignore empties, but if the nextOffset would exceed the length or not match, exit; we've found the last matching character
-- if((*curr).size() > char_offset && ((*curr).size() <= (nextOffset + 1) || (*curr)[nextOffset] != (*first)[nextOffset])) {
-- done = true;
-- break;
-- }
-- } while(++curr != finish);
-- if(!done)
-- ++nextOffset;
-- }
-- char_offset = nextOffset;
-- }
--
-- //Offsetting on identical characters. This function works a character at a time for optimal worst-case performance.
-- template<class RandomAccessIter, class get_char, class get_length>
-- inline void
-- update_offset(RandomAccessIter first, RandomAccessIter finish, unsigned &char_offset, get_char getchar, get_length length)
-- {
-- unsigned nextOffset = char_offset;
-- bool done = false;
-- while(!done) {
-- RandomAccessIter curr = first;
-- do {
-- //ignore empties, but if the nextOffset would exceed the length or not match, exit; we've found the last matching character
-- if(length(*curr) > char_offset && (length(*curr) <= (nextOffset + 1) || getchar((*curr), nextOffset) != getchar((*first), nextOffset))) {
-- done = true;
-- break;
-- }
-- } while(++curr != finish);
-- if(!done)
-- ++nextOffset;
-- }
-- char_offset = nextOffset;
-- }
--
-- //A comparison functor for strings that assumes they are identical up to char_offset
-- template<class data_type, class unsignedchar_type>
-- struct offset_lessthan {
-- offset_lessthan(unsigned char_offset) : fchar_offset(char_offset){}
-- inline bool operator()(const data_type &x, const data_type &y) const
-- {
-- unsigned minSize = std::min(x.size(), y.size());
-- for(unsigned u = fchar_offset; u < minSize; ++u) {
-- if(static_cast<unsignedchar_type>(x[u]) < static_cast<unsignedchar_type>(y[u]))
-- return true;
-- else if(static_cast<unsignedchar_type>(y[u]) < static_cast<unsignedchar_type>(x[u]))
-- return false;
-- }
-- return x.size() < y.size();
-- }
-- unsigned fchar_offset;
-- };
--
-- //A comparison functor for strings that assumes they are identical up to char_offset
-- template<class data_type, class unsignedchar_type>
-- struct offset_greaterthan {
-- offset_greaterthan(unsigned char_offset) : fchar_offset(char_offset){}
-- inline bool operator()(const data_type &x, const data_type &y) const
-- {
-- unsigned minSize = std::min(x.size(), y.size());
-- for(unsigned u = fchar_offset; u < minSize; ++u) {
-- if(static_cast<unsignedchar_type>(x[u]) > static_cast<unsignedchar_type>(y[u]))
-- return true;
-- else if(static_cast<unsignedchar_type>(y[u]) > static_cast<unsignedchar_type>(x[u]))
-- return false;
-- }
-- return x.size() > y.size();
-- }
-- unsigned fchar_offset;
-- };
--
-- //A comparison functor for strings that assumes they are identical up to char_offset
-- template<class data_type, class get_char, class get_length>
-- struct offset_char_lessthan {
-- offset_char_lessthan(unsigned char_offset) : fchar_offset(char_offset){}
-- inline bool operator()(const data_type &x, const data_type &y) const
-- {
-- unsigned minSize = std::min(length(x), length(y));
-- for(unsigned u = fchar_offset; u < minSize; ++u) {
-- if(getchar(x, u) < getchar(y, u))
-- return true;
-- else if(getchar(y, u) < getchar(x, u))
-- return false;
-- }
-- return length(x) < length(y);
-- }
-- unsigned fchar_offset;
-- get_char getchar;
-- get_length length;
-- };
--
-- //String sorting recursive implementation
-- template <class RandomAccessIter, class data_type, class unsignedchar_type>
-- inline void
-- string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache
-- , unsigned cache_offset, std::vector<size_t> &bin_sizes)
-- {
-- //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact.
-- //Iterate to the end of the empties. If all empty, return
-- while((*first).size() <= char_offset) {
-- if(++first == last)
-- return;
-- }
-- RandomAccessIter finish = last - 1;
-- //Getting the last non-empty
-- for(;(*finish).size() <= char_offset; --finish) { }
-- ++finish;
-- //Offsetting on identical characters. This section works a character at a time for optimal worst-case performance.
-- update_offset(first, finish, char_offset);
--
-- const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8));
-- //Equal worst-case between radix and comparison-based is when bin_count = n*log(n).
-- const unsigned max_size = bin_count;
-- const unsigned membin_count = bin_count + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count) + 1;
--
-- //Calculating the size of each bin; this takes roughly 10% of runtime
-- for (RandomAccessIter current = first; current != last; ++current) {
-- if((*current).size() <= char_offset) {
-- bin_sizes[0]++;
-- }
-- else
-- bin_sizes[static_cast<unsignedchar_type>((*current)[char_offset]) + 1]++;
-- }
-- //Assign the bin positions
-- bin_cache[cache_offset] = first;
-- for(unsigned u = 0; u < membin_count - 1; u++)
-- bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- //handling empty bins
-- RandomAccessIter * local_bin = &(bin_cache[cache_offset]);
-- nextbinstart += bin_sizes[0];
-- RandomAccessIter * target_bin;
-- //Iterating over each element in the bin of empties
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //empties belong in this bin
-- while((*current).size() > char_offset) {
-- target_bin = bins + static_cast<unsignedchar_type>((*current)[char_offset]);
-- iter_swap(current, (*target_bin)++);
-- }
-- }
-- *local_bin = nextbinstart;
-- //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops
-- unsigned last_bin = bin_count - 1;
-- for(; last_bin && !bin_sizes[last_bin + 1]; --last_bin) { }
-- //This dominates runtime, mostly in the swap and bin lookups
-- for(unsigned u = 0; u < last_bin; ++u) {
-- local_bin = bins + u;
-- nextbinstart += bin_sizes[u + 1];
-- //Iterating over each element in this bin
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //Swapping elements in current into place until the correct element has been swapped in
-- for(target_bin = bins + static_cast<unsignedchar_type>((*current)[char_offset]); target_bin != local_bin;
-- target_bin = bins + static_cast<unsignedchar_type>((*current)[char_offset]))
-- iter_swap(current, (*target_bin)++);
-- }
-- *local_bin = nextbinstart;
-- }
-- bins[last_bin] = last;
-- //Recursing
-- RandomAccessIter lastPos = bin_cache[cache_offset];
-- //Skip this loop for empties
-- for(unsigned u = cache_offset + 1; u < cache_offset + last_bin + 2; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- //don't sort unless there are at least two items to compare
-- if(count < 2)
-- continue;
-- //using std::sort if its worst-case is better
-- if(count < max_size)
-- std::sort(lastPos, bin_cache[u], offset_lessthan<data_type, unsignedchar_type>(char_offset + 1));
-- else
-- string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(lastPos, bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes);
-- }
-- }
--
-- //Sorts strings in reverse order, with empties at the end
-- template <class RandomAccessIter, class data_type, class unsignedchar_type>
-- inline void
-- reverse_string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache
-- , unsigned cache_offset, std::vector<size_t> &bin_sizes)
-- {
-- //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact.
-- RandomAccessIter curr = first;
-- //Iterate to the end of the empties. If all empty, return
-- while((*curr).size() <= char_offset) {
-- if(++curr == last)
-- return;
-- }
-- //Getting the last non-empty
-- while((*(--last)).size() <= char_offset) { }
-- ++last;
-- //Offsetting on identical characters. This section works a character at a time for optimal worst-case performance.
-- update_offset(curr, last, char_offset);
-- RandomAccessIter * target_bin;
--
-- const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8));
-- //Equal worst-case between radix and comparison-based is when bin_count = n*log(n).
-- const unsigned max_size = bin_count;
-- const unsigned membin_count = bin_count + 1;
-- const unsigned max_bin = bin_count - 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count);
-- RandomAccessIter * end_bin = &(bin_cache[cache_offset + max_bin]);
--
-- //Calculating the size of each bin; this takes roughly 10% of runtime
-- for (RandomAccessIter current = first; current != last; ++current) {
-- if((*current).size() <= char_offset) {
-- bin_sizes[bin_count]++;
-- }
-- else
-- bin_sizes[max_bin - static_cast<unsignedchar_type>((*current)[char_offset])]++;
-- }
-- //Assign the bin positions
-- bin_cache[cache_offset] = first;
-- for(unsigned u = 0; u < membin_count - 1; u++)
-- bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = last;
-- //handling empty bins
-- RandomAccessIter * local_bin = &(bin_cache[cache_offset + bin_count]);
-- RandomAccessIter lastFull = *local_bin;
-- //Iterating over each element in the bin of empties
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //empties belong in this bin
-- while((*current).size() > char_offset) {
-- target_bin = end_bin - static_cast<unsignedchar_type>((*current)[char_offset]);
-- iter_swap(current, (*target_bin)++);
-- }
-- }
-- *local_bin = nextbinstart;
-- nextbinstart = first;
-- //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops
-- unsigned last_bin = max_bin;
-- for(; last_bin && !bin_sizes[last_bin]; --last_bin) { }
-- //This dominates runtime, mostly in the swap and bin lookups
-- for(unsigned u = 0; u < last_bin; ++u) {
-- local_bin = bins + u;
-- nextbinstart += bin_sizes[u];
-- //Iterating over each element in this bin
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //Swapping elements in current into place until the correct element has been swapped in
-- for(target_bin = end_bin - static_cast<unsignedchar_type>((*current)[char_offset]); target_bin != local_bin;
-- target_bin = end_bin - static_cast<unsignedchar_type>((*current)[char_offset]))
-- iter_swap(current, (*target_bin)++);
-- }
-- *local_bin = nextbinstart;
-- }
-- bins[last_bin] = lastFull;
-- //Recursing
-- RandomAccessIter lastPos = first;
-- //Skip this loop for empties
-- for(unsigned u = cache_offset; u <= cache_offset + last_bin; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- //don't sort unless there are at least two items to compare
-- if(count < 2)
-- continue;
-- //using std::sort if its worst-case is better
-- if(count < max_size)
-- std::sort(lastPos, bin_cache[u], offset_greaterthan<data_type, unsignedchar_type>(char_offset + 1));
-- else
-- reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(lastPos, bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes);
-- }
-- }
--
-- //String sorting recursive implementation
-- template <class RandomAccessIter, class data_type, class unsignedchar_type, class get_char, class get_length>
-- inline void
-- string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache
-- , unsigned cache_offset, std::vector<size_t> &bin_sizes, get_char getchar, get_length length)
-- {
-- //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact.
-- //Iterate to the end of the empties. If all empty, return
-- while(length(*first) <= char_offset) {
-- if(++first == last)
-- return;
-- }
-- RandomAccessIter finish = last - 1;
-- //Getting the last non-empty
-- for(;length(*finish) <= char_offset; --finish) { }
-- ++finish;
-- update_offset(first, finish, char_offset, getchar, length);
--
-- const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8));
-- //Equal worst-case between radix and comparison-based is when bin_count = n*log(n).
-- const unsigned max_size = bin_count;
-- const unsigned membin_count = bin_count + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count) + 1;
--
-- //Calculating the size of each bin; this takes roughly 10% of runtime
-- for (RandomAccessIter current = first; current != last; ++current) {
-- if(length(*current) <= char_offset) {
-- bin_sizes[0]++;
-- }
-- else
-- bin_sizes[getchar((*current), char_offset) + 1]++;
-- }
-- //Assign the bin positions
-- bin_cache[cache_offset] = first;
-- for(unsigned u = 0; u < membin_count - 1; u++)
-- bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- //handling empty bins
-- RandomAccessIter * local_bin = &(bin_cache[cache_offset]);
-- nextbinstart += bin_sizes[0];
-- RandomAccessIter * target_bin;
-- //Iterating over each element in the bin of empties
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //empties belong in this bin
-- while(length(*current) > char_offset) {
-- target_bin = bins + getchar((*current), char_offset);
-- iter_swap(current, (*target_bin)++);
-- }
-- }
-- *local_bin = nextbinstart;
-- //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops
-- unsigned last_bin = bin_count - 1;
-- for(; last_bin && !bin_sizes[last_bin + 1]; --last_bin) { }
-- //This dominates runtime, mostly in the swap and bin lookups
-- for(unsigned ii = 0; ii < last_bin; ++ii) {
-- local_bin = bins + ii;
-- nextbinstart += bin_sizes[ii + 1];
-- //Iterating over each element in this bin
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //Swapping elements in current into place until the correct element has been swapped in
-- for(target_bin = bins + getchar((*current), char_offset); target_bin != local_bin;
-- target_bin = bins + getchar((*current), char_offset))
-- iter_swap(current, (*target_bin)++);
-- }
-- *local_bin = nextbinstart;
-- }
-- bins[last_bin] = last;
--
-- //Recursing
-- RandomAccessIter lastPos = bin_cache[cache_offset];
-- //Skip this loop for empties
-- for(unsigned u = cache_offset + 1; u < cache_offset + last_bin + 2; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- //don't sort unless there are at least two items to compare
-- if(count < 2)
-- continue;
-- //using std::sort if its worst-case is better
-- if(count < max_size)
-- std::sort(lastPos, bin_cache[u], offset_char_lessthan<data_type, get_char, get_length>(char_offset + 1));
-- else
-- string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length>(lastPos, bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes, getchar, length);
-- }
-- }
--
-- //String sorting recursive implementation
-- template <class RandomAccessIter, class data_type, class unsignedchar_type, class get_char, class get_length, class compare>
-- inline void
-- string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache
-- , unsigned cache_offset, std::vector<size_t> &bin_sizes, get_char getchar, get_length length, compare comp)
-- {
-- //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact.
-- //Iterate to the end of the empties. If all empty, return
-- while(length(*first) <= char_offset) {
-- if(++first == last)
-- return;
-- }
-- RandomAccessIter finish = last - 1;
-- //Getting the last non-empty
-- for(;length(*finish) <= char_offset; --finish) { }
-- ++finish;
-- update_offset(first, finish, char_offset, getchar, length);
--
-- const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8));
-- //Equal worst-case between radix and comparison-based is when bin_count = n*log(n).
-- const unsigned max_size = bin_count;
-- const unsigned membin_count = bin_count + 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count) + 1;
--
-- //Calculating the size of each bin; this takes roughly 10% of runtime
-- for (RandomAccessIter current = first; current != last; ++current) {
-- if(length(*current) <= char_offset) {
-- bin_sizes[0]++;
-- }
-- else
-- bin_sizes[getchar((*current), char_offset) + 1]++;
-- }
-- //Assign the bin positions
-- bin_cache[cache_offset] = first;
-- for(unsigned u = 0; u < membin_count - 1; u++)
-- bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = first;
-- //handling empty bins
-- RandomAccessIter * local_bin = &(bin_cache[cache_offset]);
-- nextbinstart += bin_sizes[0];
-- RandomAccessIter * target_bin;
-- //Iterating over each element in the bin of empties
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //empties belong in this bin
-- while(length(*current) > char_offset) {
-- target_bin = bins + getchar((*current), char_offset);
-- iter_swap(current, (*target_bin)++);
-- }
-- }
-- *local_bin = nextbinstart;
-- //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops
-- unsigned last_bin = bin_count - 1;
-- for(; last_bin && !bin_sizes[last_bin + 1]; --last_bin) { }
-- //This dominates runtime, mostly in the swap and bin lookups
-- for(unsigned u = 0; u < last_bin; ++u) {
-- local_bin = bins + u;
-- nextbinstart += bin_sizes[u + 1];
-- //Iterating over each element in this bin
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //Swapping elements in current into place until the correct element has been swapped in
-- for(target_bin = bins + getchar((*current), char_offset); target_bin != local_bin;
-- target_bin = bins + getchar((*current), char_offset))
-- iter_swap(current, (*target_bin)++);
-- }
-- *local_bin = nextbinstart;
-- }
-- bins[last_bin] = last;
--
-- //Recursing
-- RandomAccessIter lastPos = bin_cache[cache_offset];
-- //Skip this loop for empties
-- for(unsigned u = cache_offset + 1; u < cache_offset + last_bin + 2; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- //don't sort unless there are at least two items to compare
-- if(count < 2)
-- continue;
-- //using std::sort if its worst-case is better
-- if(count < max_size)
-- std::sort(lastPos, bin_cache[u], comp);
-- else
-- string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(lastPos
-- , bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes, getchar, length, comp);
-- }
-- }
--
-- //Sorts strings in reverse order, with empties at the end
-- template <class RandomAccessIter, class data_type, class unsignedchar_type, class get_char, class get_length, class compare>
-- inline void
-- reverse_string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache
-- , unsigned cache_offset, std::vector<size_t> &bin_sizes, get_char getchar, get_length length, compare comp)
-- {
-- //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact.
-- RandomAccessIter curr = first;
-- //Iterate to the end of the empties. If all empty, return
-- while(length(*curr) <= char_offset) {
-- if(++curr == last)
-- return;
-- }
-- //Getting the last non-empty
-- while(length(*(--last)) <= char_offset) { }
-- ++last;
-- //Offsetting on identical characters. This section works a character at a time for optimal worst-case performance.
-- update_offset(first, last, char_offset, getchar, length);
--
-- const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8));
-- //Equal worst-case between radix and comparison-based is when bin_count = n*log(n).
-- const unsigned max_size = bin_count;
-- const unsigned membin_count = bin_count + 1;
-- const unsigned max_bin = bin_count - 1;
-- unsigned cache_end;
-- RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count);
-- RandomAccessIter *end_bin = &(bin_cache[cache_offset + max_bin]);
--
-- //Calculating the size of each bin; this takes roughly 10% of runtime
-- for (RandomAccessIter current = first; current != last; ++current) {
-- if(length(*current) <= char_offset) {
-- bin_sizes[bin_count]++;
-- }
-- else
-- bin_sizes[max_bin - getchar((*current), char_offset)]++;
-- }
-- //Assign the bin positions
-- bin_cache[cache_offset] = first;
-- for(unsigned u = 0; u < membin_count - 1; u++)
-- bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u];
--
-- //Swap into place
-- RandomAccessIter nextbinstart = last;
-- //handling empty bins
-- RandomAccessIter * local_bin = &(bin_cache[cache_offset + bin_count]);
-- RandomAccessIter lastFull = *local_bin;
-- RandomAccessIter * target_bin;
-- //Iterating over each element in the bin of empties
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //empties belong in this bin
-- while(length(*current) > char_offset) {
-- target_bin = end_bin - getchar((*current), char_offset);
-- iter_swap(current, (*target_bin)++);
-- }
-- }
-- *local_bin = nextbinstart;
-- nextbinstart = first;
-- //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops
-- unsigned last_bin = max_bin;
-- for(; last_bin && !bin_sizes[last_bin]; --last_bin) { }
-- //This dominates runtime, mostly in the swap and bin lookups
-- for(unsigned u = 0; u < last_bin; ++u) {
-- local_bin = bins + u;
-- nextbinstart += bin_sizes[u];
-- //Iterating over each element in this bin
-- for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-- //Swapping elements in current into place until the correct element has been swapped in
-- for(target_bin = end_bin - getchar((*current), char_offset); target_bin != local_bin;
-- target_bin = end_bin - getchar((*current), char_offset))
-- iter_swap(current, (*target_bin)++);
-- }
-- *local_bin = nextbinstart;
-- }
-- bins[last_bin] = lastFull;
-- //Recursing
-- RandomAccessIter lastPos = first;
-- //Skip this loop for empties
-- for(unsigned u = cache_offset; u <= cache_offset + last_bin; lastPos = bin_cache[u], ++u) {
-- size_t count = bin_cache[u] - lastPos;
-- //don't sort unless there are at least two items to compare
-- if(count < 2)
-- continue;
-- //using std::sort if its worst-case is better
-- if(count < max_size)
-- std::sort(lastPos, bin_cache[u], comp);
-- else
-- reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(lastPos
-- , bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes, getchar, length, comp);
-- }
-- }
--
-- //Holds the bin vector and makes the initial recursive call
-- template <class RandomAccessIter, class data_type, class unsignedchar_type>
-- inline void
-- string_sort(RandomAccessIter first, RandomAccessIter last, data_type, unsignedchar_type)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(first, last, 0, bin_cache, 0, bin_sizes);
-- }
--
-- //Holds the bin vector and makes the initial recursive call
-- template <class RandomAccessIter, class data_type, class unsignedchar_type>
-- inline void
-- reverse_string_sort(RandomAccessIter first, RandomAccessIter last, data_type, unsignedchar_type)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(first, last, 0, bin_cache, 0, bin_sizes);
-- }
--
-- //Holds the bin vector and makes the initial recursive call
-- template <class RandomAccessIter, class get_char, class get_length, class data_type, class unsignedchar_type>
-- inline void
-- string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, data_type, unsignedchar_type)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length>(first, last, 0, bin_cache, 0, bin_sizes, getchar, length);
-- }
--
-- //Holds the bin vector and makes the initial recursive call
-- template <class RandomAccessIter, class get_char, class get_length, class compare, class data_type, class unsignedchar_type>
-- inline void
-- string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp, data_type, unsignedchar_type)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(first, last, 0, bin_cache, 0, bin_sizes, getchar, length, comp);
-- }
--
-- //Holds the bin vector and makes the initial recursive call
-- template <class RandomAccessIter, class get_char, class get_length, class compare, class data_type, class unsignedchar_type>
-- inline void
-- reverse_string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp, data_type, unsignedchar_type)
-- {
-- std::vector<size_t> bin_sizes;
-- std::vector<RandomAccessIter> bin_cache;
-- reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(first, last, 0, bin_cache, 0, bin_sizes, getchar, length, comp);
-- }
-- }
--
-- //Allows character-type overloads
-- template <class RandomAccessIter, class unsignedchar_type>
-- inline void string_sort(RandomAccessIter first, RandomAccessIter last, unsignedchar_type unused)
-- {
-- //Don't sort if it's too small to optimize
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last);
-- else
-- detail::string_sort(first, last, *first, unused);
-- }
--
-- //Top-level sorting call; wraps using default of unsigned char
-- template <class RandomAccessIter>
-- inline void string_sort(RandomAccessIter first, RandomAccessIter last)
-- {
-- unsigned char unused = '\0';
-- string_sort(first, last, unused);
-- }
--
-- //Allows character-type overloads
-- template <class RandomAccessIter, class compare, class unsignedchar_type>
-- inline void reverse_string_sort(RandomAccessIter first, RandomAccessIter last, compare comp, unsignedchar_type unused)
-- {
-- //Don't sort if it's too small to optimize
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last, comp);
-- else
-- detail::reverse_string_sort(first, last, *first, unused);
-- }
--
-- //Top-level sorting call; wraps using default of unsigned char
-- template <class RandomAccessIter, class compare>
-- inline void reverse_string_sort(RandomAccessIter first, RandomAccessIter last, compare comp)
-- {
-- unsigned char unused = '\0';
-- reverse_string_sort(first, last, comp, unused);
-- }
--
-- template <class RandomAccessIter, class get_char, class get_length>
-- inline void string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length)
-- {
-- //Don't sort if it's too small to optimize
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last);
-- else {
-- //skipping past empties at the beginning, which allows us to get the character type
-- //.empty() is not used so as not to require a user declaration of it
-- while(!length(*first)) {
-- if(++first == last)
-- return;
-- }
-- detail::string_sort(first, last, getchar, length, *first, getchar((*first), 0));
-- }
-- }
--
-- template <class RandomAccessIter, class get_char, class get_length, class compare>
-- inline void string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp)
-- {
-- //Don't sort if it's too small to optimize
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last, comp);
-- else {
-- //skipping past empties at the beginning, which allows us to get the character type
-- //.empty() is not used so as not to require a user declaration of it
-- while(!length(*first)) {
-- if(++first == last)
-- return;
-- }
-- detail::string_sort(first, last, getchar, length, comp, *first, getchar((*first), 0));
-- }
-- }
--
-- template <class RandomAccessIter, class get_char, class get_length, class compare>
-- inline void reverse_string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp)
-- {
-- //Don't sort if it's too small to optimize
-- if(last - first < detail::MIN_SORT_SIZE)
-- std::sort(first, last, comp);
-- else {
-- //skipping past empties at the beginning, which allows us to get the character type
-- //.empty() is not used so as not to require a user declaration of it
-- while(!length(*(--last))) {
-- //Note: if there is just one non-empty, and it's at the beginning, then it's already in sorted order
-- if(first == last)
-- return;
-- }
-- //making last just after the end of the non-empty part of the array
-- ++last;
-- detail::reverse_string_sort(first, last, getchar, length, comp, *first, getchar((*first), 0));
-- }
-- }
--}
--
--#endif
-+//Templated spread_sort library
-+
-+// Copyright Steven J. Ross 2001 - 2009.
-+// Distributed under the Boost Software License, Version 1.0.
-+// (See accompanying file LICENSE_1_0.txt or copy at
-+// http://www.boost.org/LICENSE_1_0.txt)
-+
-+// See http://www.boost.org/ for updates, documentation, and revision history.
-+
-+/*
-+Some improvements suggested by:
-+Phil Endecott and Frank Gennari
-+Cygwin fix provided by:
-+Scott McMurray
-+*/
-+
-+#ifndef BOOST_SPREAD_SORT_H
-+#define BOOST_SPREAD_SORT_H
-+#include <algorithm>
-+#include <cstring>
-+#include <vector>
-+#include "webrtc/system_wrappers/source/spreadsortlib/constants.hpp"
-+
-+#ifdef __FreeBSD__
-+# include <osreldate.h>
-+# if __FreeBSD_version < 900506
-+# define getchar boost_getchar
-+# endif
-+#endif
-+
-+namespace boost {
-+ namespace detail {
-+ //This only works on unsigned data types
-+ template <typename T>
-+ inline unsigned
-+ rough_log_2_size(const T& input)
-+ {
-+ unsigned result = 0;
-+ //The && is necessary on some compilers to avoid infinite loops; it doesn't significantly impair performance
-+ while((input >> result) && (result < (8*sizeof(T)))) ++result;
-+ return result;
-+ }
-+
-+ //Gets the maximum size which we'll call spread_sort on to control worst-case performance
-+ //Maintains both a minimum size to recurse and a check of distribution size versus count
-+ //This is called for a set of bins, instead of bin-by-bin, to avoid performance overhead
-+ inline size_t
-+ get_max_count(unsigned log_range, size_t count)
-+ {
-+ unsigned divisor = rough_log_2_size(count);
-+ //Making sure the divisor is positive
-+ if(divisor > LOG_MEAN_BIN_SIZE)
-+ divisor -= LOG_MEAN_BIN_SIZE;
-+ else
-+ divisor = 1;
-+ unsigned relative_width = (LOG_CONST * log_range)/((divisor > MAX_SPLITS) ? MAX_SPLITS : divisor);
-+ //Don't try to bitshift more than the size of an element
-+ if((8*sizeof(size_t)) <= relative_width)
-+ relative_width = (8*sizeof(size_t)) - 1;
-+ return (size_t)1 << ((relative_width < (LOG_MEAN_BIN_SIZE + LOG_MIN_SPLIT_COUNT)) ?
-+ (LOG_MEAN_BIN_SIZE + LOG_MIN_SPLIT_COUNT) : relative_width);
-+ }
-+
-+ //Find the minimum and maximum using <
-+ template <class RandomAccessIter>
-+ inline void
-+ find_extremes(RandomAccessIter current, RandomAccessIter last, RandomAccessIter & max, RandomAccessIter & min)
-+ {
-+ min = max = current;
-+ //Start from the second item, as max and min are initialized to the first
-+ while(++current < last) {
-+ if(*max < *current)
-+ max = current;
-+ else if(*current < *min)
-+ min = current;
-+ }
-+ }
-+
-+ //Uses a user-defined comparison operator to find minimum and maximum
-+ template <class RandomAccessIter, class compare>
-+ inline void
-+ find_extremes(RandomAccessIter current, RandomAccessIter last, RandomAccessIter & max, RandomAccessIter & min, compare comp)
-+ {
-+ min = max = current;
-+ while(++current < last) {
-+ if(comp(*max, *current))
-+ max = current;
-+ else if(comp(*current, *min))
-+ min = current;
-+ }
-+ }
-+
-+ //Gets a non-negative right bit shift to operate as a logarithmic divisor
-+ inline int
-+ get_log_divisor(size_t count, unsigned log_range)
-+ {
-+ int log_divisor;
-+ //If we can finish in one iteration without exceeding either (2 to the MAX_SPLITS) or n bins, do so
-+ if((log_divisor = log_range - rough_log_2_size(count)) <= 0 && log_range < MAX_SPLITS)
-+ log_divisor = 0;
-+ else {
-+ //otherwise divide the data into an optimized number of pieces
-+ log_divisor += LOG_MEAN_BIN_SIZE;
-+ if(log_divisor < 0)
-+ log_divisor = 0;
-+ //Cannot exceed MAX_SPLITS or cache misses slow down bin lookups dramatically
-+ if((log_range - log_divisor) > MAX_SPLITS)
-+ log_divisor = log_range - MAX_SPLITS;
-+ }
-+ return log_divisor;
-+ }
-+
-+ template <class RandomAccessIter>
-+ inline RandomAccessIter *
-+ size_bins(std::vector<size_t> &bin_sizes, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset, unsigned &cache_end, unsigned bin_count)
-+ {
-+ //Assure space for the size of each bin, followed by initializing sizes
-+ if(bin_count > bin_sizes.size())
-+ bin_sizes.resize(bin_count);
-+ for(size_t u = 0; u < bin_count; u++)
-+ bin_sizes[u] = 0;
-+ //Make sure there is space for the bins
-+ cache_end = cache_offset + bin_count;
-+ if(cache_end > bin_cache.size())
-+ bin_cache.resize(cache_end);
-+ return &(bin_cache[cache_offset]);
-+ }
-+
-+ //Implementation for recursive integer sorting
-+ template <class RandomAccessIter, class div_type, class data_type>
-+ inline void
-+ spread_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-+ , std::vector<size_t> &bin_sizes)
-+ {
-+ //This step is roughly 10% of runtime, but it helps avoid worst-case behavior and improve behavior with real data
-+ //If you know the maximum and minimum ahead of time, you can pass those values in and skip this step for the first iteration
-+ RandomAccessIter max, min;
-+ find_extremes(first, last, max, min);
-+ //max and min will be the same (the first item) iff all values are equivalent
-+ if(max == min)
-+ return;
-+ RandomAccessIter * target_bin;
-+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(*max >> 0) - (*min >> 0)));
-+ div_type div_min = *min >> log_divisor;
-+ div_type div_max = *max >> log_divisor;
-+ unsigned bin_count = div_max - div_min + 1;
-+ unsigned cache_end;
-+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
-+
-+ //Calculating the size of each bin; this takes roughly 10% of runtime
-+ for (RandomAccessIter current = first; current != last;)
-+ bin_sizes[(*(current++) >> log_divisor) - div_min]++;
-+ //Assign the bin positions
-+ bins[0] = first;
-+ for(unsigned u = 0; u < bin_count - 1; u++)
-+ bins[u + 1] = bins[u] + bin_sizes[u];
-+
-+ //Swap into place
-+ //This dominates runtime, mostly in the swap and bin lookups
-+ RandomAccessIter nextbinstart = first;
-+ for(unsigned u = 0; u < bin_count - 1; ++u) {
-+ RandomAccessIter * local_bin = bins + u;
-+ nextbinstart += bin_sizes[u];
-+ //Iterating over each element in this bin
-+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-+ //Swapping elements in current into place until the correct element has been swapped in
-+ for(target_bin = (bins + ((*current >> log_divisor) - div_min)); target_bin != local_bin;
-+ target_bin = bins + ((*current >> log_divisor) - div_min)) {
-+ //3-way swap; this is about 1% faster than a 2-way swap with integers
-+ //The main advantage is less copies are involved per item put in the correct place
-+ data_type tmp;
-+ RandomAccessIter b = (*target_bin)++;
-+ RandomAccessIter * b_bin = bins + ((*b >> log_divisor) - div_min);
-+ if (b_bin != local_bin) {
-+ RandomAccessIter c = (*b_bin)++;
-+ tmp = *c;
-+ *c = *b;
-+ }
-+ else
-+ tmp = *b;
-+ *b = *current;
-+ *current = tmp;
-+ }
-+ }
-+ *local_bin = nextbinstart;
-+ }
-+ bins[bin_count - 1] = last;
-+
-+ //If we've bucketsorted, the array is sorted and we should skip recursion
-+ if(!log_divisor)
-+ return;
-+
-+ //Recursing; log_divisor is the remaining range
-+ size_t max_count = get_max_count(log_divisor, last - first);
-+ RandomAccessIter lastPos = first;
-+ for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) {
-+ size_t count = bin_cache[u] - lastPos;
-+ //don't sort unless there are at least two items to compare
-+ if(count < 2)
-+ continue;
-+ //using std::sort if its worst-case is better
-+ if(count < max_count)
-+ std::sort(lastPos, bin_cache[u]);
-+ else
-+ spread_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes);
-+ }
-+ }
-+
-+ //Generic bitshift-based 3-way swapping code
-+ template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-+ inline void inner_swap_loop(RandomAccessIter * bins, const RandomAccessIter & nextbinstart, unsigned ii, right_shift &shift
-+ , const unsigned log_divisor, const div_type div_min)
-+ {
-+ RandomAccessIter * local_bin = bins + ii;
-+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-+ for(RandomAccessIter * target_bin = (bins + (shift(*current, log_divisor) - div_min)); target_bin != local_bin;
-+ target_bin = bins + (shift(*current, log_divisor) - div_min)) {
-+ data_type tmp;
-+ RandomAccessIter b = (*target_bin)++;
-+ RandomAccessIter * b_bin = bins + (shift(*b, log_divisor) - div_min);
-+ //Three-way swap; if the item to be swapped doesn't belong in the current bin, swap it to where it belongs
-+ if (b_bin != local_bin) {
-+ RandomAccessIter c = (*b_bin)++;
-+ tmp = *c;
-+ *c = *b;
-+ }
-+ //Note: we could increment current once the swap is done in this case, but that seems to impair performance
-+ else
-+ tmp = *b;
-+ *b = *current;
-+ *current = tmp;
-+ }
-+ }
-+ *local_bin = nextbinstart;
-+ }
-+
-+ //Standard swapping wrapper for ascending values
-+ template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-+ inline void swap_loop(RandomAccessIter * bins, RandomAccessIter & nextbinstart, unsigned ii, right_shift &shift
-+ , const std::vector<size_t> &bin_sizes, const unsigned log_divisor, const div_type div_min)
-+ {
-+ nextbinstart += bin_sizes[ii];
-+ inner_swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, log_divisor, div_min);
-+ }
-+
-+ //Functor implementation for recursive sorting
-+ template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare>
-+ inline void
-+ spread_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-+ , std::vector<size_t> &bin_sizes, right_shift shift, compare comp)
-+ {
-+ RandomAccessIter max, min;
-+ find_extremes(first, last, max, min, comp);
-+ if(max == min)
-+ return;
-+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(shift(*max, 0)) - (shift(*min, 0))));
-+ div_type div_min = shift(*min, log_divisor);
-+ div_type div_max = shift(*max, log_divisor);
-+ unsigned bin_count = div_max - div_min + 1;
-+ unsigned cache_end;
-+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
-+
-+ //Calculating the size of each bin
-+ for (RandomAccessIter current = first; current != last;)
-+ bin_sizes[shift(*(current++), log_divisor) - div_min]++;
-+ bins[0] = first;
-+ for(unsigned u = 0; u < bin_count - 1; u++)
-+ bins[u + 1] = bins[u] + bin_sizes[u];
-+
-+ //Swap into place
-+ RandomAccessIter nextbinstart = first;
-+ for(unsigned u = 0; u < bin_count - 1; ++u)
-+ swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, u, shift, bin_sizes, log_divisor, div_min);
-+ bins[bin_count - 1] = last;
-+
-+ //If we've bucketsorted, the array is sorted and we should skip recursion
-+ if(!log_divisor)
-+ return;
-+
-+ //Recursing
-+ size_t max_count = get_max_count(log_divisor, last - first);
-+ RandomAccessIter lastPos = first;
-+ for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) {
-+ size_t count = bin_cache[u] - lastPos;
-+ if(count < 2)
-+ continue;
-+ if(count < max_count)
-+ std::sort(lastPos, bin_cache[u], comp);
-+ else
-+ spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift, compare>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift, comp);
-+ }
-+ }
-+
-+ //Functor implementation for recursive sorting with only Shift overridden
-+ template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-+ inline void
-+ spread_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-+ , std::vector<size_t> &bin_sizes, right_shift shift)
-+ {
-+ RandomAccessIter max, min;
-+ find_extremes(first, last, max, min);
-+ if(max == min)
-+ return;
-+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(shift(*max, 0)) - (shift(*min, 0))));
-+ div_type div_min = shift(*min, log_divisor);
-+ div_type div_max = shift(*max, log_divisor);
-+ unsigned bin_count = div_max - div_min + 1;
-+ unsigned cache_end;
-+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
-+
-+ //Calculating the size of each bin
-+ for (RandomAccessIter current = first; current != last;)
-+ bin_sizes[shift(*(current++), log_divisor) - div_min]++;
-+ bins[0] = first;
-+ for(unsigned u = 0; u < bin_count - 1; u++)
-+ bins[u + 1] = bins[u] + bin_sizes[u];
-+
-+ //Swap into place
-+ RandomAccessIter nextbinstart = first;
-+ for(unsigned ii = 0; ii < bin_count - 1; ++ii)
-+ swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, bin_sizes, log_divisor, div_min);
-+ bins[bin_count - 1] = last;
-+
-+ //If we've bucketsorted, the array is sorted and we should skip recursion
-+ if(!log_divisor)
-+ return;
-+
-+ //Recursing
-+ size_t max_count = get_max_count(log_divisor, last - first);
-+ RandomAccessIter lastPos = first;
-+ for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) {
-+ size_t count = bin_cache[u] - lastPos;
-+ if(count < 2)
-+ continue;
-+ if(count < max_count)
-+ std::sort(lastPos, bin_cache[u]);
-+ else
-+ spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift);
-+ }
-+ }
-+
-+ //Holds the bin vector and makes the initial recursive call
-+ template <class RandomAccessIter, class div_type, class data_type>
-+ inline void
-+ spread_sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type)
-+ {
-+ std::vector<size_t> bin_sizes;
-+ std::vector<RandomAccessIter> bin_cache;
-+ spread_sort_rec<RandomAccessIter, div_type, data_type>(first, last, bin_cache, 0, bin_sizes);
-+ }
-+
-+ template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare>
-+ inline void
-+ spread_sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift, compare comp)
-+ {
-+ std::vector<size_t> bin_sizes;
-+ std::vector<RandomAccessIter> bin_cache;
-+ spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift, compare>(first, last, bin_cache, 0, bin_sizes, shift, comp);
-+ }
-+
-+ template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-+ inline void
-+ spread_sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift)
-+ {
-+ std::vector<size_t> bin_sizes;
-+ std::vector<RandomAccessIter> bin_cache;
-+ spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(first, last, bin_cache, 0, bin_sizes, shift);
-+ }
-+ }
-+
-+ //Top-level sorting call for integers
-+ template <class RandomAccessIter>
-+ inline void integer_sort(RandomAccessIter first, RandomAccessIter last)
-+ {
-+ //Don't sort if it's too small to optimize
-+ if(last - first < detail::MIN_SORT_SIZE)
-+ std::sort(first, last);
-+ else
-+ detail::spread_sort(first, last, *first >> 0, *first);
-+ }
-+
-+ //integer_sort with functors
-+ template <class RandomAccessIter, class right_shift, class compare>
-+ inline void integer_sort(RandomAccessIter first, RandomAccessIter last,
-+ right_shift shift, compare comp) {
-+ if(last - first < detail::MIN_SORT_SIZE)
-+ std::sort(first, last, comp);
-+ else
-+ detail::spread_sort(first, last, shift(*first, 0), *first, shift, comp);
-+ }
-+
-+ //integer_sort with right_shift functor
-+ template <class RandomAccessIter, class right_shift>
-+ inline void integer_sort(RandomAccessIter first, RandomAccessIter last,
-+ right_shift shift) {
-+ if(last - first < detail::MIN_SORT_SIZE)
-+ std::sort(first, last);
-+ else
-+ detail::spread_sort(first, last, shift(*first, 0), *first, shift);
-+ }
-+
-+ //------------------------------------------------------ float_sort source --------------------------------------
-+ //Casts a RandomAccessIter to the specified data type
-+ template<class cast_type, class RandomAccessIter>
-+ inline cast_type
-+ cast_float_iter(const RandomAccessIter & floatiter)
-+ {
-+ cast_type result;
-+ std::memcpy(&result, &(*floatiter), sizeof(cast_type));
-+ return result;
-+ }
-+
-+ //Casts a data element to the specified datinner_float_a type
-+ template<class data_type, class cast_type>
-+ inline cast_type
-+ mem_cast(const data_type & data)
-+ {
-+ cast_type result;
-+ std::memcpy(&result, &data, sizeof(cast_type));
-+ return result;
-+ }
-+
-+ namespace detail {
-+ template <class RandomAccessIter, class div_type, class right_shift>
-+ inline void
-+ find_extremes(RandomAccessIter current, RandomAccessIter last, div_type & max, div_type & min, right_shift shift)
-+ {
-+ min = max = shift(*current, 0);
-+ while(++current < last) {
-+ div_type value = shift(*current, 0);
-+ if(max < value)
-+ max = value;
-+ else if(value < min)
-+ min = value;
-+ }
-+ }
-+
-+ //Specialized swap loops for floating-point casting
-+ template <class RandomAccessIter, class div_type, class data_type>
-+ inline void inner_float_swap_loop(RandomAccessIter * bins, const RandomAccessIter & nextbinstart, unsigned ii
-+ , const unsigned log_divisor, const div_type div_min)
-+ {
-+ RandomAccessIter * local_bin = bins + ii;
-+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-+ for(RandomAccessIter * target_bin = (bins + ((cast_float_iter<div_type, RandomAccessIter>(current) >> log_divisor) - div_min)); target_bin != local_bin;
-+ target_bin = bins + ((cast_float_iter<div_type, RandomAccessIter>(current) >> log_divisor) - div_min)) {
-+ data_type tmp;
-+ RandomAccessIter b = (*target_bin)++;
-+ RandomAccessIter * b_bin = bins + ((cast_float_iter<div_type, RandomAccessIter>(b) >> log_divisor) - div_min);
-+ //Three-way swap; if the item to be swapped doesn't belong in the current bin, swap it to where it belongs
-+ if (b_bin != local_bin) {
-+ RandomAccessIter c = (*b_bin)++;
-+ tmp = *c;
-+ *c = *b;
-+ }
-+ else
-+ tmp = *b;
-+ *b = *current;
-+ *current = tmp;
-+ }
-+ }
-+ *local_bin = nextbinstart;
-+ }
-+
-+ template <class RandomAccessIter, class div_type, class data_type>
-+ inline void float_swap_loop(RandomAccessIter * bins, RandomAccessIter & nextbinstart, unsigned ii
-+ , const std::vector<size_t> &bin_sizes, const unsigned log_divisor, const div_type div_min)
-+ {
-+ nextbinstart += bin_sizes[ii];
-+ inner_float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, ii, log_divisor, div_min);
-+ }
-+
-+ template <class RandomAccessIter, class cast_type>
-+ inline void
-+ find_extremes(RandomAccessIter current, RandomAccessIter last, cast_type & max, cast_type & min)
-+ {
-+ min = max = cast_float_iter<cast_type, RandomAccessIter>(current);
-+ while(++current < last) {
-+ cast_type value = cast_float_iter<cast_type, RandomAccessIter>(current);
-+ if(max < value)
-+ max = value;
-+ else if(value < min)
-+ min = value;
-+ }
-+ }
-+
-+ //Special-case sorting of positive floats with casting instead of a right_shift
-+ template <class RandomAccessIter, class div_type, class data_type>
-+ inline void
-+ positive_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-+ , std::vector<size_t> &bin_sizes)
-+ {
-+ div_type max, min;
-+ find_extremes(first, last, max, min);
-+ if(max == min)
-+ return;
-+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-+ div_type div_min = min >> log_divisor;
-+ div_type div_max = max >> log_divisor;
-+ unsigned bin_count = div_max - div_min + 1;
-+ unsigned cache_end;
-+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
-+
-+ //Calculating the size of each bin
-+ for (RandomAccessIter current = first; current != last;)
-+ bin_sizes[(cast_float_iter<div_type, RandomAccessIter>(current++) >> log_divisor) - div_min]++;
-+ bins[0] = first;
-+ for(unsigned u = 0; u < bin_count - 1; u++)
-+ bins[u + 1] = bins[u] + bin_sizes[u];
-+
-+ //Swap into place
-+ RandomAccessIter nextbinstart = first;
-+ for(unsigned u = 0; u < bin_count - 1; ++u)
-+ float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, u, bin_sizes, log_divisor, div_min);
-+ bins[bin_count - 1] = last;
-+
-+ //Return if we've completed bucketsorting
-+ if(!log_divisor)
-+ return;
-+
-+ //Recursing
-+ size_t max_count = get_max_count(log_divisor, last - first);
-+ RandomAccessIter lastPos = first;
-+ for(unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) {
-+ size_t count = bin_cache[u] - lastPos;
-+ if(count < 2)
-+ continue;
-+ if(count < max_count)
-+ std::sort(lastPos, bin_cache[u]);
-+ else
-+ positive_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes);
-+ }
-+ }
-+
-+ //Sorting negative_ float_s
-+ //Note that bins are iterated in reverse order because max_neg_float = min_neg_int
-+ template <class RandomAccessIter, class div_type, class data_type>
-+ inline void
-+ negative_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-+ , std::vector<size_t> &bin_sizes)
-+ {
-+ div_type max, min;
-+ find_extremes(first, last, max, min);
-+ if(max == min)
-+ return;
-+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-+ div_type div_min = min >> log_divisor;
-+ div_type div_max = max >> log_divisor;
-+ unsigned bin_count = div_max - div_min + 1;
-+ unsigned cache_end;
-+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
-+
-+ //Calculating the size of each bin
-+ for (RandomAccessIter current = first; current != last;)
-+ bin_sizes[(cast_float_iter<div_type, RandomAccessIter>(current++) >> log_divisor) - div_min]++;
-+ bins[bin_count - 1] = first;
-+ for(int ii = bin_count - 2; ii >= 0; --ii)
-+ bins[ii] = bins[ii + 1] + bin_sizes[ii + 1];
-+
-+ //Swap into place
-+ RandomAccessIter nextbinstart = first;
-+ //The last bin will always have the correct elements in it
-+ for(int ii = bin_count - 1; ii > 0; --ii)
-+ float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, ii, bin_sizes, log_divisor, div_min);
-+ //Since we don't process the last bin, we need to update its end position
-+ bin_cache[cache_offset] = last;
-+
-+ //Return if we've completed bucketsorting
-+ if(!log_divisor)
-+ return;
-+
-+ //Recursing
-+ size_t max_count = get_max_count(log_divisor, last - first);
-+ RandomAccessIter lastPos = first;
-+ for(int ii = cache_end - 1; ii >= (int)cache_offset; lastPos = bin_cache[ii], --ii) {
-+ size_t count = bin_cache[ii] - lastPos;
-+ if(count < 2)
-+ continue;
-+ if(count < max_count)
-+ std::sort(lastPos, bin_cache[ii]);
-+ else
-+ negative_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes);
-+ }
-+ }
-+
-+ //Sorting negative_ float_s
-+ //Note that bins are iterated in reverse order because max_neg_float = min_neg_int
-+ template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-+ inline void
-+ negative_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-+ , std::vector<size_t> &bin_sizes, right_shift shift)
-+ {
-+ div_type max, min;
-+ find_extremes(first, last, max, min, shift);
-+ if(max == min)
-+ return;
-+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-+ div_type div_min = min >> log_divisor;
-+ div_type div_max = max >> log_divisor;
-+ unsigned bin_count = div_max - div_min + 1;
-+ unsigned cache_end;
-+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
-+
-+ //Calculating the size of each bin
-+ for (RandomAccessIter current = first; current != last;)
-+ bin_sizes[shift(*(current++), log_divisor) - div_min]++;
-+ bins[bin_count - 1] = first;
-+ for(int ii = bin_count - 2; ii >= 0; --ii)
-+ bins[ii] = bins[ii + 1] + bin_sizes[ii + 1];
-+
-+ //Swap into place
-+ RandomAccessIter nextbinstart = first;
-+ //The last bin will always have the correct elements in it
-+ for(int ii = bin_count - 1; ii > 0; --ii)
-+ swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, bin_sizes, log_divisor, div_min);
-+ //Since we don't process the last bin, we need to update its end position
-+ bin_cache[cache_offset] = last;
-+
-+ //Return if we've completed bucketsorting
-+ if(!log_divisor)
-+ return;
-+
-+ //Recursing
-+ size_t max_count = get_max_count(log_divisor, last - first);
-+ RandomAccessIter lastPos = first;
-+ for(int ii = cache_end - 1; ii >= (int)cache_offset; lastPos = bin_cache[ii], --ii) {
-+ size_t count = bin_cache[ii] - lastPos;
-+ if(count < 2)
-+ continue;
-+ if(count < max_count)
-+ std::sort(lastPos, bin_cache[ii]);
-+ else
-+ negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift);
-+ }
-+ }
-+
-+ template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare>
-+ inline void
-+ negative_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-+ , std::vector<size_t> &bin_sizes, right_shift shift, compare comp)
-+ {
-+ div_type max, min;
-+ find_extremes(first, last, max, min, shift);
-+ if(max == min)
-+ return;
-+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-+ div_type div_min = min >> log_divisor;
-+ div_type div_max = max >> log_divisor;
-+ unsigned bin_count = div_max - div_min + 1;
-+ unsigned cache_end;
-+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
-+
-+ //Calculating the size of each bin
-+ for (RandomAccessIter current = first; current != last;)
-+ bin_sizes[shift(*(current++), log_divisor) - div_min]++;
-+ bins[bin_count - 1] = first;
-+ for(int ii = bin_count - 2; ii >= 0; --ii)
-+ bins[ii] = bins[ii + 1] + bin_sizes[ii + 1];
-+
-+ //Swap into place
-+ RandomAccessIter nextbinstart = first;
-+ //The last bin will always have the correct elements in it
-+ for(int ii = bin_count - 1; ii > 0; --ii)
-+ swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, ii, shift, bin_sizes, log_divisor, div_min);
-+ //Since we don't process the last bin, we need to update its end position
-+ bin_cache[cache_offset] = last;
-+
-+ //Return if we've completed bucketsorting
-+ if(!log_divisor)
-+ return;
-+
-+ //Recursing
-+ size_t max_count = get_max_count(log_divisor, last - first);
-+ RandomAccessIter lastPos = first;
-+ for(int ii = cache_end - 1; ii >= (int)cache_offset; lastPos = bin_cache[ii], --ii) {
-+ size_t count = bin_cache[ii] - lastPos;
-+ if(count < 2)
-+ continue;
-+ if(count < max_count)
-+ std::sort(lastPos, bin_cache[ii], comp);
-+ else
-+ negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift, compare>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift, comp);
-+ }
-+ }
-+
-+ //Casting special-case for floating-point sorting
-+ template <class RandomAccessIter, class div_type, class data_type>
-+ inline void
-+ float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-+ , std::vector<size_t> &bin_sizes)
-+ {
-+ div_type max, min;
-+ find_extremes(first, last, max, min);
-+ if(max == min)
-+ return;
-+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-+ div_type div_min = min >> log_divisor;
-+ div_type div_max = max >> log_divisor;
-+ unsigned bin_count = div_max - div_min + 1;
-+ unsigned cache_end;
-+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
-+
-+ //Calculating the size of each bin
-+ for (RandomAccessIter current = first; current != last;)
-+ bin_sizes[(cast_float_iter<div_type, RandomAccessIter>(current++) >> log_divisor) - div_min]++;
-+ //The index of the first positive bin
-+ div_type first_positive = (div_min < 0) ? -div_min : 0;
-+ //Resetting if all bins are negative
-+ if(cache_offset + first_positive > cache_end)
-+ first_positive = cache_end - cache_offset;
-+ //Reversing the order of the negative bins
-+ //Note that because of the negative/positive ordering direction flip
-+ //We can not depend upon bin order and positions matching up
-+ //so bin_sizes must be reused to contain the end of the bin
-+ if(first_positive > 0) {
-+ bins[first_positive - 1] = first;
-+ for(int ii = first_positive - 2; ii >= 0; --ii) {
-+ bins[ii] = first + bin_sizes[ii + 1];
-+ bin_sizes[ii] += bin_sizes[ii + 1];
-+ }
-+ //Handling positives following negatives
-+ if((unsigned)first_positive < bin_count) {
-+ bins[first_positive] = first + bin_sizes[0];
-+ bin_sizes[first_positive] += bin_sizes[0];
-+ }
-+ }
-+ else
-+ bins[0] = first;
-+ for(unsigned u = first_positive; u < bin_count - 1; u++) {
-+ bins[u + 1] = first + bin_sizes[u];
-+ bin_sizes[u + 1] += bin_sizes[u];
-+ }
-+
-+ //Swap into place
-+ RandomAccessIter nextbinstart = first;
-+ for(unsigned u = 0; u < bin_count; ++u) {
-+ nextbinstart = first + bin_sizes[u];
-+ inner_float_swap_loop<RandomAccessIter, div_type, data_type>(bins, nextbinstart, u, log_divisor, div_min);
-+ }
-+
-+ if(!log_divisor)
-+ return;
-+
-+ //Handling negative values first
-+ size_t max_count = get_max_count(log_divisor, last - first);
-+ RandomAccessIter lastPos = first;
-+ for(int ii = cache_offset + first_positive - 1; ii >= (int)cache_offset ; lastPos = bin_cache[ii--]) {
-+ size_t count = bin_cache[ii] - lastPos;
-+ if(count < 2)
-+ continue;
-+ if(count < max_count)
-+ std::sort(lastPos, bin_cache[ii]);
-+ //sort negative values using reversed-bin spread_sort
-+ else
-+ negative_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes);
-+ }
-+
-+ for(unsigned u = cache_offset + first_positive; u < cache_end; lastPos = bin_cache[u], ++u) {
-+ size_t count = bin_cache[u] - lastPos;
-+ if(count < 2)
-+ continue;
-+ if(count < max_count)
-+ std::sort(lastPos, bin_cache[u]);
-+ //sort positive values using normal spread_sort
-+ else
-+ positive_float_sort_rec<RandomAccessIter, div_type, data_type>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes);
-+ }
-+ }
-+
-+ //Functor implementation for recursive sorting
-+ template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-+ inline void
-+ float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-+ , std::vector<size_t> &bin_sizes, right_shift shift)
-+ {
-+ div_type max, min;
-+ find_extremes(first, last, max, min, shift);
-+ if(max == min)
-+ return;
-+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-+ div_type div_min = min >> log_divisor;
-+ div_type div_max = max >> log_divisor;
-+ unsigned bin_count = div_max - div_min + 1;
-+ unsigned cache_end;
-+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
-+
-+ //Calculating the size of each bin
-+ for (RandomAccessIter current = first; current != last;)
-+ bin_sizes[shift(*(current++), log_divisor) - div_min]++;
-+ //The index of the first positive bin
-+ div_type first_positive = (div_min < 0) ? -div_min : 0;
-+ //Resetting if all bins are negative
-+ if(cache_offset + first_positive > cache_end)
-+ first_positive = cache_end - cache_offset;
-+ //Reversing the order of the negative bins
-+ //Note that because of the negative/positive ordering direction flip
-+ //We can not depend upon bin order and positions matching up
-+ //so bin_sizes must be reused to contain the end of the bin
-+ if(first_positive > 0) {
-+ bins[first_positive - 1] = first;
-+ for(int ii = first_positive - 2; ii >= 0; --ii) {
-+ bins[ii] = first + bin_sizes[ii + 1];
-+ bin_sizes[ii] += bin_sizes[ii + 1];
-+ }
-+ //Handling positives following negatives
-+ if((unsigned)first_positive < bin_count) {
-+ bins[first_positive] = first + bin_sizes[0];
-+ bin_sizes[first_positive] += bin_sizes[0];
-+ }
-+ }
-+ else
-+ bins[0] = first;
-+ for(unsigned u = first_positive; u < bin_count - 1; u++) {
-+ bins[u + 1] = first + bin_sizes[u];
-+ bin_sizes[u + 1] += bin_sizes[u];
-+ }
-+
-+ //Swap into place
-+ RandomAccessIter nextbinstart = first;
-+ for(unsigned u = 0; u < bin_count; ++u) {
-+ nextbinstart = first + bin_sizes[u];
-+ inner_swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, u, shift, log_divisor, div_min);
-+ }
-+
-+ //Return if we've completed bucketsorting
-+ if(!log_divisor)
-+ return;
-+
-+ //Handling negative values first
-+ size_t max_count = get_max_count(log_divisor, last - first);
-+ RandomAccessIter lastPos = first;
-+ for(int ii = cache_offset + first_positive - 1; ii >= (int)cache_offset ; lastPos = bin_cache[ii--]) {
-+ size_t count = bin_cache[ii] - lastPos;
-+ if(count < 2)
-+ continue;
-+ if(count < max_count)
-+ std::sort(lastPos, bin_cache[ii]);
-+ //sort negative values using reversed-bin spread_sort
-+ else
-+ negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift);
-+ }
-+
-+ for(unsigned u = cache_offset + first_positive; u < cache_end; lastPos = bin_cache[u], ++u) {
-+ size_t count = bin_cache[u] - lastPos;
-+ if(count < 2)
-+ continue;
-+ if(count < max_count)
-+ std::sort(lastPos, bin_cache[u]);
-+ //sort positive values using normal spread_sort
-+ else
-+ spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift);
-+ }
-+ }
-+
-+ template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare>
-+ inline void
-+ float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset
-+ , std::vector<size_t> &bin_sizes, right_shift shift, compare comp)
-+ {
-+ div_type max, min;
-+ find_extremes(first, last, max, min, shift);
-+ if(max == min)
-+ return;
-+ unsigned log_divisor = get_log_divisor(last - first, rough_log_2_size((size_t)(max) - min));
-+ div_type div_min = min >> log_divisor;
-+ div_type div_max = max >> log_divisor;
-+ unsigned bin_count = div_max - div_min + 1;
-+ unsigned cache_end;
-+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count);
-+
-+ //Calculating the size of each bin
-+ for (RandomAccessIter current = first; current != last;)
-+ bin_sizes[shift(*(current++), log_divisor) - div_min]++;
-+ //The index of the first positive bin
-+ div_type first_positive = (div_min < 0) ? -div_min : 0;
-+ //Resetting if all bins are negative
-+ if(cache_offset + first_positive > cache_end)
-+ first_positive = cache_end - cache_offset;
-+ //Reversing the order of the negative bins
-+ //Note that because of the negative/positive ordering direction flip
-+ //We can not depend upon bin order and positions matching up
-+ //so bin_sizes must be reused to contain the end of the bin
-+ if(first_positive > 0) {
-+ bins[first_positive - 1] = first;
-+ for(int ii = first_positive - 2; ii >= 0; --ii) {
-+ bins[ii] = first + bin_sizes[ii + 1];
-+ bin_sizes[ii] += bin_sizes[ii + 1];
-+ }
-+ //Handling positives following negatives
-+ if((unsigned)first_positive < bin_count) {
-+ bins[first_positive] = first + bin_sizes[0];
-+ bin_sizes[first_positive] += bin_sizes[0];
-+ }
-+ }
-+ else
-+ bins[0] = first;
-+ for(unsigned u = first_positive; u < bin_count - 1; u++) {
-+ bins[u + 1] = first + bin_sizes[u];
-+ bin_sizes[u + 1] += bin_sizes[u];
-+ }
-+
-+ //Swap into place
-+ RandomAccessIter nextbinstart = first;
-+ for(unsigned u = 0; u < bin_count; ++u) {
-+ nextbinstart = first + bin_sizes[u];
-+ inner_swap_loop<RandomAccessIter, div_type, data_type, right_shift>(bins, nextbinstart, u, shift, log_divisor, div_min);
-+ }
-+
-+ //Return if we've completed bucketsorting
-+ if(!log_divisor)
-+ return;
-+
-+ //Handling negative values first
-+ size_t max_count = get_max_count(log_divisor, last - first);
-+ RandomAccessIter lastPos = first;
-+ for(int ii = cache_offset + first_positive - 1; ii >= (int)cache_offset ; lastPos = bin_cache[ii--]) {
-+ size_t count = bin_cache[ii] - lastPos;
-+ if(count < 2)
-+ continue;
-+ if(count < max_count)
-+ std::sort(lastPos, bin_cache[ii]);
-+ //sort negative values using reversed-bin spread_sort
-+ else
-+ negative_float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, shift, comp);
-+ }
-+
-+ for(unsigned u = cache_offset + first_positive; u < cache_end; lastPos = bin_cache[u], ++u) {
-+ size_t count = bin_cache[u] - lastPos;
-+ if(count < 2)
-+ continue;
-+ if(count < max_count)
-+ std::sort(lastPos, bin_cache[u]);
-+ //sort positive values using normal spread_sort
-+ else
-+ spread_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, shift, comp);
-+ }
-+ }
-+
-+ template <class RandomAccessIter, class cast_type, class data_type>
-+ inline void
-+ float_Sort(RandomAccessIter first, RandomAccessIter last, cast_type, data_type)
-+ {
-+ std::vector<size_t> bin_sizes;
-+ std::vector<RandomAccessIter> bin_cache;
-+ float_sort_rec<RandomAccessIter, cast_type, data_type>(first, last, bin_cache, 0, bin_sizes);
-+ }
-+
-+ template <class RandomAccessIter, class div_type, class data_type, class right_shift>
-+ inline void
-+ float_Sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift)
-+ {
-+ std::vector<size_t> bin_sizes;
-+ std::vector<RandomAccessIter> bin_cache;
-+ float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(first, last, bin_cache, 0, bin_sizes, shift);
-+ }
-+
-+ template <class RandomAccessIter, class div_type, class data_type, class right_shift, class compare>
-+ inline void
-+ float_Sort(RandomAccessIter first, RandomAccessIter last, div_type, data_type, right_shift shift, compare comp)
-+ {
-+ std::vector<size_t> bin_sizes;
-+ std::vector<RandomAccessIter> bin_cache;
-+ float_sort_rec<RandomAccessIter, div_type, data_type, right_shift>(first, last, bin_cache, 0, bin_sizes, shift, comp);
-+ }
-+ }
-+
-+ //float_sort with casting
-+ //The cast_type must be equal in size to the data type, and must be a signed integer
-+ template <class RandomAccessIter, class cast_type>
-+ inline void float_sort_cast(RandomAccessIter first, RandomAccessIter last, cast_type cVal)
-+ {
-+ if(last - first < detail::MIN_SORT_SIZE)
-+ std::sort(first, last);
-+ else
-+ detail::float_Sort(first, last, cVal, *first);
-+ }
-+
-+ //float_sort with casting to an int
-+ //Only use this with IEEE floating-point numbers
-+ template <class RandomAccessIter>
-+ inline void float_sort_cast_to_int(RandomAccessIter first, RandomAccessIter last)
-+ {
-+ int cVal = 0;
-+ float_sort_cast(first, last, cVal);
-+ }
-+
-+ //float_sort with functors
-+ template <class RandomAccessIter, class right_shift>
-+ inline void float_sort(RandomAccessIter first, RandomAccessIter last, right_shift shift)
-+ {
-+ if(last - first < detail::MIN_SORT_SIZE)
-+ std::sort(first, last);
-+ else
-+ detail::float_Sort(first, last, shift(*first, 0), *first, shift);
-+ }
-+
-+ template <class RandomAccessIter, class right_shift, class compare>
-+ inline void float_sort(RandomAccessIter first, RandomAccessIter last, right_shift shift, compare comp)
-+ {
-+ if(last - first < detail::MIN_SORT_SIZE)
-+ std::sort(first, last, comp);
-+ else
-+ detail::float_Sort(first, last, shift(*first, 0), *first, shift, comp);
-+ }
-+
-+ //------------------------------------------------- string_sort source ---------------------------------------------
-+ namespace detail {
-+ //Offsetting on identical characters. This function works a character at a time for optimal worst-case performance.
-+ template<class RandomAccessIter>
-+ inline void
-+ update_offset(RandomAccessIter first, RandomAccessIter finish, unsigned &char_offset)
-+ {
-+ unsigned nextOffset = char_offset;
-+ bool done = false;
-+ while(!done) {
-+ RandomAccessIter curr = first;
-+ do {
-+ //ignore empties, but if the nextOffset would exceed the length or not match, exit; we've found the last matching character
-+ if((*curr).size() > char_offset && ((*curr).size() <= (nextOffset + 1) || (*curr)[nextOffset] != (*first)[nextOffset])) {
-+ done = true;
-+ break;
-+ }
-+ } while(++curr != finish);
-+ if(!done)
-+ ++nextOffset;
-+ }
-+ char_offset = nextOffset;
-+ }
-+
-+ //Offsetting on identical characters. This function works a character at a time for optimal worst-case performance.
-+ template<class RandomAccessIter, class get_char, class get_length>
-+ inline void
-+ update_offset(RandomAccessIter first, RandomAccessIter finish, unsigned &char_offset, get_char getchar, get_length length)
-+ {
-+ unsigned nextOffset = char_offset;
-+ bool done = false;
-+ while(!done) {
-+ RandomAccessIter curr = first;
-+ do {
-+ //ignore empties, but if the nextOffset would exceed the length or not match, exit; we've found the last matching character
-+ if(length(*curr) > char_offset && (length(*curr) <= (nextOffset + 1) || getchar((*curr), nextOffset) != getchar((*first), nextOffset))) {
-+ done = true;
-+ break;
-+ }
-+ } while(++curr != finish);
-+ if(!done)
-+ ++nextOffset;
-+ }
-+ char_offset = nextOffset;
-+ }
-+
-+ //A comparison functor for strings that assumes they are identical up to char_offset
-+ template<class data_type, class unsignedchar_type>
-+ struct offset_lessthan {
-+ offset_lessthan(unsigned char_offset) : fchar_offset(char_offset){}
-+ inline bool operator()(const data_type &x, const data_type &y) const
-+ {
-+ unsigned minSize = std::min(x.size(), y.size());
-+ for(unsigned u = fchar_offset; u < minSize; ++u) {
-+ if(static_cast<unsignedchar_type>(x[u]) < static_cast<unsignedchar_type>(y[u]))
-+ return true;
-+ else if(static_cast<unsignedchar_type>(y[u]) < static_cast<unsignedchar_type>(x[u]))
-+ return false;
-+ }
-+ return x.size() < y.size();
-+ }
-+ unsigned fchar_offset;
-+ };
-+
-+ //A comparison functor for strings that assumes they are identical up to char_offset
-+ template<class data_type, class unsignedchar_type>
-+ struct offset_greaterthan {
-+ offset_greaterthan(unsigned char_offset) : fchar_offset(char_offset){}
-+ inline bool operator()(const data_type &x, const data_type &y) const
-+ {
-+ unsigned minSize = std::min(x.size(), y.size());
-+ for(unsigned u = fchar_offset; u < minSize; ++u) {
-+ if(static_cast<unsignedchar_type>(x[u]) > static_cast<unsignedchar_type>(y[u]))
-+ return true;
-+ else if(static_cast<unsignedchar_type>(y[u]) > static_cast<unsignedchar_type>(x[u]))
-+ return false;
-+ }
-+ return x.size() > y.size();
-+ }
-+ unsigned fchar_offset;
-+ };
-+
-+ //A comparison functor for strings that assumes they are identical up to char_offset
-+ template<class data_type, class get_char, class get_length>
-+ struct offset_char_lessthan {
-+ offset_char_lessthan(unsigned char_offset) : fchar_offset(char_offset){}
-+ inline bool operator()(const data_type &x, const data_type &y) const
-+ {
-+ unsigned minSize = std::min(length(x), length(y));
-+ for(unsigned u = fchar_offset; u < minSize; ++u) {
-+ if(getchar(x, u) < getchar(y, u))
-+ return true;
-+ else if(getchar(y, u) < getchar(x, u))
-+ return false;
-+ }
-+ return length(x) < length(y);
-+ }
-+ unsigned fchar_offset;
-+ get_char getchar;
-+ get_length length;
-+ };
-+
-+ //String sorting recursive implementation
-+ template <class RandomAccessIter, class data_type, class unsignedchar_type>
-+ inline void
-+ string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache
-+ , unsigned cache_offset, std::vector<size_t> &bin_sizes)
-+ {
-+ //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact.
-+ //Iterate to the end of the empties. If all empty, return
-+ while((*first).size() <= char_offset) {
-+ if(++first == last)
-+ return;
-+ }
-+ RandomAccessIter finish = last - 1;
-+ //Getting the last non-empty
-+ for(;(*finish).size() <= char_offset; --finish) { }
-+ ++finish;
-+ //Offsetting on identical characters. This section works a character at a time for optimal worst-case performance.
-+ update_offset(first, finish, char_offset);
-+
-+ const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8));
-+ //Equal worst-case between radix and comparison-based is when bin_count = n*log(n).
-+ const unsigned max_size = bin_count;
-+ const unsigned membin_count = bin_count + 1;
-+ unsigned cache_end;
-+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count) + 1;
-+
-+ //Calculating the size of each bin; this takes roughly 10% of runtime
-+ for (RandomAccessIter current = first; current != last; ++current) {
-+ if((*current).size() <= char_offset) {
-+ bin_sizes[0]++;
-+ }
-+ else
-+ bin_sizes[static_cast<unsignedchar_type>((*current)[char_offset]) + 1]++;
-+ }
-+ //Assign the bin positions
-+ bin_cache[cache_offset] = first;
-+ for(unsigned u = 0; u < membin_count - 1; u++)
-+ bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u];
-+
-+ //Swap into place
-+ RandomAccessIter nextbinstart = first;
-+ //handling empty bins
-+ RandomAccessIter * local_bin = &(bin_cache[cache_offset]);
-+ nextbinstart += bin_sizes[0];
-+ RandomAccessIter * target_bin;
-+ //Iterating over each element in the bin of empties
-+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-+ //empties belong in this bin
-+ while((*current).size() > char_offset) {
-+ target_bin = bins + static_cast<unsignedchar_type>((*current)[char_offset]);
-+ iter_swap(current, (*target_bin)++);
-+ }
-+ }
-+ *local_bin = nextbinstart;
-+ //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops
-+ unsigned last_bin = bin_count - 1;
-+ for(; last_bin && !bin_sizes[last_bin + 1]; --last_bin) { }
-+ //This dominates runtime, mostly in the swap and bin lookups
-+ for(unsigned u = 0; u < last_bin; ++u) {
-+ local_bin = bins + u;
-+ nextbinstart += bin_sizes[u + 1];
-+ //Iterating over each element in this bin
-+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-+ //Swapping elements in current into place until the correct element has been swapped in
-+ for(target_bin = bins + static_cast<unsignedchar_type>((*current)[char_offset]); target_bin != local_bin;
-+ target_bin = bins + static_cast<unsignedchar_type>((*current)[char_offset]))
-+ iter_swap(current, (*target_bin)++);
-+ }
-+ *local_bin = nextbinstart;
-+ }
-+ bins[last_bin] = last;
-+ //Recursing
-+ RandomAccessIter lastPos = bin_cache[cache_offset];
-+ //Skip this loop for empties
-+ for(unsigned u = cache_offset + 1; u < cache_offset + last_bin + 2; lastPos = bin_cache[u], ++u) {
-+ size_t count = bin_cache[u] - lastPos;
-+ //don't sort unless there are at least two items to compare
-+ if(count < 2)
-+ continue;
-+ //using std::sort if its worst-case is better
-+ if(count < max_size)
-+ std::sort(lastPos, bin_cache[u], offset_lessthan<data_type, unsignedchar_type>(char_offset + 1));
-+ else
-+ string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(lastPos, bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes);
-+ }
-+ }
-+
-+ //Sorts strings in reverse order, with empties at the end
-+ template <class RandomAccessIter, class data_type, class unsignedchar_type>
-+ inline void
-+ reverse_string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache
-+ , unsigned cache_offset, std::vector<size_t> &bin_sizes)
-+ {
-+ //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact.
-+ RandomAccessIter curr = first;
-+ //Iterate to the end of the empties. If all empty, return
-+ while((*curr).size() <= char_offset) {
-+ if(++curr == last)
-+ return;
-+ }
-+ //Getting the last non-empty
-+ while((*(--last)).size() <= char_offset) { }
-+ ++last;
-+ //Offsetting on identical characters. This section works a character at a time for optimal worst-case performance.
-+ update_offset(curr, last, char_offset);
-+ RandomAccessIter * target_bin;
-+
-+ const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8));
-+ //Equal worst-case between radix and comparison-based is when bin_count = n*log(n).
-+ const unsigned max_size = bin_count;
-+ const unsigned membin_count = bin_count + 1;
-+ const unsigned max_bin = bin_count - 1;
-+ unsigned cache_end;
-+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count);
-+ RandomAccessIter * end_bin = &(bin_cache[cache_offset + max_bin]);
-+
-+ //Calculating the size of each bin; this takes roughly 10% of runtime
-+ for (RandomAccessIter current = first; current != last; ++current) {
-+ if((*current).size() <= char_offset) {
-+ bin_sizes[bin_count]++;
-+ }
-+ else
-+ bin_sizes[max_bin - static_cast<unsignedchar_type>((*current)[char_offset])]++;
-+ }
-+ //Assign the bin positions
-+ bin_cache[cache_offset] = first;
-+ for(unsigned u = 0; u < membin_count - 1; u++)
-+ bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u];
-+
-+ //Swap into place
-+ RandomAccessIter nextbinstart = last;
-+ //handling empty bins
-+ RandomAccessIter * local_bin = &(bin_cache[cache_offset + bin_count]);
-+ RandomAccessIter lastFull = *local_bin;
-+ //Iterating over each element in the bin of empties
-+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-+ //empties belong in this bin
-+ while((*current).size() > char_offset) {
-+ target_bin = end_bin - static_cast<unsignedchar_type>((*current)[char_offset]);
-+ iter_swap(current, (*target_bin)++);
-+ }
-+ }
-+ *local_bin = nextbinstart;
-+ nextbinstart = first;
-+ //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops
-+ unsigned last_bin = max_bin;
-+ for(; last_bin && !bin_sizes[last_bin]; --last_bin) { }
-+ //This dominates runtime, mostly in the swap and bin lookups
-+ for(unsigned u = 0; u < last_bin; ++u) {
-+ local_bin = bins + u;
-+ nextbinstart += bin_sizes[u];
-+ //Iterating over each element in this bin
-+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-+ //Swapping elements in current into place until the correct element has been swapped in
-+ for(target_bin = end_bin - static_cast<unsignedchar_type>((*current)[char_offset]); target_bin != local_bin;
-+ target_bin = end_bin - static_cast<unsignedchar_type>((*current)[char_offset]))
-+ iter_swap(current, (*target_bin)++);
-+ }
-+ *local_bin = nextbinstart;
-+ }
-+ bins[last_bin] = lastFull;
-+ //Recursing
-+ RandomAccessIter lastPos = first;
-+ //Skip this loop for empties
-+ for(unsigned u = cache_offset; u <= cache_offset + last_bin; lastPos = bin_cache[u], ++u) {
-+ size_t count = bin_cache[u] - lastPos;
-+ //don't sort unless there are at least two items to compare
-+ if(count < 2)
-+ continue;
-+ //using std::sort if its worst-case is better
-+ if(count < max_size)
-+ std::sort(lastPos, bin_cache[u], offset_greaterthan<data_type, unsignedchar_type>(char_offset + 1));
-+ else
-+ reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(lastPos, bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes);
-+ }
-+ }
-+
-+ //String sorting recursive implementation
-+ template <class RandomAccessIter, class data_type, class unsignedchar_type, class get_char, class get_length>
-+ inline void
-+ string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache
-+ , unsigned cache_offset, std::vector<size_t> &bin_sizes, get_char getchar, get_length length)
-+ {
-+ //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact.
-+ //Iterate to the end of the empties. If all empty, return
-+ while(length(*first) <= char_offset) {
-+ if(++first == last)
-+ return;
-+ }
-+ RandomAccessIter finish = last - 1;
-+ //Getting the last non-empty
-+ for(;length(*finish) <= char_offset; --finish) { }
-+ ++finish;
-+ update_offset(first, finish, char_offset, getchar, length);
-+
-+ const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8));
-+ //Equal worst-case between radix and comparison-based is when bin_count = n*log(n).
-+ const unsigned max_size = bin_count;
-+ const unsigned membin_count = bin_count + 1;
-+ unsigned cache_end;
-+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count) + 1;
-+
-+ //Calculating the size of each bin; this takes roughly 10% of runtime
-+ for (RandomAccessIter current = first; current != last; ++current) {
-+ if(length(*current) <= char_offset) {
-+ bin_sizes[0]++;
-+ }
-+ else
-+ bin_sizes[getchar((*current), char_offset) + 1]++;
-+ }
-+ //Assign the bin positions
-+ bin_cache[cache_offset] = first;
-+ for(unsigned u = 0; u < membin_count - 1; u++)
-+ bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u];
-+
-+ //Swap into place
-+ RandomAccessIter nextbinstart = first;
-+ //handling empty bins
-+ RandomAccessIter * local_bin = &(bin_cache[cache_offset]);
-+ nextbinstart += bin_sizes[0];
-+ RandomAccessIter * target_bin;
-+ //Iterating over each element in the bin of empties
-+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-+ //empties belong in this bin
-+ while(length(*current) > char_offset) {
-+ target_bin = bins + getchar((*current), char_offset);
-+ iter_swap(current, (*target_bin)++);
-+ }
-+ }
-+ *local_bin = nextbinstart;
-+ //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops
-+ unsigned last_bin = bin_count - 1;
-+ for(; last_bin && !bin_sizes[last_bin + 1]; --last_bin) { }
-+ //This dominates runtime, mostly in the swap and bin lookups
-+ for(unsigned ii = 0; ii < last_bin; ++ii) {
-+ local_bin = bins + ii;
-+ nextbinstart += bin_sizes[ii + 1];
-+ //Iterating over each element in this bin
-+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-+ //Swapping elements in current into place until the correct element has been swapped in
-+ for(target_bin = bins + getchar((*current), char_offset); target_bin != local_bin;
-+ target_bin = bins + getchar((*current), char_offset))
-+ iter_swap(current, (*target_bin)++);
-+ }
-+ *local_bin = nextbinstart;
-+ }
-+ bins[last_bin] = last;
-+
-+ //Recursing
-+ RandomAccessIter lastPos = bin_cache[cache_offset];
-+ //Skip this loop for empties
-+ for(unsigned u = cache_offset + 1; u < cache_offset + last_bin + 2; lastPos = bin_cache[u], ++u) {
-+ size_t count = bin_cache[u] - lastPos;
-+ //don't sort unless there are at least two items to compare
-+ if(count < 2)
-+ continue;
-+ //using std::sort if its worst-case is better
-+ if(count < max_size)
-+ std::sort(lastPos, bin_cache[u], offset_char_lessthan<data_type, get_char, get_length>(char_offset + 1));
-+ else
-+ string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length>(lastPos, bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes, getchar, length);
-+ }
-+ }
-+
-+ //String sorting recursive implementation
-+ template <class RandomAccessIter, class data_type, class unsignedchar_type, class get_char, class get_length, class compare>
-+ inline void
-+ string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache
-+ , unsigned cache_offset, std::vector<size_t> &bin_sizes, get_char getchar, get_length length, compare comp)
-+ {
-+ //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact.
-+ //Iterate to the end of the empties. If all empty, return
-+ while(length(*first) <= char_offset) {
-+ if(++first == last)
-+ return;
-+ }
-+ RandomAccessIter finish = last - 1;
-+ //Getting the last non-empty
-+ for(;length(*finish) <= char_offset; --finish) { }
-+ ++finish;
-+ update_offset(first, finish, char_offset, getchar, length);
-+
-+ const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8));
-+ //Equal worst-case between radix and comparison-based is when bin_count = n*log(n).
-+ const unsigned max_size = bin_count;
-+ const unsigned membin_count = bin_count + 1;
-+ unsigned cache_end;
-+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count) + 1;
-+
-+ //Calculating the size of each bin; this takes roughly 10% of runtime
-+ for (RandomAccessIter current = first; current != last; ++current) {
-+ if(length(*current) <= char_offset) {
-+ bin_sizes[0]++;
-+ }
-+ else
-+ bin_sizes[getchar((*current), char_offset) + 1]++;
-+ }
-+ //Assign the bin positions
-+ bin_cache[cache_offset] = first;
-+ for(unsigned u = 0; u < membin_count - 1; u++)
-+ bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u];
-+
-+ //Swap into place
-+ RandomAccessIter nextbinstart = first;
-+ //handling empty bins
-+ RandomAccessIter * local_bin = &(bin_cache[cache_offset]);
-+ nextbinstart += bin_sizes[0];
-+ RandomAccessIter * target_bin;
-+ //Iterating over each element in the bin of empties
-+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-+ //empties belong in this bin
-+ while(length(*current) > char_offset) {
-+ target_bin = bins + getchar((*current), char_offset);
-+ iter_swap(current, (*target_bin)++);
-+ }
-+ }
-+ *local_bin = nextbinstart;
-+ //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops
-+ unsigned last_bin = bin_count - 1;
-+ for(; last_bin && !bin_sizes[last_bin + 1]; --last_bin) { }
-+ //This dominates runtime, mostly in the swap and bin lookups
-+ for(unsigned u = 0; u < last_bin; ++u) {
-+ local_bin = bins + u;
-+ nextbinstart += bin_sizes[u + 1];
-+ //Iterating over each element in this bin
-+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-+ //Swapping elements in current into place until the correct element has been swapped in
-+ for(target_bin = bins + getchar((*current), char_offset); target_bin != local_bin;
-+ target_bin = bins + getchar((*current), char_offset))
-+ iter_swap(current, (*target_bin)++);
-+ }
-+ *local_bin = nextbinstart;
-+ }
-+ bins[last_bin] = last;
-+
-+ //Recursing
-+ RandomAccessIter lastPos = bin_cache[cache_offset];
-+ //Skip this loop for empties
-+ for(unsigned u = cache_offset + 1; u < cache_offset + last_bin + 2; lastPos = bin_cache[u], ++u) {
-+ size_t count = bin_cache[u] - lastPos;
-+ //don't sort unless there are at least two items to compare
-+ if(count < 2)
-+ continue;
-+ //using std::sort if its worst-case is better
-+ if(count < max_size)
-+ std::sort(lastPos, bin_cache[u], comp);
-+ else
-+ string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(lastPos
-+ , bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes, getchar, length, comp);
-+ }
-+ }
-+
-+ //Sorts strings in reverse order, with empties at the end
-+ template <class RandomAccessIter, class data_type, class unsignedchar_type, class get_char, class get_length, class compare>
-+ inline void
-+ reverse_string_sort_rec(RandomAccessIter first, RandomAccessIter last, unsigned char_offset, std::vector<RandomAccessIter> &bin_cache
-+ , unsigned cache_offset, std::vector<size_t> &bin_sizes, get_char getchar, get_length length, compare comp)
-+ {
-+ //This section is not strictly necessary, but makes handling of long identical substrings much faster, with a mild average performance impact.
-+ RandomAccessIter curr = first;
-+ //Iterate to the end of the empties. If all empty, return
-+ while(length(*curr) <= char_offset) {
-+ if(++curr == last)
-+ return;
-+ }
-+ //Getting the last non-empty
-+ while(length(*(--last)) <= char_offset) { }
-+ ++last;
-+ //Offsetting on identical characters. This section works a character at a time for optimal worst-case performance.
-+ update_offset(first, last, char_offset, getchar, length);
-+
-+ const unsigned bin_count = (1 << (sizeof(unsignedchar_type)*8));
-+ //Equal worst-case between radix and comparison-based is when bin_count = n*log(n).
-+ const unsigned max_size = bin_count;
-+ const unsigned membin_count = bin_count + 1;
-+ const unsigned max_bin = bin_count - 1;
-+ unsigned cache_end;
-+ RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count);
-+ RandomAccessIter *end_bin = &(bin_cache[cache_offset + max_bin]);
-+
-+ //Calculating the size of each bin; this takes roughly 10% of runtime
-+ for (RandomAccessIter current = first; current != last; ++current) {
-+ if(length(*current) <= char_offset) {
-+ bin_sizes[bin_count]++;
-+ }
-+ else
-+ bin_sizes[max_bin - getchar((*current), char_offset)]++;
-+ }
-+ //Assign the bin positions
-+ bin_cache[cache_offset] = first;
-+ for(unsigned u = 0; u < membin_count - 1; u++)
-+ bin_cache[cache_offset + u + 1] = bin_cache[cache_offset + u] + bin_sizes[u];
-+
-+ //Swap into place
-+ RandomAccessIter nextbinstart = last;
-+ //handling empty bins
-+ RandomAccessIter * local_bin = &(bin_cache[cache_offset + bin_count]);
-+ RandomAccessIter lastFull = *local_bin;
-+ RandomAccessIter * target_bin;
-+ //Iterating over each element in the bin of empties
-+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-+ //empties belong in this bin
-+ while(length(*current) > char_offset) {
-+ target_bin = end_bin - getchar((*current), char_offset);
-+ iter_swap(current, (*target_bin)++);
-+ }
-+ }
-+ *local_bin = nextbinstart;
-+ nextbinstart = first;
-+ //iterate backwards to find the last bin with elements in it; this saves iterations in multiple loops
-+ unsigned last_bin = max_bin;
-+ for(; last_bin && !bin_sizes[last_bin]; --last_bin) { }
-+ //This dominates runtime, mostly in the swap and bin lookups
-+ for(unsigned u = 0; u < last_bin; ++u) {
-+ local_bin = bins + u;
-+ nextbinstart += bin_sizes[u];
-+ //Iterating over each element in this bin
-+ for(RandomAccessIter current = *local_bin; current < nextbinstart; ++current) {
-+ //Swapping elements in current into place until the correct element has been swapped in
-+ for(target_bin = end_bin - getchar((*current), char_offset); target_bin != local_bin;
-+ target_bin = end_bin - getchar((*current), char_offset))
-+ iter_swap(current, (*target_bin)++);
-+ }
-+ *local_bin = nextbinstart;
-+ }
-+ bins[last_bin] = lastFull;
-+ //Recursing
-+ RandomAccessIter lastPos = first;
-+ //Skip this loop for empties
-+ for(unsigned u = cache_offset; u <= cache_offset + last_bin; lastPos = bin_cache[u], ++u) {
-+ size_t count = bin_cache[u] - lastPos;
-+ //don't sort unless there are at least two items to compare
-+ if(count < 2)
-+ continue;
-+ //using std::sort if its worst-case is better
-+ if(count < max_size)
-+ std::sort(lastPos, bin_cache[u], comp);
-+ else
-+ reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(lastPos
-+ , bin_cache[u], char_offset + 1, bin_cache, cache_end, bin_sizes, getchar, length, comp);
-+ }
-+ }
-+
-+ //Holds the bin vector and makes the initial recursive call
-+ template <class RandomAccessIter, class data_type, class unsignedchar_type>
-+ inline void
-+ string_sort(RandomAccessIter first, RandomAccessIter last, data_type, unsignedchar_type)
-+ {
-+ std::vector<size_t> bin_sizes;
-+ std::vector<RandomAccessIter> bin_cache;
-+ string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(first, last, 0, bin_cache, 0, bin_sizes);
-+ }
-+
-+ //Holds the bin vector and makes the initial recursive call
-+ template <class RandomAccessIter, class data_type, class unsignedchar_type>
-+ inline void
-+ reverse_string_sort(RandomAccessIter first, RandomAccessIter last, data_type, unsignedchar_type)
-+ {
-+ std::vector<size_t> bin_sizes;
-+ std::vector<RandomAccessIter> bin_cache;
-+ reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type>(first, last, 0, bin_cache, 0, bin_sizes);
-+ }
-+
-+ //Holds the bin vector and makes the initial recursive call
-+ template <class RandomAccessIter, class get_char, class get_length, class data_type, class unsignedchar_type>
-+ inline void
-+ string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, data_type, unsignedchar_type)
-+ {
-+ std::vector<size_t> bin_sizes;
-+ std::vector<RandomAccessIter> bin_cache;
-+ string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length>(first, last, 0, bin_cache, 0, bin_sizes, getchar, length);
-+ }
-+
-+ //Holds the bin vector and makes the initial recursive call
-+ template <class RandomAccessIter, class get_char, class get_length, class compare, class data_type, class unsignedchar_type>
-+ inline void
-+ string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp, data_type, unsignedchar_type)
-+ {
-+ std::vector<size_t> bin_sizes;
-+ std::vector<RandomAccessIter> bin_cache;
-+ string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(first, last, 0, bin_cache, 0, bin_sizes, getchar, length, comp);
-+ }
-+
-+ //Holds the bin vector and makes the initial recursive call
-+ template <class RandomAccessIter, class get_char, class get_length, class compare, class data_type, class unsignedchar_type>
-+ inline void
-+ reverse_string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp, data_type, unsignedchar_type)
-+ {
-+ std::vector<size_t> bin_sizes;
-+ std::vector<RandomAccessIter> bin_cache;
-+ reverse_string_sort_rec<RandomAccessIter, data_type, unsignedchar_type, get_char, get_length, compare>(first, last, 0, bin_cache, 0, bin_sizes, getchar, length, comp);
-+ }
-+ }
-+
-+ //Allows character-type overloads
-+ template <class RandomAccessIter, class unsignedchar_type>
-+ inline void string_sort(RandomAccessIter first, RandomAccessIter last, unsignedchar_type unused)
-+ {
-+ //Don't sort if it's too small to optimize
-+ if(last - first < detail::MIN_SORT_SIZE)
-+ std::sort(first, last);
-+ else
-+ detail::string_sort(first, last, *first, unused);
-+ }
-+
-+ //Top-level sorting call; wraps using default of unsigned char
-+ template <class RandomAccessIter>
-+ inline void string_sort(RandomAccessIter first, RandomAccessIter last)
-+ {
-+ unsigned char unused = '\0';
-+ string_sort(first, last, unused);
-+ }
-+
-+ //Allows character-type overloads
-+ template <class RandomAccessIter, class compare, class unsignedchar_type>
-+ inline void reverse_string_sort(RandomAccessIter first, RandomAccessIter last, compare comp, unsignedchar_type unused)
-+ {
-+ //Don't sort if it's too small to optimize
-+ if(last - first < detail::MIN_SORT_SIZE)
-+ std::sort(first, last, comp);
-+ else
-+ detail::reverse_string_sort(first, last, *first, unused);
-+ }
-+
-+ //Top-level sorting call; wraps using default of unsigned char
-+ template <class RandomAccessIter, class compare>
-+ inline void reverse_string_sort(RandomAccessIter first, RandomAccessIter last, compare comp)
-+ {
-+ unsigned char unused = '\0';
-+ reverse_string_sort(first, last, comp, unused);
-+ }
-+
-+ template <class RandomAccessIter, class get_char, class get_length>
-+ inline void string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length)
-+ {
-+ //Don't sort if it's too small to optimize
-+ if(last - first < detail::MIN_SORT_SIZE)
-+ std::sort(first, last);
-+ else {
-+ //skipping past empties at the beginning, which allows us to get the character type
-+ //.empty() is not used so as not to require a user declaration of it
-+ while(!length(*first)) {
-+ if(++first == last)
-+ return;
-+ }
-+ detail::string_sort(first, last, getchar, length, *first, getchar((*first), 0));
-+ }
-+ }
-+
-+ template <class RandomAccessIter, class get_char, class get_length, class compare>
-+ inline void string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp)
-+ {
-+ //Don't sort if it's too small to optimize
-+ if(last - first < detail::MIN_SORT_SIZE)
-+ std::sort(first, last, comp);
-+ else {
-+ //skipping past empties at the beginning, which allows us to get the character type
-+ //.empty() is not used so as not to require a user declaration of it
-+ while(!length(*first)) {
-+ if(++first == last)
-+ return;
-+ }
-+ detail::string_sort(first, last, getchar, length, comp, *first, getchar((*first), 0));
-+ }
-+ }
-+
-+ template <class RandomAccessIter, class get_char, class get_length, class compare>
-+ inline void reverse_string_sort(RandomAccessIter first, RandomAccessIter last, get_char getchar, get_length length, compare comp)
-+ {
-+ //Don't sort if it's too small to optimize
-+ if(last - first < detail::MIN_SORT_SIZE)
-+ std::sort(first, last, comp);
-+ else {
-+ //skipping past empties at the beginning, which allows us to get the character type
-+ //.empty() is not used so as not to require a user declaration of it
-+ while(!length(*(--last))) {
-+ //Note: if there is just one non-empty, and it's at the beginning, then it's already in sorted order
-+ if(first == last)
-+ return;
-+ }
-+ //making last just after the end of the non-empty part of the array
-+ ++last;
-+ detail::reverse_string_sort(first, last, getchar, length, comp, *first, getchar((*first), 0));
-+ }
-+ }
-+}
-+
-+#endif
+@@ -21,6 +21,13 @@ Scott McMurray
+ #include <vector>
+ #include "webrtc/system_wrappers/source/spreadsortlib/constants.hpp"
+
++#ifdef __FreeBSD__
++# include <osreldate.h>
++# if __FreeBSD_version < 900506
++# define getchar boost_getchar
++# endif
++#endif
++
+ namespace boost {
+ namespace detail {
+ //This only works on unsigned data types
diff --git a/www/firefox/patches/patch-memory_jemalloc_Makefile.in b/www/firefox/patches/patch-memory_jemalloc_Makefile.in
new file mode 100644
index 00000000000..3866d1139cb
--- /dev/null
+++ b/www/firefox/patches/patch-memory_jemalloc_Makefile.in
@@ -0,0 +1,12 @@
+$NetBSD: patch-memory_jemalloc_Makefile.in,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- memory/jemalloc/Makefile.in.orig 2014-03-15 05:19:31.000000000 +0000
++++ memory/jemalloc/Makefile.in
+@@ -21,3 +21,7 @@ endif
+ ifdef GNU_CC
+ CFLAGS += -std=gnu99
+ endif
++
++# XXX startup crash workaround for gcc47 on amd64
++jemalloc.$(OBJ_SUFFIX): OS_CFLAGS := $(filter-out -O3 -Ofast,$(OS_CFLAGS))
++jemalloc.$(OBJ_SUFFIX): MOZ_OPTIMIZE_FLAGS=
diff --git a/www/firefox/patches/patch-netwerk_dns_Makefile.in b/www/firefox/patches/patch-netwerk_dns_Makefile.in
new file mode 100644
index 00000000000..61579517fc4
--- /dev/null
+++ b/www/firefox/patches/patch-netwerk_dns_Makefile.in
@@ -0,0 +1,12 @@
+$NetBSD: patch-netwerk_dns_Makefile.in,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- netwerk/dns/Makefile.in.orig 2014-03-15 05:19:32.000000000 +0000
++++ netwerk/dns/Makefile.in
+@@ -9,3 +9,7 @@ include $(topsrcdir)/config/rules.mk
+ # for effective TLD data.
+ etld_data.inc: $(srcdir)/prepare_tlds.py $(srcdir)/effective_tld_names.dat
+ $(PYTHON) $(srcdir)/prepare_tlds.py $(srcdir)/effective_tld_names.dat > etld_data.inc
++
++ifdef MOZ_NATIVE_HARFBUZZ
++nsIDNService.$(OBJ_SUFFIX): CXXFLAGS+=$(MOZ_HARFBUZZ_CFLAGS)
++endif
diff --git a/www/firefox/patches/patch-netwerk_wifi_moz.build b/www/firefox/patches/patch-netwerk_wifi_moz.build
index 6445bbc1a07..9a7758f7ed0 100644
--- a/www/firefox/patches/patch-netwerk_wifi_moz.build
+++ b/www/firefox/patches/patch-netwerk_wifi_moz.build
@@ -1,15 +1,15 @@
-$NetBSD: patch-netwerk_wifi_moz.build,v 1.5 2014/02/20 13:19:03 ryoon Exp $
+$NetBSD: patch-netwerk_wifi_moz.build,v 1.6 2014/03/20 21:02:00 ryoon Exp $
---- netwerk/wifi/moz.build.orig 2014-02-12 21:29:17.000000000 +0000
+--- netwerk/wifi/moz.build.orig 2014-03-15 05:19:33.000000000 +0000
+++ netwerk/wifi/moz.build
-@@ -38,6 +38,10 @@ if CONFIG['OS_ARCH'] == 'Darwin':
- SOURCES += [
+@@ -35,6 +35,10 @@ if CONFIG['OS_ARCH'] == 'Darwin':
+ UNIFIED_SOURCES += [
'osx_corewlan.mm',
]
+elif CONFIG['OS_ARCH'] == 'FreeBSD':
-+ CPP_SOURCES += [
++ UNIFIED_SOURCES += [
+ 'nsWifiScannerFreeBSD.cpp',
+ ]
elif CONFIG['OS_ARCH'] == 'WINNT':
- SOURCES += [
+ UNIFIED_SOURCES += [
'nsWifiScannerWin.cpp',
diff --git a/www/firefox/patches/patch-netwerk_wifi_nsWifiScannerFreeBSD.cpp b/www/firefox/patches/patch-netwerk_wifi_nsWifiScannerFreeBSD.cpp
index 5c6f323114c..c22f84d1c30 100644
--- a/www/firefox/patches/patch-netwerk_wifi_nsWifiScannerFreeBSD.cpp
+++ b/www/firefox/patches/patch-netwerk_wifi_nsWifiScannerFreeBSD.cpp
@@ -1,8 +1,8 @@
-$NetBSD: patch-netwerk_wifi_nsWifiScannerFreeBSD.cpp,v 1.3 2014/02/20 13:19:03 ryoon Exp $
+$NetBSD: patch-netwerk_wifi_nsWifiScannerFreeBSD.cpp,v 1.4 2014/03/20 21:02:00 ryoon Exp $
---- netwerk/wifi/nsWifiScannerFreeBSD.cpp.orig 2013-09-14 15:17:47.000000000 +0000
+--- netwerk/wifi/nsWifiScannerFreeBSD.cpp.orig 2014-03-20 11:09:40.000000000 +0000
+++ netwerk/wifi/nsWifiScannerFreeBSD.cpp
-@@ -0,0 +1,172 @@
+@@ -0,0 +1,167 @@
+/* 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/. */
@@ -31,43 +31,39 @@ $NetBSD: patch-netwerk_wifi_nsWifiScannerFreeBSD.cpp,v 1.3 2014/02/20 13:19:03 r
+static nsresult
+FreeBSDGetAccessPointData(nsCOMArray<nsWifiAccessPoint> &accessPoints)
+{
-+ bool res = false;
-+ char *dupn = NULL;
-+ struct ifaddrs *ifal, *ifa;
-+ unsigned len;
-+
+ // get list of interfaces
-+ if (getifaddrs(&ifal) < 0)
++ struct ifaddrs *ifal;
++ if (getifaddrs(&ifal) < 0) {
+ return NS_ERROR_FAILURE;
++ }
+
+ accessPoints.Clear();
+
+ // loop through the interfaces
++ nsresult rv = NS_ERROR_FAILURE;
++ struct ifaddrs *ifa;
+ for (ifa = ifal; ifa; ifa = ifa->ifa_next) {
-+ int s;
-+ struct ifreq ifr;
-+ struct ifmediareq ifmr;
-+ struct ieee80211req i802r;
-+ char iscanbuf[32*1024], *vsr;
-+
-+ memset(&ifr, 0, sizeof(ifr));
-+
-+ // list can contain duplicates, so ignore those
-+ if (dupn != NULL && strcmp(dupn, ifa->ifa_name) == 0)
++ // limit to one interface per address
++ if (ifa->ifa_addr->sa_family != AF_LINK) {
+ continue;
-+ dupn = ifa->ifa_name;
++ }
+
+ // store interface name in socket structure
++ struct ifreq ifr;
++ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, ifa->ifa_name, sizeof(ifr.ifr_name));
+ ifr.ifr_addr.sa_family = AF_LOCAL;
+
+ // open socket to interface
-+ if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0)
++ int s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0);
++ if (s < 0) {
+ continue;
++ }
+
+ // clear interface media structure
-+ (void) memset(&ifmr, 0, sizeof(ifmr));
-+ (void) strncpy(ifmr.ifm_name, ifa->ifa_name, sizeof(ifmr.ifm_name));
++ struct ifmediareq ifmr;
++ memset(&ifmr, 0, sizeof(ifmr));
++ strncpy(ifmr.ifm_name, ifa->ifa_name, sizeof(ifmr.ifm_name));
+
+ // get interface media information
+ if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
@@ -82,8 +78,10 @@ $NetBSD: patch-netwerk_wifi_nsWifiScannerFreeBSD.cpp,v 1.3 2014/02/20 13:19:03 r
+ }
+
+ // perform WiFi scan
-+ (void) memset(&i802r, 0, sizeof(i802r));
-+ (void) strncpy(i802r.i_name, ifa->ifa_name, sizeof(i802r.i_name));
++ struct ieee80211req i802r;
++ char iscanbuf[32*1024];
++ memset(&i802r, 0, sizeof(i802r));
++ strncpy(i802r.i_name, ifa->ifa_name, sizeof(i802r.i_name));
+ i802r.i_type = IEEE80211_IOC_SCAN_RESULTS;
+ i802r.i_data = iscanbuf;
+ i802r.i_len = sizeof(iscanbuf);
@@ -96,36 +94,33 @@ $NetBSD: patch-netwerk_wifi_nsWifiScannerFreeBSD.cpp,v 1.3 2014/02/20 13:19:03 r
+ close(s);
+
+ // loop through WiFi networks and build geoloc-lookup structure
-+ vsr = (char *) i802r.i_data;
-+ len = i802r.i_len;
++ char *vsr = (char *) i802r.i_data;
++ unsigned len = i802r.i_len;
+ while (len >= sizeof(struct ieee80211req_scan_result)) {
-+ struct ieee80211req_scan_result *isr;
-+ char *id;
-+ int idlen;
-+ char ssid[IEEE80211_NWID_LEN+1];
-+ nsWifiAccessPoint *ap;
-+
-+ isr = (struct ieee80211req_scan_result *) vsr;
++ struct ieee80211req_scan_result *isr =
++ (struct ieee80211req_scan_result *) vsr;
+
+ // determine size of this entry
++ char *id;
++ int idlen;
+ if (isr->isr_meshid_len) {
+ id = vsr + isr->isr_ie_off + isr->isr_ssid_len;
+ idlen = isr->isr_meshid_len;
-+ }
-+ else {
++ } else {
+ id = vsr + isr->isr_ie_off;
+ idlen = isr->isr_ssid_len;
+ }
+
+ // copy network data
++ char ssid[IEEE80211_NWID_LEN+1];
+ strncpy(ssid, id, idlen);
+ ssid[idlen] = '\0';
-+ ap = new nsWifiAccessPoint();
++ nsWifiAccessPoint *ap = new nsWifiAccessPoint();
+ ap->setSSID(ssid, strlen(ssid));
+ ap->setMac(isr->isr_bssid);
+ ap->setSignal(isr->isr_rssi);
+ accessPoints.AppendObject(ap);
-+ res = true;
++ rv = NS_OK;
+
+ // log the data
+ LOG(( "FreeBSD access point: "
@@ -143,7 +138,7 @@ $NetBSD: patch-netwerk_wifi_nsWifiScannerFreeBSD.cpp,v 1.3 2014/02/20 13:19:03 r
+
+ freeifaddrs(ifal);
+
-+ return res ? NS_OK : NS_ERROR_FAILURE;
++ return rv;
+}
+
+nsresult
diff --git a/www/firefox/patches/patch-toolkit_components_osfile_modules_osfile__unix__allthreads.jsm b/www/firefox/patches/patch-toolkit_components_osfile_modules_osfile__unix__allthreads.jsm
new file mode 100644
index 00000000000..0484c0e325f
--- /dev/null
+++ b/www/firefox/patches/patch-toolkit_components_osfile_modules_osfile__unix__allthreads.jsm
@@ -0,0 +1,13 @@
+$NetBSD: patch-toolkit_components_osfile_modules_osfile__unix__allthreads.jsm,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- toolkit/components/osfile/modules/osfile_unix_allthreads.jsm.orig 2014-03-15 05:19:36.000000000 +0000
++++ toolkit/components/osfile/modules/osfile_unix_allthreads.jsm
+@@ -41,7 +41,7 @@ let Const = SharedAll.Constants.libc;
+ // Open libc
+ let libc;
+ let libc_candidates = [ "libSystem.B.dylib",
+- "libc.so.6",
++ "libc.so.7",
+ "libc.so" ];
+ for (let i = 0; i < libc_candidates.length; ++i) {
+ try {
diff --git a/www/firefox/patches/patch-toolkit_components_osfile_modules_osfile__unix__back.jsm b/www/firefox/patches/patch-toolkit_components_osfile_modules_osfile__unix__back.jsm
index 25b786955ee..3440a9762dd 100644
--- a/www/firefox/patches/patch-toolkit_components_osfile_modules_osfile__unix__back.jsm
+++ b/www/firefox/patches/patch-toolkit_components_osfile_modules_osfile__unix__back.jsm
@@ -1,61 +1,33 @@
-$NetBSD: patch-toolkit_components_osfile_modules_osfile__unix__back.jsm,v 1.4 2014/02/20 13:19:03 ryoon Exp $
+$NetBSD: patch-toolkit_components_osfile_modules_osfile__unix__back.jsm,v 1.5 2014/03/20 21:02:00 ryoon Exp $
Based on martin@'s patch for firefox 27.0
* Use off_t for st_size
* Use function name for NetBSD
---- toolkit/components/osfile/modules/osfile_unix_back.jsm.orig 2014-02-12 21:29:22.000000000 +0000
+--- toolkit/components/osfile/modules/osfile_unix_back.jsm.orig 2014-03-15 05:19:36.000000000 +0000
+++ toolkit/components/osfile/modules/osfile_unix_back.jsm
-@@ -380,9 +380,15 @@
- /*oflags*/Type.int,
- /*mode*/ Type.int);
-
-+ if (OS.Constants.Sys.Name == "NetBSD") {
-+ declareLazyFFI(SysFile, "opendir", libc, "__opendir30", ctypes.default_abi,
-+ /*return*/ Type.null_or_DIR_ptr,
-+ /*path*/ Type.path);
-+ } else {
- declareLazyFFI(SysFile, "opendir", libc, "opendir", ctypes.default_abi,
- /*return*/ Type.null_or_DIR_ptr,
- /*path*/ Type.path);
-+ }
-
- declareLazyFFI(SysFile, "pread", libc, "pread", ctypes.default_abi,
- /*return*/ Type.negativeone_or_ssize_t,
-@@ -419,6 +425,10 @@
- declareLazyFFI(SysFile, "readdir", libc, "readdir$INODE64", ctypes.default_abi,
- /*return*/Type.null_or_dirent_ptr,
- /*dir*/ Type.DIR.in_ptr); // For MacOS X
-+ } else if (OS.Constants.Sys.Name == "NetBSD") {
-+ declareLazyFFI(SysFile, "readdir", libc, "__readdir30", ctypes.default_abi,
-+ /*return*/Type.null_or_dirent_ptr,
-+ /*dir*/ Type.DIR.in_ptr);
- } else {
- declareLazyFFI(SysFile, "readdir", libc, "readdir", ctypes.default_abi,
- /*return*/Type.null_or_dirent_ptr,
-@@ -529,6 +539,24 @@
- SysFile.fstat = function fstat(fd, buf) {
+@@ -558,18 +558,19 @@
return Stat.fxstat(ver, fd, buf);
};
-+ } else if (OS.Constants.Sys.Name == "NetBSD") {
+ } else if (OS.Constants.Sys.Name == "NetBSD") {
+- // NetBSD 5.0 and newer
+- declareLazyFFI(SysFile, "stat", libc, "__stat50", ctypes.default_abi,
+ // NetBSD 5.0 uses *30, and netbsd-6 uses *50
+ let v = OS.Constants.libc.OSFILE_SIZEOF_TIME_T < 8 ? "30" : "50";
+ declareLazyFFI(SysFile, "stat", libc, "__stat"+v, ctypes.default_abi,
-+ /*return*/ Type.negativeone_or_nothing,
-+ /*path*/ Type.path,
-+ /*buf*/ Type.stat.out_ptr
-+ );
+ /*return*/ Type.negativeone_or_nothing,
+ /*path*/ Type.path,
+ /*buf*/ Type.stat.out_ptr
+ );
+- declareLazyFFI(SysFile, "lstat", libc, "__lstat50", ctypes.default_abi,
+ declareLazyFFI(SysFile, "lstat", libc, "__lstat"+v, ctypes.default_abi,
-+ /*return*/ Type.negativeone_or_nothing,
-+ /*path*/ Type.path,
-+ /*buf*/ Type.stat.out_ptr
-+ );
+ /*return*/ Type.negativeone_or_nothing,
+ /*path*/ Type.path,
+ /*buf*/ Type.stat.out_ptr
+ );
+- declareLazyFFI(SysFile, "fstat", libc, "__fstat50", ctypes.default_abi,
+ declareLazyFFI(SysFile, "fstat", libc, "__fstat"+v, ctypes.default_abi,
-+ /*return*/ Type.negativeone_or_nothing,
-+ /*fd*/ Type.fd,
-+ /*buf*/ Type.stat.out_ptr
-+ );
- } else {
- // Mac OS X 32-bits, other Unix
- declareLazyFFI(SysFile, "stat", libc, "stat", ctypes.default_abi,
+ /*return*/ Type.negativeone_or_nothing,
+ /*fd*/ Type.fd,
+ /*buf*/ Type.stat.out_ptr
diff --git a/www/firefox/patches/patch-toolkit_library_Makefile.in b/www/firefox/patches/patch-toolkit_library_Makefile.in
index ad7ba8d21f9..38c60e0f543 100644
--- a/www/firefox/patches/patch-toolkit_library_Makefile.in
+++ b/www/firefox/patches/patch-toolkit_library_Makefile.in
@@ -1,23 +1,46 @@
-$NetBSD: patch-toolkit_library_Makefile.in,v 1.4 2014/02/20 13:19:03 ryoon Exp $
+$NetBSD: patch-toolkit_library_Makefile.in,v 1.5 2014/03/20 21:02:00 ryoon Exp $
---- toolkit/library/Makefile.in.orig 2014-02-12 21:29:23.000000000 +0000
+--- toolkit/library/Makefile.in.orig 2014-03-15 05:19:37.000000000 +0000
+++ toolkit/library/Makefile.in
-@@ -407,6 +407,7 @@ endif
- EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME_PATH,gkmedias,$(DIST)/lib)
+@@ -164,6 +164,18 @@ ifdef MOZ_NATIVE_HUNSPELL
+ EXTRA_DSO_LDOPTS += $(MOZ_HUNSPELL_LIBS)
+ endif
- ifdef MOZ_WEBRTC
-+EXTRA_DSO_LDOPTS += $(MOZ_LIBV4L2_LIBS)
- ifdef MOZ_PEERCONNECTION
- COMPONENT_LIBS += peerconnection
++ifdef MOZ_NATIVE_OGG
++EXTRA_DSO_LDOPTS += $(MOZ_OGG_LIBS)
++endif
++
++ifdef MOZ_NATIVE_VORBIS
++EXTRA_DSO_LDOPTS += $(MOZ_VORBIS_LIBS)
++endif
++
++ifdef MOZ_NATIVE_OPUS
++EXTRA_DSO_LDOPTS += $(MOZ_OPUS_LIBS)
++endif
++
+ ifdef MOZ_NATIVE_LIBEVENT
+ EXTRA_DSO_LDOPTS += $(MOZ_LIBEVENT_LIBS)
endif
-@@ -552,6 +553,10 @@ OS_LIBS += $(call EXPAND_LIBNAME,kvm)
- EXTRA_DSO_LDOPTS += -Wl,--warn-unresolved-symbols
+@@ -176,6 +188,14 @@ ifndef MOZ_TREE_PIXMAN
+ EXTRA_DSO_LDOPTS += $(MOZ_PIXMAN_LIBS)
endif
-+ifeq ($(OS_ARCH),FreeBSD)
-+OS_LIBS += $(call EXPAND_LIBNAME,util)
++ifdef MOZ_NATIVE_GRAPHITE2
++EXTRA_DSO_LDOPTS += $(MOZ_GRAPHITE2_LIBS)
++endif
++
++ifdef MOZ_NATIVE_HARFBUZZ
++EXTRA_DSO_LDOPTS += $(MOZ_HARFBUZZ_LIBS)
+endif
+
- ifeq ($(OS_ARCH),WINNT)
- OS_LIBS += $(call EXPAND_LIBNAME,shell32 ole32 version winspool comdlg32 imm32 msimg32 shlwapi psapi ws2_32 dbghelp rasapi32 rasdlg iphlpapi uxtheme setupapi secur32 sensorsapi portabledeviceguids windowscodecs wininet wbemuuid)
- ifdef ACCESSIBILITY
+ ifdef MOZ_DMD
+ EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME_PATH,dmd,$(DIST)/lib)
+ endif
+@@ -183,6 +203,7 @@ endif
+ EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME_PATH,gkmedias,$(DIST)/lib)
+
+ ifdef MOZ_WEBRTC
++EXTRA_DSO_LDOPTS += $(MOZ_LIBV4L2_LIBS)
+ ifdef MOZ_WEBRTC_SIGNALING
+ SHARED_LIBRARY_LIBS += \
+ $(DEPTH)/media/webrtc/signaling/signaling_ecc/$(LIB_PREFIX)ecc.$(LIB_SUFFIX) \
diff --git a/www/firefox/patches/patch-toolkit_xre_Makefile.in b/www/firefox/patches/patch-toolkit_xre_Makefile.in
deleted file mode 100644
index faa15117e87..00000000000
--- a/www/firefox/patches/patch-toolkit_xre_Makefile.in
+++ /dev/null
@@ -1,10 +0,0 @@
-$NetBSD: patch-toolkit_xre_Makefile.in,v 1.3 2014/02/20 13:19:03 ryoon Exp $
-
---- toolkit/xre/Makefile.in.orig 2013-09-10 03:43:56.000000000 +0000
-+++ toolkit/xre/Makefile.in
-@@ -216,5 +216,3 @@ GARBAGE += platform.ini
- libs:: platform.ini
- $(INSTALL) $^ $(DIST)/bin
-
--install::
-- $(INSTALL) $(IFLAGS1) $^ $(DESTDIR)$(mozappdir)
diff --git a/www/firefox/patches/patch-xpcom_base_nsMemoryInfoDumper.cpp b/www/firefox/patches/patch-xpcom_base_nsMemoryInfoDumper.cpp
deleted file mode 100644
index 05e91e98444..00000000000
--- a/www/firefox/patches/patch-xpcom_base_nsMemoryInfoDumper.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-$NetBSD: patch-xpcom_base_nsMemoryInfoDumper.cpp,v 1.3 2014/02/20 13:19:03 ryoon Exp $
-
---- xpcom/base/nsMemoryInfoDumper.cpp.orig 2013-12-05 16:08:00.000000000 +0000
-+++ xpcom/base/nsMemoryInfoDumper.cpp
-@@ -30,7 +30,7 @@
- #include <unistd.h>
- #endif
-
--#ifdef XP_LINUX
-+#if defined(XP_LINUX) || defined(__FreeBSD__)
- #include <fcntl.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-@@ -109,7 +109,7 @@ private:
-
- } // anonymous namespace
-
--#ifdef XP_LINUX // {
-+#if defined(XP_LINUX) || defined(__FreeBSD__) // {
- namespace {
-
- /*
-@@ -548,7 +548,7 @@ nsMemoryInfoDumper::~nsMemoryInfoDumper(
- /* static */ void
- nsMemoryInfoDumper::Initialize()
- {
--#ifdef XP_LINUX
-+#if defined(XP_LINUX) || defined(__FreeBSD__)
- SignalPipeWatcher::Create();
- FifoWatcher::MaybeCreate();
- #endif
diff --git a/www/firefox/patches/patch-xpcom_base_nsMemoryReporterManager.cpp b/www/firefox/patches/patch-xpcom_base_nsMemoryReporterManager.cpp
deleted file mode 100644
index e5091575c76..00000000000
--- a/www/firefox/patches/patch-xpcom_base_nsMemoryReporterManager.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-$NetBSD: patch-xpcom_base_nsMemoryReporterManager.cpp,v 1.3 2014/02/20 13:19:03 ryoon Exp $
-
---- xpcom/base/nsMemoryReporterManager.cpp.orig 2014-02-12 21:29:26.000000000 +0000
-+++ xpcom/base/nsMemoryReporterManager.cpp
-@@ -201,6 +201,43 @@ ResidentFastDistinguishedAmount(int64_t*
- return ResidentDistinguishedAmount(aN);
- }
-
-+#ifdef __FreeBSD__
-+#include <libutil.h>
-+
-+static nsresult
-+GetKinfoVmentrySelf(int64_t* prss)
-+{
-+ int cnt;
-+ struct kinfo_vmentry *vmmap, *kve;
-+ if ((vmmap = kinfo_getvmmap(getpid(), &cnt)) == NULL)
-+ return NS_ERROR_FAILURE;
-+
-+ if (prss)
-+ *prss = 0;
-+
-+ for (int i = 0; i < cnt; i++) {
-+ kve = &vmmap[i];
-+ if (prss)
-+ *prss += kve->kve_private_resident;
-+ }
-+
-+ free(vmmap);
-+ return NS_OK;
-+}
-+
-+#define HAVE_PRIVATE_REPORTER
-+static nsresult
-+GetPrivate(int64_t* aN)
-+{
-+ int64_t priv;
-+ nsresult rv = GetKinfoVmentrySelf(&priv);
-+ if (NS_SUCCEEDED(rv))
-+ *aN = priv * getpagesize();
-+
-+ return NS_OK;
-+}
-+#endif // FreeBSD
-+
- #elif defined(SOLARIS)
-
- #include <procfs.h>
-@@ -428,6 +465,24 @@ public:
- };
-
- #define HAVE_PRIVATE_REPORTER
-+static nsresult
-+GetPrivate(int64_t* aN)
-+{
-+ PROCESS_MEMORY_COUNTERS_EX pmcex;
-+ pmcex.cb = sizeof(PROCESS_MEMORY_COUNTERS_EX);
-+
-+ if (!GetProcessMemoryInfo(
-+ GetCurrentProcess(),
-+ (PPROCESS_MEMORY_COUNTERS) &pmcex, sizeof(pmcex))) {
-+ return NS_ERROR_FAILURE;
-+ }
-+
-+ *aN = pmcex.PrivateUsage;
-+ return NS_OK;
-+}
-+#endif // XP_<PLATFORM>
-+
-+#ifdef HAVE_PRIVATE_REPORTER
- class PrivateReporter MOZ_FINAL : public MemoryUniReporter
- {
- public:
-@@ -440,21 +495,10 @@ public:
-
- NS_IMETHOD GetAmount(int64_t* aAmount)
- {
-- PROCESS_MEMORY_COUNTERS_EX pmcex;
-- pmcex.cb = sizeof(PROCESS_MEMORY_COUNTERS_EX);
--
-- if (!GetProcessMemoryInfo(
-- GetCurrentProcess(),
-- (PPROCESS_MEMORY_COUNTERS) &pmcex, sizeof(pmcex))) {
-- return NS_ERROR_FAILURE;
-- }
--
-- *aAmount = pmcex.PrivateUsage;
-- return NS_OK;
-+ return GetPrivate(aAmount);
- }
- };
--
--#endif // XP_<PLATFORM>
-+#endif
-
- #ifdef HAVE_VSIZE_AND_RESIDENT_REPORTERS
- class VsizeReporter MOZ_FINAL : public MemoryUniReporter
-@@ -842,7 +886,7 @@ nsMemoryReporterManager::Init()
- RegisterReporter(new mozilla::dmd::DMDReporter);
- #endif
-
--#if defined(XP_LINUX)
-+#if defined(XP_LINUX) || defined(__FreeBSD__)
- nsMemoryInfoDumper::Initialize();
- #endif
-
diff --git a/www/firefox/patches/patch-xpcom_base_nsStackWalk.cpp b/www/firefox/patches/patch-xpcom_base_nsStackWalk.cpp
index ac07762d6c1..1d877e7db6f 100644
--- a/www/firefox/patches/patch-xpcom_base_nsStackWalk.cpp
+++ b/www/firefox/patches/patch-xpcom_base_nsStackWalk.cpp
@@ -1,8 +1,21 @@
-$NetBSD: patch-xpcom_base_nsStackWalk.cpp,v 1.3 2014/02/20 13:19:03 ryoon Exp $
+$NetBSD: patch-xpcom_base_nsStackWalk.cpp,v 1.4 2014/03/20 21:02:00 ryoon Exp $
---- xpcom/base/nsStackWalk.cpp.orig 2013-05-11 19:19:56.000000000 +0000
+--- xpcom/base/nsStackWalk.cpp.orig 2014-03-15 05:19:39.000000000 +0000
+++ xpcom/base/nsStackWalk.cpp
-@@ -853,7 +853,7 @@ void DemangleSymbol(const char * aSymbol
+@@ -23,6 +23,12 @@ struct CriticalAddress {
+ };
+ static CriticalAddress gCriticalAddress;
+
++// for _Unwind_Backtrace from libcxxrt or libunwind
++// cxxabi.h from libcxxrt implicitly includes unwind.h first
++#if defined(HAVE__UNWIND_BACKTRACE) && !defined(_GNU_SOURCE)
++#define _GNU_SOURCE
++#endif
++
+ #if defined(HAVE_DLOPEN) || defined(XP_MACOSX)
+ #include <dlfcn.h>
+ #endif
+@@ -874,7 +880,7 @@ void DemangleSymbol(const char * aSymbol
}
@@ -11,3 +24,13 @@ $NetBSD: patch-xpcom_base_nsStackWalk.cpp,v 1.3 2014/02/20 13:19:03 ryoon Exp $
/*
* Stack walking code for Solaris courtesy of Bart Smaalder's "memtrak".
+@@ -1223,9 +1229,6 @@ NS_StackWalk(NS_WalkStackCallback aCallb
+ #elif defined(HAVE__UNWIND_BACKTRACE)
+
+ // libgcc_s.so symbols _Unwind_Backtrace@@GCC_3.3 and _Unwind_GetIP@@GCC_3.0
+-#ifndef _GNU_SOURCE
+-#define _GNU_SOURCE
+-#endif
+ #include <unwind.h>
+
+ struct unwind_info {
diff --git a/www/firefox/patches/patch-xpcom_base_nscore.h b/www/firefox/patches/patch-xpcom_base_nscore.h
new file mode 100644
index 00000000000..b3c515a227d
--- /dev/null
+++ b/www/firefox/patches/patch-xpcom_base_nscore.h
@@ -0,0 +1,13 @@
+$NetBSD: patch-xpcom_base_nscore.h,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- xpcom/base/nscore.h.orig 2014-03-15 05:19:39.000000000 +0000
++++ xpcom/base/nscore.h
+@@ -110,7 +110,7 @@
+ * NS_HIDDEN_(int) NS_FASTCALL func2(char *foo);
+ */
+
+-#if defined(__i386__) && defined(__GNUC__) && !defined(XP_OS2)
++#if defined(__i386__) && defined(__GNUC__) && !defined(XP_OS2) && !(defined(__clang__) && __clang_major__ == 3 && __clang_minor__ == 4 && __clang_patchlevel__ == 0)
+ #define NS_FASTCALL __attribute__ ((regparm (3), stdcall))
+ #define NS_CONSTRUCTOR_FASTCALL __attribute__ ((regparm (3), stdcall))
+ #elif defined(XP_WIN) && !defined(_WIN64)
diff --git a/www/firefox/patches/patch-xpcom_io_nsLocalFileUnix.cpp b/www/firefox/patches/patch-xpcom_io_nsLocalFileUnix.cpp
new file mode 100644
index 00000000000..52e4acf2f88
--- /dev/null
+++ b/www/firefox/patches/patch-xpcom_io_nsLocalFileUnix.cpp
@@ -0,0 +1,13 @@
+$NetBSD: patch-xpcom_io_nsLocalFileUnix.cpp,v 1.1 2014/03/20 21:02:00 ryoon Exp $
+
+--- xpcom/io/nsLocalFileUnix.cpp.orig 2014-03-15 05:19:39.000000000 +0000
++++ xpcom/io/nsLocalFileUnix.cpp
+@@ -382,7 +382,7 @@ nsLocalFile::OpenNSPRFileDesc(int32_t fl
+ PR_Delete(mPath.get());
+ }
+
+-#if defined(LINUX) && !defined(ANDROID)
++#if defined(HAVE_POSIX_FADVISE)
+ if (flags & OS_READAHEAD) {
+ posix_fadvise(PR_FileDesc2NativeHandle(*_retval), 0, 0,
+ POSIX_FADV_SEQUENTIAL);
diff --git a/www/firefox/patches/patch-xpcom_reflect_xptcall_src_md_unix_moz.build b/www/firefox/patches/patch-xpcom_reflect_xptcall_src_md_unix_moz.build
index 125358e5e43..9230f7f5c7b 100644
--- a/www/firefox/patches/patch-xpcom_reflect_xptcall_src_md_unix_moz.build
+++ b/www/firefox/patches/patch-xpcom_reflect_xptcall_src_md_unix_moz.build
@@ -1,12 +1,12 @@
-$NetBSD: patch-xpcom_reflect_xptcall_src_md_unix_moz.build,v 1.4 2014/02/20 13:19:03 ryoon Exp $
+$NetBSD: patch-xpcom_reflect_xptcall_src_md_unix_moz.build,v 1.5 2014/03/20 21:02:00 ryoon Exp $
* Support NetBSD/amd64 and DragonFly/amd64.
---- xpcom/reflect/xptcall/src/md/unix/moz.build.orig 2014-02-12 21:29:26.000000000 +0000
+--- xpcom/reflect/xptcall/src/md/unix/moz.build.orig 2014-03-15 05:19:39.000000000 +0000
+++ xpcom/reflect/xptcall/src/md/unix/moz.build
-@@ -12,14 +12,14 @@ if CONFIG['OS_ARCH'] == 'Darwin':
- 'xptcstubs_darwin.cpp',
- ]
+@@ -19,14 +19,14 @@ if CONFIG['OS_ARCH'] == 'Darwin':
+ if '86' in CONFIG['OS_TEST'] and CONFIG['OS_TEST'] != 'x86_64':
+ DEFINES['MOZ_NEED_LEADING_UNDERSCORE'] = True
-if CONFIG['OS_ARCH'] in ('NetBSD', 'OpenBSD', 'GNU'):
+if CONFIG['OS_ARCH'] in ('OpenBSD', 'GNU'):
diff --git a/www/firefox/patches/patch-xn b/www/firefox/patches/patch-xpcom_reflect_xptcall_src_md_unix_xptcinvoke__asm__mips.S
index 14337f2dd70..c897f719e43 100644
--- a/www/firefox/patches/patch-xn
+++ b/www/firefox/patches/patch-xpcom_reflect_xptcall_src_md_unix_xptcinvoke__asm__mips.S
@@ -1,7 +1,7 @@
-$NetBSD: patch-xn,v 1.3 2014/02/20 13:19:03 ryoon Exp $
+$NetBSD: patch-xpcom_reflect_xptcall_src_md_unix_xptcinvoke__asm__mips.S,v 1.1 2014/03/20 21:02:00 ryoon Exp $
---- xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_mips.s.orig 2013-01-04 23:44:47.000000000 +0000
-+++ xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_mips.s
+--- xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_mips.S.orig 2014-03-15 05:19:39.000000000 +0000
++++ xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_mips.S
@@ -16,6 +16,47 @@
#include <sys/asm.h>
#endif
diff --git a/www/firefox/patches/patch-xo b/www/firefox/patches/patch-xpcom_reflect_xptcall_src_md_unix_xptcstubs__asm__mips.S
index 49691c084fd..574949c7757 100644
--- a/www/firefox/patches/patch-xo
+++ b/www/firefox/patches/patch-xpcom_reflect_xptcall_src_md_unix_xptcstubs__asm__mips.S
@@ -1,7 +1,7 @@
-$NetBSD: patch-xo,v 1.3 2014/02/20 13:19:03 ryoon Exp $
+$NetBSD: patch-xpcom_reflect_xptcall_src_md_unix_xptcstubs__asm__mips.S,v 1.1 2014/03/20 21:02:00 ryoon Exp $
---- xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_mips.s.orig 2013-01-04 23:44:47.000000000 +0000
-+++ xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_mips.s
+--- xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_mips.S.orig 2014-03-15 05:19:39.000000000 +0000
++++ xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_mips.S
@@ -14,6 +14,47 @@
#include <sys/asm.h>
#endif