iOS: Get WebRTC building for Mac Catalyst

- Add an option for disabling the OpenGL renderer
- Change the build script to use correct header location
- Use Metal compatibility for h264 CoreVideo buffers

Bug: webrtc:11516
Change-Id: Ia34a9305648e75904ac36e69593ffefedd833bfb
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/224200
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Kári Helgason <kthelgason@webrtc.org>
Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34426}
diff --git a/examples/BUILD.gn b/examples/BUILD.gn
index e0e11ae..ab3dff0 100644
--- a/examples/BUILD.gn
+++ b/examples/BUILD.gn
@@ -345,10 +345,12 @@
         "../sdk:metal_objc",
         "../sdk:peerconnectionfactory_base_objc",
         "../sdk:peerconnectionfactory_base_objc",
-        "../sdk:ui_objc",
         "../sdk:videocapture_objc",
         "../sdk:videocodec_objc",
       ]
+      if (rtc_ios_macos_use_opengl_rendering) {
+        deps += [ "../sdk:opengl_ui_objc" ]
+      }
 
       frameworks = [ "AVFoundation.framework" ]
     }
@@ -499,13 +501,12 @@
         "../sdk:helpers_objc",
         "../sdk:metal_objc",
         "../sdk:native_api",
-        "../sdk:ui_objc",
         "../sdk:videocapture_objc",
         "../sdk:videotoolbox_objc",
       ]
 
-      if (current_cpu == "arm64") {
-        deps += [ "../sdk:metal_objc" ]
+      if (rtc_ios_macos_use_opengl_rendering) {
+        deps += [ "../sdk:opengl_ui_objc" ]
       }
     }
 
@@ -543,9 +544,9 @@
         "../sdk:helpers_objc",
         "../sdk:mediaconstraints_objc",
         "../sdk:metal_objc",
+        "../sdk:opengl_ui_objc",
         "../sdk:peerconnectionfactory_base_objc",
         "../sdk:peerconnectionfactory_base_objc",
-        "../sdk:ui_objc",
         "../sdk:videocapture_objc",
         "../sdk:videocodec_objc",
       ]
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index d63f416..516d848 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -434,7 +434,7 @@
       ]
     }
 
-    rtc_library("video_objc") {
+    rtc_library("opengl_objc") {
       sources = [
         "objc/components/renderer/opengl/RTCDefaultShader.h",
         "objc/components/renderer/opengl/RTCDefaultShader.mm",
@@ -490,7 +490,7 @@
       ]
     }
 
-    rtc_library("ui_objc") {
+    rtc_library("opengl_ui_objc") {
       visibility = [ "*" ]
       allow_poison = [
         "audio_codecs",  # TODO(bugs.webrtc.org/8396): Remove.
@@ -519,12 +519,27 @@
         ":base_objc",
         ":helpers_objc",
         ":metal_objc",
-        ":video_objc",
+        ":opengl_objc",
         ":videocapture_objc",
         ":videoframebuffer_objc",
       ]
     }
 
+    # For backward compatibility.
+    rtc_source_set("video_objc") {
+      visibility = [ "*" ]
+      public_deps = [ ":opengl_objc" ]  # no-presubmit-check TODO(webrtc:8603)
+    }
+    rtc_source_set("ui_objc") {
+      visibility = [ "*" ]
+      allow_poison = [
+        "audio_codecs",  # TODO(bugs.webrtc.org/8396): Remove.
+        "default_task_queue",
+      ]
+      public_deps =  # no-presubmit-check TODO(webrtc:8603)
+          [ ":opengl_ui_objc" ]
+    }
+
     rtc_library("metal_objc") {
       visibility = [ "*" ]
       allow_poison = [
@@ -563,7 +578,6 @@
       deps = [
         ":base_objc",
         ":peerconnectionfactory_base_objc",
-        ":video_objc",
         ":videoframebuffer_objc",
         "../api/video:video_frame",
         "../api/video:video_rtp_headers",
@@ -611,7 +625,6 @@
       deps = [
         ":base_objc",
         ":helpers_objc",
-        ":video_objc",
         ":videoframebuffer_objc",
         "../rtc_base/system:gcd_helpers",
       ]
@@ -983,7 +996,6 @@
         ":mediasource_objc",
         ":native_api",
         ":native_video",
-        ":video_objc",
         ":videoframebuffer_objc",
         ":videorendereradapter_objc",
         ":videosource_objc",
@@ -1071,7 +1083,6 @@
             ":native_api_audio_device_module",
             ":native_video",
             ":peerconnectionfactory_base_objc",
-            ":video_objc",
             ":video_toolbox_cc",
             ":videocapture_objc",
             ":videocodec_objc",
@@ -1090,6 +1101,10 @@
             "//third_party/libyuv",
           ]
 
+          if (rtc_ios_macos_use_opengl_rendering) {
+            deps += [ ":opengl_objc" ]
+          }
+
           public_deps = [
             "//build/config/ios:xctest",
             "//third_party/ocmock",
@@ -1181,7 +1196,6 @@
           ":native_api",
           ":native_video",
           ":peerconnectionfactory_base_objc",
-          ":video_objc",
           ":videocapture_objc",
           ":videocodec_objc",
           ":videoframebuffer_objc",
@@ -1324,12 +1338,14 @@
           ":native_api",
           ":native_video",
           ":peerconnectionfactory_base_objc",
-          ":ui_objc",
           ":videocapture_objc",
           ":videocodec_objc",
           ":videotoolbox_objc",
           "../rtc_base:rtc_base_approved",
         ]
+        if (rtc_ios_macos_use_opengl_rendering) {
+          deps += [ ":opengl_ui_objc" ]
+        }
         if (!build_with_chromium) {
           deps += [
             ":callback_logger_objc",
@@ -1341,7 +1357,6 @@
           "AVFoundation.framework",
           "CoreGraphics.framework",
           "CoreMedia.framework",
-          "GLKit.framework",
         ]
 
         configs += [
@@ -1454,8 +1469,8 @@
           ":default_codec_factory_objc",
           ":native_api",
           ":native_video",
+          ":opengl_ui_objc",
           ":peerconnectionfactory_base_objc",
-          ":ui_objc",
           ":videocapture_objc",
           ":videocodec_objc",
           ":videotoolbox_objc",
diff --git a/sdk/objc/components/video_codec/RTCVideoDecoderH264.mm b/sdk/objc/components/video_codec/RTCVideoDecoderH264.mm
index 6675530..06cfb74 100644
--- a/sdk/objc/components/video_codec/RTCVideoDecoderH264.mm
+++ b/sdk/objc/components/video_codec/RTCVideoDecoderH264.mm
@@ -209,7 +209,9 @@
 #endif
 
   CFTypeRef keys[attributesSize] = {
-#if defined(WEBRTC_IOS)
+#if defined(WEBRTC_IOS) && TARGET_OS_MACCATALYST
+      kCVPixelBufferMetalCompatibilityKey,
+#elif defined(WEBRTC_IOS)
       kCVPixelBufferOpenGLESCompatibilityKey,
 #elif defined(WEBRTC_MAC)
       kCVPixelBufferOpenGLCompatibilityKey,
diff --git a/sdk/objc/components/video_codec/RTCVideoEncoderH264.mm b/sdk/objc/components/video_codec/RTCVideoEncoderH264.mm
index 3451703..7c0d029 100644
--- a/sdk/objc/components/video_codec/RTCVideoEncoderH264.mm
+++ b/sdk/objc/components/video_codec/RTCVideoEncoderH264.mm
@@ -602,14 +602,15 @@
   // buffers retrieved from the encoder's pixel buffer pool.
   const size_t attributesSize = 3;
   CFTypeRef keys[attributesSize] = {
-#if defined(WEBRTC_IOS)
-    kCVPixelBufferOpenGLESCompatibilityKey,
+#if defined(WEBRTC_IOS) && TARGET_OS_MACCATALYST
+      kCVPixelBufferMetalCompatibilityKey,
+#elif defined(WEBRTC_IOS)
+      kCVPixelBufferOpenGLESCompatibilityKey,
 #elif defined(WEBRTC_MAC)
-    kCVPixelBufferOpenGLCompatibilityKey,
+      kCVPixelBufferOpenGLCompatibilityKey,
 #endif
-    kCVPixelBufferIOSurfacePropertiesKey,
-    kCVPixelBufferPixelFormatTypeKey
-  };
+      kCVPixelBufferIOSurfacePropertiesKey,
+      kCVPixelBufferPixelFormatTypeKey};
   CFDictionaryRef ioSurfaceValue = CreateCFTypeDictionary(nullptr, nullptr, 0);
   int64_t pixelFormatType = framePixelFormat;
   CFNumberRef pixelFormat = CFNumberCreate(nullptr, kCFNumberLongType, &pixelFormatType);
diff --git a/webrtc.gni b/webrtc.gni
index 13308ac..c0ff14f 100644
--- a/webrtc.gni
+++ b/webrtc.gni
@@ -183,6 +183,10 @@
     rtc_apprtcmobile_broadcast_extension = false
   }
 
+  # Determines whether OpenGL is available on iOS/macOS.
+  rtc_ios_macos_use_opengl_rendering =
+      !(is_ios && target_environment == "catalyst")
+
   # When set to false, builtin audio encoder/decoder factories and all the
   # audio codecs they depend on will not be included in libwebrtc.{a|lib}
   # (they will still be included in libjingle_peerconnection_so.so and
@@ -992,10 +996,16 @@
       deps = [ ":create_bracket_include_headers_$this_target_name" ]
     }
 
+    if (target_environment == "catalyst") {
+      # Catalyst frameworks use the same layout as regular Mac frameworks.
+      headers_dir = "Versions/A/Headers"
+    } else {
+      headers_dir = "Headers"
+    }
     copy("copy_umbrella_header_$target_name") {
       sources = [ umbrella_header_path ]
       outputs =
-          [ "$root_out_dir/$output_name.framework/Headers/$output_name.h" ]
+          [ "$root_out_dir/$output_name.framework/$headers_dir/$output_name.h" ]
 
       deps = [ ":umbrella_header_$target_name" ]
     }