firefox 112.0.2-1 (x86_64) 2023-17475
9999

Status published
Submitter cris [@T] beebames.com
Platform rolling
Repository main
URL https://abf.openmandriva.org/build_lists/335180
Packages
firefox-112.0.2-1.x86_64.source
firefox-112.0.2-1.x86_64.binary
firefox-af-112.0.2-1.x86_64.binary
firefox-ar-112.0.2-1.x86_64.binary
firefox-ast-112.0.2-1.x86_64.binary
firefox-bg-112.0.2-1.x86_64.binary
firefox-bn-112.0.2-1.x86_64.binary
firefox-br-112.0.2-1.x86_64.binary
firefox-bs-112.0.2-1.x86_64.binary
firefox-ca-112.0.2-1.x86_64.binary
firefox-cs-112.0.2-1.x86_64.binary
firefox-cy-112.0.2-1.x86_64.binary
firefox-da-112.0.2-1.x86_64.binary
firefox-de-112.0.2-1.x86_64.binary
firefox-debuginfo-112.0.2-1.x86_64.debuginfo
firefox-debugsource-112.0.2-1.x86_64.binary
firefox-devel-112.0.2-1.x86_64.binary
firefox-el-112.0.2-1.x86_64.binary
firefox-en_GB-112.0.2-1.x86_64.binary
firefox-eo-112.0.2-1.x86_64.binary
firefox-es_AR-112.0.2-1.x86_64.binary
firefox-es_CL-112.0.2-1.x86_64.binary
firefox-es_ES-112.0.2-1.x86_64.binary
firefox-es_MX-112.0.2-1.x86_64.binary
firefox-et-112.0.2-1.x86_64.binary
firefox-eu-112.0.2-1.x86_64.binary
firefox-fa-112.0.2-1.x86_64.binary
firefox-fi-112.0.2-1.x86_64.binary
firefox-fr-112.0.2-1.x86_64.binary
firefox-fy-112.0.2-1.x86_64.binary
firefox-ga_IE-112.0.2-1.x86_64.binary
firefox-gd-112.0.2-1.x86_64.binary
firefox-gl-112.0.2-1.x86_64.binary
firefox-gu_IN-112.0.2-1.x86_64.binary
firefox-he-112.0.2-1.x86_64.binary
firefox-hi-112.0.2-1.x86_64.binary
firefox-hr-112.0.2-1.x86_64.binary
firefox-hu-112.0.2-1.x86_64.binary
firefox-hy-112.0.2-1.x86_64.binary
firefox-id-112.0.2-1.x86_64.binary
firefox-is-112.0.2-1.x86_64.binary
firefox-it-112.0.2-1.x86_64.binary
firefox-ja-112.0.2-1.x86_64.binary
firefox-kk-112.0.2-1.x86_64.binary
firefox-km-112.0.2-1.x86_64.binary
firefox-kn-112.0.2-1.x86_64.binary
firefox-ko-112.0.2-1.x86_64.binary
firefox-lt-112.0.2-1.x86_64.binary
firefox-lv-112.0.2-1.x86_64.binary
firefox-mk-112.0.2-1.x86_64.binary
firefox-mr-112.0.2-1.x86_64.binary
firefox-nb_NO-112.0.2-1.x86_64.binary
firefox-nl-112.0.2-1.x86_64.binary
firefox-nn_NO-112.0.2-1.x86_64.binary
firefox-pa_IN-112.0.2-1.x86_64.binary
firefox-pl-112.0.2-1.x86_64.binary
firefox-pt_BR-112.0.2-1.x86_64.binary
firefox-pt_PT-112.0.2-1.x86_64.binary
firefox-ro-112.0.2-1.x86_64.binary
firefox-ru-112.0.2-1.x86_64.binary
firefox-si-112.0.2-1.x86_64.binary
firefox-sk-112.0.2-1.x86_64.binary
firefox-sl-112.0.2-1.x86_64.binary
firefox-sq-112.0.2-1.x86_64.binary
firefox-sr-112.0.2-1.x86_64.binary
firefox-sv_SE-112.0.2-1.x86_64.binary
firefox-ta-112.0.2-1.x86_64.binary
firefox-te-112.0.2-1.x86_64.binary
firefox-th-112.0.2-1.x86_64.binary
firefox-tr-112.0.2-1.x86_64.binary
firefox-uk-112.0.2-1.x86_64.binary
firefox-vi-112.0.2-1.x86_64.binary
firefox-zh_CN-112.0.2-1.x86_64.binary
firefox-zh_TW-112.0.2-1.x86_64.binary
Build Date 2023-04-25 14:08:00 +0000 UTC
Last Updated 2023-05-06 02:48:03.821653997 +0000 UTC
$ git diff --patch-with-stat --summary 1948d4e55c985be795dc3f87e7e9cda5f6ea54e1..bb93bbed722801ef4db147809ba0711f03f34f52

 .abf.yml                                           | 140 +++---
 0001-GLIBCXX-fix-for-GCC-12.patch                  |  44 ++
 D173814.diff                                       |  82 +++
 firefox-107.0.1-kde.patch                          |  91 +---
 firefox-112.0-commasplit.patch                     |  76 +++
 firefox-112.0.1-no-static-libstdc++.patch          |  44 ++
 firefox-enable-vaapi.patch                         |  16 +-
 firefox-gcc-13-build.patch                         |  24 +
 firefox-glibc-dynstack.patch                       |  64 ---
 firefox.spec                                       |  31 +-
 ...import-dmabuf-directly-into-desktop-frame.patch | 505 +++++++++++++++++++
 mozilla-107.0.1-kde.patch                          |  52 +-
 mozilla-1196777.patch                              |  13 +
 mozilla-1516803.patch                              |  15 +
 mozilla-1663844.patch                              |  37 ++
 mozilla-1667096.patch                              | 549 +++++++++++++++++++++
 mozilla-1669639.patch                              |  14 +
 mozilla-1670333.patch                              |  68 +++
 mozilla-1775202.patch                              |  14 +
 19 files changed, 1635 insertions(+), 244 deletions(-)
 create mode 100644 0001-GLIBCXX-fix-for-GCC-12.patch
 create mode 100644 D173814.diff
 create mode 100644 firefox-112.0-commasplit.patch
 create mode 100644 firefox-112.0.1-no-static-libstdc++.patch
 create mode 100644 firefox-gcc-13-build.patch
 delete mode 100644 firefox-glibc-dynstack.patch
 create mode 100644 libwebrtc-pipewire-capturer-import-dmabuf-directly-into-desktop-frame.patch
 create mode 100644 mozilla-1196777.patch
 create mode 100644 mozilla-1516803.patch
 create mode 100644 mozilla-1663844.patch
 create mode 100644 mozilla-1667096.patch
 create mode 100644 mozilla-1669639.patch
 create mode 100644 mozilla-1670333.patch
 create mode 100644 mozilla-1775202.patch

diff --git a/.abf.yml b/.abf.yml
index 05b9ae4..26586aa 100644
--- a/.abf.yml
+++ b/.abf.yml
@@ -1,72 +1,72 @@
 sources:
-  af.xpi: ad17f929c1d03c38178f6344958b1939e3a712d5
-  ar.xpi: 96b922e7c1fd2646e37f805ced1fbad03bd522a0
-  ast.xpi: 13e5d45f323e16e98c9361b718f47b07cc94bac4
-  bg.xpi: 9301976a0c8d55f167d6b58f05cd9fd720fd8ff7
-  bn.xpi: 2d75c191243d7d035a7d81db29c698cc36f1ac0c
-  br.xpi: 0a5fae0c86c742bbbee4c45acaa9e24b33eed1f9
-  bs.xpi: a9ca714ef6ad77376fe46b9ef9ff66485a5c2a61
-  ca.xpi: 3edeab7066f3deb0426ced0bd3f6d16961e64189
+  af.xpi: 09fc8a1b64c52bcae2aa55c8126c018b4a839d50
+  ar.xpi: 6c55f611e6e69ec7cc39c5689988074d26b7a27f
+  ast.xpi: 9af20ceae798f0dc34e027a35578487e6d941369
+  bg.xpi: 0b48984d2c2f0106a7f6f9437d0135b8c214b4e9
+  bn.xpi: 29cd9aae339a2db24926decb6181613b2e8d51eb
+  br.xpi: 9b173e9c77b6896e2347ab992ef9e6104d284b6c
+  bs.xpi: 4f2ad26cd8a4b6c7f17f9efbc4ccbbdda36b82a8
+  ca.xpi: bc45b30fbfade45ac01f125b9f26b1a5a9311e2a
   cbindgen-vendor.tar.xz: 8faf49463f1705b8604b2d121dc844aad7e37eae
-  cs.xpi: 7d61238019c9f4d34fddcca1df1f8c9b77641274
-  cy.xpi: 89e86f0ad6f2c4a5717a05e3dc6a665b8a05ed61
-  da.xpi: ae1896e762874b3b3a2064e6074e42d518a079b5
-  de.xpi: bb0528cb436e2ef66660e170841bbe974869237e
-  el.xpi: 73a39dddd62318fa476efe085a6ef574dbbd28da
-  en-GB.xpi: 8afbbc51dfb4c5d48739fa2b7423cff4fe448f19
-  eo.xpi: 2edb4e33eb21f542d5f3543b5d5f8fe6fddc2ed6
-  es-AR.xpi: 6d0b3d425c1819c9e5f94a4d8238686836d36482
-  es-CL.xpi: de9418411c00c77fdaa9570c916db00cff167a74
-  es-ES.xpi: f86090052bf73b5fdec8c6367da44adf83872b41
-  es-MX.xpi: 194cf90d8ec34104fb54bce14a7459364ca7037d
-  et.xpi: cc5bba72c8528598f957948f892697d6892bafb8
-  eu.xpi: 0f178afeb454fa6ec5b7f15334c6136a4b4e24ca
-  fa.xpi: 63a14c93ef2587eca9ac75c01b4f27773ba8375c
-  fi.xpi: 0f3ee9344b3349a69009df94fbd792d3af9aaaeb
-  firefox-108.0.source.tar.xz: 27acd01319b4e26ffc0cf72c089181391aad0c58
-  fr.xpi: a96bcf1006b736245e0ad0465f5295445ecfd7d9
-  fy-NL.xpi: 416a47f12447067384436eb84b2de1043bd2663c
-  ga-IE.xpi: 8a8abeb3029483a06f4323abb463eaad0b01bb77
-  gd.xpi: 70fb4170048f38ed38e8aeb91cc55563b21007a6
-  gl.xpi: a516eab4c91eb3dd37bde1706f1d97ddbe8e6ba8
-  gu-IN.xpi: 750730313f93417499050fe559a721b93c8bb122
-  he.xpi: 6c9bae49469c4661c911a6f30bc922024a649273
-  hi-IN.xpi: ec084fe4ba2be515a74bb3c22589d8528b886f44
-  hr.xpi: f81dd31f2ba15d21c74f8495e696b9442113f118
-  hu.xpi: 192f3213ce08debd1d60fa7ec5aca22f6c89936c
-  hy-AM.xpi: 7b8877bfbb610aeb1ef2fff03f33fadd56d7d986
-  id.xpi: e1a1370df48e95f37c5740994d2c352306748b3b
-  is.xpi: 00928397b22d0acd1f74cba253d2ae31eab97258
-  it.xpi: b2bcc81ed9eefa62c0516abebfcf77c37129eedc
-  ja.xpi: 3773aead6aef785d83d2e0f236482f321e87ce68
-  kk.xpi: 0c72552b3a77fc658b76615861cc35979aa99c96
-  km.xpi: 7e6d8246a8b5fd57db3874d4555a8d7dec5d426c
-  kn.xpi: 8df723dd97098098f29b823d1d44f4c628ab8b41
-  ko.xpi: 22bfe6b9d75f3620586cdcdd9485f15bfc64cce9
-  lt.xpi: 73cb2148cc9cfb219bf9807a3b4bda663c99c66b
-  lv.xpi: 512fe167a3a750645881b57376f6ac98fa874097
-  mk.xpi: f71959f7ab1fc02c4d6acd819e41a0b42064002a
-  mr.xpi: 8e875cb3d42fb3cb5a75c23f47a8bd23b450b5de
-  nb-NO.xpi: 6cd0097c221e830d0e44718b3989aead88c7d69c
-  nl.xpi: cfc729792ce2dc86cb845738bb6c8d09f9311b33
-  nn-NO.xpi: d717c56921b4348a445631268b7ab2a68c5f8b22
-  pa-IN.xpi: dbf76054f23ca211391dd6fa06f211da067f55f4
-  pl.xpi: fb3607c7cd55fa0087ff76fb13283e59887c86ae
-  pt-BR.xpi: 8be37305e3319fee63da76fd46fdf61f34f6c29a
-  pt-PT.xpi: 23963679dc87c491ca242c978d2a8ff7d57ccd51
-  ro.xpi: cd2fa386921e90679335668d3a86b7cc62db8730
-  ru.xpi: 0330166632a9ebc209b0add36b8b45b1ad3936e5
-  si.xpi: 68e9d56c2bd17565c68f08417e64823ebec05038
-  sk.xpi: 7595813176919c9f51044fe5f4e68567f927b0b2
-  sl.xpi: a7082eff14d892341c6d6ad2d43d93ee9f42bfcb
-  sq.xpi: c4e45f4de9358b772d13e0be8cdeb6b638c1a1a3
-  sr.xpi: f24adae21f7cc890cfd88476f1039bc972f25a77
-  sv-SE.xpi: ad865af97a6fc7f93940e04e9ef1cf3d1eaa6660
-  ta.xpi: b7b2da0ee18459df64502f42d01fddc3efbda2a2
-  te.xpi: a93e0d8da24be62c6d353fc0e80914f06efcefe7
-  th.xpi: 5918a17cb6a9f9dc8dfd26c5cb037dc5c007f11c
-  tr.xpi: 37f39fa203db662aafd0d93e531abd302f411a53
-  uk.xpi: fe2ddd890294124d2217a08928766d0f635b6d29
-  vi.xpi: 8b2770ae1065de4f35c8fdcd0263f3d52897716a
-  zh-CN.xpi: bfa651cb7c981700d4fb697d049b52221824a91e
-  zh-TW.xpi: e56cd50aa31ce734b432f65b4c69867522d6d6c6
+  cs.xpi: 4471a0afa4ca83c5644dc2691c25da2b6d09b690
+  cy.xpi: ebe262935e3a05f602379350025dc2e05322874e
+  da.xpi: 347638e79e3906fa521a2b7a80ee39a2715bf49c
+  de.xpi: 70791b195882da777bfb9a65af5251ad943501d9
+  el.xpi: 053b9014b5f4cf7a522ab3b81d11acab5f4a951b
+  en-GB.xpi: 97b11d254a2ede34d8932c03b13c0bb308110619
+  eo.xpi: 11d3d9083cab58b03bf2613c84a7ff35ce0a4d3e
+  es-AR.xpi: 0a41b12b7c5a572155fe1b9ff2d6e83fbc4ea8f5
+  es-CL.xpi: 49c9b8969d51256b237ce0794ce833736b0ed093
+  es-ES.xpi: 8bd3989ca918eae58f10a0fbf4f11f9c1f7ca1f3
+  es-MX.xpi: e27ab4f1d187f4b81c10a89647d323eb8058a3ae
+  et.xpi: 0597217bb6448c7050617001448f43b762c005dc
+  eu.xpi: 63ef4f382beea46da155a27008f8ae3575818576
+  fa.xpi: 20992f693d65b3eab448aece45477debf2710b1c
+  fi.xpi: f2fd09b39695776566e52f9ef78cc398a29be6d8
+  firefox-112.0.2.source.tar.xz: 65deb4379e6d8104216ce9ba0f743403964efee5
+  fr.xpi: d4c181f65e7a0b62e0bd2a8cd88a246a80172cec
+  fy-NL.xpi: a660fffcf9fa2aa186181785f972f4bcc735d809
+  ga-IE.xpi: 7c7bc423ea25c619d88cd1120681ee087c44306c
+  gd.xpi: 565788ed5f1358b516c432c3b94a9a4137f479cd
+  gl.xpi: 5f8d69832f160ded2d6fe586be0935adccb9cf6d
+  gu-IN.xpi: caca5d023f08ad03caae4d54945ffaf3e762b4b4
+  he.xpi: 1dc3e383b4936a0ed5195cb6d5af22613968973f
+  hi-IN.xpi: 0a55d1e9b068fed90c4efb6cfcfecd7680efe31a
+  hr.xpi: 08eaddb6d7a6562c3e16c0908ae5ab48b858702d
+  hu.xpi: 9903acb8e4e0cf8444005e2b88eb9e11341bb8d2
+  hy-AM.xpi: 8fd47b637e1851a6a7ce3543617ee34d884bbce2
+  id.xpi: bf4f9d3020a02e75805de237179ee96495de0744
+  is.xpi: 9f8d2a42494d8ea7be94458de3ff4fa06b00599f
+  it.xpi: bf72a30420c152ef89707255465a7f4fb22ee691
+  ja.xpi: 983e4005a7bd0a9a1a156d80c7b1a148130d30cb
+  kk.xpi: 2132b972eecab3d872fffb587fedeeebad53d666
+  km.xpi: 96300907645c7416d9ce21b6bf1c993570f82df4
+  kn.xpi: 058635203bb40fd782e736de953cb79f9f0794a4
+  ko.xpi: e45bcfaa0bbf816ab0c74e6f53f2aa33aa2e4cf9
+  lt.xpi: e804ff6a8116101e8cd01ecc24bc3c6ac3a56c23
+  lv.xpi: 45169074947be30de5550398cec7802f0e75200e
+  mk.xpi: 827ffeca958221023b903c41166e56b2d5babc58
+  mr.xpi: 793d14aa979470b58fee27d119f9cf95c38434ed
+  nb-NO.xpi: 3bc95e3a22d598aadab06b99804f894337740ee4
+  nl.xpi: 159a602697a63fec3742270f9d07fdd7fa0565b0
+  nn-NO.xpi: ce2e1571bb7d4a1baceac9a855537fde3fd3b302
+  pa-IN.xpi: edbee4f4410353e7d048430cb25db34dbd4ba001
+  pl.xpi: 97a63853ffd911f33719917a09134fa30ede4541
+  pt-BR.xpi: e1844c6eac74a51ef392245a6e58a5df4f8aa55a
+  pt-PT.xpi: 0b5d074c9faea27c1bbeefb08ceaf918b7faf01e
+  ro.xpi: 1048fecfbeb33a2bc43469f76c11cefa65aff575
+  ru.xpi: f37f7030d84ed60563f4a47af632b8bb556463bf
+  si.xpi: 08ddf24d22f6677d244a6c41559e2d4854e7ef7e
+  sk.xpi: e46baa1a7d75becd00a2a27fbb5aa636978ef78e
+  sl.xpi: fa0dd952311c8063cc8785ee01ed31e8034b9ed7
+  sq.xpi: b89dbaaae741b99ed4eb2ab9d59be3cfd1c83f1e
+  sr.xpi: bd7d9a612d9690d6215f3f8c2bd8b0b638d4d1b8
+  sv-SE.xpi: 7be54d76f70d6cd2855d6f2de6b78c2fe053b114
+  ta.xpi: f7aa318b22e41ede2456d2f2bb637cf1ecead63a
+  te.xpi: c1da7e0fec7a8e81ea27df5dccd9bea121b28ed3
+  th.xpi: c8bfd62fe5c89fb1cd835d26357a15bde5bb5fde
+  tr.xpi: f205e48ecd3005c10020afd4920c8d9a11b625bc
+  uk.xpi: 1b9bd4199ec87054b67c65084900747c1fe856a7
+  vi.xpi: 14ac7ef15fd257a5e5670939314c602ecf3337c6
+  zh-CN.xpi: e7f7d089560f7233308b3d9b9ddc8d28b9091253
+  zh-TW.xpi: e3b62af1a84c2ebc9dbfd7492f707b964b0248ae
diff --git a/0001-GLIBCXX-fix-for-GCC-12.patch b/0001-GLIBCXX-fix-for-GCC-12.patch
new file mode 100644
index 0000000..37d6f50
--- /dev/null
+++ b/0001-GLIBCXX-fix-for-GCC-12.patch
@@ -0,0 +1,44 @@
+From efd5bc0715e5477318be95a76811cda0a89e8289 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= <emilio@crisal.io>
+Date: Fri, 4 Mar 2022 12:00:26 +0100
+Subject: [PATCH] GLIBCXX fix for GCC 12?
+
+---
+ build/unix/stdc++compat/stdc++compat.cpp | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/build/unix/stdc++compat/stdc++compat.cpp b/build/unix/stdc++compat/stdc++compat.cpp
+index 0180f6bcfa998..8d7a542ff11f0 100644
+--- a/build/unix/stdc++compat/stdc++compat.cpp
++++ b/build/unix/stdc++compat/stdc++compat.cpp
+@@ -24,6 +24,7 @@
+    GLIBCXX_3.4.27 is from gcc 10
+    GLIBCXX_3.4.28 is from gcc 10
+    GLIBCXX_3.4.29 is from gcc 11
++   GLIBCXX_3.4.30 is from gcc 12
+ 
+ This file adds the necessary compatibility tricks to avoid symbols with
+ version GLIBCXX_3.4.20 and bigger, keeping binary compatibility with
+@@ -69,6 +70,19 @@ void __attribute__((weak)) __throw_bad_array_new_length() { MOZ_CRASH(); }
+ }  // namespace std
+ #endif
+ 
++#if _GLIBCXX_RELEASE >= 12
++namespace std {
++
++/* This avoids the GLIBCXX_3.4.30 symbol version. */
++void __attribute__((weak))
++__glibcxx_assert_fail(const char* __file, int __line, const char* __function,
++                      const char* __condition) {
++  MOZ_CRASH();
++}
++
++}  // namespace std
++#endif
++
+ /* While we generally don't build with exceptions, we have some host tools
+  * that do use them. libstdc++ from GCC 5.0 added exception constructors with
+  * char const* argument. Older versions only have a constructor with
+-- 
+2.35.1
+
diff --git a/D173814.diff b/D173814.diff
new file mode 100644
index 0000000..91898aa
--- /dev/null
+++ b/D173814.diff
@@ -0,0 +1,82 @@
+diff --git a/widget/gtk/MozContainerWayland.h b/widget/gtk/MozContainerWayland.h
+--- a/widget/gtk/MozContainerWayland.h
++++ b/widget/gtk/MozContainerWayland.h
+@@ -83,10 +83,13 @@
+                                                         nsIntSize aSize,
+                                                         int scale);
+ void moz_container_wayland_set_scale_factor(MozContainer* container);
+ void moz_container_wayland_set_scale_factor_locked(
+     const mozilla::MutexAutoLock& aProofOfLock, MozContainer* container);
++bool moz_container_wayland_size_matches_scale_factor_locked(
++    const mozilla::MutexAutoLock& aProofOfLock, MozContainer* container,
++    int aWidth, int aHeight);
+ 
+ void moz_container_wayland_add_initial_draw_callback_locked(
+     MozContainer* container, const std::function<void(void)>& initial_draw_cb);
+ void moz_container_wayland_add_or_fire_initial_draw_callback(
+     MozContainer* container, const std::function<void(void)>& initial_draw_cb);
+diff --git a/widget/gtk/MozContainerWayland.cpp b/widget/gtk/MozContainerWayland.cpp
+--- a/widget/gtk/MozContainerWayland.cpp
++++ b/widget/gtk/MozContainerWayland.cpp
+@@ -595,10 +595,17 @@
+   if (container->wl_container.surface) {
+     moz_container_wayland_set_scale_factor_locked(lock, container);
+   }
+ }
+ 
++bool moz_container_wayland_size_matches_scale_factor_locked(
++    const MutexAutoLock& aProofOfLock, MozContainer* container, int aWidth,
++    int aHeight) {
++  return aWidth % container->wl_container.buffer_scale == 0 &&
++         aHeight % container->wl_container.buffer_scale == 0;
++}
++
+ static bool moz_container_wayland_surface_create_locked(
+     const MutexAutoLock& aProofOfLock, MozContainer* container) {
+   MozContainerWayland* wl_container = &container->wl_container;
+ 
+   LOGWAYLAND("%s [%p]\n", __FUNCTION__,
+diff --git a/widget/gtk/WindowSurfaceWaylandMultiBuffer.cpp b/widget/gtk/WindowSurfaceWaylandMultiBuffer.cpp
+--- a/widget/gtk/WindowSurfaceWaylandMultiBuffer.cpp
++++ b/widget/gtk/WindowSurfaceWaylandMultiBuffer.cpp
+@@ -283,12 +283,12 @@
+     return;
+   }
+   mFrameInProcess = false;
+ 
+   MozContainer* container = mWindow->GetMozContainer();
+-  MozContainerSurfaceLock lock(container);
+-  struct wl_surface* waylandSurface = lock.GetSurface();
++  MozContainerSurfaceLock MozContainerLock(container);
++  struct wl_surface* waylandSurface = MozContainerLock.GetSurface();
+   if (!waylandSurface) {
+     LOGWAYLAND(
+         "WindowSurfaceWaylandMB::Commit [%p] frame queued: can't lock "
+         "wl_surface\n",
+         (void*)mWindow.get());
+@@ -317,12 +317,23 @@
+       LayoutDeviceIntRect r = iter.Get();
+       wl_surface_damage_buffer(waylandSurface, r.x, r.y, r.width, r.height);
+     }
+   }
+ 
++  // aProofOfLock is a kind of substitution of MozContainerSurfaceLock.
++  // MozContainer is locked but MozContainerSurfaceLock doen't convert to
++  // MutexAutoLock& so we use aProofOfLock here.
+   moz_container_wayland_set_scale_factor_locked(aProofOfLock, container);
+-  mInProgressBuffer->AttachAndCommit(waylandSurface);
++
++  // It's possible that scale factor changed between Lock() and Commit()
++  // but window size is the same.
++  // Don't attach such buffer as it may have incorrect size,
++  // we'll paint new content soon.
++  if (moz_container_wayland_size_matches_scale_factor_locked(
++          aProofOfLock, container, mWindowSize.width, mWindowSize.height)) {
++    mInProgressBuffer->AttachAndCommit(waylandSurface);
++  }
+ 
+   mInProgressBuffer->ResetBufferAge();
+   mFrontBuffer = mInProgressBuffer;
+   mFrontBufferInvalidRegion = aInvalidRegion;
+   mInProgressBuffer = nullptr;
+
diff --git a/firefox-107.0.1-kde.patch b/firefox-107.0.1-kde.patch
index b872e14..fbfd4be 100644
--- a/firefox-107.0.1-kde.patch
+++ b/firefox-107.0.1-kde.patch
@@ -1,25 +1,7 @@
-# HG changeset patch
-# User msirringhaus@suse.de
-# Date 1559300151 -7200
-#      Fri May 31 12:55:51 2019 +0200
-# Node ID 54d41b0033b8d649d842a1f862c6fed8b9874dec
-# Parent  c9baf1c9eb9359b7968a52157e8892cdd20f2c6d
-How to apply this patch:
-1. Import and apply it
-2. cp browser/base/content/browser.xul browser/base/content/browser-kde.xul
-3. Find editBookmarkPanelDoneButton
-4. Replace #ifndef with #ifdef in the line above (this hanges the button order from Gnome-style to KDE-style)
-5. hg qrefresh
-
-diff --git a/browser/components/preferences/main.js b/browser/components/preferences/main.js
---- a/browser/components/preferences/main.js
-+++ b/browser/components/preferences/main.js
-@@ -303,16 +303,23 @@ var gMainPane = {
-         }, backoffTimes[this._backoffIndex + 1 < backoffTimes.length ? this._backoffIndex++ : backoffTimes.length - 1]);
-       };
- 
-       window.setTimeout(() => {
-         window.requestIdleCallback(pollForDefaultBrowser);
+diff -up firefox-111.0/browser/components/preferences/main.js.1~ firefox-111.0/browser/components/preferences/main.js
+--- firefox-111.0/browser/components/preferences/main.js.1~	2023-03-10 01:01:02.000000000 +0100
++++ firefox-111.0/browser/components/preferences/main.js	2023-03-13 22:04:44.877132062 +0100
+@@ -301,6 +301,13 @@ var gMainPane = {
        }, backoffTimes[this._backoffIndex]);
      }
  
@@ -33,17 +15,7 @@ diff --git a/browser/components/preferences/main.js b/browser/components/prefere
      this.initBrowserContainers();
      this.buildContentProcessCountMenuList();
  
-     let performanceSettingsLink = document.getElementById(
-       "performanceSettingsLearnMore"
-     );
-     let performanceSettingsUrl =
-       Services.urlFormatter.formatURLPref("app.support.baseURL") +
-@@ -1334,16 +1341,27 @@ var gMainPane = {
-       this._backoffIndex = 0;
- 
-       let shellSvc = getShellService();
-       if (!shellSvc) {
-         return;
+@@ -1303,6 +1310,17 @@ var gMainPane = {
        }
        try {
          shellSvc.setDefaultBrowser(true, false);
@@ -59,22 +31,12 @@ diff --git a/browser/components/preferences/main.js b/browser/components/prefere
 +          process.run(false, args, args.length);
 +        }
        } catch (ex) {
-         Cu.reportError(ex);
+         console.error(ex);
          return;
-       }
- 
-       let isDefault = shellSvc.isDefaultBrowser(false, true);
-       let setDefaultPane = document.getElementById("setDefaultPane");
-       setDefaultPane.classList.toggle("is-default", isDefault);
-diff --git a/browser/components/shell/moz.build b/browser/components/shell/moz.build
---- a/browser/components/shell/moz.build
-+++ b/browser/components/shell/moz.build
-@@ -31,16 +31,18 @@ if CONFIG["MOZ_WIDGET_TOOLKIT"] == "coco
-     ]
- elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk":
-     XPIDL_SOURCES += [
-         "nsIGNOMEShellService.idl",
-     ]
+diff -up firefox-111.0/browser/components/shell/moz.build.1~ firefox-111.0/browser/components/shell/moz.build
+--- firefox-111.0/browser/components/shell/moz.build.1~	2023-03-10 01:01:02.000000000 +0100
++++ firefox-111.0/browser/components/shell/moz.build	2023-03-13 22:02:54.952405761 +0100
+@@ -36,6 +36,8 @@ elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "gt
  
      SOURCES += [
          "nsGNOMEShellService.cpp",
@@ -83,15 +45,9 @@ diff --git a/browser/components/shell/moz.build b/browser/components/shell/moz.b
      ]
      if CONFIG["MOZ_ENABLE_DBUS"]:
          SOURCES += [
-             "nsGNOMEShellDBusHelper.cpp",
-             "nsGNOMEShellSearchProvider.cpp",
-         ]
-         include("/ipc/chromium/chromium-config.mozbuild")
- 
-diff --git a/browser/components/shell/nsKDEShellService.cpp b/browser/components/shell/nsKDEShellService.cpp
-new file mode 100644
---- /dev/null
-+++ b/browser/components/shell/nsKDEShellService.cpp
+diff -up firefox-111.0/browser/components/shell/nsKDEShellService.cpp.1~ firefox-111.0/browser/components/shell/nsKDEShellService.cpp
+--- firefox-111.0/browser/components/shell/nsKDEShellService.cpp.1~	2023-03-13 22:02:54.952405761 +0100
++++ firefox-111.0/browser/components/shell/nsKDEShellService.cpp	2023-03-13 22:02:54.952405761 +0100
 @@ -0,0 +1,109 @@
 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 +/* This Source Code Form is subject to the terms of the Mozilla Public
@@ -202,10 +158,9 @@ new file mode 100644
 +    return NS_ERROR_NOT_IMPLEMENTED;
 +}
 +
-diff --git a/browser/components/shell/nsKDEShellService.h b/browser/components/shell/nsKDEShellService.h
-new file mode 100644
---- /dev/null
-+++ b/browser/components/shell/nsKDEShellService.h
+diff -up firefox-111.0/browser/components/shell/nsKDEShellService.h.1~ firefox-111.0/browser/components/shell/nsKDEShellService.h
+--- firefox-111.0/browser/components/shell/nsKDEShellService.h.1~	2023-03-13 22:02:54.952405761 +0100
++++ firefox-111.0/browser/components/shell/nsKDEShellService.h	2023-03-13 22:02:54.952405761 +0100
 @@ -0,0 +1,32 @@
 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 +/* This Source Code Form is subject to the terms of the Mozilla Public
@@ -239,10 +194,9 @@ new file mode 100644
 +};
 +
 +#endif // nskdeshellservice_h____
-diff --git a/browser/components/shell/nsUnixShellService.cpp b/browser/components/shell/nsUnixShellService.cpp
-new file mode 100644
---- /dev/null
-+++ b/browser/components/shell/nsUnixShellService.cpp
+diff -up firefox-111.0/browser/components/shell/nsUnixShellService.cpp.1~ firefox-111.0/browser/components/shell/nsUnixShellService.cpp
+--- firefox-111.0/browser/components/shell/nsUnixShellService.cpp.1~	2023-03-13 22:02:54.953405768 +0100
++++ firefox-111.0/browser/components/shell/nsUnixShellService.cpp	2023-03-13 22:02:54.952405761 +0100
 @@ -0,0 +1,22 @@
 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 +/* This Source Code Form is subject to the terms of the Mozilla Public
@@ -266,10 +220,9 @@ new file mode 100644
 +        return nsKDEShellServiceConstructor( aIID, aResult );
 +    return nsGNOMEShellServiceConstructor( aIID, aResult );
 +}
-diff --git a/browser/components/shell/nsUnixShellService.h b/browser/components/shell/nsUnixShellService.h
-new file mode 100644
---- /dev/null
-+++ b/browser/components/shell/nsUnixShellService.h
+diff -up firefox-111.0/browser/components/shell/nsUnixShellService.h.1~ firefox-111.0/browser/components/shell/nsUnixShellService.h
+--- firefox-111.0/browser/components/shell/nsUnixShellService.h.1~	2023-03-13 22:02:54.953405768 +0100
++++ firefox-111.0/browser/components/shell/nsUnixShellService.h	2023-03-13 22:02:54.953405768 +0100
 @@ -0,0 +1,15 @@
 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 +/* This Source Code Form is subject to the terms of the Mozilla Public
diff --git a/firefox-112.0-commasplit.patch b/firefox-112.0-commasplit.patch
new file mode 100644
index 0000000..a56aec4
--- /dev/null
+++ b/firefox-112.0-commasplit.patch
@@ -0,0 +1,76 @@
+--- firefox-111.0.1/build/moz.configure/rust.configure	2023-03-21 06:16:03.000000000 -0700
++++ firefox-111.0.1/build/moz.configure/rust.configure.new	2023-04-05 08:57:29.403219120 -0700
+@@ -593,7 +593,7 @@
+ 
+ # ==============================================================
+ 
+-option(env="RUSTFLAGS", nargs=1, help="Rust compiler flags")
++option(env="RUSTFLAGS", nargs=1, help="Rust compiler flags", comma_split=False)
+ set_config("RUSTFLAGS", depends("RUSTFLAGS")(lambda flags: flags))
+ 
+ 
+--- firefox-111.0.1/python/mozbuild/mozbuild/configure/options.py	2023-03-21 06:16:09.000000000 -0700
++++ firefox-111.0.1/python/mozbuild/mozbuild/configure/options.py.new	2023-04-05 08:57:31.270193468 -0700
+@@ -191,6 +191,10 @@
+       to instantiate an option indirectly. Set this to a positive integer to
+       force the script to look into a deeper stack frame when inferring the
+       `category`.
++    - `comma_split` specifies whether the value string should be split on
++      commas. The default is True. Setting it False is necessary for things
++      like compiler flags which should be a single string that may contain
++      commas.
+     """
+ 
+     __slots__ = (
+@@ -205,6 +209,7 @@
+         "possible_origins",
+         "category",
+         "define_depth",
++        "comma_split",
+     )
+ 
+     def __init__(
+@@ -218,6 +223,7 @@
+         category=None,
+         help=None,
+         define_depth=0,
++        comma_split=True,
+     ):
+         if not name and not env:
+             raise InvalidOptionError(
+@@ -335,9 +341,10 @@
+         self.choices = choices
+         self.help = help
+         self.category = category or _infer_option_category(define_depth)
++        self.comma_split = comma_split
+ 
+     @staticmethod
+-    def split_option(option):
++    def split_option(option, comma_split=True):
+         """Split a flag or variable into a prefix, a name and values
+ 
+         Variables come in the form NAME=values (no prefix).
+@@ -350,7 +357,13 @@
+ 
+         elements = option.split("=", 1)
+         name = elements[0]
+-        values = tuple(elements[1].split(",")) if len(elements) == 2 else ()
++        if len(elements) == 2:
++            if comma_split:
++                values = tuple(elements[1].split(","))
++            else:
++                values = (elements[1],)
++        else:
++            values = ()
+         if name.startswith("--"):
+             name = name[2:]
+             if not name.islower():
+@@ -426,7 +439,7 @@
+                 % (option, origin, ", ".join(self.possible_origins))
+             )
+ 
+-        prefix, name, values = self.split_option(option)
++        prefix, name, values = self.split_option(option, self.comma_split)
+         option = self._join_option(prefix, name)
+ 
+         assert name in (self.name, self.env)
diff --git a/firefox-112.0.1-no-static-libstdc++.patch b/firefox-112.0.1-no-static-libstdc++.patch
new file mode 100644
index 0000000..efafb8c
--- /dev/null
+++ b/firefox-112.0.1-no-static-libstdc++.patch
@@ -0,0 +1,44 @@
+diff -up firefox-112.0.1/memory/replace/logalloc/replay/moz.build.omv~ firefox-112.0.1/memory/replace/logalloc/replay/moz.build
+--- firefox-112.0.1/memory/replace/logalloc/replay/moz.build.omv~	2023-04-24 23:42:13.903890709 +0200
++++ firefox-112.0.1/memory/replace/logalloc/replay/moz.build	2023-04-24 23:42:21.526954354 +0200
+@@ -21,9 +21,6 @@ if CONFIG["OS_TARGET"] == "WINNT":
+         "/mozglue/misc/ProcessType.cpp",
+     ]
+ 
+-if CONFIG["OS_TARGET"] == "Linux":
+-    LDFLAGS += ["-static-libstdc++"]
+-
+ if CONFIG["OS_TARGET"] == "Darwin":
+     # Work around "warning: 'aligned_alloc' is only available on macOS 10.15 or newer"
+     # when building with MACOSX_DEPLOYMENT_TARGET < 10.15 with >= 10.15 SDK.
+diff -up firefox-112.0.1/third_party/jpeg-xl/CMakeLists.txt.omv~ firefox-112.0.1/third_party/jpeg-xl/CMakeLists.txt
+--- firefox-112.0.1/third_party/jpeg-xl/CMakeLists.txt.omv~	2023-04-24 23:42:52.833216472 +0200
++++ firefox-112.0.1/third_party/jpeg-xl/CMakeLists.txt	2023-04-24 23:43:14.731400505 +0200
+@@ -200,7 +200,7 @@ if(JPEGXL_STATIC)
+   if (NOT MSVC AND NOT APPLE)
+     set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
+     set(CMAKE_EXE_LINKER_FLAGS
+-        "${CMAKE_EXE_LINKER_FLAGS} -static -static-libgcc -static-libstdc++")
++        "${CMAKE_EXE_LINKER_FLAGS}")
+   endif()
+ endif()  # JPEGXL_STATIC
+ 
+diff -up firefox-112.0.1/third_party/libwebrtc/build/config/chromecast/BUILD.gn.omv~ firefox-112.0.1/third_party/libwebrtc/build/config/chromecast/BUILD.gn
+--- firefox-112.0.1/third_party/libwebrtc/build/config/chromecast/BUILD.gn.omv~	2023-04-24 23:42:33.599055289 +0200
++++ firefox-112.0.1/third_party/libwebrtc/build/config/chromecast/BUILD.gn	2023-04-24 23:42:45.376153928 +0200
+@@ -14,15 +14,6 @@ config("static_config") {
+       # http://b/26390825
+       "-Wl,--exclude-libs=libffmpeg.a",
+     ]
+-
+-    if (!is_android) {
+-      ldflags += [
+-        # We want to statically link libstdc++/libgcc on Linux.
+-        # (On Android, libstdc++ and libgcc aren't used.)
+-        "-static-libstdc++",
+-        "-static-libgcc",
+-      ]
+-    }
+   }
+ }
+ 
diff --git a/firefox-enable-vaapi.patch b/firefox-enable-vaapi.patch
index 7d8fdf0..dbe92bc 100644
--- a/firefox-enable-vaapi.patch
+++ b/firefox-enable-vaapi.patch
@@ -1,11 +1,10 @@
-diff -up firefox-104.0/gfx/thebes/gfxPlatformGtk.cpp.firefox-enable-vaapi firefox-104.0/gfx/thebes/gfxPlatformGtk.cpp
-diff -up firefox-104.0/widget/gtk/GfxInfo.cpp.firefox-enable-vaapi firefox-104.0/widget/gtk/GfxInfo.cpp
---- firefox-104.0/widget/gtk/GfxInfo.cpp.firefox-enable-vaapi	2022-08-16 15:14:53.014042400 +0200
-+++ firefox-104.0/widget/gtk/GfxInfo.cpp	2022-08-16 15:15:30.482301677 +0200
-@@ -873,15 +873,6 @@ const nsTArray<GfxDriverInfo>& GfxInfo::
+diff -up firefox-112.0/widget/gtk/GfxInfo.cpp.firefox-enable-vaapi firefox-112.0/widget/gtk/GfxInfo.cpp
+--- firefox-112.0/widget/gtk/GfxInfo.cpp.firefox-enable-vaapi	2023-04-05 11:10:14.156695694 +0200
++++ firefox-112.0/widget/gtk/GfxInfo.cpp	2023-04-05 11:11:40.697665718 +0200
+@@ -810,14 +810,6 @@ const nsTArray<GfxDriverInfo>& GfxInfo::
          nsIGfxInfo::FEATURE_BLOCKED_DEVICE, DRIVER_COMPARISON_IGNORED,
          V(0, 0, 0, 0), "FEATURE_HARDWARE_VIDEO_DECODING_NO_LINUX_AMD", "");
-
+ 
 -    // Disable on Release/late Beta
 -#if !defined(EARLY_BETA_OR_EARLIER)
 -    APPEND_TO_DRIVER_BLOCKLIST(OperatingSystem::Linux, DeviceFamily::All,
@@ -14,7 +13,6 @@ diff -up firefox-104.0/widget/gtk/GfxInfo.cpp.firefox-enable-vaapi firefox-104.0
 -                               DRIVER_COMPARISON_IGNORED, V(0, 0, 0, 0),
 -                               "FEATURE_HARDWARE_VIDEO_DECODING_DISABLE", "");
 -#endif
--
      ////////////////////////////////////
-     // FEATURE_WEBRENDER_PARTIAL_PRESENT
-     APPEND_TO_DRIVER_BLOCKLIST_EXT(
+     // FEATURE_HW_DECODED_VIDEO_ZERO_COPY - ALLOWLIST
+     APPEND_TO_DRIVER_BLOCKLIST2(OperatingSystem::Linux, DeviceFamily::All,
diff --git a/firefox-gcc-13-build.patch b/firefox-gcc-13-build.patch
new file mode 100644
index 0000000..8512b76
--- /dev/null
+++ b/firefox-gcc-13-build.patch
@@ -0,0 +1,24 @@
+--- firefox-109.0.1/gfx/2d/Rect.h.old   2023-02-07 09:44:24.946279843 +0100
++++ firefox-109.0.1/gfx/2d/Rect.h       2023-02-07 09:44:47.969032049 +0100
+@@ -324,8 +324,8 @@ IntRectTyped<Units> RoundedToInt(const R
+
+ template <class Units>
+ bool RectIsInt32Safe(const RectTyped<Units>& aRect) {
+-  float min = (float)std::numeric_limits<std::int32_t>::min();
+-  float max = (float)std::numeric_limits<std::int32_t>::max();
++  float min = (float)std::numeric_limits<int32_t>::min();
++  float max = (float)std::numeric_limits<int32_t>::max();
+   return aRect.x > min && aRect.y > min && aRect.width < max &&
+          aRect.height < max && aRect.XMost() < max && aRect.YMost() < max;
+ }
+diff -up firefox-109.0.1/toolkit/components/telemetry/pingsender/pingsender.cpp.old firefox-109.0.1/toolkit/components/telemetry/pingsender/pingsender.cpp
+--- firefox-109.0.1/toolkit/components/telemetry/pingsender/pingsender.cpp.old  2023-02-07 11:03:41.788720090 +0100
++++ firefox-109.0.1/toolkit/components/telemetry/pingsender/pingsender.cpp      2023-02-07 11:04:29.195345659 +0100
+@@ -10,6 +10,7 @@
+ #include <iomanip>
+ #include <string>
+ #include <vector>
++#include <cstdint>
+
+ #include <zlib.h>
+
diff --git a/firefox-glibc-dynstack.patch b/firefox-glibc-dynstack.patch
deleted file mode 100644
index b0487d7..0000000
--- a/firefox-glibc-dynstack.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-diff -ur firefox-90.0.orig/js/xpconnect/src/XPCJSContext.cpp firefox-90.0/js/xpconnect/src/XPCJSContext.cpp
---- firefox-90.0.orig/js/xpconnect/src/XPCJSContext.cpp	2021-07-05 21:16:02.000000000 +0200
-+++ firefox-90.0/js/xpconnect/src/XPCJSContext.cpp	2021-07-19 15:01:24.083460460 +0200
-@@ -85,14 +85,6 @@
- using namespace xpc;
- using namespace JS;
- 
--// The watchdog thread loop is pretty trivial, and should not require much stack
--// space to do its job. So only give it 32KiB or the platform minimum.
--#if !defined(PTHREAD_STACK_MIN)
--#  define PTHREAD_STACK_MIN 0
--#endif
--static constexpr size_t kWatchdogStackSize =
--    PTHREAD_STACK_MIN < 32 * 1024 ? 32 * 1024 : PTHREAD_STACK_MIN;
--
- static void WatchdogMain(void* arg);
- class Watchdog;
- class WatchdogManager;
-@@ -163,7 +155,7 @@
-       // watchdog, we need to join it on shutdown.
-       mThread = PR_CreateThread(PR_USER_THREAD, WatchdogMain, this,
-                                 PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
--                                PR_JOINABLE_THREAD, kWatchdogStackSize);
-+                                PR_JOINABLE_THREAD, 0);
-       if (!mThread) {
-         MOZ_CRASH("PR_CreateThread failed!");
-       }
-Only in firefox-90.0/js/xpconnect/src: XPCJSContext.cpp.firefox-glibc-dynstack
-diff -ur firefox-90.0.orig/security/sandbox/linux/launch/SandboxLaunch.cpp firefox-90.0/security/sandbox/linux/launch/SandboxLaunch.cpp
---- firefox-90.0.orig/security/sandbox/linux/launch/SandboxLaunch.cpp	2021-07-05 18:20:36.000000000 +0200
-+++ firefox-90.0/security/sandbox/linux/launch/SandboxLaunch.cpp	2021-07-20 08:39:17.272136982 +0200
-@@ -501,8 +501,7 @@
- MOZ_NEVER_INLINE MOZ_ASAN_BLACKLIST static pid_t DoClone(int aFlags,
-                                                          jmp_buf* aCtx) {
-   static constexpr size_t kStackAlignment = 16;
--  uint8_t miniStack[PTHREAD_STACK_MIN]
--      __attribute__((aligned(kStackAlignment)));
-+  uint8_t miniStack[4096] __attribute__((aligned(kStackAlignment)));
- #ifdef __hppa__
-   void* stackPtr = miniStack;
- #else
-@@ -523,13 +522,19 @@
-                                CLONE_CHILD_CLEARTID;
-   MOZ_RELEASE_ASSERT((aFlags & kBadFlags) == 0);
- 
-+  // Block signals due to small stack in DoClone.
-+  sigset_t oldSigs;
-+  BlockAllSignals(&oldSigs);
-+
-+  int ret = 0;
-   jmp_buf ctx;
-   if (setjmp(ctx) == 0) {
-     // In the parent and just called setjmp:
--    return DoClone(aFlags | SIGCHLD, &ctx);
-+    ret = DoClone(aFlags | SIGCHLD, &ctx);
-   }
-+  RestoreSignals(&oldSigs);
-   // In the child and have longjmp'ed:
--  return 0;
-+  return ret;
- }
- 
- static bool WriteStringToFile(const char* aPath, const char* aStr,
-Only in firefox-90.0/security/sandbox/linux/launch: SandboxLaunch.cpp~
diff --git a/firefox.spec b/firefox.spec
index 78a7f40..9abd7bb 100644
--- a/firefox.spec
+++ b/firefox.spec
@@ -239,8 +239,8 @@ Name:		firefox
 Epoch:		0
 # IMPORTANT: When updating, you MUST also update the l10n files by running
 # download.sh after editing the version number
-Version:	108.0
-Release:	%{?beta:0.%{beta}.1}1
+Version:	112.0.2
+Release:	%{?beta:0.%{beta}.}1
 License:	MPLv1+
 Group:		Networking/WWW
 Url:		http://www.mozilla.com/firefox/
@@ -272,11 +272,24 @@ Source100:      firefox.rpmlintrc
 Patch11:	firefox-107.0.1-kde.patch
 Patch12:	mozilla-107.0.1-kde.patch
 
-Patch14:	build-aarch64-skia.patch
 Patch15:	build-arm-libopus.patch
 Patch16:	firefox-103.0-glibc-2.36.patch
-
-Patch50:    	https://src.fedoraproject.org/rpms/firefox/blob/rawhide/f/firefox-enable-vaapi.patch
+Patch17:	firefox-112.0.1-no-static-libstdc++.patch
+
+Patch50:    	https://src.fedoraproject.org/rpms/firefox/raw/rawhide/f/firefox-enable-vaapi.patch
+Patch51:	https://src.fedoraproject.org/rpms/firefox/raw/rawhide/f/0001-GLIBCXX-fix-for-GCC-12.patch
+Patch52:	https://src.fedoraproject.org/rpms/firefox/raw/rawhide/f/build-aarch64-skia.patch
+Patch55:	https://src.fedoraproject.org/rpms/firefox/raw/rawhide/f/D173814.diff
+Patch57:	https://src.fedoraproject.org/rpms/firefox/raw/rawhide/f/firefox-112.0-commasplit.patch
+Patch58:	https://src.fedoraproject.org/rpms/firefox/raw/rawhide/f/firefox-gcc-13-build.patch
+Patch60:	https://src.fedoraproject.org/rpms/firefox/raw/rawhide/f/libwebrtc-pipewire-capturer-import-dmabuf-directly-into-desktop-frame.patch
+Patch61:	https://src.fedoraproject.org/rpms/firefox/raw/rawhide/f/mozilla-1196777.patch
+Patch62:	https://src.fedoraproject.org/rpms/firefox/raw/rawhide/f/mozilla-1516803.patch
+Patch63:	https://src.fedoraproject.org/rpms/firefox/raw/rawhide/f/mozilla-1663844.patch
+#Patch64:	https://src.fedoraproject.org/rpms/firefox/raw/rawhide/f/mozilla-1667096.patch
+Patch65:	https://src.fedoraproject.org/rpms/firefox/raw/rawhide/f/mozilla-1669639.patch
+Patch66:	https://src.fedoraproject.org/rpms/firefox/raw/rawhide/f/mozilla-1670333.patch
+Patch67:	https://src.fedoraproject.org/rpms/firefox/raw/rawhide/f/mozilla-1775202.patch
 
 BuildRequires:	doxygen
 BuildRequires:	makedepend
@@ -331,7 +344,7 @@ BuildRequires:	pkgconfig(libproxy-1.0)
 BuildRequires:	pkgconfig(libpulse)
 BuildRequires:	pkgconfig(libstartup-notification-1.0)
 BuildRequires:	pkgconfig(nspr) >= 4.32.0
-BuildRequires:	pkgconfig(nss) >= 3.85
+BuildRequires:	pkgconfig(nss) >= 3.87
 BuildRequires:	pkgconfig(ogg)
 BuildRequires:	pkgconfig(opus)
 BuildRequires:	pkgconfig(libpulse)
@@ -480,7 +493,7 @@ ac_add_options --enable-system-ffi
 ac_add_options --with-unsigned-addon-scopes=app,system
 ac_add_options --allow-addon-sideload
 ac_add_options --without-wasm-sandboxed-libraries
-%ifarch aarch64
+%ifarch %{aarch64}
 ac_add_options --enable-rust-simd
 %endif
 %ifarch %{arm}
@@ -500,6 +513,10 @@ ac_add_options MOZ_PGO=1
 %endif
 ac_add_options --disable-lto
 
+# We don't care about binary compatibility
+# with prehistoric libstdc++ versions. No need
+# to bloat things
+unset MOZ_STDCXX_COMPAT
 EOF
 
 %build
diff --git a/libwebrtc-pipewire-capturer-import-dmabuf-directly-into-desktop-frame.patch b/libwebrtc-pipewire-capturer-import-dmabuf-directly-into-desktop-frame.patch
new file mode 100644
index 0000000..69f9df2
--- /dev/null
+++ b/libwebrtc-pipewire-capturer-import-dmabuf-directly-into-desktop-frame.patch
@@ -0,0 +1,505 @@
+From d9faa73cbbc186d7dd0dbfce0589012a0bed9f17 Mon Sep 17 00:00:00 2001
+From: Jan Grulich <grulja@gmail.com>
+Date: Fri, 17 Mar 2023 10:58:10 +0100
+Subject: [PATCH] PipeWire capturer: import DMABufs directly into desktop frame
+
+Originally DMABufs were imported into a temporary buffer followed by a
+copy operation into the desktop frame itself. This is not needed as we
+can import them directly into desktop frames and avoid this overhead.
+
+Also drop support for MemPtr buffers as both Mutter and KWin don't seem
+to support them and they are going to be too slow anyway.
+
+Testing with latest Chromium, I could see two processes with usage around 20% and 40% without this change going down to 10% and 20% with
+this change applied.
+
+Bug: webrtc:13429
+Bug: chrome:1378258
+Change-Id: Ice3292528ff56300931c8638f8e03d4883d5e331
+Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/297501
+Reviewed-by: Alexander Cooper <alcooper@chromium.org>
+Commit-Queue: Jan Grulich <grulja@gmail.com>
+Cr-Commit-Position: refs/heads/main@{#39594}
+---
+
+diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/egl_dmabuf.cc b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/egl_dmabuf.cc
+index 5bbd5d7aba..b529077c6d 100644
+--- a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/egl_dmabuf.cc
++++ b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/egl_dmabuf.cc
+@@ -101,11 +101,23 @@ typedef void (*glDeleteTextures_func)(GLsizei n, const GLuint* textures);
+ typedef void (*glGenTextures_func)(GLsizei n, GLuint* textures);
+ typedef GLenum (*glGetError_func)(void);
+ typedef const GLubyte* (*glGetString_func)(GLenum name);
+-typedef void (*glGetTexImage_func)(GLenum target,
+-                                   GLint level,
+-                                   GLenum format,
+-                                   GLenum type,
+-                                   void* pixels);
++typedef void (*glReadPixels_func)(GLint x,
++                                  GLint y,
++                                  GLsizei width,
++                                  GLsizei height,
++                                  GLenum format,
++                                  GLenum type,
++                                  void* data);
++typedef void (*glGenFramebuffers_func)(GLsizei n, GLuint* ids);
++typedef void (*glDeleteFramebuffers_func)(GLsizei n,
++                                          const GLuint* framebuffers);
++typedef void (*glBindFramebuffer_func)(GLenum target, GLuint framebuffer);
++typedef void (*glFramebufferTexture2D_func)(GLenum target,
++                                            GLenum attachment,
++                                            GLenum textarget,
++                                            GLuint texture,
++                                            GLint level);
++typedef GLenum (*glCheckFramebufferStatus_func)(GLenum target);
+ typedef void (*glTexParameteri_func)(GLenum target, GLenum pname, GLint param);
+ typedef void* (*glXGetProcAddressARB_func)(const char*);
+
+@@ -118,7 +130,12 @@ glDeleteTextures_func GlDeleteTextures = nullptr;
+ glGenTextures_func GlGenTextures = nullptr;
+ glGetError_func GlGetError = nullptr;
+ glGetString_func GlGetString = nullptr;
+-glGetTexImage_func GlGetTexImage = nullptr;
++glReadPixels_func GlReadPixels = nullptr;
++glGenFramebuffers_func GlGenFramebuffers = nullptr;
++glDeleteFramebuffers_func GlDeleteFramebuffers = nullptr;
++glBindFramebuffer_func GlBindFramebuffer = nullptr;
++glFramebufferTexture2D_func GlFramebufferTexture2D = nullptr;
++glCheckFramebufferStatus_func GlCheckFramebufferStatus = nullptr;
+ glTexParameteri_func GlTexParameteri = nullptr;
+ glXGetProcAddressARB_func GlXGetProcAddressARB = nullptr;
+
+@@ -279,12 +296,26 @@ static bool LoadGL() {
+         (glDeleteTextures_func)GlXGetProcAddressARB("glDeleteTextures");
+     GlGenTextures = (glGenTextures_func)GlXGetProcAddressARB("glGenTextures");
+     GlGetError = (glGetError_func)GlXGetProcAddressARB("glGetError");
+-    GlGetTexImage = (glGetTexImage_func)GlXGetProcAddressARB("glGetTexImage");
++    GlReadPixels = (glReadPixels_func)GlXGetProcAddressARB("glReadPixels");
++    GlGenFramebuffers =
++        (glGenFramebuffers_func)GlXGetProcAddressARB("glGenFramebuffers");
++    GlDeleteFramebuffers =
++        (glDeleteFramebuffers_func)GlXGetProcAddressARB("glDeleteFramebuffers");
++    GlBindFramebuffer =
++        (glBindFramebuffer_func)GlXGetProcAddressARB("glBindFramebuffer");
++    GlFramebufferTexture2D = (glFramebufferTexture2D_func)GlXGetProcAddressARB(
++        "glFramebufferTexture2D");
++    GlCheckFramebufferStatus =
++        (glCheckFramebufferStatus_func)GlXGetProcAddressARB(
++            "glCheckFramebufferStatus");
++
+     GlTexParameteri =
+         (glTexParameteri_func)GlXGetProcAddressARB("glTexParameteri");
+
+     return GlBindTexture && GlDeleteTextures && GlGenTextures && GlGetError &&
+-           GlGetTexImage && GlTexParameteri;
++           GlReadPixels && GlGenFramebuffers && GlDeleteFramebuffers &&
++           GlBindFramebuffer && GlFramebufferTexture2D &&
++           GlCheckFramebufferStatus && GlTexParameteri;
+   }
+
+   return false;
+@@ -435,6 +466,14 @@ EglDmaBuf::~EglDmaBuf() {
+     EglTerminate(egl_.display);
+   }
+
++  if (fbo_) {
++    GlDeleteFramebuffers(1, &fbo_);
++  }
++
++  if (texture_) {
++    GlDeleteTextures(1, &texture_);
++  }
++
+   // BUG: crbug.com/1290566
+   // Closing libEGL.so.1 when using NVidia drivers causes a crash
+   // when EglGetPlatformDisplayEXT() is used, at least this one is enough
+@@ -466,20 +505,20 @@ bool EglDmaBuf::GetClientExtensions(EGLDisplay dpy, EGLint name) {
+ }
+
+ RTC_NO_SANITIZE("cfi-icall")
+-std::unique_ptr<uint8_t[]> EglDmaBuf::ImageFromDmaBuf(
+-    const DesktopSize& size,
+-    uint32_t format,
+-    const std::vector<PlaneData>& plane_datas,
+-    uint64_t modifier) {
+-  std::unique_ptr<uint8_t[]> src;
+-
++bool EglDmaBuf::ImageFromDmaBuf(const DesktopSize& size,
++                                uint32_t format,
++                                const std::vector<PlaneData>& plane_datas,
++                                uint64_t modifier,
++                                const DesktopVector& offset,
++                                const DesktopSize& buffer_size,
++                                uint8_t* data) {
+   if (!egl_initialized_) {
+-    return src;
++    return false;
+   }
+
+   if (plane_datas.size() <= 0) {
+     RTC_LOG(LS_ERROR) << "Failed to process buffer: invalid number of planes";
+-    return src;
++    return false;
+   }
+
+   EGLint attribs[47];
+@@ -568,20 +607,32 @@ std::unique_ptr<uint8_t[]> EglDmaBuf::ImageFromDmaBuf(
+   if (image == EGL_NO_IMAGE) {
+     RTC_LOG(LS_ERROR) << "Failed to record frame: Error creating EGLImage - "
+                       << FormatEGLError(EglGetError());
+-    return src;
++    return false;
+   }
+
+   // create GL 2D texture for framebuffer
+-  GLuint texture;
+-  GlGenTextures(1, &texture);
+-  GlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+-  GlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+-  GlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+-  GlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+-  GlBindTexture(GL_TEXTURE_2D, texture);
++  if (!texture_) {
++    GlGenTextures(1, &texture_);
++    GlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
++    GlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
++    GlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
++    GlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
++  }
++  GlBindTexture(GL_TEXTURE_2D, texture_);
+   GlEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
+
+-  src = std::make_unique<uint8_t[]>(plane_datas[0].stride * size.height());
++  if (!fbo_) {
++    GlGenFramebuffers(1, &fbo_);
++  }
++
++  GlBindFramebuffer(GL_FRAMEBUFFER, fbo_);
++  GlFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
++                         texture_, 0);
++  if (GlCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
++    RTC_LOG(LS_ERROR) << "Failed to bind DMA buf framebuffer";
++    EglDestroyImageKHR(egl_.display, image);
++    return false;
++  }
+
+   GLenum gl_format = GL_BGRA;
+   switch (format) {
+@@ -598,17 +649,18 @@ std::unique_ptr<uint8_t[]> EglDmaBuf::ImageFromDmaBuf(
+       gl_format = GL_BGRA;
+       break;
+   }
+-  GlGetTexImage(GL_TEXTURE_2D, 0, gl_format, GL_UNSIGNED_BYTE, src.get());
+
+-  if (GlGetError()) {
++  GlReadPixels(offset.x(), offset.y(), buffer_size.width(),
++               buffer_size.height(), gl_format, GL_UNSIGNED_BYTE, data);
++
++  const GLenum error = GlGetError();
++  if (error) {
+     RTC_LOG(LS_ERROR) << "Failed to get image from DMA buffer.";
+-    return src;
+   }
+
+-  GlDeleteTextures(1, &texture);
+   EglDestroyImageKHR(egl_.display, image);
+
+-  return src;
++  return !error;
+ }
+
+ RTC_NO_SANITIZE("cfi-icall")
+diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/egl_dmabuf.h b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/egl_dmabuf.h
+index f1d96b2f80..22a8f5ab52 100644
+--- a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/egl_dmabuf.h
++++ b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/egl_dmabuf.h
+@@ -41,11 +41,15 @@ class EglDmaBuf {
+   EglDmaBuf();
+   ~EglDmaBuf();
+
+-  std::unique_ptr<uint8_t[]> ImageFromDmaBuf(
+-      const DesktopSize& size,
+-      uint32_t format,
+-      const std::vector<PlaneData>& plane_datas,
+-      uint64_t modifiers);
++  // Returns whether the image was successfully imported from
++  // given DmaBuf and its parameters
++  bool ImageFromDmaBuf(const DesktopSize& size,
++                       uint32_t format,
++                       const std::vector<PlaneData>& plane_datas,
++                       uint64_t modifiers,
++                       const DesktopVector& offset,
++                       const DesktopSize& buffer_size,
++                       uint8_t* data);
+   std::vector<uint64_t> QueryDmaBufModifiers(uint32_t format);
+
+   bool IsEglInitialized() const { return egl_initialized_; }
+@@ -58,6 +62,8 @@ class EglDmaBuf {
+   int32_t drm_fd_ = -1;               // for GBM buffer mmap
+   gbm_device* gbm_device_ = nullptr;  // for passed GBM buffer retrieval
+
++  GLuint fbo_ = 0;
++  GLuint texture_ = 0;
+   EGLStruct egl_;
+
+   absl::optional<std::string> GetRenderNode();
+diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
+index 0ca75d00fc..a8879764c7 100644
+--- a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
++++ b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
+@@ -149,6 +149,12 @@ class SharedScreenCastStreamPrivate {
+   struct spa_video_info_raw spa_video_format_;
+
+   void ProcessBuffer(pw_buffer* buffer);
++  bool ProcessMemFDBuffer(pw_buffer* buffer,
++                          DesktopFrame& frame,
++                          const DesktopVector& offset);
++  bool ProcessDMABuffer(pw_buffer* buffer,
++                        DesktopFrame& frame,
++                        const DesktopVector& offset);
+   void ConvertRGBxToBGRx(uint8_t* frame, uint32_t size);
+
+   // PipeWire callbacks
+@@ -268,9 +274,8 @@ void SharedScreenCastStreamPrivate::OnStreamParamChanged(
+   std::vector<const spa_pod*> params;
+   const int buffer_types =
+       has_modifier || (that->pw_server_version_ >= kDmaBufMinVersion)
+-          ? (1 << SPA_DATA_DmaBuf) | (1 << SPA_DATA_MemFd) |
+-                (1 << SPA_DATA_MemPtr)
+-          : (1 << SPA_DATA_MemFd) | (1 << SPA_DATA_MemPtr);
++          ? (1 << SPA_DATA_DmaBuf) | (1 << SPA_DATA_MemFd)
++          : (1 << SPA_DATA_MemFd);
+
+   params.push_back(reinterpret_cast<spa_pod*>(spa_pod_builder_add_object(
+       &builder, SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers,
+@@ -605,9 +610,6 @@ DesktopVector SharedScreenCastStreamPrivate::CaptureCursorPosition() {
+ RTC_NO_SANITIZE("cfi-icall")
+ void SharedScreenCastStreamPrivate::ProcessBuffer(pw_buffer* buffer) {
+   spa_buffer* spa_buffer = buffer->buffer;
+-  ScopedBuf map;
+-  std::unique_ptr<uint8_t[]> src_unique_ptr;
+-  uint8_t* src = nullptr;
+
+   // Try to update the mouse cursor first, because it can be the only
+   // information carried by the buffer
+@@ -641,76 +643,6 @@ void SharedScreenCastStreamPrivate::ProcessBuffer(pw_buffer* buffer) {
+     return;
+   }
+
+-  if (spa_buffer->datas[0].type == SPA_DATA_MemFd) {
+-    map.initialize(
+-        static_cast<uint8_t*>(
+-            mmap(nullptr,
+-                 spa_buffer->datas[0].maxsize + spa_buffer->datas[0].mapoffset,
+-                 PROT_READ, MAP_PRIVATE, spa_buffer->datas[0].fd, 0)),
+-        spa_buffer->datas[0].maxsize + spa_buffer->datas[0].mapoffset,
+-        spa_buffer->datas[0].fd);
+-
+-    if (!map) {
+-      RTC_LOG(LS_ERROR) << "Failed to mmap the memory: "
+-                        << std::strerror(errno);
+-      return;
+-    }
+-
+-    src = SPA_MEMBER(map.get(), spa_buffer->datas[0].mapoffset, uint8_t);
+-  } else if (spa_buffer->datas[0].type == SPA_DATA_DmaBuf) {
+-    const uint n_planes = spa_buffer->n_datas;
+-
+-    if (!n_planes) {
+-      return;
+-    }
+-
+-    std::vector<EglDmaBuf::PlaneData> plane_datas;
+-    for (uint32_t i = 0; i < n_planes; ++i) {
+-      EglDmaBuf::PlaneData data = {
+-          static_cast<int32_t>(spa_buffer->datas[i].fd),
+-          static_cast<uint32_t>(spa_buffer->datas[i].chunk->stride),
+-          static_cast<uint32_t>(spa_buffer->datas[i].chunk->offset)};
+-      plane_datas.push_back(data);
+-    }
+-
+-    // When importing DMA-BUFs, we use the stride (number of bytes from one row
+-    // of pixels in the buffer) provided by PipeWire. The stride from PipeWire
+-    // is given by the graphics driver and some drivers might add some
+-    // additional padding for memory layout optimizations so not everytime the
+-    // stride is equal to BYTES_PER_PIXEL x WIDTH. This is fine, because during
+-    // the import we will use OpenGL and same graphics driver so it will be able
+-    // to work with the stride it provided, but later on when we work with
+-    // images we get from DMA-BUFs we will need to update the stride to be equal
+-    // to BYTES_PER_PIXEL x WIDTH as that's the size of the DesktopFrame we
+-    // allocate for each captured frame.
+-    src_unique_ptr = egl_dmabuf_->ImageFromDmaBuf(
+-        stream_size_, spa_video_format_.format, plane_datas, modifier_);
+-    if (src_unique_ptr) {
+-      src = src_unique_ptr.get();
+-    } else {
+-      RTC_LOG(LS_ERROR) << "Dropping DMA-BUF modifier: " << modifier_
+-                        << " and trying to renegotiate stream parameters";
+-
+-      if (pw_server_version_ >= kDropSingleModifierMinVersion) {
+-        modifiers_.erase(
+-            std::remove(modifiers_.begin(), modifiers_.end(), modifier_),
+-            modifiers_.end());
+-      } else {
+-        modifiers_.clear();
+-      }
+-
+-      pw_loop_signal_event(pw_thread_loop_get_loop(pw_main_loop_),
+-                           renegotiate_);
+-      return;
+-    }
+-  } else if (spa_buffer->datas[0].type == SPA_DATA_MemPtr) {
+-    src = static_cast<uint8_t*>(spa_buffer->datas[0].data);
+-  }
+-
+-  if (!src) {
+-    return;
+-  }
+-
+   // Use SPA_META_VideoCrop metadata to get the frame size. KDE and GNOME do
+   // handle screen/window sharing differently. KDE/KWin doesn't use
+   // SPA_META_VideoCrop metadata and when sharing a window, it always sets
+@@ -763,8 +695,8 @@ void SharedScreenCastStreamPrivate::ProcessBuffer(pw_buffer* buffer) {
+   }
+
+   // Get the position of the video crop within the stream. Just double-check
+-  // that the position doesn't exceed the size of the stream itself. NOTE:
+-  // Currently it looks there is no implementation using this.
++  // that the position doesn't exceed the size of the stream itself.
++  // NOTE: Currently it looks there is no implementation using this.
+   uint32_t y_offset =
+       videocrop_metadata_use &&
+               (videocrop_metadata->region.position.y + frame_size_.height() <=
+@@ -777,22 +709,7 @@ void SharedScreenCastStreamPrivate::ProcessBuffer(pw_buffer* buffer) {
+                stream_size_.width())
+           ? videocrop_metadata->region.position.x
+           : 0;
+-
+-  const uint32_t stream_stride = kBytesPerPixel * stream_size_.width();
+-  uint32_t buffer_stride = spa_buffer->datas[0].chunk->stride;
+-  uint32_t src_stride = buffer_stride;
+-
+-  if (spa_buffer->datas[0].type == SPA_DATA_DmaBuf &&
+-      buffer_stride > stream_stride) {
+-    // When DMA-BUFs are used, sometimes spa_buffer->stride we get might
+-    // contain additional padding, but after we import the buffer, the stride
+-    // we used is no longer relevant and we should just calculate it based on
+-    // the stream width. For more context see https://crbug.com/1333304.
+-    src_stride = stream_stride;
+-  }
+-
+-  uint8_t* updated_src =
+-      src + (src_stride * y_offset) + (kBytesPerPixel * x_offset);
++  DesktopVector offset = DesktopVector(x_offset, y_offset);
+
+   webrtc::MutexLock lock(&queue_lock_);
+
+@@ -813,9 +730,17 @@ void SharedScreenCastStreamPrivate::ProcessBuffer(pw_buffer* buffer) {
+     queue_.ReplaceCurrentFrame(SharedDesktopFrame::Wrap(std::move(frame)));
+   }
+
+-  queue_.current_frame()->CopyPixelsFrom(
+-      updated_src, (src_stride - (kBytesPerPixel * x_offset)),
+-      DesktopRect::MakeWH(frame_size_.width(), frame_size_.height()));
++  bool bufferProcessed = false;
++  if (spa_buffer->datas[0].type == SPA_DATA_MemFd) {
++    bufferProcessed =
++        ProcessMemFDBuffer(buffer, *queue_.current_frame(), offset);
++  } else if (spa_buffer->datas[0].type == SPA_DATA_DmaBuf) {
++    bufferProcessed = ProcessDMABuffer(buffer, *queue_.current_frame(), offset);
++  }
++
++  if (!bufferProcessed) {
++    return;
++  }
+
+   if (spa_video_format_.format == SPA_VIDEO_FORMAT_RGBx ||
+       spa_video_format_.format == SPA_VIDEO_FORMAT_RGBA) {
+@@ -832,6 +757,87 @@ void SharedScreenCastStreamPrivate::ProcessBuffer(pw_buffer* buffer) {
+       DesktopRect::MakeSize(queue_.current_frame()->size()));
+ }
+
++RTC_NO_SANITIZE("cfi-icall")
++bool SharedScreenCastStreamPrivate::ProcessMemFDBuffer(
++    pw_buffer* buffer,
++    DesktopFrame& frame,
++    const DesktopVector& offset) {
++  spa_buffer* spa_buffer = buffer->buffer;
++  ScopedBuf map;
++  uint8_t* src = nullptr;
++
++  map.initialize(
++      static_cast<uint8_t*>(
++          mmap(nullptr,
++               spa_buffer->datas[0].maxsize + spa_buffer->datas[0].mapoffset,
++               PROT_READ, MAP_PRIVATE, spa_buffer->datas[0].fd, 0)),
++      spa_buffer->datas[0].maxsize + spa_buffer->datas[0].mapoffset,
++      spa_buffer->datas[0].fd);
++
++  if (!map) {
++    RTC_LOG(LS_ERROR) << "Failed to mmap the memory: " << std::strerror(errno);
++    return false;
++  }
++
++  src = SPA_MEMBER(map.get(), spa_buffer->datas[0].mapoffset, uint8_t);
++
++  uint32_t buffer_stride = spa_buffer->datas[0].chunk->stride;
++  uint32_t src_stride = buffer_stride;
++
++  uint8_t* updated_src =
++      src + (src_stride * offset.y()) + (kBytesPerPixel * offset.x());
++
++  frame.CopyPixelsFrom(
++      updated_src, (src_stride - (kBytesPerPixel * offset.x())),
++      DesktopRect::MakeWH(frame.size().width(), frame.size().height()));
++
++  return true;
++}
++
++RTC_NO_SANITIZE("cfi-icall")
++bool SharedScreenCastStreamPrivate::ProcessDMABuffer(
++    pw_buffer* buffer,
++    DesktopFrame& frame,
++    const DesktopVector& offset) {
++  spa_buffer* spa_buffer = buffer->buffer;
++
++  const uint n_planes = spa_buffer->n_datas;
++
++  if (!n_planes) {
++    return false;
++  }
++
++  std::vector<EglDmaBuf::PlaneData> plane_datas;
++  for (uint32_t i = 0; i < n_planes; ++i) {
++    EglDmaBuf::PlaneData data = {
++        static_cast<int32_t>(spa_buffer->datas[i].fd),
++        static_cast<uint32_t>(spa_buffer->datas[i].chunk->stride),
++        static_cast<uint32_t>(spa_buffer->datas[i].chunk->offset)};
++    plane_datas.push_back(data);
++  }
++
++  const bool imported = egl_dmabuf_->ImageFromDmaBuf(
++      stream_size_, spa_video_format_.format, plane_datas, modifier_, offset,
++      frame.size(), frame.data());
++  if (!imported) {
++    RTC_LOG(LS_ERROR) << "Dropping DMA-BUF modifier: " << modifier_
++                      << " and trying to renegotiate stream parameters";
++
++    if (pw_server_version_ >= kDropSingleModifierMinVersion) {
++      modifiers_.erase(
++          std::remove(modifiers_.begin(), modifiers_.end(), modifier_),
++          modifiers_.end());
++    } else {
++      modifiers_.clear();
++    }
++
++    pw_loop_signal_event(pw_thread_loop_get_loop(pw_main_loop_), renegotiate_);
++    return false;
++  }
++
++  return true;
++}
++
+ void SharedScreenCastStreamPrivate::ConvertRGBxToBGRx(uint8_t* frame,
+                                                       uint32_t size) {
+   for (uint32_t i = 0; i < size; i += 4) {
diff --git a/mozilla-107.0.1-kde.patch b/mozilla-107.0.1-kde.patch
index 4882590..859ee20 100644
--- a/mozilla-107.0.1-kde.patch
+++ b/mozilla-107.0.1-kde.patch
@@ -14,8 +14,8 @@ diff --git a/modules/libpref/Preferences.cpp b/modules/libpref/Preferences.cpp
 --- a/modules/libpref/Preferences.cpp
 +++ b/modules/libpref/Preferences.cpp
 @@ -89,16 +89,17 @@
- #include "PLDHashTable.h"
  #include "plstr.h"
+ #include "prdtoa.h"
  #include "prlink.h"
  #include "xpcpublic.h"
  #include "js/RootingAPI.h"
@@ -57,8 +57,8 @@ diff --git a/modules/libpref/Preferences.cpp b/modules/libpref/Preferences.cpp
      NS_WARNING("Error parsing application default preferences.");
    }
  
- #if defined(MOZ_WIDGET_GTK)
-   // Under Flatpak/Snap package, load /etc/firefox/defaults/pref/*.js.
+   // Load jar:$app/omni.jar!/defaults/preferences/*.js
+   // or jar:$gre/omni.jar!/defaults/preferences/*.js.
 @@ -4923,17 +4935,17 @@ nsresult Preferences::InitInitialObjects
        }
  
@@ -73,11 +73,11 @@ diff --git a/modules/libpref/Preferences.cpp b/modules/libpref/Preferences.cpp
      }
    }
  
-   if (XRE_IsParentProcess()) {
-     SetupTelemetryPref();
-   }
- 
-   if (aIsStartup) {
+ #if defined(MOZ_WIDGET_GTK)
+   // To ensure the system-wide preferences are not overwritten by
+   // firefox/browser/defauts/preferences/*.js we need to load
+   // the /etc/firefox/defaults/pref/*.js settings as last.
+   // Under Flatpak, the NS_OS_SYSTEM_CONFIG_DIR points to /app/etc/firefox
 diff --git a/modules/libpref/moz.build b/modules/libpref/moz.build
 --- a/modules/libpref/moz.build
 +++ b/modules/libpref/moz.build
@@ -1055,7 +1055,7 @@ new file mode 100644
 diff --git a/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp b/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp
 --- a/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp
 +++ b/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp
-@@ -1,46 +1,49 @@
+@@ -1,48 +1,51 @@
  /* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*-
   *
   * This Source Code Form is subject to the terms of the Mozilla Public
@@ -1079,13 +1079,15 @@ diff --git a/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp b/uriloader/exthandler
 -  return nsGNOMERegistry::LoadURL(aURI);
 +  return nsCommonRegistry::LoadURL(aURI);
  }
- 
+
  NS_IMETHODIMP
  nsMIMEInfoUnix::GetHasDefaultHandler(bool* _retval) {
-   // if mDefaultApplication is set, it means the application has been set from
+   // if a default app is set, it means the application has been set from
    // either /etc/mailcap or ${HOME}/.mailcap, in which case we don't want to
    // give the GNOME answer.
-   if (mDefaultApplication) return nsMIMEInfoImpl::GetHasDefaultHandler(_retval);
+   if (GetDefaultApplication()) {
+     return nsMIMEInfoImpl::GetHasDefaultHandler(_retval);
+   }
  
    *_retval = false;
  
@@ -1111,10 +1113,10 @@ diff --git a/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp b/uriloader/exthandler
  
    return NS_OK;
 @@ -50,16 +53,33 @@ nsresult nsMIMEInfoUnix::LaunchDefaultWi
-   // if mDefaultApplication is set, it means the application has been set from
-   // either /etc/mailcap or ${HOME}/.mailcap, in which case we don't want to
    // give the GNOME answer.
-   if (mDefaultApplication) return nsMIMEInfoImpl::LaunchDefaultWithFile(aFile);
+   if (GetDefaultApplication()) {
+     return nsMIMEInfoImpl::LaunchDefaultWithFile(aFile);
+   }
  
    nsAutoCString nativePath;
    aFile->GetNativePath(nativePath);
@@ -1130,10 +1132,10 @@ diff --git a/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp b/uriloader/exthandler
 +      if( nsKDEUtils::command( command ))
 +        return NS_OK;
 +    }
-+    if (!mDefaultApplication)
++    if (!GetDefaultApplication())
 +      return NS_ERROR_FILE_NOT_FOUND;
 +
-+    return LaunchWithIProcess(mDefaultApplication, nativePath);
++    return LaunchWithIProcess(GetDefaultApplication(), nativePath);
 +  }
 +
    nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
@@ -1339,7 +1341,7 @@ diff --git a/widget/gtk/nsFilePicker.cpp b/widget/gtk/nsFilePicker.cpp
 +    NS_ADDREF_THIS();
 +    g_idle_add([](gpointer data) -> gboolean {
 +      nsFilePicker* queuedPicker = (nsFilePicker*) data;
-+      int16_t result;
++      nsIFilePicker::ResultCode result;
 +      queuedPicker->kdeFileDialog(&result);
 +      if (queuedPicker->mCallback) {
 +        queuedPicker->mCallback->Done(result);
@@ -1395,7 +1397,7 @@ diff --git a/widget/gtk/nsFilePicker.cpp b/widget/gtk/nsFilePicker.cpp
 +    return GDK_WINDOW_XID( gdk_window );
 +    }
 +
-+NS_IMETHODIMP nsFilePicker::kdeFileDialog(PRInt16 *aReturn)
++NS_IMETHODIMP nsFilePicker::kdeFileDialog(nsIFilePicker::ResultCode *aReturn)
 +    {
 +    NS_ENSURE_ARG_POINTER(aReturn);
 +
@@ -1569,7 +1571,7 @@ diff --git a/widget/gtk/nsFilePicker.cpp b/widget/gtk/nsFilePicker.cpp
 +    }
 +
 +
-+NS_IMETHODIMP nsFilePicker::kdeAppsDialog(PRInt16 *aReturn)
++NS_IMETHODIMP nsFilePicker::kdeAppsDialog(nsIFilePicker::ResultCode *aReturn)
 +    {
 +    NS_ENSURE_ARG_POINTER(aReturn);
 +
@@ -1622,8 +1624,8 @@ diff --git a/widget/gtk/nsFilePicker.h b/widget/gtk/nsFilePicker.h
  
 +  bool kdeRunning();
 +  bool getKdeRunning();
-+  NS_IMETHODIMP kdeFileDialog(PRInt16 *aReturn);
-+  NS_IMETHODIMP kdeAppsDialog(PRInt16 *aReturn);
++  NS_IMETHODIMP kdeFileDialog(nsIFilePicker::ResultCode *aReturn);
++  NS_IMETHODIMP kdeAppsDialog(nsIFilePicker::ResultCode *aReturn);
 +  nsCString kdeMakeFilter( int index );
 +
    void* GtkFileChooserNew(const gchar* title, GtkWindow* parent,
@@ -1704,9 +1706,9 @@ diff --git a/xpcom/components/ManifestParser.cpp b/xpcom/components/ManifestPars
 +  desktop = nsKDEUtils::kdeSession() ? u"kde"_ns : u"gnome"_ns;
  #elif defined(MOZ_WIDGET_ANDROID)
    bool isTablet = false;
-   if (mozilla::AndroidBridge::Bridge()) {
-     mozilla::AndroidBridge::Bridge()->GetStaticStringField(
-         "android/os/Build$VERSION", "RELEASE", osVersion);
+   if (jni::IsAvailable()) {
+     jni::String::LocalRef release = java::sdk::Build::VERSION::RELEASE();
+     osVersion.Assign(release->ToString());
      isTablet = java::GeckoAppShell::IsTablet();
    }
 +  desktop = u"android"_ns;
diff --git a/mozilla-1196777.patch b/mozilla-1196777.patch
new file mode 100644
index 0000000..864741e
--- /dev/null
+++ b/mozilla-1196777.patch
@@ -0,0 +1,13 @@
+diff -up firefox-100.0/widget/gtk/nsWindow.cpp.1196777 firefox-100.0/widget/gtk/nsWindow.cpp
+--- firefox-100.0/widget/gtk/nsWindow.cpp.1196777	2022-05-02 11:29:06.763325015 +0200
++++ firefox-100.0/widget/gtk/nsWindow.cpp	2022-05-02 11:30:49.100717334 +0200
+@@ -163,7 +163,8 @@ const gint kEvents = GDK_TOUCHPAD_GESTUR
+                      GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
+                      GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
+                      GDK_SMOOTH_SCROLL_MASK | GDK_TOUCH_MASK | GDK_SCROLL_MASK |
+-                     GDK_POINTER_MOTION_MASK | GDK_PROPERTY_CHANGE_MASK;
++                     GDK_POINTER_MOTION_MASK | GDK_PROPERTY_CHANGE_MASK |
++                     GDK_FOCUS_CHANGE_MASK;
+ 
+ /* utility functions */
+ static bool is_mouse_in_window(GdkWindow* aWindow, gdouble aMouseX,
diff --git a/mozilla-1516803.patch b/mozilla-1516803.patch
new file mode 100644
index 0000000..5053e51
--- /dev/null
+++ b/mozilla-1516803.patch
@@ -0,0 +1,15 @@
+diff -up firefox-84.0/security/sandbox/linux/moz.build.1516803 firefox-84.0/security/sandbox/linux/moz.build
+--- firefox-84.0/security/sandbox/linux/moz.build.1516803	2020-12-10 16:17:55.425139545 +0100
++++ firefox-84.0/security/sandbox/linux/moz.build	2020-12-10 16:29:21.945860841 +0100
+@@ -114,9 +114,8 @@ if CONFIG["CC_TYPE"] in ("clang", "gcc")
+ # gcc lto likes to put the top level asm in syscall.cc in a different partition
+ # from the function using it which breaks the build.  Work around that by
+ # forcing there to be only one partition.
+-for f in CONFIG["OS_CXXFLAGS"]:
+-    if f.startswith("-flto") and CONFIG["CC_TYPE"] != "clang":
+-        LDFLAGS += ["--param lto-partitions=1"]
++if CONFIG['CC_TYPE'] != 'clang':
++    LDFLAGS += ['--param', 'lto-partitions=1']
+ 
+ DEFINES["NS_NO_XPCOM"] = True
+ DisableStlWrapping()
diff --git a/mozilla-1663844.patch b/mozilla-1663844.patch
new file mode 100644
index 0000000..afa5168
--- /dev/null
+++ b/mozilla-1663844.patch
@@ -0,0 +1,37 @@
+diff -up firefox-109.0/dom/media/gmp/GMPSharedMemManager.h.1663844 firefox-109.0/dom/media/gmp/GMPSharedMemManager.h
+--- firefox-109.0/dom/media/gmp/GMPSharedMemManager.h.1663844	2023-01-09 20:34:10.000000000 +0100
++++ firefox-109.0/dom/media/gmp/GMPSharedMemManager.h	2023-01-12 09:28:56.035741438 +0100
+@@ -26,7 +26,7 @@ class GMPSharedMem {
+   // returned to the parent pool (which is not included).  If more than
+   // this are needed, we presume the client has either crashed or hung
+   // (perhaps temporarily).
+-  static const uint32_t kGMPBufLimit = 20;
++  static const uint32_t kGMPBufLimit = 40;
+ 
+   GMPSharedMem() {
+     for (size_t i = 0; i < sizeof(mGmpAllocated) / sizeof(mGmpAllocated[0]);
+diff -up firefox-109.0/dom/media/platforms/agnostic/gmp/GMPDecoderModule.cpp.1663844 firefox-109.0/dom/media/platforms/agnostic/gmp/GMPDecoderModule.cpp
+--- firefox-109.0/dom/media/platforms/agnostic/gmp/GMPDecoderModule.cpp.1663844	2023-01-09 20:34:10.000000000 +0100
++++ firefox-109.0/dom/media/platforms/agnostic/gmp/GMPDecoderModule.cpp	2023-01-12 09:28:56.036741473 +0100
+@@ -84,6 +84,9 @@ media::DecodeSupportSet GMPDecoderModule
+ 
+ media::DecodeSupportSet GMPDecoderModule::SupportsMimeType(
+     const nsACString& aMimeType, DecoderDoctorDiagnostics* aDiagnostics) const {
++  if (MP4Decoder::IsH264(aMimeType)) {
++    return media::DecodeSupport::SoftwareDecode;
++  }
+   return media::DecodeSupport::Unsupported;
+ }
+ 
+diff -up firefox-109.0/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp.1663844 firefox-109.0/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp
+--- firefox-109.0/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp.1663844	2023-01-12 09:28:56.036741473 +0100
++++ firefox-109.0/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp	2023-01-12 14:18:12.354866405 +0100
+@@ -81,6 +81,8 @@ void GMPVideoDecoder::Decoded(GMPVideoi4
+                                 });
+ 
+     mDecodedData.AppendElement(std::move(v));
++    mDecodePromise.ResolveIfExists(std::move(mDecodedData), __func__);
++    mDecodedData = DecodedData();
+   } else {
+     mDecodedData.Clear();
+     mDecodePromise.RejectIfExists(
diff --git a/mozilla-1667096.patch b/mozilla-1667096.patch
new file mode 100644
index 0000000..85dd729
--- /dev/null
+++ b/mozilla-1667096.patch
@@ -0,0 +1,549 @@
+diff -up firefox-108.0/media/ffvpx/libavcodec/codec_list.c.1667096 firefox-108.0/media/ffvpx/libavcodec/codec_list.c
+--- firefox-108.0/media/ffvpx/libavcodec/codec_list.c.1667096	2022-12-05 21:18:00.000000000 +0100
++++ firefox-108.0/media/ffvpx/libavcodec/codec_list.c	2022-12-08 08:29:54.513562296 +0100
+@@ -11,6 +11,9 @@ static const FFCodec * const codec_list[
+ #if CONFIG_MP3_DECODER
+     &ff_mp3_decoder,
+ #endif
++#ifdef CONFIG_LIBFDK_AAC
++    &ff_libfdk_aac_decoder,
++#endif
+ #if CONFIG_LIBDAV1D
+     &ff_libdav1d_decoder,
+ #endif
+diff -up firefox-108.0/media/ffvpx/libavcodec/libfdk-aacdec.c.1667096 firefox-108.0/media/ffvpx/libavcodec/libfdk-aacdec.c
+--- firefox-108.0/media/ffvpx/libavcodec/libfdk-aacdec.c.1667096	2022-12-08 08:29:54.514562328 +0100
++++ firefox-108.0/media/ffvpx/libavcodec/libfdk-aacdec.c	2022-09-03 18:20:04.000000000 +0200
+@@ -0,0 +1,497 @@
++/*
++ * AAC decoder wrapper
++ * Copyright (c) 2012 Martin Storsjo
++ *
++ * This file is part of FFmpeg.
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <fdk-aac/aacdecoder_lib.h>
++
++#include "libavutil/channel_layout.h"
++#include "libavutil/common.h"
++#include "libavutil/opt.h"
++#include "avcodec.h"
++#include "codec_internal.h"
++#include "decode.h"
++
++#ifdef AACDECODER_LIB_VL0
++#define FDKDEC_VER_AT_LEAST(vl0, vl1) \
++    ((AACDECODER_LIB_VL0 > vl0) || \
++     (AACDECODER_LIB_VL0 == vl0 && AACDECODER_LIB_VL1 >= vl1))
++#else
++#define FDKDEC_VER_AT_LEAST(vl0, vl1) 0
++#endif
++
++#if !FDKDEC_VER_AT_LEAST(2, 5) // < 2.5.10
++#define AAC_PCM_MAX_OUTPUT_CHANNELS AAC_PCM_OUTPUT_CHANNELS
++#endif
++
++enum ConcealMethod {
++    CONCEAL_METHOD_SPECTRAL_MUTING      =  0,
++    CONCEAL_METHOD_NOISE_SUBSTITUTION   =  1,
++    CONCEAL_METHOD_ENERGY_INTERPOLATION =  2,
++    CONCEAL_METHOD_NB,
++};
++
++typedef struct FDKAACDecContext {
++    const AVClass *class;
++    HANDLE_AACDECODER handle;
++    uint8_t *decoder_buffer;
++    int decoder_buffer_size;
++    uint8_t *anc_buffer;
++    int conceal_method;
++    int drc_level;
++    int drc_boost;
++    int drc_heavy;
++    int drc_effect;
++    int drc_cut;
++    int album_mode;
++    int level_limit;
++#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10
++    int output_delay_set;
++    int flush_samples;
++    int delay_samples;
++#endif
++    AVChannelLayout downmix_layout;
++} FDKAACDecContext;
++
++
++#define DMX_ANC_BUFFSIZE       128
++#define DECODER_MAX_CHANNELS     8
++#define DECODER_BUFFSIZE      2048 * sizeof(INT_PCM)
++
++#define OFFSET(x) offsetof(FDKAACDecContext, x)
++#define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM
++static const AVOption fdk_aac_dec_options[] = {
++    { "conceal", "Error concealment method", OFFSET(conceal_method), AV_OPT_TYPE_INT, { .i64 = CONCEAL_METHOD_NOISE_SUBSTITUTION }, CONCEAL_METHOD_SPECTRAL_MUTING, CONCEAL_METHOD_NB - 1, AD, "conceal" },
++    { "spectral", "Spectral muting",      0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_SPECTRAL_MUTING },      INT_MIN, INT_MAX, AD, "conceal" },
++    { "noise",    "Noise Substitution",   0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_NOISE_SUBSTITUTION },   INT_MIN, INT_MAX, AD, "conceal" },
++    { "energy",   "Energy Interpolation", 0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_ENERGY_INTERPOLATION }, INT_MIN, INT_MAX, AD, "conceal" },
++    { "drc_boost", "Dynamic Range Control: boost, where [0] is none and [127] is max boost",
++                     OFFSET(drc_boost),      AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, 127, AD, NULL    },
++    { "drc_cut",   "Dynamic Range Control: attenuation factor, where [0] is none and [127] is max compression",
++                     OFFSET(drc_cut),        AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, 127, AD, NULL    },
++    { "drc_level", "Dynamic Range Control: reference level, quantized to 0.25dB steps where [0] is 0dB and [127] is -31.75dB, -1 for auto, and -2 for disabled",
++                     OFFSET(drc_level),      AV_OPT_TYPE_INT,   { .i64 = -1},  -2, 127, AD, NULL    },
++    { "drc_heavy", "Dynamic Range Control: heavy compression, where [1] is on (RF mode) and [0] is off",
++                     OFFSET(drc_heavy),      AV_OPT_TYPE_INT,   { .i64 = -1},  -1, 1,   AD, NULL    },
++#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10
++    { "level_limit", "Signal level limiting",
++                     OFFSET(level_limit),    AV_OPT_TYPE_BOOL,  { .i64 = -1 }, -1, 1, AD },
++#endif
++#if FDKDEC_VER_AT_LEAST(3, 0) // 3.0.0
++    { "drc_effect","Dynamic Range Control: effect type, where e.g. [0] is none and [6] is general",
++                     OFFSET(drc_effect),     AV_OPT_TYPE_INT,   { .i64 = -1},  -1, 8,   AD, NULL    },
++#endif
++#if FDKDEC_VER_AT_LEAST(3, 1) // 3.1.0
++    { "album_mode","Dynamic Range Control: album mode, where [0] is off and [1] is on",
++                     OFFSET(album_mode),     AV_OPT_TYPE_INT,   { .i64 = -1},  -1, 1,   AD, NULL    },
++#endif
++    { "downmix", "Request a specific channel layout from the decoder", OFFSET(downmix_layout), AV_OPT_TYPE_CHLAYOUT, {.str = NULL}, .flags = AD },
++    { NULL }
++};
++
++static const AVClass fdk_aac_dec_class = {
++    .class_name = "libfdk-aac decoder",
++    .item_name  = av_default_item_name,
++    .option     = fdk_aac_dec_options,
++    .version    = LIBAVUTIL_VERSION_INT,
++};
++
++static int get_stream_info(AVCodecContext *avctx)
++{
++    FDKAACDecContext *s   = avctx->priv_data;
++    CStreamInfo *info     = aacDecoder_GetStreamInfo(s->handle);
++    int channel_counts[0x24] = { 0 };
++    int i, ch_error       = 0;
++    uint64_t ch_layout    = 0;
++
++    if (!info) {
++        av_log(avctx, AV_LOG_ERROR, "Unable to get stream info\n");
++        return AVERROR_UNKNOWN;
++    }
++
++    if (info->sampleRate <= 0) {
++        av_log(avctx, AV_LOG_ERROR, "Stream info not initialized\n");
++        return AVERROR_UNKNOWN;
++    }
++    avctx->sample_rate = info->sampleRate;
++    avctx->frame_size  = info->frameSize;
++#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10
++    if (!s->output_delay_set && info->outputDelay) {
++        // Set this only once.
++        s->flush_samples    = info->outputDelay;
++        s->delay_samples    = info->outputDelay;
++        s->output_delay_set = 1;
++    }
++#endif
++
++    for (i = 0; i < info->numChannels; i++) {
++        AUDIO_CHANNEL_TYPE ctype = info->pChannelType[i];
++        if (ctype <= ACT_NONE || ctype >= FF_ARRAY_ELEMS(channel_counts)) {
++            av_log(avctx, AV_LOG_WARNING, "unknown channel type\n");
++            break;
++        }
++        channel_counts[ctype]++;
++    }
++    av_log(avctx, AV_LOG_DEBUG,
++           "%d channels - front:%d side:%d back:%d lfe:%d top:%d\n",
++           info->numChannels,
++           channel_counts[ACT_FRONT], channel_counts[ACT_SIDE],
++           channel_counts[ACT_BACK],  channel_counts[ACT_LFE],
++           channel_counts[ACT_FRONT_TOP] + channel_counts[ACT_SIDE_TOP] +
++           channel_counts[ACT_BACK_TOP]  + channel_counts[ACT_TOP]);
++
++    switch (channel_counts[ACT_FRONT]) {
++    case 4:
++        ch_layout |= AV_CH_LAYOUT_STEREO | AV_CH_FRONT_LEFT_OF_CENTER |
++                     AV_CH_FRONT_RIGHT_OF_CENTER;
++        break;
++    case 3:
++        ch_layout |= AV_CH_LAYOUT_STEREO | AV_CH_FRONT_CENTER;
++        break;
++    case 2:
++        ch_layout |= AV_CH_LAYOUT_STEREO;
++        break;
++    case 1:
++        ch_layout |= AV_CH_FRONT_CENTER;
++        break;
++    default:
++        av_log(avctx, AV_LOG_WARNING,
++               "unsupported number of front channels: %d\n",
++               channel_counts[ACT_FRONT]);
++        ch_error = 1;
++        break;
++    }
++    if (channel_counts[ACT_SIDE] > 0) {
++        if (channel_counts[ACT_SIDE] == 2) {
++            ch_layout |= AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT;
++        } else {
++            av_log(avctx, AV_LOG_WARNING,
++                   "unsupported number of side channels: %d\n",
++                   channel_counts[ACT_SIDE]);
++            ch_error = 1;
++        }
++    }
++    if (channel_counts[ACT_BACK] > 0) {
++        switch (channel_counts[ACT_BACK]) {
++        case 3:
++            ch_layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT | AV_CH_BACK_CENTER;
++            break;
++        case 2:
++            ch_layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT;
++            break;
++        case 1:
++            ch_layout |= AV_CH_BACK_CENTER;
++            break;
++        default:
++            av_log(avctx, AV_LOG_WARNING,
++                   "unsupported number of back channels: %d\n",
++                   channel_counts[ACT_BACK]);
++            ch_error = 1;
++            break;
++        }
++    }
++    if (channel_counts[ACT_LFE] > 0) {
++        if (channel_counts[ACT_LFE] == 1) {
++            ch_layout |= AV_CH_LOW_FREQUENCY;
++        } else {
++            av_log(avctx, AV_LOG_WARNING,
++                   "unsupported number of LFE channels: %d\n",
++                   channel_counts[ACT_LFE]);
++            ch_error = 1;
++        }
++    }
++
++    av_channel_layout_uninit(&avctx->ch_layout);
++    av_channel_layout_from_mask(&avctx->ch_layout, ch_layout);
++    if (!ch_error && avctx->ch_layout.nb_channels != info->numChannels) {
++        av_log(avctx, AV_LOG_WARNING, "unsupported channel configuration\n");
++        ch_error = 1;
++    }
++    if (ch_error)
++        avctx->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
++
++    return 0;
++}
++
++static av_cold int fdk_aac_decode_close(AVCodecContext *avctx)
++{
++    FDKAACDecContext *s = avctx->priv_data;
++
++    if (s->handle)
++        aacDecoder_Close(s->handle);
++    av_freep(&s->decoder_buffer);
++    av_freep(&s->anc_buffer);
++
++    return 0;
++}
++
++static av_cold int fdk_aac_decode_init(AVCodecContext *avctx)
++{
++    FDKAACDecContext *s = avctx->priv_data;
++    AAC_DECODER_ERROR err;
++
++    s->handle = aacDecoder_Open(avctx->extradata_size ? TT_MP4_RAW : TT_MP4_ADTS, 1);
++    if (!s->handle) {
++        av_log(avctx, AV_LOG_ERROR, "Error opening decoder\n");
++        return AVERROR_UNKNOWN;
++    }
++
++    if (avctx->extradata_size) {
++        if ((err = aacDecoder_ConfigRaw(s->handle, &avctx->extradata,
++                                        &avctx->extradata_size)) != AAC_DEC_OK) {
++            av_log(avctx, AV_LOG_ERROR, "Unable to set extradata\n");
++            return AVERROR_INVALIDDATA;
++        }
++    }
++
++    if ((err = aacDecoder_SetParam(s->handle, AAC_CONCEAL_METHOD,
++                                   s->conceal_method)) != AAC_DEC_OK) {
++        av_log(avctx, AV_LOG_ERROR, "Unable to set error concealment method\n");
++        return AVERROR_UNKNOWN;
++    }
++
++#if FF_API_OLD_CHANNEL_LAYOUT
++FF_DISABLE_DEPRECATION_WARNINGS
++    if (avctx->request_channel_layout) {
++        av_channel_layout_uninit(&s->downmix_layout);
++        av_channel_layout_from_mask(&s->downmix_layout, avctx->request_channel_layout);
++    }
++FF_ENABLE_DEPRECATION_WARNINGS
++#endif
++    if (s->downmix_layout.nb_channels > 0 &&
++        s->downmix_layout.order != AV_CHANNEL_ORDER_NATIVE) {
++        int downmix_channels = -1;
++
++        switch (s->downmix_layout.u.mask) {
++        case AV_CH_LAYOUT_STEREO:
++        case AV_CH_LAYOUT_STEREO_DOWNMIX:
++            downmix_channels = 2;
++            break;
++        case AV_CH_LAYOUT_MONO:
++            downmix_channels = 1;
++            break;
++        default:
++            av_log(avctx, AV_LOG_WARNING, "Invalid downmix option\n");
++            break;
++        }
++
++        if (downmix_channels != -1) {
++            if (aacDecoder_SetParam(s->handle, AAC_PCM_MAX_OUTPUT_CHANNELS,
++                                    downmix_channels) != AAC_DEC_OK) {
++               av_log(avctx, AV_LOG_WARNING, "Unable to set output channels in the decoder\n");
++            } else {
++               s->anc_buffer = av_malloc(DMX_ANC_BUFFSIZE);
++               if (!s->anc_buffer) {
++                   av_log(avctx, AV_LOG_ERROR, "Unable to allocate ancillary buffer for the decoder\n");
++                   return AVERROR(ENOMEM);
++               }
++               if (aacDecoder_AncDataInit(s->handle, s->anc_buffer, DMX_ANC_BUFFSIZE)) {
++                   av_log(avctx, AV_LOG_ERROR, "Unable to register downmix ancillary buffer in the decoder\n");
++                   return AVERROR_UNKNOWN;
++               }
++            }
++        }
++    }
++
++    if (s->drc_boost != -1) {
++        if (aacDecoder_SetParam(s->handle, AAC_DRC_BOOST_FACTOR, s->drc_boost) != AAC_DEC_OK) {
++            av_log(avctx, AV_LOG_ERROR, "Unable to set DRC boost factor in the decoder\n");
++            return AVERROR_UNKNOWN;
++        }
++    }
++
++    if (s->drc_cut != -1) {
++        if (aacDecoder_SetParam(s->handle, AAC_DRC_ATTENUATION_FACTOR, s->drc_cut) != AAC_DEC_OK) {
++            av_log(avctx, AV_LOG_ERROR, "Unable to set DRC attenuation factor in the decoder\n");
++            return AVERROR_UNKNOWN;
++        }
++    }
++
++    if (s->drc_level != -1) {
++        // This option defaults to -1, i.e. not calling
++        // aacDecoder_SetParam(AAC_DRC_REFERENCE_LEVEL) at all, which defaults
++        // to the level from DRC metadata, if available. The user can set
++        // -drc_level -2, which calls aacDecoder_SetParam(
++        // AAC_DRC_REFERENCE_LEVEL) with a negative value, which then
++        // explicitly disables the feature.
++        if (aacDecoder_SetParam(s->handle, AAC_DRC_REFERENCE_LEVEL, s->drc_level) != AAC_DEC_OK) {
++            av_log(avctx, AV_LOG_ERROR, "Unable to set DRC reference level in the decoder\n");
++            return AVERROR_UNKNOWN;
++        }
++    }
++
++    if (s->drc_heavy != -1) {
++        if (aacDecoder_SetParam(s->handle, AAC_DRC_HEAVY_COMPRESSION, s->drc_heavy) != AAC_DEC_OK) {
++            av_log(avctx, AV_LOG_ERROR, "Unable to set DRC heavy compression in the decoder\n");
++            return AVERROR_UNKNOWN;
++        }
++    }
++
++#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10
++    // Setting this parameter to -1 enables the auto behaviour in the library.
++    if (aacDecoder_SetParam(s->handle, AAC_PCM_LIMITER_ENABLE, s->level_limit) != AAC_DEC_OK) {
++        av_log(avctx, AV_LOG_ERROR, "Unable to set in signal level limiting in the decoder\n");
++        return AVERROR_UNKNOWN;
++    }
++#endif
++
++#if FDKDEC_VER_AT_LEAST(3, 0) // 3.0.0
++    if (s->drc_effect != -1) {
++        if (aacDecoder_SetParam(s->handle, AAC_UNIDRC_SET_EFFECT, s->drc_effect) != AAC_DEC_OK) {
++            av_log(avctx, AV_LOG_ERROR, "Unable to set DRC effect type in the decoder\n");
++            return AVERROR_UNKNOWN;
++        }
++    }
++#endif
++
++#if FDKDEC_VER_AT_LEAST(3, 1) // 3.1.0
++    if (s->album_mode != -1) {
++        if (aacDecoder_SetParam(s->handle, AAC_UNIDRC_ALBUM_MODE, s->album_mode) != AAC_DEC_OK) {
++            av_log(avctx, AV_LOG_ERROR, "Unable to set album mode in the decoder\n");
++            return AVERROR_UNKNOWN;
++        }
++    }
++#endif
++
++    avctx->sample_fmt = AV_SAMPLE_FMT_S16;
++
++    s->decoder_buffer_size = DECODER_BUFFSIZE * DECODER_MAX_CHANNELS;
++    s->decoder_buffer = av_malloc(s->decoder_buffer_size);
++    if (!s->decoder_buffer)
++        return AVERROR(ENOMEM);
++
++    return 0;
++}
++
++static int fdk_aac_decode_frame(AVCodecContext *avctx, AVFrame *frame,
++                                int *got_frame_ptr, AVPacket *avpkt)
++{
++    FDKAACDecContext *s = avctx->priv_data;
++    int ret;
++    AAC_DECODER_ERROR err;
++    UINT valid = avpkt->size;
++    UINT flags = 0;
++    int input_offset = 0;
++
++    if (avpkt->size) {
++        err = aacDecoder_Fill(s->handle, &avpkt->data, &avpkt->size, &valid);
++        if (err != AAC_DEC_OK) {
++            av_log(avctx, AV_LOG_ERROR, "aacDecoder_Fill() failed: %x\n", err);
++            return AVERROR_INVALIDDATA;
++        }
++    } else {
++#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10
++        /* Handle decoder draining */
++        if (s->flush_samples > 0) {
++            flags |= AACDEC_FLUSH;
++        } else {
++            return AVERROR_EOF;
++        }
++#else
++        return AVERROR_EOF;
++#endif
++    }
++
++    err = aacDecoder_DecodeFrame(s->handle, (INT_PCM *) s->decoder_buffer,
++                                 s->decoder_buffer_size / sizeof(INT_PCM),
++                                 flags);
++    if (err == AAC_DEC_NOT_ENOUGH_BITS) {
++        ret = avpkt->size - valid;
++        goto end;
++    }
++    if (err != AAC_DEC_OK) {
++        av_log(avctx, AV_LOG_ERROR,
++               "aacDecoder_DecodeFrame() failed: %x\n", err);
++        ret = AVERROR_UNKNOWN;
++        goto end;
++    }
++
++    if ((ret = get_stream_info(avctx)) < 0)
++        goto end;
++    frame->nb_samples = avctx->frame_size;
++
++#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10
++    if (flags & AACDEC_FLUSH) {
++        // Only return the right amount of samples at the end; if calling the
++        // decoder with AACDEC_FLUSH, it will keep returning frames indefinitely.
++        frame->nb_samples = FFMIN(s->flush_samples, frame->nb_samples);
++        av_log(s, AV_LOG_DEBUG, "Returning %d/%d delayed samples.\n",
++                                frame->nb_samples, s->flush_samples);
++        s->flush_samples -= frame->nb_samples;
++    } else {
++        // Trim off samples from the start to compensate for extra decoder
++        // delay. We could also just adjust the pts, but this avoids
++        // including the extra samples in the output altogether.
++        if (s->delay_samples) {
++            int drop_samples = FFMIN(s->delay_samples, frame->nb_samples);
++            av_log(s, AV_LOG_DEBUG, "Dropping %d/%d delayed samples.\n",
++                                    drop_samples, s->delay_samples);
++            s->delay_samples  -= drop_samples;
++            frame->nb_samples -= drop_samples;
++            input_offset = drop_samples * avctx->ch_layout.nb_channels;
++            if (frame->nb_samples <= 0)
++                return 0;
++        }
++    }
++#endif
++
++    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
++        goto end;
++
++    memcpy(frame->extended_data[0], s->decoder_buffer + input_offset,
++           avctx->ch_layout.nb_channels * frame->nb_samples *
++           av_get_bytes_per_sample(avctx->sample_fmt));
++
++    *got_frame_ptr = 1;
++    ret = avpkt->size - valid;
++
++end:
++    return ret;
++}
++
++static av_cold void fdk_aac_decode_flush(AVCodecContext *avctx)
++{
++    FDKAACDecContext *s = avctx->priv_data;
++    AAC_DECODER_ERROR err;
++
++    if (!s->handle)
++        return;
++
++    if ((err = aacDecoder_SetParam(s->handle,
++                                   AAC_TPDEC_CLEAR_BUFFER, 1)) != AAC_DEC_OK)
++        av_log(avctx, AV_LOG_WARNING, "failed to clear buffer when flushing\n");
++}
++
++const FFCodec ff_libfdk_aac_decoder = {
++    .p.name         = "libfdk_aac",
++    CODEC_LONG_NAME("Fraunhofer FDK AAC"),
++    .p.type         = AVMEDIA_TYPE_AUDIO,
++    .p.id           = AV_CODEC_ID_AAC,
++    .priv_data_size = sizeof(FDKAACDecContext),
++    .init           = fdk_aac_decode_init,
++    FF_CODEC_DECODE_CB(fdk_aac_decode_frame),
++    .close          = fdk_aac_decode_close,
++    .flush          = fdk_aac_decode_flush,
++    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF
++#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10
++                      | AV_CODEC_CAP_DELAY
++#endif
++    ,
++    .p.priv_class   = &fdk_aac_dec_class,
++    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
++    .p.wrapper_name = "libfdk",
++};
+diff -up firefox-108.0/media/ffvpx/libavcodec/moz.build.1667096 firefox-108.0/media/ffvpx/libavcodec/moz.build
+--- firefox-108.0/media/ffvpx/libavcodec/moz.build.1667096	2022-12-05 21:18:01.000000000 +0100
++++ firefox-108.0/media/ffvpx/libavcodec/moz.build	2022-12-08 08:29:54.514562328 +0100
+@@ -130,6 +130,12 @@ if CONFIG['MOZ_LIBAV_FFT']:
+         'avfft.c',
+     ]
+ 
++if CONFIG['MOZ_FDK_AAC']:
++    SOURCES += [
++        'libfdk-aacdec.c',
++    ]
++    OS_LIBS += CONFIG['MOZ_FDK_AAC_LIBS']
++
+ SYMBOLS_FILE = 'avcodec.symbols'
+ NoVisibilityFlags()
+ 
+diff -up firefox-108.0/toolkit/moz.configure.1667096 firefox-108.0/toolkit/moz.configure
+--- firefox-108.0/toolkit/moz.configure.1667096	2022-12-05 21:21:08.000000000 +0100
++++ firefox-108.0/toolkit/moz.configure	2022-12-08 08:29:54.514562328 +0100
+@@ -2134,6 +2134,15 @@ with only_when(compile_environment):
+ 
+     set_config("MOZ_SYSTEM_PNG", True, when="--with-system-png")
+ 
++# FDK AAC support
++# ==============================================================
++option('--with-system-fdk-aac',
++       help='Use system libfdk-aac (located with pkgconfig)')
++
++system_fdk_aac = pkg_check_modules('MOZ_FDK_AAC', 'fdk-aac',
++                                   when='--with-system-fdk-aac')
++
++set_config('MOZ_FDK_AAC', depends(when=system_fdk_aac)(lambda: True))
+ 
+ # FFmpeg's ffvpx configuration
+ # ==============================================================
diff --git a/mozilla-1669639.patch b/mozilla-1669639.patch
new file mode 100644
index 0000000..cd04aab
--- /dev/null
+++ b/mozilla-1669639.patch
@@ -0,0 +1,14 @@
+--- firefox-81.0.1/build/mach_initialize.py.old	2020-10-06 14:16:06.212974910 +0200
++++ firefox-81.0.1/build/mach_initialize.py	2020-10-06 14:19:03.313179557 +0200
+@@ -507,7 +507,10 @@ class ImportHook(object):
+         # doesn't happen or because it doesn't matter).
+         if not os.path.exists(module.__file__[:-1]):
+             if os.path.exists(module.__file__):
+-                os.remove(module.__file__)
++                try:
++                    os.remove(module.__file__)
++                except:
++                    pass
+             del sys.modules[module.__name__]
+             module = self(name, globals, locals, fromlist, level)
+ 
diff --git a/mozilla-1670333.patch b/mozilla-1670333.patch
new file mode 100644
index 0000000..a1eaa9a
--- /dev/null
+++ b/mozilla-1670333.patch
@@ -0,0 +1,68 @@
+diff -up firefox-105.0/dom/media/mp4/MP4Demuxer.cpp.1670333 firefox-105.0/dom/media/mp4/MP4Demuxer.cpp
+--- firefox-105.0/dom/media/mp4/MP4Demuxer.cpp.1670333	2022-09-15 20:49:09.000000000 +0200
++++ firefox-105.0/dom/media/mp4/MP4Demuxer.cpp	2022-09-20 09:16:35.404519249 +0200
+@@ -31,6 +31,8 @@ mozilla::LogModule* GetDemuxerLog() { re
+   DDMOZ_LOG(gMediaDemuxerLog, mozilla::LogLevel::Debug, "::%s: " arg, \
+             __func__, ##__VA_ARGS__)
+ 
++extern bool gUseKeyframeFromContainer;
++
+ namespace mozilla {
+ 
+ DDLoggedTypeDeclNameAndBase(MP4TrackDemuxer, MediaTrackDemuxer);
+@@ -394,6 +396,12 @@ already_AddRefed<MediaRawData> MP4TrackD
+           [[fallthrough]];
+         case H264::FrameType::OTHER: {
+           bool keyframe = type == H264::FrameType::I_FRAME;
++          if (gUseKeyframeFromContainer) {
++            if (sample->mKeyframe && sample->mKeyframe != keyframe) {
++              sample->mKeyframe = keyframe;
++            }
++            break;
++          }
+           if (sample->mKeyframe != keyframe) {
+             NS_WARNING(nsPrintfCString("Frame incorrectly marked as %skeyframe "
+                                        "@ pts:%" PRId64 " dur:%" PRId64
+diff -up firefox-105.0/dom/media/platforms/PDMFactory.cpp.1670333 firefox-105.0/dom/media/platforms/PDMFactory.cpp
+--- firefox-105.0/dom/media/platforms/PDMFactory.cpp.1670333	2022-09-15 20:49:09.000000000 +0200
++++ firefox-105.0/dom/media/platforms/PDMFactory.cpp	2022-09-20 09:20:05.369572900 +0200
+@@ -61,6 +61,8 @@
+ 
+ #include <functional>
+ 
++bool gUseKeyframeFromContainer = false;
++
+ using DecodeSupport = mozilla::media::DecodeSupport;
+ using DecodeSupportSet = mozilla::media::DecodeSupportSet;
+ using MediaCodec = mozilla::media::MediaCodec;
+@@ -553,7 +555,7 @@ void PDMFactory::CreateRddPDMs() {
+ #ifdef MOZ_FFMPEG
+   if (StaticPrefs::media_ffmpeg_enabled() &&
+       StaticPrefs::media_rdd_ffmpeg_enabled() &&
+-      !CreateAndStartupPDM<FFmpegRuntimeLinker>()) {
++      !(mFFmpegUsed = CreateAndStartupPDM<FFmpegRuntimeLinker>())) {
+     mFailureFlags += GetFailureFlagBasedOnFFmpegStatus(
+         FFmpegRuntimeLinker::LinkStatusCode());
+   }
+@@ -653,8 +655,9 @@ void PDMFactory::CreateContentPDMs() {
+ 
+   CreateAndStartupPDM<AgnosticDecoderModule>();
+ 
+-  if (StaticPrefs::media_gmp_decoder_enabled() &&
++  if (StaticPrefs::media_gmp_decoder_enabled() && !mFFmpegUsed &&
+       !CreateAndStartupPDM<GMPDecoderModule>()) {
++    gUseKeyframeFromContainer = true;
+     mFailureFlags += DecoderDoctorDiagnostics::Flags::GMPPDMFailedToStartup;
+   }
+ }
+diff -up firefox-105.0/dom/media/platforms/PDMFactory.h.1670333 firefox-105.0/dom/media/platforms/PDMFactory.h
+--- firefox-105.0/dom/media/platforms/PDMFactory.h.1670333	2022-09-15 20:49:08.000000000 +0200
++++ firefox-105.0/dom/media/platforms/PDMFactory.h	2022-09-20 09:16:35.404519249 +0200
+@@ -102,6 +102,7 @@ class PDMFactory final {
+   RefPtr<PlatformDecoderModule> mNullPDM;
+ 
+   DecoderDoctorDiagnostics::FlagsSet mFailureFlags;
++  bool mFFmpegUsed = false;
+ 
+   friend class RemoteVideoDecoderParent;
+   static void EnsureInit();
diff --git a/mozilla-1775202.patch b/mozilla-1775202.patch
new file mode 100644
index 0000000..e237f4c
--- /dev/null
+++ b/mozilla-1775202.patch
@@ -0,0 +1,14 @@
+diff -up firefox-109.0/third_party/libwebrtc/moz.build.ppc-mobzuild firefox-109.0/third_party/libwebrtc/moz.build
+--- firefox-109.0/third_party/libwebrtc/moz.build.ppc-mobzuild	2023-01-12 21:02:15.000000000 +0100
++++ firefox-109.0/third_party/libwebrtc/moz.build	2023-01-16 13:30:28.404450100 +0100
+@@ -621,7 +621,9 @@ if CONFIG["CPU_ARCH"] == "ppc64" and CON
+         "/third_party/libwebrtc/api/audio_codecs/isac/audio_decoder_isac_float_gn",
+         "/third_party/libwebrtc/api/audio_codecs/isac/audio_encoder_isac_float_gn",
+         "/third_party/libwebrtc/modules/audio_coding/isac_c_gn",
+-        "/third_party/libwebrtc/modules/audio_coding/isac_gn"
++        "/third_party/libwebrtc/modules/audio_coding/isac_gn",
++        "/third_party/libwebrtc/modules/desktop_capture/desktop_capture_gn",
++        "/third_party/libwebrtc/modules/desktop_capture/primitives_gn"
+     ]
+ 
+ if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
Not Available

benbullard79 [@T] cox.netNo Comment.349d 20hrs
benbullard79 [@T] cox.netNo Comment.349d 20hrs