Submitted By: Ken Moffat <ken at linuxfromscratch dot org>
Date: 2024-04-05
Initial Package Version: 20240403 git pull
Upstream Status: Not applied
Origin: Gentoo, qtwebengine-5.15.13_p20240322-patchset.tar.xz
Description: Build current qtwebengine-5.15.17 with python3.11 in /opt

The fixes to use python3 have been upstreamed.  I previously altered
those to invoke /usr/bin/python3 instead of /usr/bin/python and thought
that many parts were not used in a BLFS build.  It seems that I built
what we called qtwebengine-5.15.17 in early December 2023 on an
experimental system mixing qt5 and qt6 (bad idea!) using
 PATH=/opt/python3.11/bin:$PATH qmake - (+options)
which implies that /usr/bin/python (non-existent on that system) was not
used.  But at the moment I am not totally sure how I built it.

Some patches came from Arch or Debian or even Chromium, check each.

001-disable-fatal-warnings.patch  gentoo bug 695446

diff --git a/src/buildtools/config/common.pri b/src/buildtools/config/common.pri
index cf990c79..910a88ca 100644
--- a/src/buildtools/config/common.pri
+++ b/src/buildtools/config/common.pri
@@ -26,6 +26,7 @@ gn_args += \
     skia_use_dawn=false \
     toolkit_views=false \
     treat_warnings_as_errors=false \
+    fatal_linker_warnings=false \
     use_allocator_shim=false \
     use_allocator=\"none\" \
     use_custom_libcxx=false \

003-chromium-87-v8-icu68.patch  gentoo bug 757606

From b0a7f5691113534c2cf771f2dd3cece5e93bc7d4 Mon Sep 17 00:00:00 2001
From: Frank Tang <ftang@chromium.org>
Date: Tue, 03 Nov 2020 23:20:37 -0800
Subject: [PATCH] Update to ICU68-1

ICU68-1 change the output skeleton format. So we need to change
resolvedOptions code for 68 migration.

Chromium roll
https://chromium-review.googlesource.com/c/chromium/src/+/2474093

Bug: v8:10945
Change-Id: I3b2c7fbe8abb22df8fa51287c498ca3245b8c55b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2477431
Commit-Queue: Frank Tang <ftang@chromium.org>
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70972}

(ported to work with <ICU-68.1 and rebased chromium)
---

diff --git a/src/3rdparty/chromium/v8/src/objects/js-number-format.cc b/src/3rdparty/chromium/v8/src/objects/js-number-format.cc
index 45b0eab..d18b133 100644
--- a/src/3rdparty/chromium/v8/src/objects/js-number-format.cc
+++ b/src/3rdparty/chromium/v8/src/objects/js-number-format.cc
@@ -389,17 +389,20 @@ Handle<String> CurrencySignString(Isolate* isolate,
 Handle<String> UnitDisplayString(Isolate* isolate,
                                  const icu::UnicodeString& skeleton) {
   // Ex: skeleton as
-  // "measure-unit/length-meter .### rounding-mode-half-up unit-width-full-name"
+  // <ICU-68.1:  "measure-unit/length-meter .### rounding-mode-half-up unit-width-full-name".
+  // >=ICU-68.1: "unit/length-meter .### rounding-mode-half-up unit-width-full-name"
   if (skeleton.indexOf("unit-width-full-name") >= 0) {
     return ReadOnlyRoots(isolate).long_string_handle();
   }
   // Ex: skeleton as
-  // "measure-unit/length-meter .### rounding-mode-half-up unit-width-narrow".
+  // <ICU-68.1:  "measure-unit/length-meter .### rounding-mode-half-up unit-width-narrow".
+  // >=ICU-68.1: "unit/length-meter .### rounding-mode-half-up unit-width-narrow".
   if (skeleton.indexOf("unit-width-narrow") >= 0) {
     return ReadOnlyRoots(isolate).narrow_string_handle();
   }
   // Ex: skeleton as
-  // "measure-unit/length-foot .### rounding-mode-half-up"
+  // <ICU-68.1:  "measure-unit/length-foot .### rounding-mode-half-up"
+  // >=ICU-68.1: "unit/length-foot .### rounding-mode-half-up"
   return ReadOnlyRoots(isolate).short_string_handle();
 }
 
@@ -422,7 +425,8 @@ Notation NotationFromSkeleton(const icu::UnicodeString& skeleton) {
     return Notation::COMPACT;
   }
   // Ex: skeleton as
-  // "measure-unit/length-foot .### rounding-mode-half-up"
+  // <ICU-68.1:  "measure-unit/length-foot .### rounding-mode-half-up"
+  // >=ICU-68.1: "unit/length-foot .### rounding-mode-half-up"
   return Notation::STANDARD;
 }
 
@@ -562,14 +566,23 @@ namespace {
 
 // Ex: percent .### rounding-mode-half-up
 // Special case for "percent"
-// Ex: "measure-unit/length-kilometer per-measure-unit/duration-hour .###
-// rounding-mode-half-up" should return "kilometer-per-unit".
-// Ex: "measure-unit/duration-year .### rounding-mode-half-up" should return
-// "year".
+// <ICU-68.1:
+//   Ex: "measure-unit/length-kilometer per-measure-unit/duration-hour .###
+//   rounding-mode-half-up" should return "kilometer-per-unit".
+//   Ex: "measure-unit/duration-year .### rounding-mode-half-up" should return
+// >=ICU-68.1:
+//   Ex: "unit/milliliter-per-acre .### rounding-mode-half-up"
+//   should return "milliliter-per-acre".
+//   Ex: "unit/year .### rounding-mode-half-up" should return
+//   "year".
 std::string UnitFromSkeleton(const icu::UnicodeString& skeleton) {
   std::string str;
   str = skeleton.toUTF8String<std::string>(str);
+#if U_ICU_VERSION_MAJOR_NUM < 68
   std::string search("measure-unit/");
+#else
+  std::string search("unit/");
+#endif
   size_t begin = str.find(search);
   if (begin == str.npos) {
     // Special case for "percent".
@@ -578,20 +591,41 @@ std::string UnitFromSkeleton(const icu::UnicodeString& skeleton) {
     }
     return "";
   }
+#if U_ICU_VERSION_MAJOR_NUM < 68
   // Skip the type (ex: "length").
   // "measure-unit/length-kilometer per-measure-unit/duration-hour"
   //                     b
   begin = str.find("-", begin + search.size());
+#else
+  // Ex:
+  // "unit/acre .### rounding-mode-half-up"
+  //       b
+  // Ex:
+  // "unit/milliliter-per-acre .### rounding-mode-half-up"
+  //       b
+  begin += search.size();
+#endif
   if (begin == str.npos) {
     return "";
   }
+#if U_ICU_VERSION_MAJOR_NUM < 68
   begin++;  // Skip the '-'.
+#endif
   // Find the end of the subtype.
   size_t end = str.find(" ", begin);
-  // "measure-unit/length-kilometer per-measure-unit/duration-hour"
-  //                      b        e
+  // <ICU-68.1:
+  //   "measure-unit/length-kilometer per-measure-unit/duration-hour"
+  //                        b        e
+  // >=ICU-68.1:
+  //   Ex:
+  //   "unit/acre .### rounding-mode-half-up"
+  //         b   e
+  //   Ex:
+  //   "unit/milliliter-per-acre .### rounding-mode-half-up"
+  //         b                  e
   if (end == str.npos) {
     end = str.size();
+#if U_ICU_VERSION_MAJOR_NUM < 68
     return str.substr(begin, end - begin);
   }
   // "measure-unit/length-kilometer per-measure-unit/duration-hour"
@@ -625,17 +659,36 @@ std::string UnitFromSkeleton(const icu::UnicodeString& skeleton) {
   // "measure-unit/length-kilometer per-measure-unit/duration-hour"
   //                      [result ]                           b   e
   return result + "-per-" + str.substr(begin, end - begin);
+#else
+  }
+  return str.substr(begin, end - begin);
+#endif
 }
 
 Style StyleFromSkeleton(const icu::UnicodeString& skeleton) {
   if (skeleton.indexOf("currency/") >= 0) {
     return Style::CURRENCY;
   }
+#if U_ICU_VERSION_MAJOR_NUM < 68
   if (skeleton.indexOf("measure-unit/") >= 0) {
     if (skeleton.indexOf("scale/100") >= 0 &&
         skeleton.indexOf("measure-unit/concentr-percent") >= 0) {
+#else
+  if (skeleton.indexOf("percent") >= 0) {
+    // percent precision-integer rounding-mode-half-up scale/100
+    if (skeleton.indexOf("scale/100") >= 0) {
+#endif
       return Style::PERCENT;
+#if U_ICU_VERSION_MAJOR_NUM >= 68
+    } else {
+      return Style::UNIT;
+#endif
     }
+#if U_ICU_VERSION_MAJOR_NUM >= 68
+  }
+  // Before ICU68: "measure-unit/", since ICU68 "unit/"
+  if (skeleton.indexOf("unit/") >= 0) {
+#endif
     return Style::UNIT;
   }
   return Style::DECIMAL;
diff --git a/src/3rdparty/chromium/v8/src/objects/js-relative-time-format.cc b/src/3rdparty/chromium/v8/src/objects/js-relative-time-format.cc
index 267343aaae..64d56a1c12 100644
--- a/src/3rdparty/chromium/v8/src/objects/js-relative-time-format.cc
+++ b/src/3rdparty/chromium/v8/src/objects/js-relative-time-format.cc
@@ -195,9 +195,18 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::New(
     }
   }
 
+#if U_ICU_VERSION_MAJOR_NUM < 68
   icu::DecimalFormat* decimal_format =
       static_cast<icu::DecimalFormat*>(number_format);
   decimal_format->setMinimumGroupingDigits(-2);
+#else
+  if (number_format->getDynamicClassID() ==
+      icu::DecimalFormat::getStaticClassID()) {
+    icu::DecimalFormat* decimal_format =
+        static_cast<icu::DecimalFormat*>(number_format);
+    decimal_format->setMinimumGroupingDigits(-2);
+  }
+#endif
 
   // Change UDISPCTX_CAPITALIZATION_NONE to other values if
   // ECMA402 later include option to change capitalization.

004-disable-git.patch - we've been using this for ages

generate_gni.sh: update_readme() runs git at the end of process, prevent it.

Thanks-to: Georgy Yakovlev <gyakovlev@gentoo.org>

--- a/src/3rdparty/chromium/third_party/libvpx/generate_gni.sh	2021-02-07 12:51:49.438514897 +0100
+++ b/src/3rdparty/chromium/third_party/libvpx/generate_gni.sh	2021-02-21 16:23:38.375724515 +0100
@@ -519,8 +519,3 @@
 
 gn format --in-place $BASE_DIR/BUILD.gn
 gn format --in-place $BASE_DIR/libvpx_srcs.gni
-
-cd $BASE_DIR/$LIBVPX_SRC_DIR
-update_readme
-
-cd $BASE_DIR

005-pdfium-system-lcms2.patch   # by Debian, QTBUG-61746

Description: Use system lcms2
Author: Sandro Knauß <hefee@debian.org>
Origin: Debian
Forwarded: https://bugreports.qt.io/browse/QTBUG-61746
Reviewed-by: Sandro Knauß <hefee@debian.org>
Last-Update: 2021-03-08
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
--- a/src/3rdparty/chromium/third_party/pdfium/third_party/BUILD.gn
+++ b/src/3rdparty/chromium/third_party/pdfium/third_party/BUILD.gn
@@ -239,58 +239,19 @@ if (!pdf_use_skia && !pdf_use_skia_paths
   }
 }
 
-config("fx_lcms2_warnings") {
-  visibility = [ ":*" ]
-  if (is_clang) {
-    cflags = [
-      # cmslut.cc is sloppy with aggregate initialization. Version 2.7 of this
-      # library doesn't appear to have this problem.
-      "-Wno-missing-braces",
-    ]
-  }
+import("//build/shim_headers.gni")
+
+shim_headers("lcms2_shim") {
+  root_path = "lcms/include"
+  headers = [
+    "lcms2.h",
+    "lcms2_plugin.h",
+  ]
 }
 
 source_set("fx_lcms2") {
-  configs -= [ "//build/config/compiler:chromium_code" ]
-  configs += [
-    "//build/config/compiler:no_chromium_code",
-    "//build/config/sanitizers:cfi_icall_generalize_pointers",
-    ":pdfium_third_party_config",
-
-    # Must be after no_chromium_code for warning flags to be ordered correctly.
-    ":fx_lcms2_warnings",
-  ]
-  sources = [
-    "lcms/include/lcms2.h",
-    "lcms/include/lcms2_plugin.h",
-    "lcms/src/cmsalpha.c",
-    "lcms/src/cmscam02.c",
-    "lcms/src/cmscgats.c",
-    "lcms/src/cmscnvrt.c",
-    "lcms/src/cmserr.c",
-    "lcms/src/cmsgamma.c",
-    "lcms/src/cmsgmt.c",
-    "lcms/src/cmshalf.c",
-    "lcms/src/cmsintrp.c",
-    "lcms/src/cmsio0.c",
-    "lcms/src/cmsio1.c",
-    "lcms/src/cmslut.c",
-    "lcms/src/cmsmd5.c",
-    "lcms/src/cmsmtrx.c",
-    "lcms/src/cmsnamed.c",
-    "lcms/src/cmsopt.c",
-    "lcms/src/cmspack.c",
-    "lcms/src/cmspcs.c",
-    "lcms/src/cmsplugin.c",
-    "lcms/src/cmsps2.c",
-    "lcms/src/cmssamp.c",
-    "lcms/src/cmssm.c",
-    "lcms/src/cmstypes.c",
-    "lcms/src/cmsvirt.c",
-    "lcms/src/cmswtpnt.c",
-    "lcms/src/cmsxform.c",
-  ]
-  deps = [ "../core/fxcrt" ]
+  deps = [ ":lcms2_shim" ]
+  libs = ["lcms2"]
 }
 
 if (!build_with_chromium) {

006-clang14.patch  from FreeBSD, gentoo bug 836604

I think I've seen something like this in my failed attempt earlier
this year to build current source. -- ken

From 0825e7bc64e47d87e1f1026cc80c933550f114f5 Mon Sep 17 00:00:00 2001
From: Dimitry Andric <dim@FreeBSD.org>
Date: Mon, 14 Feb 2022 13:55:25 +0100
Subject: www/qt5-webengine: fix build with clang 14

Fixes compile error:

In file included from gen/third_party/blink/renderer/platform/platform_jumbo_63.cc:8:
src/3rdparty/chromium/third_party/blink/renderer/platform/text/text_break_iterator_icu.cc:122:15: error: anonymous non-C-compatible type given name for linkage purposes by typedef declaration after its linkage was computed; add a tag name here to establish linkage prior to definition
typedef struct {
              ^
               UTextWithBuffer
src/3rdparty/chromium/third_party/blink/renderer/platform/text/text_break_iterator_icu.cc:123:3: note: type is not C-compatible due to this member declaration
  DISALLOW_NEW();
  ^~~~~~~~~~~~~~
src/3rdparty/chromium/third_party/blink/renderer/platform/wtf/allocator/allocator.h:40:2: note: expanded from macro 'DISALLOW_NEW'
 public:                                                                      \
 ^~~~~~~
src/3rdparty/chromium/third_party/blink/renderer/platform/text/text_break_iterator_icu.cc:126:3: note: type is given name 'UTextWithBuffer' for linkage purposes by this typedef declaration
} UTextWithBuffer;
  ^

PR:		261949
Approved by:	adridg (maintainer)
MFH:		2022Q1

--- a/src/3rdparty/chromium/third_party/blink/renderer/platform/text/text_break_iterator_icu.cc
+++ b/src/3rdparty/chromium/third_party/blink/renderer/platform/text/text_break_iterator_icu.cc
@@ -119,11 +119,11 @@ enum TextContext { kNoContext, kPriorContext, kPrimary
 
 const int kTextBufferCapacity = 16;
 
-typedef struct {
+struct UTextWithBuffer {
   DISALLOW_NEW();
   UText text;
   UChar buffer[kTextBufferCapacity];
-} UTextWithBuffer;
+};
 
 static inline int64_t TextPinIndex(int64_t& index, int64_t limit) {
   if (index < 0)

007-gcc12-includes.patch        # by openSUSE, gentoo 840326

https://build.opensuse.org/package/view_file/KDE:Qt:5.15/libqt5-qtwebengine/0001-skia-Some-includes-to-fix-build-with-GCC-12.patch?expand=1
https://bugs.gentoo.org/840326

From 68799a1e0815b20ca59ce354a55280399257a201 Mon Sep 17 00:00:00 2001
From: Fabian Vogt <fvogt@suse.de>
Date: Fri, 25 Mar 2022 15:29:28 +0100
Subject: [PATCH] skia: Some includes to fix build with GCC 12

Those includes got introduced upstream for other reasons and fixed building
with GCC 12 as a side effect.
--- a/src/3rdparty/chromium/third_party/skia/include/core/SkColor.h
+++ b/src/3rdparty/chromium/third_party/skia/include/core/SkColor.h
@@ -12,6 +12,8 @@
 #include "include/core/SkScalar.h"
 #include "include/core/SkTypes.h"
 
+#include <array>
+
 /** \file SkColor.h
 
     Types, consts, functions, and macros for colors.
--- a/src/3rdparty/chromium/third_party/skia/src/utils/SkParseColor.cpp
+++ b/src/3rdparty/chromium/third_party/skia/src/utils/SkParseColor.cpp
@@ -8,6 +8,8 @@
 
 #include "include/utils/SkParse.h"
 
+#include <algorithm> // std::lower_bound
+
 static constexpr const char* gColorNames[] = {
     "aliceblue",
     "antiquewhite",

011-chromium-drop-catapult.patch  gentoo bug 698988

Catapult provides performance-tunng tools for chromium. Removing
it should speed up the build. -ken

From b0581c62625e57a63e56369f7eb24a141687cc7a Mon Sep 17 00:00:00 2001
From: Jimi Huotari <chiitoo@gentoo.org>
Date: Wed, 6 Apr 2022 14:35:14 +0300
Subject: [PATCH] Remove dependency on catapult

Signed-off-by: Andreas Sturmlechner <asturm@gentoo.org>
---
 chromium/BUILD.gn                             | 11 ----
 chromium/chrome/chrome_paks.gni               |  2 -
 chromium/chrome/test/BUILD.gn                 |  6 ---
 chromium/content/browser/BUILD.gn             |  1 -
 chromium/content/browser/tracing/BUILD.gn     | 51 -------------------
 .../content/browser/tracing/tracing_ui.cc     |  3 --
 chromium/content/shell/BUILD.gn               |  2 -
 chromium/fuchsia/engine/BUILD.gn              |  2 -
 chromium/headless/BUILD.gn                    |  2 -
 chromium/mojo/public/tools/BUILD.gn           |  1 -
 chromium/testing/BUILD.gn                     |  1 -
 chromium/third_party/webrtc/test/BUILD.gn     |  5 --
 chromium/tools/binary_size/BUILD.gn           |  1 -
 chromium/tools/grit/BUILD.gn                  |  1 -
 chromium/tools/gritsettings/resource_ids.spec |  6 ---
 chromium/tools/metrics/BUILD.gn               |  1 -
 .../perf/chrome_telemetry_build/BUILD.gn      |  3 --
 .../perf/core/perfetto_binary_roller/BUILD.gn |  1 -
 chromium/tools/polymer/BUILD.gn               |  1 -
 chromium/v8/tools/BUILD.gn                    |  4 --
 chromium/weblayer/shell/BUILD.gn              |  2 -
 21 files changed, 107 deletions(-)
 delete mode 100644 chromium/content/browser/tracing/BUILD.gn

diff --git a/chromium/BUILD.gn b/chromium/BUILD.gn
index 8d9657d545c..59e9447f456 100644
--- a/src/3rdparty/chromium/BUILD.gn
+++ b/src/3rdparty/chromium/BUILD.gn
@@ -239,7 +239,6 @@ group("gn_all") {
       "//media/capture:capture_unittests",
       "//media/cast:cast_unittests",
       "//third_party/angle/src/tests:angle_white_box_tests",
-      "//third_party/catapult/telemetry:bitmaptools($host_toolchain)",
     ]
   } else if (is_ios && !use_qt) {
     deps += [
@@ -354,7 +353,6 @@ group("gn_all") {
       "//net/android:net_junit_tests",
       "//services:services_junit_tests",
       "//testing/android/junit:junit_unit_tests",
-      "//third_party/catapult/devil",
       "//third_party/smhasher:murmurhash3",
       "//tools/android:android_tools",
       "//tools/android:memconsumer",
@@ -959,7 +957,6 @@ if (is_chromeos) {
       "//third_party/dawn/src/tests:dawn_unittests",
 
       # Blocked on https://github.com/catapult-project/catapult/issues/2297
-      #"//third_party/catapult/telemetry:bitmaptools",
       "//tools/perf/clear_system_cache",
       "//ui/ozone/gl:ozone_gl_unittests",
     ]
@@ -1037,7 +1034,6 @@ if (!is_ios && !use_qt) {
       data_deps = [
         "//chrome:chrome",
         "//chrome/test/chromedriver",
-        "//third_party/catapult/third_party/typ",
       ]
       if (is_win) {
         data_deps += [ "//build/win:copy_cdb_to_output" ]
@@ -1084,7 +1080,6 @@ if (!is_ios && !use_qt) {
       "//third_party/blink/public:blink_devtools_inspector_resources",
       "//third_party/blink/public/mojom:mojom_platform_js_data_deps",
       "//third_party/blink/renderer/core/html:js_files_for_form_controls_web_tests",
-      "//third_party/catapult/third_party/typ",
       "//third_party/mesa_headers",
       "//tools/imagediff",
     ]
@@ -1152,7 +1147,6 @@ if (!is_ios && !use_qt) {
 
     if (is_android) {
       data += [
-        "//third_party/catapult/",
         "//build/android/",
       ]
     }
@@ -1259,11 +1253,6 @@ if (!is_ios && !use_qt) {
       "//third_party/blink/web_tests/StaleTestExpectations",
       "//third_party/blink/web_tests/TestExpectations",
       "//third_party/blink/web_tests/VirtualTestSuites",
-      "//third_party/catapult/common/py_utils/",
-      "//third_party/catapult/devil/",
-      "//third_party/catapult/dependency_manager/",
-      "//third_party/catapult/third_party/zipfile/",
-      "//third_party/catapult/third_party/typ/",
       "//third_party/depot_tools/pylint",
       "//third_party/depot_tools/pylint-1.5",
       "//third_party/depot_tools/pylint_main.py",
diff --git a/chromium/chrome/chrome_paks.gni b/chromium/chrome/chrome_paks.gni
index 9323a774a56..0362b6501aa 100644
--- a/src/3rdparty/chromium/chrome/chrome_paks.gni
+++ b/src/3rdparty/chromium/chrome/chrome_paks.gni
@@ -94,7 +94,6 @@ template("chrome_extra_paks") {
       "$root_gen_dir/chrome/common_resources.pak",
       "$root_gen_dir/components/autofill/core/browser/autofill_address_rewriter_resources.pak",
       "$root_gen_dir/components/components_resources.pak",
-      "$root_gen_dir/content/browser/tracing/tracing_resources.pak",
       "$root_gen_dir/content/content_resources.pak",
       "$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak",
       "$root_gen_dir/net/net_resources.pak",
@@ -110,7 +109,6 @@ template("chrome_extra_paks") {
       "//components/autofill/core/browser:autofill_address_rewriter_resources",
       "//components/resources",
       "//content:content_resources",
-      "//content/browser/tracing:resources",
       "//mojo/public/js:resources",
       "//net:net_resources",
       "//skia:skia_resources",
diff --git a/chromium/chrome/test/BUILD.gn b/chromium/chrome/test/BUILD.gn
index 1a369fa56d2..eb5bc9676fb 100644
--- a/src/3rdparty/chromium/chrome/test/BUILD.gn
+++ b/src/3rdparty/chromium/chrome/test/BUILD.gn
@@ -7103,8 +7103,6 @@ if (!is_fuchsia && !is_android) {
       "//chrome/test/data/password/captured_sites/",
       "//chrome/test/data/web_page_replay_go_helper_scripts/automation_helper.js",
       "//components/test/data/autofill/web_page_replay_support_files/",
-      "//third_party/catapult/telemetry/telemetry/bin/",
-      "//third_party/catapult/web_page_replay_go/deterministic.js",
     ]
 
     if (is_linux || is_chromeos || is_win) {
@@ -7141,7 +7139,6 @@ if (!is_fuchsia && !is_android) {
 
       # TODO(uwyiming@chromium.org) create a gn target for Web Page Replay Go (WPR Go) and only WPR Go.
       # So that test targets requiring WPR Go does not pull down the whole telemetry tool chain.
-      "//third_party/catapult:telemetry_chrome_test_support",
       "//third_party/hunspell",
       "//third_party/icu",
       "//third_party/libpng",
@@ -7171,7 +7168,6 @@ if (!is_fuchsia && !is_android) {
     deps = [ "//tools/perf/chrome_telemetry_build:telemetry_chrome_test" ]
 
     data = [
-      "//third_party/catapult/telemetry/telemetry/internal/bin/",
       "//tools/perf/run_telemetry_tests",
 
       # For isolate contract.
@@ -7189,7 +7185,6 @@ if (!is_fuchsia && !is_android) {
   group("telemetry_gpu_unittests") {
     testonly = true
     deps = [
-      "//third_party/catapult:telemetry_chrome_test_support",
       "//tools/metrics:metrics_python_tests",
     ]
     data = [
@@ -7313,7 +7308,6 @@ if (is_mac || is_win || is_android) {
       "//testing/scripts",
       "//testing/test_env.py",
       "//testing/xvfb.py",
-      "//third_party/catapult",
       "//tools",
     ]
   }
diff --git a/chromium/content/browser/BUILD.gn b/chromium/content/browser/BUILD.gn
index 1466f33d462..51039e0da19 100644
--- a/src/3rdparty/chromium/content/browser/BUILD.gn
+++ b/src/3rdparty/chromium/content/browser/BUILD.gn
@@ -2169,7 +2169,6 @@ jumbo_static_library("browser") {
   if (!is_android) {
     deps += [
       "//components/vector_icons",
-      "//content/browser/tracing:resources",
     ]
   }
 
diff --git a/chromium/content/browser/tracing/BUILD.gn b/chromium/content/browser/tracing/BUILD.gn
deleted file mode 100644
index eac05999fac..00000000000
--- a/src/3rdparty/chromium/content/browser/tracing/BUILD.gn
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//tools/grit/grit_rule.gni")
-
-# generate_about_tracing puts its files in this directory
-tracing_gen_dir = "$root_gen_dir/content/browser/tracing"
-
-# The script just writes filename with no dirs to the .grd, so we always need
-# this file to be in the same directory as the inputs.
-tracing_grd = "$tracing_gen_dir/tracing_resources.grd"
-
-action("generate_tracing_grd") {
-  visibility = [ ":*" ]  # Depend on ":resources" to get this.
-  script = "generate_trace_viewer_grd.py"
-
-  input_pages = [
-    "$tracing_gen_dir/about_tracing.html",
-    "$tracing_gen_dir/about_tracing.js",
-  ]
-  inputs = input_pages
-  outputs = [ tracing_grd ]
-
-  args = rebase_path(input_pages, target_gen_dir) + [
-           "--output",
-           rebase_path(tracing_grd, root_build_dir),
-         ]
-
-  deps = [ "//third_party/catapult/tracing:generate_about_tracing" ]
-}
-
-grit("resources") {
-  source = tracing_grd
-
-  # Required because the .grd is generated.
-  enable_input_discovery_for_gn_analyze = false
-
-  outputs = [
-    "grit/tracing_resources.h",
-    "tracing_resources.pak",
-  ]
-
-  # resource_ids has an entry for our .grd file that looks like:
-  # "<(SHARED_INTERMEDIATE_DIR)/content/browser/tracing/tracing_resources.grd"
-  # and what we pass here should make that resolve to our .grd file.
-  defines =
-      [ "SHARED_INTERMEDIATE_DIR=" + rebase_path(root_gen_dir, root_build_dir) ]
-
-  deps = [ ":generate_tracing_grd" ]
-}
diff --git a/chromium/content/browser/tracing/tracing_ui.cc b/chromium/content/browser/tracing/tracing_ui.cc
index 2bffb5eb3b0..8965922dfba 100644
--- a/src/3rdparty/chromium/content/browser/tracing/tracing_ui.cc
+++ b/src/3rdparty/chromium/content/browser/tracing/tracing_ui.cc
@@ -27,7 +27,6 @@
 #include "base/strings/stringprintf.h"
 #include "base/trace_event/trace_event.h"
 #include "base/values.h"
-#include "content/browser/tracing/grit/tracing_resources.h"
 #include "content/browser/tracing/tracing_controller_impl.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
@@ -242,8 +241,6 @@ TracingUI::TracingUI(WebUI* web_ui)
   WebUIDataSource* source = WebUIDataSource::Create(kChromeUITracingHost);
   source->DisableTrustedTypesCSP();
   source->UseStringsJs();
-  source->SetDefaultResource(IDR_TRACING_HTML);
-  source->AddResourcePath("tracing.js", IDR_TRACING_JS);
   source->SetRequestFilter(base::BindRepeating(OnShouldHandleRequest),
                            base::BindRepeating(OnTracingRequest));
   WebUIDataSource::Add(browser_context, source);
diff --git a/chromium/content/shell/BUILD.gn b/chromium/content/shell/BUILD.gn
index 56c0e8b48e3..6e4ffbe962d 100644
--- a/src/3rdparty/chromium/content/shell/BUILD.gn
+++ b/src/3rdparty/chromium/content/shell/BUILD.gn
@@ -390,7 +390,6 @@ repack("pak") {
   sources = [
     "$root_gen_dir/content/app/resources/content_resources_100_percent.pak",
     "$root_gen_dir/content/browser/resources/media/media_internals_resources.pak",
-    "$root_gen_dir/content/browser/tracing/tracing_resources.pak",
     "$root_gen_dir/content/browser/webrtc/resources/webrtc_internals_resources.pak",
     "$root_gen_dir/content/content_resources.pak",
     "$root_gen_dir/content/dev_ui_content_resources.pak",
@@ -413,7 +412,6 @@ repack("pak") {
     "//content:dev_ui_content_resources",
     "//content/app/resources",
     "//content/browser/resources/media:media_internals_resources",
-    "//content/browser/tracing:resources",
     "//content/browser/webrtc/resources",
     "//mojo/public/js:resources",
     "//net:net_resources",
diff --git a/chromium/fuchsia/engine/BUILD.gn b/chromium/fuchsia/engine/BUILD.gn
index a502b7fc273..39df2a7028a 100644
--- a/src/3rdparty/chromium/fuchsia/engine/BUILD.gn
+++ b/src/3rdparty/chromium/fuchsia/engine/BUILD.gn
@@ -43,7 +43,6 @@ repack("web_engine_pak") {
     "$root_gen_dir/components/components_resources.pak",
     "$root_gen_dir/components/strings/components_strings_en-US.pak",
     "$root_gen_dir/content/app/resources/content_resources_100_percent.pak",
-    "$root_gen_dir/content/browser/tracing/tracing_resources.pak",
     "$root_gen_dir/content/content_resources.pak",
     "$root_gen_dir/content/dev_ui_content_resources.pak",
     "$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak",
@@ -66,7 +65,6 @@ repack("web_engine_pak") {
     "//content:content_resources",
     "//content:dev_ui_content_resources",
     "//content/app/resources",
-    "//content/browser/tracing:resources",
     "//gpu/command_buffer/service",
     "//mojo/public/js:resources",
     "//net:net_resources",
diff --git a/chromium/headless/BUILD.gn b/chromium/headless/BUILD.gn
index d2ab76aed32..15e4b78009d 100644
--- a/src/3rdparty/chromium/headless/BUILD.gn
+++ b/src/3rdparty/chromium/headless/BUILD.gn
@@ -37,7 +37,6 @@ repack("pak") {
     "$root_gen_dir/components/components_resources.pak",
     "$root_gen_dir/components/strings/components_strings_en-US.pak",
     "$root_gen_dir/content/app/resources/content_resources_100_percent.pak",
-    "$root_gen_dir/content/browser/tracing/tracing_resources.pak",
     "$root_gen_dir/content/content_resources.pak",
     "$root_gen_dir/content/dev_ui_content_resources.pak",
     "$root_gen_dir/headless/headless_lib_resources.pak",
@@ -65,7 +64,6 @@ repack("pak") {
     "//content:content_resources",
     "//content:dev_ui_content_resources",
     "//content/app/resources",
-    "//content/browser/tracing:resources",
     "//mojo/public/js:resources",
     "//net:net_resources",
     "//third_party/blink/public:resources",
diff --git a/chromium/mojo/public/tools/BUILD.gn b/chromium/mojo/public/tools/BUILD.gn
index 4c68350b399..1cc01256f00 100644
--- a/src/3rdparty/chromium/mojo/public/tools/BUILD.gn
+++ b/src/3rdparty/chromium/mojo/public/tools/BUILD.gn
@@ -14,5 +14,4 @@ group("mojo_python_unittests") {
     "//testing/xvfb.py",
   ]
   deps = [ "//mojo/public/tools/mojom/mojom:tests" ]
-  data_deps = [ "//third_party/catapult/third_party/typ/" ]
 }
diff --git a/chromium/testing/BUILD.gn b/chromium/testing/BUILD.gn
index 56ebf8d46c9..7d51bc0ccf7 100644
--- a/src/3rdparty/chromium/testing/BUILD.gn
+++ b/src/3rdparty/chromium/testing/BUILD.gn
@@ -27,7 +27,6 @@ group("run_perf_test") {
 
   data_deps = [
     ":test_scripts_shared",
-    "//third_party/catapult/tracing:convert_chart_json",
   ]
 
   if (is_android) {
diff --git a/chromium/third_party/webrtc/test/BUILD.gn b/chromium/third_party/webrtc/test/BUILD.gn
index 58d3dab5219..48328298d2e 100644
--- a/src/3rdparty/chromium/third_party/webrtc/test/BUILD.gn
+++ b/src/3rdparty/chromium/third_party/webrtc/test/BUILD.gn
@@ -258,10 +258,6 @@ rtc_library("perf_test") {
   absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
   if (rtc_enable_protobuf) {
     sources += [ "testsupport/perf_test_histogram_writer.cc" ]
-    deps += [
-      "//third_party/catapult/tracing/tracing:histogram",
-      "//third_party/catapult/tracing/tracing:reserved_infos",
-    ]
   } else {
     sources += [ "testsupport/perf_test_histogram_writer_no_protobuf.cc" ]
   }
@@ -566,7 +562,6 @@ if (rtc_include_tests) {
 
     if (rtc_enable_protobuf) {
       sources += [ "testsupport/perf_test_histogram_writer_unittest.cc" ]
-      deps += [ "//third_party/catapult/tracing/tracing:histogram" ]
     }
 
     data = test_support_unittests_resources
diff --git a/chromium/tools/binary_size/BUILD.gn b/chromium/tools/binary_size/BUILD.gn
index e6806bf7754..2c985d15fab 100644
--- a/src/3rdparty/chromium/tools/binary_size/BUILD.gn
+++ b/src/3rdparty/chromium/tools/binary_size/BUILD.gn
@@ -18,7 +18,6 @@ python_library("binary_size_trybot_py") {
 python_library("sizes_py") {
   testonly = true
   pydeps_file = "sizes.pydeps"
-  data_deps = [ "//third_party/catapult/tracing:convert_chart_json" ]
 }
 
 if (is_linux || is_chromeos) {
diff --git a/chromium/tools/grit/BUILD.gn b/chromium/tools/grit/BUILD.gn
index 1cd3c75b553..60c4cf2f77a 100644
--- a/src/3rdparty/chromium/tools/grit/BUILD.gn
+++ b/src/3rdparty/chromium/tools/grit/BUILD.gn
@@ -33,7 +33,6 @@ group("grit_python_unittests") {
     "//testing/scripts/run_isolated_script_test.py",
     "//testing/xvfb.py",
     "//tools/grit/",
-    "//third_party/catapult/third_party/typ/",
   ]
 }
 
diff --git a/chromium/tools/gritsettings/resource_ids.spec b/chromium/tools/gritsettings/resource_ids.spec
index d0a4545514c..80b0bf1737b 100644
--- a/src/3rdparty/chromium/tools/gritsettings/resource_ids.spec
+++ b/src/3rdparty/chromium/tools/gritsettings/resource_ids.spec
@@ -499,12 +499,6 @@
   "content/shell/shell_resources.grd": {
     "includes": [2940],
   },
-
-  # This file is generated during the build.
-  "<(SHARED_INTERMEDIATE_DIR)/content/browser/tracing/tracing_resources.grd": {
-    "META": {"sizes": {"includes": [20],}},
-    "includes": [2960],
-  },
   # END content/ section.
 
   # START ios/web/ section.
diff --git a/chromium/tools/metrics/BUILD.gn b/chromium/tools/metrics/BUILD.gn
index 846d5248bfa..cb57d2bdae1 100644
--- a/src/3rdparty/chromium/tools/metrics/BUILD.gn
+++ b/src/3rdparty/chromium/tools/metrics/BUILD.gn
@@ -56,7 +56,6 @@ group("metrics_python_tests") {
     "//testing/scripts/common.py",
     "//testing/xvfb.py",
     "//testing/test_env.py",
-    "//third_party/catapult/third_party/typ/",
 
     # Scripts we depend on. Their unit tests are also included.
     "//tools/json_comment_eater/json_comment_eater.py",
diff --git a/chromium/tools/perf/chrome_telemetry_build/BUILD.gn b/chromium/tools/perf/chrome_telemetry_build/BUILD.gn
index 280bb754c2c..c287fdcebb3 100644
--- a/src/3rdparty/chromium/tools/perf/chrome_telemetry_build/BUILD.gn
+++ b/src/3rdparty/chromium/tools/perf/chrome_telemetry_build/BUILD.gn
@@ -107,7 +107,6 @@ group("telemetry_chrome_test_without_chrome") {
     "//tools/perf/core/",  # chrome_telemetry_build/ depends on core/
   ]
   data_deps = [
-    "//third_party/catapult:telemetry_chrome_test_support",
     "//tools/metrics:metrics_python_tests",
   ]
 
@@ -151,7 +150,5 @@ group("telemetry_chrome_test_without_chrome") {
       "//build/android:devil_chromium_py",
       "//build/android:stack_tools",
     ]
-  } else if (!is_fuchsia) {
-    data_deps += [ "//third_party/catapult/telemetry:bitmaptools" ]
   }
 }
diff --git a/chromium/tools/perf/core/perfetto_binary_roller/BUILD.gn b/chromium/tools/perf/core/perfetto_binary_roller/BUILD.gn
index 7fe48cba143..e9c7f0261a5 100644
--- a/src/3rdparty/chromium/tools/perf/core/perfetto_binary_roller/BUILD.gn
+++ b/src/3rdparty/chromium/tools/perf/core/perfetto_binary_roller/BUILD.gn
@@ -7,7 +7,6 @@ import("//build/util/generate_wrapper.gni")
 generate_wrapper("upload_trace_processor") {
   testonly = true
   data_deps = [
-    "//third_party/catapult:telemetry_chrome_test_support",
     "//third_party/perfetto/src/trace_processor:trace_processor_shell",
   ]
   data = [
diff --git a/chromium/tools/polymer/BUILD.gn b/chromium/tools/polymer/BUILD.gn
index 092066b7c04..d115144cd61 100644
--- a/src/3rdparty/chromium/tools/polymer/BUILD.gn
+++ b/src/3rdparty/chromium/tools/polymer/BUILD.gn
@@ -10,6 +10,5 @@ group("polymer_tools_python_unittests") {
     "//testing/scripts/run_isolated_script_test.py",
     "//testing/xvfb.py",
     "//tools/polymer/",
-    "//third_party/catapult/third_party/typ/",
   ]
 }
diff --git a/chromium/v8/tools/BUILD.gn b/chromium/v8/tools/BUILD.gn
index 2f8197dd369..83304b6342b 100644
--- a/src/3rdparty/chromium/v8/tools/BUILD.gn
+++ b/src/3rdparty/chromium/v8/tools/BUILD.gn
@@ -31,10 +31,6 @@ group("v8_android_test_runner_deps") {
 
   if (is_android && !build_with_chromium) {
     data_deps = [ "//build/android:test_runner_py" ]
-    data = [
-      # This is used by android.py, but not included by test_runner_py above.
-      "//third_party/catapult/devil/devil/android/perf/",
-    ]
   }
 }
 
diff --git a/chromium/weblayer/shell/BUILD.gn b/chromium/weblayer/shell/BUILD.gn
index 66984a7da54..1815fad623d 100644
--- a/src/3rdparty/chromium/weblayer/shell/BUILD.gn
+++ b/src/3rdparty/chromium/weblayer/shell/BUILD.gn
@@ -161,7 +161,6 @@ repack("support_pak") {
     "$root_gen_dir/components/strings/components_locale_settings_en-US.pak",
     "$root_gen_dir/components/strings/components_strings_en-US.pak",
     "$root_gen_dir/content/app/resources/content_resources_100_percent.pak",
-    "$root_gen_dir/content/browser/tracing/tracing_resources.pak",
     "$root_gen_dir/content/content_resources.pak",
     "$root_gen_dir/content/dev_ui_content_resources.pak",
     "$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak",
@@ -182,7 +181,6 @@ repack("support_pak") {
     "//content:content_resources",
     "//content:dev_ui_content_resources",
     "//content/app/resources",
-    "//content/browser/tracing:resources",
     "//mojo/public/js:resources",
     "//net:net_resources",
     "//third_party/blink/public:resources",
-- 
2.35.1

012-drop-catapult.patch  gentoo bug 698988 part 2.

From b60fc250d65144532cd47eac72279e93baaec2b8 Mon Sep 17 00:00:00 2001
From: Jimi Huotari <chiitoo@gentoo.org>
Date: Wed, 6 Apr 2022 14:35:14 +0300
Subject: [PATCH] Remove dependency on catapult

---
 src/core/qtwebengine_resources.gni | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/core/qtwebengine_resources.gni b/src/core/qtwebengine_resources.gni
index 3bf1a5d57..29fd2603c 100644
--- a/src/core/qtwebengine_resources.gni
+++ b/src/core/qtwebengine_resources.gni
@@ -27,7 +27,6 @@ repack("qtwebengine_repack_resources") {
     "$root_gen_dir/components/components_resources.pak",
     "$root_gen_dir/components/dev_ui_components_resources.pak",
     "$root_gen_dir/content/browser/resources/media/media_internals_resources.pak",
-    "$root_gen_dir/content/browser/tracing/tracing_resources.pak",
     "$root_gen_dir/content/content_resources.pak",
     "$root_gen_dir/content/dev_ui_content_resources.pak",
     "$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak",
@@ -44,7 +43,6 @@ repack("qtwebengine_repack_resources") {
      "//components/resources:components_resources_grit",
      "//components/resources:dev_ui_components_resources_grit",
      "//content/browser/resources/media:media_internals_resources",
-     "//content/browser/tracing:resources",
      "//content:content_resources_grit",
      "//content:dev_ui_content_resources_grit",
      "//mojo/public/js:resources",
-- 
2.35.1

013-port-to-pipewire-0.3.patch  gentoo bug 698988

I cannot test this, I have not installed pipewire --ken

From 77f70aae4c97cad1dea5fba9c04c8d2ffd3826ec Mon Sep 17 00:00:00 2001
From: Antonio Rojas <arojas@archlinux.org>
Date: Sun, 20 Feb 2022 11:12:00 +0000
Subject: [PATCH 3/3] Port to pipewire 0.3

---
 .../webrtc/modules/desktop_capture/BUILD.gn   |  42 +-
 .../linux/base_capturer_pipewire.cc           | 770 ++++++++++++++----
 .../linux/base_capturer_pipewire.h            |  58 +-
 .../linux/{pipewire.sigs => pipewire02.sigs}  |   3 +
 .../desktop_capture/linux/pipewire03.sigs     |  46 ++
 .../linux/screen_capturer_pipewire.cc         |  29 -
 .../linux/screen_capturer_pipewire.h          |  33 -
 .../linux/window_capturer_pipewire.cc         |  29 -
 .../linux/window_capturer_pipewire.h          |  33 -
 .../desktop_capture/screen_capturer_linux.cc  |   4 +-
 .../desktop_capture/window_capturer_linux.cc  |   4 +-
 chromium/third_party/webrtc/webrtc.gni        |   4 +
 12 files changed, 750 insertions(+), 305 deletions(-)
 rename chromium/third_party/webrtc/modules/desktop_capture/linux/{pipewire.sigs => pipewire02.sigs} (91%)
 create mode 100644 chromium/third_party/webrtc/modules/desktop_capture/linux/pipewire03.sigs
 delete mode 100644 chromium/third_party/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc
 delete mode 100644 chromium/third_party/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.h
 delete mode 100644 chromium/third_party/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc
 delete mode 100644 chromium/third_party/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.h

diff --git a/chromium/third_party/webrtc/modules/desktop_capture/BUILD.gn b/chromium/third_party/webrtc/modules/desktop_capture/BUILD.gn
index 5235512735d..8259442f811 100644
--- a/src/3rdparty/chromium/third_party/webrtc/modules/desktop_capture/BUILD.gn
+++ b/src/3rdparty/chromium/third_party/webrtc/modules/desktop_capture/BUILD.gn
@@ -11,6 +11,11 @@ import("//build/config/ui.gni")
 import("//tools/generate_stubs/rules.gni")
 import("../../webrtc.gni")
 
+if (rtc_use_pipewire) {
+  assert(rtc_pipewire_version == "0.2" || rtc_pipewire_version == "0.3",
+         "Unsupported PipeWire version")
+}
+
 use_desktop_capture_differ_sse2 = current_cpu == "x86" || current_cpu == "x64"
 
 config("x11_config") {
@@ -200,22 +205,41 @@ if (is_linux || is_chromeos) {
       ]
     }
 
-    if (rtc_link_pipewire) {
+    if (rtc_pipewire_version == "0.3") {
       pkg_config("pipewire") {
-        packages = [ "libpipewire-0.2" ]
+        packages = [ "libpipewire-0.3" ]
+        if (!rtc_link_pipewire) {
+          ignore_libs = true
+        }
       }
     } else {
+      pkg_config("pipewire") {
+        packages = [ "libpipewire-0.2" ]
+        if (!rtc_link_pipewire) {
+          ignore_libs = true
+        }
+      }
+    }
+
+    if (!rtc_link_pipewire) {
       # When libpipewire is not directly linked, use stubs to allow for dlopening of
       # the binary.
       generate_stubs("pipewire_stubs") {
-        configs = [ "../../:common_config" ]
+        configs = [
+          "../../:common_config",
+          ":pipewire",
+        ]
         deps = [ "../../rtc_base" ]
         extra_header = "linux/pipewire_stub_header.fragment"
         logging_function = "RTC_LOG(LS_VERBOSE)"
         logging_include = "rtc_base/logging.h"
         output_name = "linux/pipewire_stubs"
         path_from_source = "modules/desktop_capture/linux"
-        sigs = [ "linux/pipewire.sigs" ]
+        if (rtc_pipewire_version == "0.3") {
+          sigs = [ "linux/pipewire03.sigs" ]
+        } else {
+          sigs = [ "linux/pipewire02.sigs" ]
+        }
       }
     }
 
@@ -506,6 +530,7 @@ rtc_library("desktop_capture_generic") {
   absl_deps = [
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings",
+    "//third_party/abseil-cpp/absl/types:optional",
   ]
 
   if (rtc_use_x11_extensions) {
@@ -526,20 +551,15 @@ rtc_library("desktop_capture_generic") {
     sources += [
       "linux/base_capturer_pipewire.cc",
       "linux/base_capturer_pipewire.h",
-      "linux/screen_capturer_pipewire.cc",
-      "linux/screen_capturer_pipewire.h",
-      "linux/window_capturer_pipewire.cc",
-      "linux/window_capturer_pipewire.h",
     ]
 
     configs += [
       ":pipewire_config",
       ":gio",
+      ":pipewire",
     ]
 
-    if (rtc_link_pipewire) {
-      configs += [ ":pipewire" ]
-    } else {
+    if (!rtc_link_pipewire) {
       deps += [ ":pipewire_stubs" ]
     }
   }
diff --git a/chromium/third_party/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc b/chromium/third_party/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc
index 2640e93aa98..c302a086ead 100644
--- a/src/3rdparty/chromium/third_party/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc
+++ b/src/3rdparty/chromium/third_party/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc
@@ -14,8 +14,14 @@
 #include <glib-object.h>
 #include <spa/param/format-utils.h>
 #include <spa/param/props.h>
+#if !PW_CHECK_VERSION(0, 3, 0)
 #include <spa/param/video/raw-utils.h>
 #include <spa/support/type-map.h>
+#endif
+
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/syscall.h>
 
 #include <memory>
 #include <utility>
@@ -30,7 +36,11 @@
 #include "modules/desktop_capture/linux/pipewire_stubs.h"
 
 using modules_desktop_capture_linux::InitializeStubs;
-using modules_desktop_capture_linux::kModulePipewire;
+#if PW_CHECK_VERSION(0, 3, 0)
+using modules_desktop_capture_linux::kModulePipewire03;
+#else
+using modules_desktop_capture_linux::kModulePipewire02;
+#endif
 using modules_desktop_capture_linux::StubPathMap;
 #endif  // defined(WEBRTC_DLOPEN_PIPEWIRE)
 
@@ -47,9 +57,156 @@ const char kScreenCastInterfaceName[] = "org.freedesktop.portal.ScreenCast";
 const int kBytesPerPixel = 4;
 
 #if defined(WEBRTC_DLOPEN_PIPEWIRE)
+#if PW_CHECK_VERSION(0, 3, 0)
+const char kPipeWireLib[] = "libpipewire-0.3.so.0";
+#else
 const char kPipeWireLib[] = "libpipewire-0.2.so.1";
 #endif
+#endif
 
+// static
+struct dma_buf_sync {
+  uint64_t flags;
+};
+#define DMA_BUF_SYNC_READ (1 << 0)
+#define DMA_BUF_SYNC_START (0 << 2)
+#define DMA_BUF_SYNC_END (1 << 2)
+#define DMA_BUF_BASE 'b'
+#define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync)
+
+static void SyncDmaBuf(int fd, uint64_t start_or_end) {
+  struct dma_buf_sync sync = {0};
+
+  sync.flags = start_or_end | DMA_BUF_SYNC_READ;
+
+  while (true) {
+    int ret;
+    ret = ioctl(fd, DMA_BUF_IOCTL_SYNC, &sync);
+    if (ret == -1 && errno == EINTR) {
+      continue;
+    } else if (ret == -1) {
+      RTC_LOG(LS_ERROR) << "Failed to synchronize DMA buffer: "
+                        << g_strerror(errno);
+      break;
+    } else {
+      break;
+    }
+  }
+}
+
+class ScopedBuf {
+ public:
+  ScopedBuf() {}
+  ScopedBuf(unsigned char* map, int map_size, bool is_dma_buf, int fd)
+      : map_(map), map_size_(map_size), is_dma_buf_(is_dma_buf), fd_(fd) {}
+  ~ScopedBuf() {
+    if (map_ != MAP_FAILED) {
+      if (is_dma_buf_) {
+        SyncDmaBuf(fd_, DMA_BUF_SYNC_END);
+      }
+      munmap(map_, map_size_);
+    }
+  }
+
+  operator bool() { return map_ != MAP_FAILED; }
+
+  void initialize(unsigned char* map, int map_size, bool is_dma_buf, int fd) {
+    map_ = map;
+    map_size_ = map_size;
+    is_dma_buf_ = is_dma_buf;
+    fd_ = fd;
+  }
+
+  unsigned char* get() { return map_; }
+
+ protected:
+  unsigned char* map_ = nullptr;
+  int map_size_;
+  bool is_dma_buf_;
+  int fd_;
+};
+
+template <class T>
+class Scoped {
+ public:
+  Scoped() {}
+  explicit Scoped(T* val) { ptr_ = val; }
+  ~Scoped() { RTC_NOTREACHED(); }
+
+  T* operator->() { return ptr_; }
+
+  bool operator!() { return ptr_ == nullptr; }
+
+  T* get() { return ptr_; }
+
+  T** receive() {
+    RTC_CHECK(!ptr_);
+    return &ptr_;
+  }
+
+  Scoped& operator=(T* val) {
+    ptr_ = val;
+    return *this;
+  }
+
+ protected:
+  T* ptr_ = nullptr;
+};
+
+template <>
+Scoped<GError>::~Scoped() {
+  if (ptr_) {
+    g_error_free(ptr_);
+  }
+}
+
+template <>
+Scoped<gchar>::~Scoped() {
+  if (ptr_) {
+    g_free(ptr_);
+  }
+}
+
+template <>
+Scoped<GVariant>::~Scoped() {
+  if (ptr_) {
+    g_variant_unref(ptr_);
+  }
+}
+
+template <>
+Scoped<GVariantIter>::~Scoped() {
+  if (ptr_) {
+    g_variant_iter_free(ptr_);
+  }
+}
+
+template <>
+Scoped<GDBusMessage>::~Scoped() {
+  if (ptr_) {
+    g_object_unref(ptr_);
+  }
+}
+
+template <>
+Scoped<GUnixFDList>::~Scoped() {
+  if (ptr_) {
+    g_object_unref(ptr_);
+  }
+}
+
+#if PW_CHECK_VERSION(0, 3, 0)
+void BaseCapturerPipeWire::OnCoreError(void* data,
+                                       uint32_t id,
+                                       int seq,
+                                       int res,
+                                       const char* message) {
+  BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(data);
+  RTC_DCHECK(that);
+
+  RTC_LOG(LS_ERROR) << "PipeWire remote error: " << message;
+}
+#else
 // static
 void BaseCapturerPipeWire::OnStateChanged(void* data,
                                           pw_remote_state old_state,
@@ -64,7 +221,7 @@ void BaseCapturerPipeWire::OnStateChanged(void* data,
       break;
     case PW_REMOTE_STATE_CONNECTED:
       RTC_LOG(LS_INFO) << "PipeWire remote state: connected.";
-      that->CreateReceivingStream();
+      that->pw_stream_ = that->CreateReceivingStream();
       break;
     case PW_REMOTE_STATE_CONNECTING:
       RTC_LOG(LS_INFO) << "PipeWire remote state: connecting.";
@@ -74,6 +231,7 @@ void BaseCapturerPipeWire::OnStateChanged(void* data,
       break;
   }
 }
+#endif
 
 // static
 void BaseCapturerPipeWire::OnStreamStateChanged(void* data,
@@ -83,6 +241,18 @@ void BaseCapturerPipeWire::OnStreamStateChanged(void* data,
   BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(data);
   RTC_DCHECK(that);
 
+#if PW_CHECK_VERSION(0, 3, 0)
+  switch (state) {
+    case PW_STREAM_STATE_ERROR:
+      RTC_LOG(LS_ERROR) << "PipeWire stream state error: " << error_message;
+      break;
+    case PW_STREAM_STATE_PAUSED:
+    case PW_STREAM_STATE_STREAMING:
+    case PW_STREAM_STATE_UNCONNECTED:
+    case PW_STREAM_STATE_CONNECTING:
+      break;
+  }
+#else
   switch (state) {
     case PW_STREAM_STATE_ERROR:
       RTC_LOG(LS_ERROR) << "PipeWire stream state error: " << error_message;
@@ -97,36 +267,74 @@ void BaseCapturerPipeWire::OnStreamStateChanged(void* data,
     case PW_STREAM_STATE_STREAMING:
       break;
   }
+#endif
 }
 
 // static
+#if PW_CHECK_VERSION(0, 3, 0)
+void BaseCapturerPipeWire::OnStreamParamChanged(void* data,
+                                                uint32_t id,
+                                                const struct spa_pod* format) {
+#else
 void BaseCapturerPipeWire::OnStreamFormatChanged(void* data,
                                                  const struct spa_pod* format) {
+#endif
   BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(data);
   RTC_DCHECK(that);
 
   RTC_LOG(LS_INFO) << "PipeWire stream format changed.";
 
+#if PW_CHECK_VERSION(0, 3, 0)
+  if (!format || id != SPA_PARAM_Format) {
+#else
   if (!format) {
     pw_stream_finish_format(that->pw_stream_, /*res=*/0, /*params=*/nullptr,
                             /*n_params=*/0);
+#endif
     return;
   }
 
+#if PW_CHECK_VERSION(0, 3, 0)
+  spa_format_video_raw_parse(format, &that->spa_video_format_);
+#else
   that->spa_video_format_ = new spa_video_info_raw();
   spa_format_video_raw_parse(format, that->spa_video_format_,
                              &that->pw_type_->format_video);
+#endif
 
+#if PW_CHECK_VERSION(0, 3, 0)
+  auto width = that->spa_video_format_.size.width;
+  auto height = that->spa_video_format_.size.height;
+#else
   auto width = that->spa_video_format_->size.width;
   auto height = that->spa_video_format_->size.height;
+#endif
   auto stride = SPA_ROUND_UP_N(width * kBytesPerPixel, 4);
   auto size = height * stride;
 
+  that->desktop_size_ = DesktopSize(width, height);
+
   uint8_t buffer[1024] = {};
   auto builder = spa_pod_builder{buffer, sizeof(buffer)};
 
   // Setup buffers and meta header for new format.
-  const struct spa_pod* params[2];
+  const struct spa_pod* params[3];
+#if PW_CHECK_VERSION(0, 3, 0)
+  params[0] = reinterpret_cast<spa_pod*>(spa_pod_builder_add_object(
+      &builder, SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers,
+      SPA_PARAM_BUFFERS_size, SPA_POD_Int(size), SPA_PARAM_BUFFERS_stride,
+      SPA_POD_Int(stride), SPA_PARAM_BUFFERS_buffers,
+      SPA_POD_CHOICE_RANGE_Int(8, 1, 32)));
+  params[1] = reinterpret_cast<spa_pod*>(spa_pod_builder_add_object(
+      &builder, SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, SPA_PARAM_META_type,
+      SPA_POD_Id(SPA_META_Header), SPA_PARAM_META_size,
+      SPA_POD_Int(sizeof(struct spa_meta_header))));
+  params[2] = reinterpret_cast<spa_pod*>(spa_pod_builder_add_object(
+      &builder, SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, SPA_PARAM_META_type,
+      SPA_POD_Id(SPA_META_VideoCrop), SPA_PARAM_META_size,
+      SPA_POD_Int(sizeof(struct spa_meta_region))));
+  pw_stream_update_params(that->pw_stream_, params, 3);
+#else
   params[0] = reinterpret_cast<spa_pod*>(spa_pod_builder_object(
       &builder,
       // id to enumerate buffer requirements
@@ -155,8 +363,18 @@ void BaseCapturerPipeWire::OnStreamFormatChanged(void* data,
       // Size: size of the metadata, specified as integer (i)
       ":", that->pw_core_type_->param_meta.size, "i",
       sizeof(struct spa_meta_header)));
-
-  pw_stream_finish_format(that->pw_stream_, /*res=*/0, params, /*n_params=*/2);
+  params[2] = reinterpret_cast<spa_pod*>(spa_pod_builder_object(
+      &builder,
+      // id to enumerate supported metadata
+      that->pw_core_type_->param.idMeta, that->pw_core_type_->param_meta.Meta,
+      // Type: specified as id or enum (I)
+      ":", that->pw_core_type_->param_meta.type, "I",
+      that->pw_core_type_->meta.VideoCrop,
+      // Size: size of the metadata, specified as integer (i)
+      ":", that->pw_core_type_->param_meta.size, "i",
+      sizeof(struct spa_meta_video_crop)));
+  pw_stream_finish_format(that->pw_stream_, /*res=*/0, params, /*n_params=*/3);
+#endif
 }
 
 // static
@@ -164,15 +382,26 @@ void BaseCapturerPipeWire::OnStreamProcess(void* data) {
   BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(data);
   RTC_DCHECK(that);
 
-  pw_buffer* buf = nullptr;
+  struct pw_buffer* next_buffer;
+  struct pw_buffer* buffer = nullptr;
+
+  next_buffer = pw_stream_dequeue_buffer(that->pw_stream_);
+  while (next_buffer) {
+    buffer = next_buffer;
+    next_buffer = pw_stream_dequeue_buffer(that->pw_stream_);
 
-  if (!(buf = pw_stream_dequeue_buffer(that->pw_stream_))) {
+    if (next_buffer) {
+      pw_stream_queue_buffer(that->pw_stream_, buffer);
+    }
+  }
+
+  if (!buffer) {
     return;
   }
 
-  that->HandleBuffer(buf);
+  that->HandleBuffer(buffer);
 
-  pw_stream_queue_buffer(that->pw_stream_, buf);
+  pw_stream_queue_buffer(that->pw_stream_, buffer);
 }
 
 BaseCapturerPipeWire::BaseCapturerPipeWire(CaptureSourceType source_type)
@@ -183,6 +412,7 @@ BaseCapturerPipeWire::~BaseCapturerPipeWire() {
     pw_thread_loop_stop(pw_main_loop_);
   }
 
+#if !PW_CHECK_VERSION(0, 3, 0)
   if (pw_type_) {
     delete pw_type_;
   }
@@ -190,30 +420,41 @@ BaseCapturerPipeWire::~BaseCapturerPipeWire() {
   if (spa_video_format_) {
     delete spa_video_format_;
   }
+#endif
 
   if (pw_stream_) {
     pw_stream_destroy(pw_stream_);
   }
 
+#if !PW_CHECK_VERSION(0, 3, 0)
   if (pw_remote_) {
     pw_remote_destroy(pw_remote_);
   }
+#endif
 
+#if PW_CHECK_VERSION(0, 3, 0)
+  if (pw_core_) {
+    pw_core_disconnect(pw_core_);
+  }
+
+  if (pw_context_) {
+    pw_context_destroy(pw_context_);
+  }
+#else
   if (pw_core_) {
     pw_core_destroy(pw_core_);
   }
+#endif
 
   if (pw_main_loop_) {
     pw_thread_loop_destroy(pw_main_loop_);
   }
 
+#if !PW_CHECK_VERSION(0, 3, 0)
   if (pw_loop_) {
     pw_loop_destroy(pw_loop_);
   }
-
-  if (current_frame_) {
-    free(current_frame_);
-  }
+#endif
 
   if (start_request_signal_id_) {
     g_dbus_connection_signal_unsubscribe(connection_, start_request_signal_id_);
@@ -228,18 +469,16 @@ BaseCapturerPipeWire::~BaseCapturerPipeWire() {
   }
 
   if (session_handle_) {
-    GDBusMessage* message = g_dbus_message_new_method_call(
-        kDesktopBusName, session_handle_, kSessionInterfaceName, "Close");
-    if (message) {
-      GError* error = nullptr;
-      g_dbus_connection_send_message(connection_, message,
+    Scoped<GDBusMessage> message(g_dbus_message_new_method_call(
+        kDesktopBusName, session_handle_, kSessionInterfaceName, "Close"));
+    if (message.get()) {
+      Scoped<GError> error;
+      g_dbus_connection_send_message(connection_, message.get(),
                                      G_DBUS_SEND_MESSAGE_FLAGS_NONE,
-                                     /*out_serial=*/nullptr, &error);
-      if (error) {
+                                     /*out_serial=*/nullptr, error.receive());
+      if (error.get()) {
         RTC_LOG(LS_ERROR) << "Failed to close the session: " << error->message;
-        g_error_free(error);
       }
-      g_object_unref(message);
     }
   }
 
@@ -274,7 +513,11 @@ void BaseCapturerPipeWire::InitPipeWire() {
   StubPathMap paths;
 
   // Check if the PipeWire library is available.
-  paths[kModulePipewire].push_back(kPipeWireLib);
+#if PW_CHECK_VERSION(0, 3, 0)
+  paths[kModulePipewire03].push_back(kPipeWireLib);
+#else
+  paths[kModulePipewire02].push_back(kPipeWireLib);
+#endif
   if (!InitializeStubs(paths)) {
     RTC_LOG(LS_ERROR) << "Failed to load the PipeWire library and symbols.";
     portal_init_failed_ = true;
@@ -284,16 +527,46 @@ void BaseCapturerPipeWire::InitPipeWire() {
 
   pw_init(/*argc=*/nullptr, /*argc=*/nullptr);
 
+#if PW_CHECK_VERSION(0, 3, 0)
+  pw_main_loop_ = pw_thread_loop_new("pipewire-main-loop", nullptr);
+
+  pw_thread_loop_lock(pw_main_loop_);
+
+  pw_context_ =
+      pw_context_new(pw_thread_loop_get_loop(pw_main_loop_), nullptr, 0);
+  if (!pw_context_) {
+    RTC_LOG(LS_ERROR) << "Failed to create PipeWire context";
+    return;
+  }
+
+  pw_core_ = pw_context_connect(pw_context_, nullptr, 0);
+  if (!pw_core_) {
+    RTC_LOG(LS_ERROR) << "Failed to connect PipeWire context";
+    return;
+  }
+#else
   pw_loop_ = pw_loop_new(/*properties=*/nullptr);
   pw_main_loop_ = pw_thread_loop_new(pw_loop_, "pipewire-main-loop");
 
+  pw_thread_loop_lock(pw_main_loop_);
+
   pw_core_ = pw_core_new(pw_loop_, /*properties=*/nullptr);
   pw_core_type_ = pw_core_get_type(pw_core_);
   pw_remote_ = pw_remote_new(pw_core_, nullptr, /*user_data_size=*/0);
 
   InitPipeWireTypes();
+#endif
 
   // Initialize event handlers, remote end and stream-related.
+#if PW_CHECK_VERSION(0, 3, 0)
+  pw_core_events_.version = PW_VERSION_CORE_EVENTS;
+  pw_core_events_.error = &OnCoreError;
+
+  pw_stream_events_.version = PW_VERSION_STREAM_EVENTS;
+  pw_stream_events_.state_changed = &OnStreamStateChanged;
+  pw_stream_events_.param_changed = &OnStreamParamChanged;
+  pw_stream_events_.process = &OnStreamProcess;
+#else
   pw_remote_events_.version = PW_VERSION_REMOTE_EVENTS;
   pw_remote_events_.state_changed = &OnStateChanged;
 
@@ -301,19 +574,33 @@ void BaseCapturerPipeWire::InitPipeWire() {
   pw_stream_events_.state_changed = &OnStreamStateChanged;
   pw_stream_events_.format_changed = &OnStreamFormatChanged;
   pw_stream_events_.process = &OnStreamProcess;
+#endif
 
+#if PW_CHECK_VERSION(0, 3, 0)
+  pw_core_add_listener(pw_core_, &spa_core_listener_, &pw_core_events_, this);
+
+  pw_stream_ = CreateReceivingStream();
+  if (!pw_stream_) {
+    RTC_LOG(LS_ERROR) << "Failed to create PipeWire stream";
+    return;
+  }
+#else
   pw_remote_add_listener(pw_remote_, &spa_remote_listener_, &pw_remote_events_,
                          this);
   pw_remote_connect_fd(pw_remote_, pw_fd_);
+#endif
 
   if (pw_thread_loop_start(pw_main_loop_) < 0) {
     RTC_LOG(LS_ERROR) << "Failed to start main PipeWire loop";
     portal_init_failed_ = true;
   }
 
+  pw_thread_loop_unlock(pw_main_loop_);
+
   RTC_LOG(LS_INFO) << "PipeWire remote opened.";
 }
 
+#if !PW_CHECK_VERSION(0, 3, 0)
 void BaseCapturerPipeWire::InitPipeWireTypes() {
   spa_type_map* map = pw_core_type_->map;
   pw_type_ = new PipeWireType();
@@ -323,23 +610,44 @@ void BaseCapturerPipeWire::InitPipeWireTypes() {
   spa_type_format_video_map(map, &pw_type_->format_video);
   spa_type_video_format_map(map, &pw_type_->video_format);
 }
+#endif
 
-void BaseCapturerPipeWire::CreateReceivingStream() {
+pw_stream* BaseCapturerPipeWire::CreateReceivingStream() {
+#if !PW_CHECK_VERSION(0, 3, 0)
+  if (pw_remote_get_state(pw_remote_, nullptr) != PW_REMOTE_STATE_CONNECTED) {
+    RTC_LOG(LS_ERROR) << "Cannot create pipewire stream";
+    return nullptr;
+  }
+#endif
   spa_rectangle pwMinScreenBounds = spa_rectangle{1, 1};
-  spa_rectangle pwScreenBounds =
-      spa_rectangle{static_cast<uint32_t>(desktop_size_.width()),
-                    static_cast<uint32_t>(desktop_size_.height())};
-
-  spa_fraction pwFrameRateMin = spa_fraction{0, 1};
-  spa_fraction pwFrameRateMax = spa_fraction{60, 1};
+  spa_rectangle pwMaxScreenBounds = spa_rectangle{UINT32_MAX, UINT32_MAX};
 
   pw_properties* reuseProps =
       pw_properties_new_string("pipewire.client.reuse=1");
-  pw_stream_ = pw_stream_new(pw_remote_, "webrtc-consume-stream", reuseProps);
+#if PW_CHECK_VERSION(0, 3, 0)
+  auto stream = pw_stream_new(pw_core_, "webrtc-consume-stream", reuseProps);
+#else
+  auto stream = pw_stream_new(pw_remote_, "webrtc-consume-stream", reuseProps);
+#endif
 
   uint8_t buffer[1024] = {};
   const spa_pod* params[1];
   spa_pod_builder builder = spa_pod_builder{buffer, sizeof(buffer)};
+
+#if PW_CHECK_VERSION(0, 3, 0)
+  params[0] = reinterpret_cast<spa_pod*>(spa_pod_builder_add_object(
+      &builder, SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
+      SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_video),
+      SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
+      SPA_FORMAT_VIDEO_format,
+      SPA_POD_CHOICE_ENUM_Id(5, SPA_VIDEO_FORMAT_BGRx, SPA_VIDEO_FORMAT_RGBx,
+                             SPA_VIDEO_FORMAT_RGBA, SPA_VIDEO_FORMAT_BGRx,
+                             SPA_VIDEO_FORMAT_BGRA),
+      SPA_FORMAT_VIDEO_size,
+      SPA_POD_CHOICE_RANGE_Rectangle(&pwMinScreenBounds, &pwMinScreenBounds,
+                                     &pwMaxScreenBounds),
+      0));
+#else
   params[0] = reinterpret_cast<spa_pod*>(spa_pod_builder_object(
       &builder,
       // id to enumerate formats
@@ -349,69 +657,218 @@ void BaseCapturerPipeWire::CreateReceivingStream() {
       // then allowed formats are enumerated (e) and the format is undecided (u)
       // to allow negotiation
       ":", pw_type_->format_video.format, "Ieu", pw_type_->video_format.BGRx,
-      SPA_POD_PROP_ENUM(2, pw_type_->video_format.RGBx,
-                        pw_type_->video_format.BGRx),
+      SPA_POD_PROP_ENUM(
+          4, pw_type_->video_format.RGBx, pw_type_->video_format.BGRx,
+          pw_type_->video_format.RGBA, pw_type_->video_format.BGRA),
       // Video size: specified as rectangle (R), preferred size is specified as
       // first parameter, then allowed size is defined as range (r) from min and
       // max values and the format is undecided (u) to allow negotiation
-      ":", pw_type_->format_video.size, "Rru", &pwScreenBounds, 2,
-      &pwMinScreenBounds, &pwScreenBounds,
-      // Frame rate: specified as fraction (F) and set to minimum frame rate
-      // value
-      ":", pw_type_->format_video.framerate, "F", &pwFrameRateMin,
-      // Max frame rate: specified as fraction (F), preferred frame rate is set
-      // to maximum value, then allowed frame rate is defined as range (r) from
-      // min and max values and it is undecided (u) to allow negotiation
-      ":", pw_type_->format_video.max_framerate, "Fru", &pwFrameRateMax, 2,
-      &pwFrameRateMin, &pwFrameRateMax));
-
-  pw_stream_add_listener(pw_stream_, &spa_stream_listener_, &pw_stream_events_,
+      ":", pw_type_->format_video.size, "Rru", &pwMinScreenBounds,
+      SPA_POD_PROP_MIN_MAX(&pwMinScreenBounds, &pwMaxScreenBounds)));
+#endif
+
+  pw_stream_add_listener(stream, &spa_stream_listener_, &pw_stream_events_,
                          this);
+#if PW_CHECK_VERSION(0, 3, 0)
+  if (pw_stream_connect(stream, PW_DIRECTION_INPUT, pw_stream_node_id_,
+                        PW_STREAM_FLAG_AUTOCONNECT, params, 1) != 0) {
+#else
   pw_stream_flags flags = static_cast<pw_stream_flags>(
-      PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_INACTIVE |
-      PW_STREAM_FLAG_MAP_BUFFERS);
-  if (pw_stream_connect(pw_stream_, PW_DIRECTION_INPUT, /*port_path=*/nullptr,
+      PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_INACTIVE);
+  if (pw_stream_connect(stream, PW_DIRECTION_INPUT, /*port_path=*/nullptr,
                         flags, params,
                         /*n_params=*/1) != 0) {
+#endif
     RTC_LOG(LS_ERROR) << "Could not connect receiving stream.";
     portal_init_failed_ = true;
-    return;
+    return nullptr;
   }
+
+  return stream;
 }
 
 void BaseCapturerPipeWire::HandleBuffer(pw_buffer* buffer) {
   spa_buffer* spaBuffer = buffer->buffer;
-  void* src = nullptr;
+  ScopedBuf map;
+  uint8_t* src = nullptr;
+
+  if (spaBuffer->datas[0].chunk->size == 0) {
+    RTC_LOG(LS_ERROR) << "Failed to get video stream: Zero size.";
+    return;
+  }
+
+#if PW_CHECK_VERSION(0, 3, 0)
+  if (spaBuffer->datas[0].type == SPA_DATA_MemFd ||
+      spaBuffer->datas[0].type == SPA_DATA_DmaBuf) {
+#else
+  if (spaBuffer->datas[0].type == pw_core_type_->data.MemFd ||
+      spaBuffer->datas[0].type == pw_core_type_->data.DmaBuf) {
+#endif
+    map.initialize(
+        static_cast<uint8_t*>(
+            mmap(nullptr,
+                 spaBuffer->datas[0].maxsize + spaBuffer->datas[0].mapoffset,
+                 PROT_READ, MAP_PRIVATE, spaBuffer->datas[0].fd, 0)),
+        spaBuffer->datas[0].maxsize + spaBuffer->datas[0].mapoffset,
+#if PW_CHECK_VERSION(0, 3, 0)
+        spaBuffer->datas[0].type == SPA_DATA_DmaBuf,
+#else
+        spaBuffer->datas[0].type == pw_core_type_->data.DmaBuf,
+#endif
+        spaBuffer->datas[0].fd);
+
+    if (!map) {
+      RTC_LOG(LS_ERROR) << "Failed to mmap the memory: "
+                        << std::strerror(errno);
+      return;
+    }
+
+#if PW_CHECK_VERSION(0, 3, 0)
+    if (spaBuffer->datas[0].type == SPA_DATA_DmaBuf) {
+#else
+    if (spaBuffer->datas[0].type == pw_core_type_->data.DmaBuf) {
+#endif
+      SyncDmaBuf(spaBuffer->datas[0].fd, DMA_BUF_SYNC_START);
+    }
+
+    src = SPA_MEMBER(map.get(), spaBuffer->datas[0].mapoffset, uint8_t);
+#if PW_CHECK_VERSION(0, 3, 0)
+  } else if (spaBuffer->datas[0].type == SPA_DATA_MemPtr) {
+#else
+  } else if (spaBuffer->datas[0].type == pw_core_type_->data.MemPtr) {
+#endif
+    src = static_cast<uint8_t*>(spaBuffer->datas[0].data);
+  }
 
-  if (!(src = spaBuffer->datas[0].data)) {
+  if (!src) {
+    return;
+  }
+
+#if PW_CHECK_VERSION(0, 3, 0)
+  struct spa_meta_region* video_metadata =
+      static_cast<struct spa_meta_region*>(spa_buffer_find_meta_data(
+          spaBuffer, SPA_META_VideoCrop, sizeof(*video_metadata)));
+#else
+  struct spa_meta_video_crop* video_metadata =
+      static_cast<struct spa_meta_video_crop*>(
+          spa_buffer_find_meta(spaBuffer, pw_core_type_->meta.VideoCrop));
+#endif
+
+  // Video size from metadata is bigger than an actual video stream size.
+  // The metadata are wrong or we should up-scale the video...in both cases
+  // just quit now.
+#if PW_CHECK_VERSION(0, 3, 0)
+  if (video_metadata && (video_metadata->region.size.width >
+                             static_cast<uint32_t>(desktop_size_.width()) ||
+                         video_metadata->region.size.height >
+                             static_cast<uint32_t>(desktop_size_.height()))) {
+#else
+  if (video_metadata && (video_metadata->width > desktop_size_.width() ||
+                         video_metadata->height > desktop_size_.height())) {
+#endif
+    RTC_LOG(LS_ERROR) << "Stream metadata sizes are wrong!";
     return;
   }
 
-  uint32_t maxSize = spaBuffer->datas[0].maxsize;
-  int32_t srcStride = spaBuffer->datas[0].chunk->stride;
-  if (srcStride != (desktop_size_.width() * kBytesPerPixel)) {
+  // Use video metadata when video size from metadata is set and smaller than
+  // video stream size, so we need to adjust it.
+  bool video_is_full_width = true;
+  bool video_is_full_height = true;
+#if PW_CHECK_VERSION(0, 3, 0)
+  if (video_metadata && video_metadata->region.size.width != 0 &&
+      video_metadata->region.size.height != 0) {
+    if (video_metadata->region.size.width <
+        static_cast<uint32_t>(desktop_size_.width())) {
+      video_is_full_width = false;
+    } else if (video_metadata->region.size.height <
+               static_cast<uint32_t>(desktop_size_.height())) {
+      video_is_full_height = false;
+    }
+  }
+#else
+  if (video_metadata && video_metadata->width != 0 &&
+      video_metadata->height != 0) {
+    if (video_metadata->width < desktop_size_.width()) {
+    } else if (video_metadata->height < desktop_size_.height()) {
+      video_is_full_height = false;
+    }
+  }
+#endif
+
+  DesktopSize video_size_prev = video_size_;
+  if (!video_is_full_height || !video_is_full_width) {
+#if PW_CHECK_VERSION(0, 3, 0)
+    video_size_ = DesktopSize(video_metadata->region.size.width,
+                              video_metadata->region.size.height);
+#else
+    video_size_ = DesktopSize(video_metadata->width, video_metadata->height);
+#endif
+  } else {
+    video_size_ = desktop_size_;
+  }
+
+  webrtc::MutexLock lock(&current_frame_lock_);
+  if (!current_frame_ || !video_size_.equals(video_size_prev)) {
+    current_frame_ = std::make_unique<uint8_t[]>(
+        video_size_.width() * video_size_.height() * kBytesPerPixel);
+  }
+
+  const int32_t dst_stride = video_size_.width() * kBytesPerPixel;
+  const int32_t src_stride = spaBuffer->datas[0].chunk->stride;
+
+  if (src_stride != (desktop_size_.width() * kBytesPerPixel)) {
     RTC_LOG(LS_ERROR) << "Got buffer with stride different from screen stride: "
-                      << srcStride
+                      << src_stride
                       << " != " << (desktop_size_.width() * kBytesPerPixel);
     portal_init_failed_ = true;
+
     return;
   }
 
-  if (!current_frame_) {
-    current_frame_ = static_cast<uint8_t*>(malloc(maxSize));
-  }
-  RTC_DCHECK(current_frame_ != nullptr);
-
-  // If both sides decided to go with the RGBx format we need to convert it to
-  // BGRx to match color format expected by WebRTC.
-  if (spa_video_format_->format == pw_type_->video_format.RGBx) {
-    uint8_t* tempFrame = static_cast<uint8_t*>(malloc(maxSize));
-    std::memcpy(tempFrame, src, maxSize);
-    ConvertRGBxToBGRx(tempFrame, maxSize);
-    std::memcpy(current_frame_, tempFrame, maxSize);
-    free(tempFrame);
-  } else {
-    std::memcpy(current_frame_, src, maxSize);
+  // Adjust source content based on metadata video position
+#if PW_CHECK_VERSION(0, 3, 0)
+  if (!video_is_full_height &&
+      (video_metadata->region.position.y + video_size_.height() <=
+       desktop_size_.height())) {
+    src += src_stride * video_metadata->region.position.y;
+  }
+  const int x_offset =
+      !video_is_full_width &&
+              (video_metadata->region.position.x + video_size_.width() <=
+               desktop_size_.width())
+          ? video_metadata->region.position.x * kBytesPerPixel
+          : 0;
+#else
+  if (!video_is_full_height &&
+      (video_metadata->y + video_size_.height() <= desktop_size_.height())) {
+    src += src_stride * video_metadata->y;
+  }
+
+  const int x_offset =
+      !video_is_full_width &&
+              (video_metadata->x + video_size_.width() <= desktop_size_.width())
+          ? video_metadata->x * kBytesPerPixel
+          : 0;
+#endif
+
+  uint8_t* dst = current_frame_.get();
+  for (int i = 0; i < video_size_.height(); ++i) {
+    // Adjust source content based on crop video position if needed
+    src += x_offset;
+    std::memcpy(dst, src, dst_stride);
+    // If both sides decided to go with the RGBx format we need to convert it to
+    // BGRx to match color format expected by WebRTC.
+#if PW_CHECK_VERSION(0, 3, 0)
+    if (spa_video_format_.format == SPA_VIDEO_FORMAT_RGBx ||
+        spa_video_format_.format == SPA_VIDEO_FORMAT_RGBA) {
+#else
+    if (spa_video_format_->format == pw_type_->video_format.RGBx ||
+        spa_video_format_->format == pw_type_->video_format.RGBA) {
+#endif
+      ConvertRGBxToBGRx(dst, dst_stride);
+    }
+    src += src_stride - x_offset;
+    dst += dst_stride;
   }
 }
 
@@ -441,14 +898,13 @@ void BaseCapturerPipeWire::OnProxyRequested(GObject* /*object*/,
   BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(user_data);
   RTC_DCHECK(that);
 
-  GError* error = nullptr;
-  GDBusProxy *proxy = g_dbus_proxy_new_finish(result, &error);
+  Scoped<GError> error;
+  GDBusProxy* proxy = g_dbus_proxy_new_finish(result, error.receive());
   if (!proxy) {
-    if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+    if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
       return;
     RTC_LOG(LS_ERROR) << "Failed to create a proxy for the screen cast portal: "
                       << error->message;
-    g_error_free(error);
     that->portal_init_failed_ = true;
     return;
   }
@@ -462,38 +918,36 @@ void BaseCapturerPipeWire::OnProxyRequested(GObject* /*object*/,
 // static
 gchar* BaseCapturerPipeWire::PrepareSignalHandle(GDBusConnection* connection,
                                                  const gchar* token) {
-  gchar* sender = g_strdup(g_dbus_connection_get_unique_name(connection) + 1);
-  for (int i = 0; sender[i]; i++) {
-    if (sender[i] == '.') {
-      sender[i] = '_';
+  Scoped<gchar> sender(
+      g_strdup(g_dbus_connection_get_unique_name(connection) + 1));
+  for (int i = 0; sender.get()[i]; i++) {
+    if (sender.get()[i] == '.') {
+      sender.get()[i] = '_';
     }
   }
 
-  gchar* handle = g_strconcat(kDesktopRequestObjectPath, "/", sender, "/",
+  gchar* handle = g_strconcat(kDesktopRequestObjectPath, "/", sender.get(), "/",
                               token, /*end of varargs*/ nullptr);
-  g_free(sender);
 
   return handle;
 }
 
 void BaseCapturerPipeWire::SessionRequest() {
   GVariantBuilder builder;
-  gchar* variant_string;
+  Scoped<gchar> variant_string;
 
   g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
   variant_string =
       g_strdup_printf("webrtc_session%d", g_random_int_range(0, G_MAXINT));
   g_variant_builder_add(&builder, "{sv}", "session_handle_token",
-                        g_variant_new_string(variant_string));
-  g_free(variant_string);
+                        g_variant_new_string(variant_string.get()));
   variant_string = g_strdup_printf("webrtc%d", g_random_int_range(0, G_MAXINT));
   g_variant_builder_add(&builder, "{sv}", "handle_token",
-                        g_variant_new_string(variant_string));
+                        g_variant_new_string(variant_string.get()));
 
-  portal_handle_ = PrepareSignalHandle(connection_, variant_string);
+  portal_handle_ = PrepareSignalHandle(connection_, variant_string.get());
   session_request_signal_id_ = SetupRequestResponseSignal(
       portal_handle_, OnSessionRequestResponseSignal);
-  g_free(variant_string);
 
   RTC_LOG(LS_INFO) << "Screen cast session requested.";
   g_dbus_proxy_call(
@@ -509,22 +963,21 @@ void BaseCapturerPipeWire::OnSessionRequested(GDBusProxy *proxy,
   BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(user_data);
   RTC_DCHECK(that);
 
-  GError* error = nullptr;
-  GVariant* variant = g_dbus_proxy_call_finish(proxy, result, &error);
+  Scoped<GError> error;
+  Scoped<GVariant> variant(
+      g_dbus_proxy_call_finish(proxy, result, error.receive()));
   if (!variant) {
-    if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+    if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
       return;
     RTC_LOG(LS_ERROR) << "Failed to create a screen cast session: "
                       << error->message;
-    g_error_free(error);
     that->portal_init_failed_ = true;
     return;
   }
   RTC_LOG(LS_INFO) << "Initializing the screen cast session.";
 
-  gchar* handle = nullptr;
-  g_variant_get_child(variant, 0, "o", &handle);
-  g_variant_unref(variant);
+  Scoped<gchar> handle;
+  g_variant_get_child(variant.get(), 0, "o", &handle);
   if (!handle) {
     RTC_LOG(LS_ERROR) << "Failed to initialize the screen cast session.";
     if (that->session_request_signal_id_) {
@@ -536,8 +989,6 @@ void BaseCapturerPipeWire::OnSessionRequested(GDBusProxy *proxy,
     return;
   }
 
-  g_free(handle);
-
   RTC_LOG(LS_INFO) << "Subscribing to the screen cast session.";
 }
 
@@ -557,11 +1008,11 @@ void BaseCapturerPipeWire::OnSessionRequestResponseSignal(
       << "Received response for the screen cast session subscription.";
 
   guint32 portal_response;
-  GVariant* response_data;
-  g_variant_get(parameters, "(u@a{sv})", &portal_response, &response_data);
-  g_variant_lookup(response_data, "session_handle", "s",
+  Scoped<GVariant> response_data;
+  g_variant_get(parameters, "(u@a{sv})", &portal_response,
+                response_data.receive());
+  g_variant_lookup(response_data.get(), "session_handle", "s",
                    &that->session_handle_);
-  g_variant_unref(response_data);
 
   if (!that->session_handle_ || portal_response) {
     RTC_LOG(LS_ERROR)
@@ -575,23 +1026,23 @@ void BaseCapturerPipeWire::OnSessionRequestResponseSignal(
 
 void BaseCapturerPipeWire::SourcesRequest() {
   GVariantBuilder builder;
-  gchar* variant_string;
+  Scoped<gchar> variant_string;
 
   g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
   // We want to record monitor content.
-  g_variant_builder_add(&builder, "{sv}", "types",
-                        g_variant_new_uint32(capture_source_type_));
+  g_variant_builder_add(
+      &builder, "{sv}", "types",
+      g_variant_new_uint32(static_cast<uint32_t>(capture_source_type_)));
   // We don't want to allow selection of multiple sources.
   g_variant_builder_add(&builder, "{sv}", "multiple",
                         g_variant_new_boolean(false));
   variant_string = g_strdup_printf("webrtc%d", g_random_int_range(0, G_MAXINT));
   g_variant_builder_add(&builder, "{sv}", "handle_token",
-                        g_variant_new_string(variant_string));
+                        g_variant_new_string(variant_string.get()));
 
-  sources_handle_ = PrepareSignalHandle(connection_, variant_string);
+  sources_handle_ = PrepareSignalHandle(connection_, variant_string.get());
   sources_request_signal_id_ = SetupRequestResponseSignal(
       sources_handle_, OnSourcesRequestResponseSignal);
-  g_free(variant_string);
 
   RTC_LOG(LS_INFO) << "Requesting sources from the screen cast session.";
   g_dbus_proxy_call(
@@ -608,22 +1059,21 @@ void BaseCapturerPipeWire::OnSourcesRequested(GDBusProxy *proxy,
   BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(user_data);
   RTC_DCHECK(that);
 
-  GError* error = nullptr;
-  GVariant* variant = g_dbus_proxy_call_finish(proxy, result, &error);
+  Scoped<GError> error;
+  Scoped<GVariant> variant(
+      g_dbus_proxy_call_finish(proxy, result, error.receive()));
   if (!variant) {
-    if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+    if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
       return;
     RTC_LOG(LS_ERROR) << "Failed to request the sources: " << error->message;
-    g_error_free(error);
     that->portal_init_failed_ = true;
     return;
   }
 
   RTC_LOG(LS_INFO) << "Sources requested from the screen cast session.";
 
-  gchar* handle = nullptr;
-  g_variant_get_child(variant, 0, "o", &handle);
-  g_variant_unref(variant);
+  Scoped<gchar> handle;
+  g_variant_get_child(variant.get(), 0, "o", handle.receive());
   if (!handle) {
     RTC_LOG(LS_ERROR) << "Failed to initialize the screen cast session.";
     if (that->sources_request_signal_id_) {
@@ -635,8 +1085,6 @@ void BaseCapturerPipeWire::OnSourcesRequested(GDBusProxy *proxy,
     return;
   }
 
-  g_free(handle);
-
   RTC_LOG(LS_INFO) << "Subscribed to sources signal.";
 }
 
@@ -668,17 +1116,16 @@ void BaseCapturerPipeWire::OnSourcesRequestResponseSignal(
 
 void BaseCapturerPipeWire::StartRequest() {
   GVariantBuilder builder;
-  gchar* variant_string;
+  Scoped<gchar> variant_string;
 
   g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
   variant_string = g_strdup_printf("webrtc%d", g_random_int_range(0, G_MAXINT));
   g_variant_builder_add(&builder, "{sv}", "handle_token",
-                        g_variant_new_string(variant_string));
+                        g_variant_new_string(variant_string.get()));
 
-  start_handle_ = PrepareSignalHandle(connection_, variant_string);
+  start_handle_ = PrepareSignalHandle(connection_, variant_string.get());
   start_request_signal_id_ =
       SetupRequestResponseSignal(start_handle_, OnStartRequestResponseSignal);
-  g_free(variant_string);
 
   // "Identifier for the application window", this is Wayland, so not "x11:...".
   const gchar parent_window[] = "";
@@ -698,23 +1145,22 @@ void BaseCapturerPipeWire::OnStartRequested(GDBusProxy *proxy,
   BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(user_data);
   RTC_DCHECK(that);
 
-  GError* error = nullptr;
-  GVariant* variant = g_dbus_proxy_call_finish(proxy, result, &error);
+  Scoped<GError> error;
+  Scoped<GVariant> variant(
+      g_dbus_proxy_call_finish(proxy, result, error.receive()));
   if (!variant) {
-    if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+    if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
       return;
     RTC_LOG(LS_ERROR) << "Failed to start the screen cast session: "
                       << error->message;
-    g_error_free(error);
     that->portal_init_failed_ = true;
     return;
   }
 
   RTC_LOG(LS_INFO) << "Initializing the start of the screen cast session.";
 
-  gchar* handle = nullptr;
-  g_variant_get_child(variant, 0, "o", &handle);
-  g_variant_unref(variant);
+  Scoped<gchar> handle;
+  g_variant_get_child(variant.get(), 0, "o", handle.receive());
   if (!handle) {
     RTC_LOG(LS_ERROR)
         << "Failed to initialize the start of the screen cast session.";
@@ -727,8 +1173,6 @@ void BaseCapturerPipeWire::OnStartRequested(GDBusProxy *proxy,
     return;
   }
 
-  g_free(handle);
-
   RTC_LOG(LS_INFO) << "Subscribed to the start signal.";
 }
 
@@ -746,9 +1190,10 @@ void BaseCapturerPipeWire::OnStartRequestResponseSignal(
 
   RTC_LOG(LS_INFO) << "Start signal received.";
   guint32 portal_response;
-  GVariant* response_data;
-  GVariantIter* iter = nullptr;
-  g_variant_get(parameters, "(u@a{sv})", &portal_response, &response_data);
+  Scoped<GVariant> response_data;
+  Scoped<GVariantIter> iter;
+  g_variant_get(parameters, "(u@a{sv})", &portal_response,
+                response_data.receive());
   if (portal_response || !response_data) {
     RTC_LOG(LS_ERROR) << "Failed to start the screen cast session.";
     that->portal_init_failed_ = true;
@@ -758,28 +1203,28 @@ void BaseCapturerPipeWire::OnStartRequestResponseSignal(
   // Array of PipeWire streams. See
   // https://github.com/flatpak/xdg-desktop-portal/blob/master/data/org.freedesktop.portal.ScreenCast.xml
   // documentation for <method name="Start">.
-  if (g_variant_lookup(response_data, "streams", "a(ua{sv})", &iter)) {
-    GVariant* variant;
+  if (g_variant_lookup(response_data.get(), "streams", "a(ua{sv})",
+                       iter.receive())) {
+    Scoped<GVariant> variant;
 
-    while (g_variant_iter_next(iter, "@(ua{sv})", &variant)) {
+    while (g_variant_iter_next(iter.get(), "@(ua{sv})", variant.receive())) {
       guint32 stream_id;
-      gint32 width;
-      gint32 height;
-      GVariant* options;
+      guint32 type;
+      Scoped<GVariant> options;
 
-      g_variant_get(variant, "(u@a{sv})", &stream_id, &options);
-      RTC_DCHECK(options != nullptr);
+      g_variant_get(variant.get(), "(u@a{sv})", &stream_id, options.receive());
+      RTC_DCHECK(options.get());
 
-      g_variant_lookup(options, "size", "(ii)", &width, &height);
+      if (g_variant_lookup(options.get(), "source_type", "u", &type)) {
+        that->capture_source_type_ =
+            static_cast<BaseCapturerPipeWire::CaptureSourceType>(type);
+      }
 
-      that->desktop_size_.set(width, height);
+      that->pw_stream_node_id_ = stream_id;
 
-      g_variant_unref(options);
-      g_variant_unref(variant);
+      break;
     }
   }
-  g_variant_iter_free(iter);
-  g_variant_unref(response_data);
 
   that->OpenPipeWireRemote();
 }
@@ -807,35 +1252,30 @@ void BaseCapturerPipeWire::OnOpenPipeWireRemoteRequested(
   BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(user_data);
   RTC_DCHECK(that);
 
-  GError* error = nullptr;
-  GUnixFDList* outlist = nullptr;
-  GVariant* variant = g_dbus_proxy_call_with_unix_fd_list_finish(
-      proxy, &outlist, result, &error);
+  Scoped<GError> error;
+  Scoped<GUnixFDList> outlist;
+  Scoped<GVariant> variant(g_dbus_proxy_call_with_unix_fd_list_finish(
+      proxy, outlist.receive(), result, error.receive()));
   if (!variant) {
-    if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+    if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
       return;
     RTC_LOG(LS_ERROR) << "Failed to open the PipeWire remote: "
                       << error->message;
-    g_error_free(error);
     that->portal_init_failed_ = true;
     return;
   }
 
   gint32 index;
-  g_variant_get(variant, "(h)", &index);
+  g_variant_get(variant.get(), "(h)", &index);
 
-  if ((that->pw_fd_ = g_unix_fd_list_get(outlist, index, &error)) == -1) {
+  if ((that->pw_fd_ =
+           g_unix_fd_list_get(outlist.get(), index, error.receive())) == -1) {
     RTC_LOG(LS_ERROR) << "Failed to get file descriptor from the list: "
                       << error->message;
-    g_error_free(error);
-    g_variant_unref(variant);
     that->portal_init_failed_ = true;
     return;
   }
 
-  g_variant_unref(variant);
-  g_object_unref(outlist);
-
   that->InitPipeWire();
 }
 
@@ -854,15 +1294,18 @@ void BaseCapturerPipeWire::CaptureFrame() {
     return;
   }
 
+  webrtc::MutexLock lock(&current_frame_lock_);
   if (!current_frame_) {
     callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
     return;
   }
 
-  std::unique_ptr<DesktopFrame> result(new BasicDesktopFrame(desktop_size_));
+  DesktopSize frame_size = video_size_;
+
+  std::unique_ptr<DesktopFrame> result(new BasicDesktopFrame(frame_size));
   result->CopyPixelsFrom(
-      current_frame_, (desktop_size_.width() * kBytesPerPixel),
-      DesktopRect::MakeWH(desktop_size_.width(), desktop_size_.height()));
+      current_frame_.get(), (frame_size.width() * kBytesPerPixel),
+      DesktopRect::MakeWH(frame_size.width(), frame_size.height()));
   if (!result) {
     callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
     return;
@@ -887,4 +1330,11 @@ bool BaseCapturerPipeWire::SelectSource(SourceId id) {
   return true;
 }
 
+// static
+std::unique_ptr<DesktopCapturer> BaseCapturerPipeWire::CreateRawCapturer(
+    const DesktopCaptureOptions& options) {
+  return std::make_unique<BaseCapturerPipeWire>(
+      BaseCapturerPipeWire::CaptureSourceType::kAny);
+}
+
 }  // namespace webrtc
diff --git a/chromium/third_party/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h b/chromium/third_party/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h
index f28d7a558bc..75d20dbf1db 100644
--- a/src/3rdparty/chromium/third_party/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h
+++ b/src/3rdparty/chromium/third_party/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h
@@ -10,18 +10,23 @@
 
 #ifndef MODULES_DESKTOP_CAPTURE_LINUX_BASE_CAPTURER_PIPEWIRE_H_
 #define MODULES_DESKTOP_CAPTURE_LINUX_BASE_CAPTURER_PIPEWIRE_H_
-
 #include <gio/gio.h>
 #define typeof __typeof__
 #include <pipewire/pipewire.h>
 #include <spa/param/video/format-utils.h>
+#if PW_CHECK_VERSION(0, 3, 0)
+#include <spa/utils/result.h>
+#endif
 
+#include "absl/types/optional.h"
 #include "modules/desktop_capture/desktop_capture_options.h"
 #include "modules/desktop_capture/desktop_capturer.h"
 #include "rtc_base/constructor_magic.h"
+#include "rtc_base/synchronization/mutex.h"
 
 namespace webrtc {
 
+#if !PW_CHECK_VERSION(0, 3, 0)
 class PipeWireType {
  public:
   spa_type_media_type media_type;
@@ -29,14 +34,25 @@ class PipeWireType {
   spa_type_format_video format_video;
   spa_type_video_format video_format;
 };
+#endif
 
 class BaseCapturerPipeWire : public DesktopCapturer {
  public:
-  enum CaptureSourceType { Screen = 1, Window };
+  // Values are set based on source type property in
+  // xdg-desktop-portal/screencast
+  // https://github.com/flatpak/xdg-desktop-portal/blob/master/data/org.freedesktop.portal.ScreenCast.xml
+  enum class CaptureSourceType : uint32_t {
+    kScreen = 0b01,
+    kWindow = 0b10,
+    kAny = 0b11
+  };
 
   explicit BaseCapturerPipeWire(CaptureSourceType source_type);
   ~BaseCapturerPipeWire() override;
 
+  static std::unique_ptr<DesktopCapturer> CreateRawCapturer(
+      const DesktopCaptureOptions& options);
+
   // DesktopCapturer interface.
   void Start(Callback* delegate) override;
   void CaptureFrame() override;
@@ -45,6 +61,21 @@ class BaseCapturerPipeWire : public DesktopCapturer {
 
  private:
   // PipeWire types -->
+#if PW_CHECK_VERSION(0, 3, 0)
+  struct pw_context* pw_context_ = nullptr;
+  struct pw_core* pw_core_ = nullptr;
+  struct pw_stream* pw_stream_ = nullptr;
+  struct pw_thread_loop* pw_main_loop_ = nullptr;
+
+  spa_hook spa_core_listener_;
+  spa_hook spa_stream_listener_;
+
+  // event handlers
+  pw_core_events pw_core_events_ = {};
+  pw_stream_events pw_stream_events_ = {};
+
+  struct spa_video_info_raw spa_video_format_;
+#else
   pw_core* pw_core_ = nullptr;
   pw_type* pw_core_type_ = nullptr;
   pw_stream* pw_stream_ = nullptr;
@@ -60,11 +91,13 @@ class BaseCapturerPipeWire : public DesktopCapturer {
   pw_remote_events pw_remote_events_ = {};
 
   spa_video_info_raw* spa_video_format_ = nullptr;
+#endif
 
+  guint32 pw_stream_node_id_ = 0;
   gint32 pw_fd_ = -1;
 
   CaptureSourceType capture_source_type_ =
-      BaseCapturerPipeWire::CaptureSourceType::Screen;
+      BaseCapturerPipeWire::CaptureSourceType::kScreen;
 
   // <-- end of PipeWire types
 
@@ -79,10 +112,12 @@ class BaseCapturerPipeWire : public DesktopCapturer {
   guint sources_request_signal_id_ = 0;
   guint start_request_signal_id_ = 0;
 
+  DesktopSize video_size_;
   DesktopSize desktop_size_ = {};
   DesktopCaptureOptions options_ = {};
 
-  uint8_t* current_frame_ = nullptr;
+  webrtc::Mutex current_frame_lock_;
+  std::unique_ptr<uint8_t[]> current_frame_;
   Callback* callback_ = nullptr;
 
   bool portal_init_failed_ = false;
@@ -91,21 +126,32 @@ class BaseCapturerPipeWire : public DesktopCapturer {
   void InitPipeWire();
   void InitPipeWireTypes();
 
-  void CreateReceivingStream();
+  pw_stream* CreateReceivingStream();
   void HandleBuffer(pw_buffer* buffer);
 
   void ConvertRGBxToBGRx(uint8_t* frame, uint32_t size);
 
+#if PW_CHECK_VERSION(0, 3, 0)
+  static void OnCoreError(void* data,
+                          uint32_t id,
+                          int seq,
+                          int res,
+                          const char* message);
+  static void OnStreamParamChanged(void* data,
+                                   uint32_t id,
+                                   const struct spa_pod* format);
+#else
   static void OnStateChanged(void* data,
                              pw_remote_state old_state,
                              pw_remote_state state,
                              const char* error);
+  static void OnStreamFormatChanged(void* data, const struct spa_pod* format);
+#endif
   static void OnStreamStateChanged(void* data,
                                    pw_stream_state old_state,
                                    pw_stream_state state,
                                    const char* error_message);
 
-  static void OnStreamFormatChanged(void* data, const struct spa_pod* format);
   static void OnStreamProcess(void* data);
   static void OnNewBuffer(void* data, uint32_t id);
 
diff --git a/chromium/third_party/webrtc/modules/desktop_capture/linux/pipewire.sigs b/chromium/third_party/webrtc/modules/desktop_capture/linux/pipewire02.sigs
similarity index 91%
rename from chromium/third_party/webrtc/modules/desktop_capture/linux/pipewire.sigs
rename to chromium/third_party/webrtc/modules/desktop_capture/linux/pipewire02.sigs
index 3e21e9dc07c..5ac3d1d22b8 100644
--- a/src/3rdparty/chromium/third_party/webrtc/modules/desktop_capture/linux/pipewire.sigs
+++ b/src/3rdparty/chromium/third_party/webrtc/modules/desktop_capture/linux/pipewire02.sigs
@@ -26,6 +26,7 @@ void pw_remote_add_listener(pw_remote *remote, spa_hook *listener, const pw_remo
 int pw_remote_connect_fd(pw_remote *remote, int fd);
 void pw_remote_destroy(pw_remote *remote);
 pw_remote * pw_remote_new(pw_core *core, pw_properties *properties, size_t user_data_size);
+enum pw_remote_state pw_remote_get_state(pw_remote *remote, const char **error);
 
 // stream.h
 void pw_stream_add_listener(pw_stream *stream, spa_hook *listener, const pw_stream_events *events, void *data);
@@ -42,3 +43,5 @@ void pw_thread_loop_destroy(pw_thread_loop *loop);
 pw_thread_loop * pw_thread_loop_new(pw_loop *loop, const char *name);
 int pw_thread_loop_start(pw_thread_loop *loop);
 void pw_thread_loop_stop(pw_thread_loop *loop);
+void pw_thread_loop_lock(struct pw_thread_loop *loop);
+void pw_thread_loop_unlock(struct pw_thread_loop *loop);
diff --git a/chromium/third_party/webrtc/modules/desktop_capture/linux/pipewire03.sigs b/chromium/third_party/webrtc/modules/desktop_capture/linux/pipewire03.sigs
new file mode 100644
index 00000000000..78d241f40c6
--- /dev/null
+++ b/src/3rdparty/chromium/third_party/webrtc/modules/desktop_capture/linux/pipewire03.sigs
@@ -0,0 +1,46 @@
+// Copyright 2018 The WebRTC project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//------------------------------------------------
+// Functions from PipeWire used in capturer code.
+//------------------------------------------------
+
+// core.h
+int pw_core_disconnect(pw_core *core);
+
+// loop.h
+void pw_loop_destroy(pw_loop *loop);
+pw_loop * pw_loop_new(const spa_dict *props);
+
+
+// pipewire.h
+void pw_init(int *argc, char **argv[]);
+
+// properties.h
+pw_properties * pw_properties_new_string(const char *args);
+
+// stream.h
+void pw_stream_add_listener(pw_stream *stream, spa_hook *listener, const pw_stream_events *events, void *data);
+int pw_stream_connect(pw_stream *stream, enum pw_direction direction, uint32_t target_id, enum pw_stream_flags flags, const spa_pod **params, uint32_t n_params);
+pw_buffer *pw_stream_dequeue_buffer(pw_stream *stream);
+void pw_stream_destroy(pw_stream *stream);
+pw_stream * pw_stream_new(pw_core *core, const char *name, pw_properties *props);
+int pw_stream_queue_buffer(pw_stream *stream, pw_buffer *buffer);
+int pw_stream_set_active(pw_stream *stream, bool active);
+int pw_stream_update_params(pw_stream *stream, const spa_pod **params, uint32_t n_params);
+
+// thread-loop.h
+void pw_thread_loop_destroy(pw_thread_loop *loop);
+pw_thread_loop * pw_thread_loop_new(const char *name, const spa_dict *props);
+int pw_thread_loop_start(pw_thread_loop *loop);
+void pw_thread_loop_stop(pw_thread_loop *loop);
+void pw_thread_loop_lock(pw_thread_loop *loop);
+void pw_thread_loop_unlock(pw_thread_loop *loop);
+pw_loop * pw_thread_loop_get_loop(pw_thread_loop *loop);
+
+
+// context.h
+void pw_context_destroy(pw_context *context);
+pw_context *pw_context_new(pw_loop *main_loop, pw_properties *props, size_t user_data_size);
+pw_core * pw_context_connect(pw_context *context, pw_properties *properties, size_t user_data_size);
diff --git a/chromium/third_party/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc b/chromium/third_party/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc
deleted file mode 100644
index fe672140cca..00000000000
--- a/src/3rdparty/chromium/third_party/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- *  Copyright 2018 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "modules/desktop_capture/linux/screen_capturer_pipewire.h"
-
-#include <memory>
-
-
-namespace webrtc {
-
-ScreenCapturerPipeWire::ScreenCapturerPipeWire()
-    : BaseCapturerPipeWire(BaseCapturerPipeWire::CaptureSourceType::Screen) {}
-ScreenCapturerPipeWire::~ScreenCapturerPipeWire() {}
-
-// static
-std::unique_ptr<DesktopCapturer>
-ScreenCapturerPipeWire::CreateRawScreenCapturer(
-    const DesktopCaptureOptions& options) {
-  return std::make_unique<ScreenCapturerPipeWire>();
-}
-
-}  // namespace webrtc
diff --git a/chromium/third_party/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.h b/chromium/third_party/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.h
deleted file mode 100644
index 66dcd680e06..00000000000
--- a/src/3rdparty/chromium/third_party/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *  Copyright 2018 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef MODULES_DESKTOP_CAPTURE_LINUX_SCREEN_CAPTURER_PIPEWIRE_H_
-#define MODULES_DESKTOP_CAPTURE_LINUX_SCREEN_CAPTURER_PIPEWIRE_H_
-
-#include <memory>
-
-#include "modules/desktop_capture/linux/base_capturer_pipewire.h"
-
-namespace webrtc {
-
-class ScreenCapturerPipeWire : public BaseCapturerPipeWire {
- public:
-  ScreenCapturerPipeWire();
-  ~ScreenCapturerPipeWire() override;
-
-  static std::unique_ptr<DesktopCapturer> CreateRawScreenCapturer(
-      const DesktopCaptureOptions& options);
-
-  RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerPipeWire);
-};
-
-}  // namespace webrtc
-
-#endif  // MODULES_DESKTOP_CAPTURE_LINUX_SCREEN_CAPTURER_PIPEWIRE_H_
diff --git a/chromium/third_party/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc b/chromium/third_party/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc
deleted file mode 100644
index b4559156dce..00000000000
--- a/src/3rdparty/chromium/third_party/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- *  Copyright 2018 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "modules/desktop_capture/linux/window_capturer_pipewire.h"
-
-#include <memory>
-
-
-namespace webrtc {
-
-WindowCapturerPipeWire::WindowCapturerPipeWire()
-    : BaseCapturerPipeWire(BaseCapturerPipeWire::CaptureSourceType::Window) {}
-WindowCapturerPipeWire::~WindowCapturerPipeWire() {}
-
-// static
-std::unique_ptr<DesktopCapturer>
-WindowCapturerPipeWire::CreateRawWindowCapturer(
-    const DesktopCaptureOptions& options) {
-  return std::make_unique<WindowCapturerPipeWire>();
-}
-
-}  // namespace webrtc
diff --git a/chromium/third_party/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.h b/chromium/third_party/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.h
deleted file mode 100644
index 7f184ef2999..00000000000
--- a/src/3rdparty/chromium/third_party/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *  Copyright 2018 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef MODULES_DESKTOP_CAPTURE_LINUX_WINDOW_CAPTURER_PIPEWIRE_H_
-#define MODULES_DESKTOP_CAPTURE_LINUX_WINDOW_CAPTURER_PIPEWIRE_H_
-
-#include <memory>
-
-#include "modules/desktop_capture/linux/base_capturer_pipewire.h"
-
-namespace webrtc {
-
-class WindowCapturerPipeWire : public BaseCapturerPipeWire {
- public:
-  WindowCapturerPipeWire();
-  ~WindowCapturerPipeWire() override;
-
-  static std::unique_ptr<DesktopCapturer> CreateRawWindowCapturer(
-      const DesktopCaptureOptions& options);
-
-  RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerPipeWire);
-};
-
-}  // namespace webrtc
-
-#endif  // MODULES_DESKTOP_CAPTURE_LINUX_WINDOW_CAPTURER_PIPEWIRE_H_
diff --git a/chromium/third_party/webrtc/modules/desktop_capture/screen_capturer_linux.cc b/chromium/third_party/webrtc/modules/desktop_capture/screen_capturer_linux.cc
index 82dbae48137..ed48b7d6d59 100644
--- a/src/3rdparty/chromium/third_party/webrtc/modules/desktop_capture/screen_capturer_linux.cc
+++ b/src/3rdparty/chromium/third_party/webrtc/modules/desktop_capture/screen_capturer_linux.cc
@@ -14,7 +14,7 @@
 #include "modules/desktop_capture/desktop_capturer.h"
 
 #if defined(WEBRTC_USE_PIPEWIRE)
-#include "modules/desktop_capture/linux/screen_capturer_pipewire.h"
+#include "modules/desktop_capture/linux/base_capturer_pipewire.h"
 #endif  // defined(WEBRTC_USE_PIPEWIRE)
 
 #if defined(WEBRTC_USE_X11)
@@ -28,7 +28,7 @@ std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawScreenCapturer(
     const DesktopCaptureOptions& options) {
 #if defined(WEBRTC_USE_PIPEWIRE)
   if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) {
-    return ScreenCapturerPipeWire::CreateRawScreenCapturer(options);
+    return BaseCapturerPipeWire::CreateRawCapturer(options);
   }
 #endif  // defined(WEBRTC_USE_PIPEWIRE)
 
diff --git a/chromium/third_party/webrtc/modules/desktop_capture/window_capturer_linux.cc b/chromium/third_party/webrtc/modules/desktop_capture/window_capturer_linux.cc
index 41dbf836b03..2b142ae3b92 100644
--- a/src/3rdparty/chromium/third_party/webrtc/modules/desktop_capture/window_capturer_linux.cc
+++ b/src/3rdparty/chromium/third_party/webrtc/modules/desktop_capture/window_capturer_linux.cc
@@ -14,7 +14,7 @@
 #include "modules/desktop_capture/desktop_capturer.h"
 
 #if defined(WEBRTC_USE_PIPEWIRE)
-#include "modules/desktop_capture/linux/window_capturer_pipewire.h"
+#include "modules/desktop_capture/linux/base_capturer_pipewire.h"
 #endif  // defined(WEBRTC_USE_PIPEWIRE)
 
 #if defined(WEBRTC_USE_X11)
@@ -28,7 +28,7 @@ std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawWindowCapturer(
     const DesktopCaptureOptions& options) {
 #if defined(WEBRTC_USE_PIPEWIRE)
   if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) {
-    return WindowCapturerPipeWire::CreateRawWindowCapturer(options);
+    return BaseCapturerPipeWire::CreateRawCapturer(options);
   }
 #endif  // defined(WEBRTC_USE_PIPEWIRE)
 
diff --git a/chromium/third_party/webrtc/webrtc.gni b/chromium/third_party/webrtc/webrtc.gni
index ca8acdbf259..505c975cece 100644
--- a/src/3rdparty/chromium/third_party/webrtc/webrtc.gni
+++ b/src/3rdparty/chromium/third_party/webrtc/webrtc.gni
@@ -117,6 +117,10 @@ declare_args() {
   # Set this to link PipeWire directly instead of using the dlopen.
   rtc_link_pipewire = false
 
+  # Set this to use certain PipeWire version
+  # Currently we support PipeWire 0.2 (default) and PipeWire 0.3
+  rtc_pipewire_version = "0.3"
+
   # Enable to use the Mozilla internal settings.
   build_with_mozilla = false
 
-- 
2.35.1

014-widevine.patch  gentoo bug 888783

Obviously from upstream, but not in upstream qt5.
Again, I cannot test this -ken

From b99042fb839021a0a3d2fe0cac7ac3899c4acbba Mon Sep 17 00:00:00 2001
From: Allan Sandfeld Jensen <allan.jensen@qt.io>
Date: Tue, 14 Jun 2022 14:19:24 +0200
Subject: [PATCH] Find modern Chrome, Chromium and Firefox CDM modules

The default download location has moved again, but we can now
also use firefox CDMs.

Pick-to: 6.4 6.3
Task-number: QTBUG-104238
Change-Id: I7ee581fa63e50df970acb31ea6d3f67d332aef59
Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
---
 src/core/content_client_qt.cpp | 54 ++++++++++++++++++++++++++++++----
 1 file changed, 49 insertions(+), 5 deletions(-)

diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp
index 6c914b7729..7167332d9b 100644
--- a/src/core/content_client_qt.cpp
+++ b/src/core/content_client_qt.cpp
@@ -250,15 +251,56 @@ static bool IsWidevineAvailable(base::FilePath *cdm_path,
         }
     }
 #elif defined(Q_OS_LINUX)
-        pluginPaths << QStringLiteral("/opt/google/chrome/libwidevinecdm.so") // Old Google Chrome
+        QList<QDir> potentialWidevineVersionDirs;
+
+        // Google Chrome widevine modules
+        QDir chromeWidevineDir(QDir::homePath() + "/.config/google-chrome/WidevineCdm");
+        if (chromeWidevineDir.exists())
+            potentialWidevineVersionDirs << chromeWidevineDir;
+
+        // Firefox widevine modules
+        QDir firefoxPotentialProfilesDir(QDir::homePath() + "/.mozilla/firefox");
+        if (firefoxPotentialProfilesDir.exists()) {
+            QFileInfoList firefoxProfileDirs = firefoxPotentialProfilesDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name | QDir::Reversed);
+            for (const QFileInfo &info : firefoxProfileDirs) {
+                QDir widevinePluginsDir(info.absoluteFilePath() + "/gmp-widevinecdm");
+                if (widevinePluginsDir.exists())
+                    potentialWidevineVersionDirs << widevinePluginsDir;
+            }
+        }
+
+        // Chromium widevine modules (might not work with proprietary codecs)
+        QDir chromiumWidevineDir(QDir::homePath() + "/.config/chromium/WidevineCdm");
+        if (chromiumWidevineDir.exists())
+            potentialWidevineVersionDirs << chromiumWidevineDir;
+
+        // Search for widewine versions
+        for (const QDir &dir : potentialWidevineVersionDirs) {
+            QFileInfoList widevineVersionDirs = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name | QDir::Reversed);
+            // ### alternatively look up in the manifest.json and take the path from there.
 #if Q_PROCESSOR_WORDSIZE == 8
-                    << QStringLiteral("/opt/google/chrome/WidevineCdm/_platform_specific/linux_x64/libwidevinecdm.so")
+            const QString library = QLatin1String("/_platform_specific/linux_x64/libwidevinecdm.so");
 #else
-                    << QStringLiteral("/opt/google/chrome/WidevineCdm/_platform_specific/linux_x86/libwidevinecdm.so")
+            const QString library = QLatin1String("/_platform_specific/linux_x86/libwidevinecdm.so");
 #endif
-                    << QStringLiteral("/usr/lib/chromium/libwidevinecdm.so") // Arch
+            for (const QFileInfo &info : widevineVersionDirs) {
+                pluginPaths << info.absoluteFilePath() + "/libwidevinecdm.so";
+                pluginPaths << info.absoluteFilePath() + library;
+            }
+        }
+
+        // Fixed paths:
+        pluginPaths << QStringLiteral("/usr/lib/chromium/libwidevinecdm.so") // Arch
                     << QStringLiteral("/usr/lib/chromium-browser/libwidevinecdm.so") // Ubuntu/neon
-                    << QStringLiteral("/usr/lib64/chromium/libwidevinecdm.so"); // OpenSUSE style
+                    << QStringLiteral("/usr/lib64/chromium/libwidevinecdm.so") // OpenSUSE style
+#if Q_PROCESSOR_WORDSIZE == 8
+                    << QStringLiteral("/usr/lib64/chromium-browser/WidevineCdm/_platform_specific/linux_x64/libwidevinecdm.so") // Gentoo
+                    << QStringLiteral("/opt/google/chrome/WidevineCdm/_platform_specific/linux_x64/libwidevinecdm.so") // Old Google Chrome
+#else
+                    << QStringLiteral("/usr/lib/chromium-browser/WidevineCdm/_platform_specific/linux_x86/libwidevinecdm.so") // Gentoo
+                    << QStringLiteral("/opt/google/chrome/WidevineCdm/_platform_specific/linux_x86/libwidevinecdm.so") // Old Google Chrome
+#endif
+                    << QStringLiteral("/opt/google/chrome/libwidevinecdm.so"); // Older Google Chrome
 #endif
     }
 

016-clang16.patch  gentoo bug 903573

https://bugs.gentoo.org/903573
--- a/src/3rdparty/chromium/v8/src/base/bit-field.h
+++ b/src/3rdparty/chromium/v8/src/base/bit-field.h
@@ -39,8 +39,11 @@
   static constexpr int kLastUsedBit = kShift + kSize - 1;
   static constexpr U kNumValues = U{1} << kSize;
 
+  #pragma clang diagnostic push
+  #pragma clang diagnostic ignored "-Wenum-constexpr-conversion"
   // Value for the field with all bits set.
   static constexpr T kMax = static_cast<T>(kNumValues - 1);
+  #pragma clang diagnostic pop
 
   template <class T2, int size2>
   using Next = BitField<T2, kShift + kSize, size2, U>;


