diff --git a/apps/ios/CrossDeskMobile/Bridge/CrossDeskRTCBridge.h b/apps/ios/CrossDeskMobile/Bridge/CrossDeskRTCBridge.h index ba2d04b9..e79bb6dc 100644 --- a/apps/ios/CrossDeskMobile/Bridge/CrossDeskRTCBridge.h +++ b/apps/ios/CrossDeskMobile/Bridge/CrossDeskRTCBridge.h @@ -100,7 +100,6 @@ typedef NS_ENUM(NSInteger, CrossDeskVideoAdaptationPolicy) { - (void)configureWithSignalHost:(NSString *)host signalPort:(NSInteger)signalPort; -- (void)setHardwareAccelerationEnabled:(BOOL)enabled; - (void)setVideoAdaptationPolicy:(CrossDeskVideoAdaptationPolicy)policy; - (void)requestPresenceForRemoteIDs:(NSArray *)remoteIDs subscribe:(BOOL)subscribe diff --git a/apps/ios/CrossDeskMobile/Bridge/CrossDeskRTCBridge.mm b/apps/ios/CrossDeskMobile/Bridge/CrossDeskRTCBridge.mm index 994580f1..84c9d7da 100644 --- a/apps/ios/CrossDeskMobile/Bridge/CrossDeskRTCBridge.mm +++ b/apps/ios/CrossDeskMobile/Bridge/CrossDeskRTCBridge.mm @@ -75,7 +75,6 @@ struct RTCState { CallbackContext controller_context; std::string signal_host; int signal_port = 0; - bool hardware_acceleration = true; VideoDegradationPreference video_adaptation_policy = VideoDegradationPreference::MaintainResolution; bool identity_ready = false; @@ -332,7 +331,8 @@ Params MakeParams(const RTCState &state, const std::string &user_id, state.signal_host); params.signal_server_port = state.signal_port; CopyCString(params.log_path, sizeof(params.log_path), state.log_path); - params.hardware_acceleration = state.hardware_acceleration; + // iOS H.264 is provided exclusively by VideoToolbox. + params.hardware_acceleration = true; params.native_video_output = true; params.av1_encoding = false; params.turn_mode = TurnMode::TurnAutoUdpTcp; @@ -495,12 +495,6 @@ Params MakeParams(const RTCState &state, const std::string &user_id, }); } -- (void)setHardwareAccelerationEnabled:(BOOL)enabled { - dispatch_async(_rtcQueue, ^{ - self->_state->hardware_acceleration = enabled; - }); -} - - (void)setVideoAdaptationPolicy:(CrossDeskVideoAdaptationPolicy)policy { dispatch_async(_rtcQueue, ^{ switch (policy) { diff --git a/apps/ios/CrossDeskMobile/ContentView.swift b/apps/ios/CrossDeskMobile/ContentView.swift index 02e11caa..4283f7c6 100644 --- a/apps/ios/CrossDeskMobile/ContentView.swift +++ b/apps/ios/CrossDeskMobile/ContentView.swift @@ -686,22 +686,6 @@ private struct ServerSettingsView: View { .font(.footnote) .foregroundStyle(.secondary) } - Section("视频编解码") { - Picker("处理方式", selection: $session.videoCodecMode) { - ForEach(VideoCodecMode.allCases) { mode in - Text(mode.title).tag(mode) - } - } - .pickerStyle(.segmented) - - Text(session.videoCodecMode.detail) - .font(.footnote) - .foregroundStyle(.secondary) - - Text("修改后从下一次连接开始生效。") - .font(.caption) - .foregroundStyle(.tertiary) - } Section("画面偏好") { Picker("偏好模式", selection: $session.videoAdaptationPolicy) { ForEach(VideoAdaptationPolicy.allCases) { policy in diff --git a/apps/ios/CrossDeskMobile/RemoteSessionModel.swift b/apps/ios/CrossDeskMobile/RemoteSessionModel.swift index f72b186b..99f62ba6 100644 --- a/apps/ios/CrossDeskMobile/RemoteSessionModel.swift +++ b/apps/ios/CrossDeskMobile/RemoteSessionModel.swift @@ -42,43 +42,6 @@ enum MouseControlMode: String, CaseIterable, Identifiable { } } -enum VideoCodecMode: String, CaseIterable, Identifiable { - case hardware - case software - - private static let defaultsKey = "crossdesk.mobile.video-codec-mode" - - var id: String { rawValue } - - var title: String { - switch self { - case .hardware: return "硬件" - case .software: return "软件" - } - } - - var detail: String { - switch self { - case .hardware: - return "使用 VideoToolbox,延迟和耗电更低,推荐日常使用。" - case .software: - return "使用 OpenH264 软件编解码,适合兼容性测试。" - } - } - - static var saved: VideoCodecMode { - guard let rawValue = UserDefaults.standard.string(forKey: defaultsKey), - let mode = VideoCodecMode(rawValue: rawValue) else { - return .hardware - } - return mode - } - - func save() { - UserDefaults.standard.set(rawValue, forKey: Self.defaultsKey) - } -} - enum VideoAdaptationPolicy: String, CaseIterable, Identifiable { case frameRatePriority case qualityPriority @@ -361,9 +324,6 @@ final class RemoteSessionModel: NSObject, ObservableObject, CrossDeskRTCBridgeDe @Published var mouseControlMode = MouseControlMode.saved { didSet { mouseControlMode.save() } } - @Published var videoCodecMode = VideoCodecMode.saved { - didSet { videoCodecMode.save() } - } @Published var videoAdaptationPolicy = VideoAdaptationPolicy.saved { didSet { videoAdaptationPolicy.save() } } @@ -467,7 +427,6 @@ final class RemoteSessionModel: NSObject, ObservableObject, CrossDeskRTCBridgeDe } else if signalConnected { signalStatus = "已连接服务器" } - bridge.setHardwareAccelerationEnabled(videoCodecMode == .hardware) bridge.setVideoAdaptationPolicy(videoAdaptationPolicy.bridgeValue) bridge.configure(withSignalHost: host, signalPort: signal) diff --git a/apps/ios/README.md b/apps/ios/README.md index 9c508d4e..40d26540 100644 --- a/apps/ios/README.md +++ b/apps/ios/README.md @@ -56,11 +56,16 @@ the desktop-compatible `DisplayN`, `control_audio`, `mouse`, `keyboard`, ## Video codecs -Every iOS build includes VideoToolbox, OpenH264, dav1d, and SVT-AV1. H.264 uses -VideoToolbox by default; choose software processing under **设置 → 视频编解码 → -处理方式** (Settings → Video codec → Processing mode) to use OpenH264 for H.264. -The change takes effect on the next connection. AV1 encoding uses SVT-AV1 and AV1 decoding -uses dav1d; VideoToolbox AV1 hardware decoding is currently unsupported. +Every iOS build includes VideoToolbox, dav1d, and SVT-AV1. H.264 uses +VideoToolbox exclusively; OpenH264 is excluded from the iOS dependencies and +native archive. The hardware/software processing setting has been removed, +and preferences saved by older versions are no longer read. H.264 codec +initialization failure is reported without a software fallback. +AV1 encoding uses SVT-AV1 and AV1 decoding uses dav1d; VideoToolbox AV1 hardware +decoding is currently unsupported. Desktop builds retain OpenH264. + +The native build script checks the merged archive for OpenH264 entry points +and rejects a build if they are present, including in cached archives. The unused libaom backends are excluded by default. To include them for development, set the `MINIRTC_ENABLE_AOM` environment variable (or Xcode user-defined build setting) diff --git a/apps/ios/scripts/build_minirtc_ios.sh b/apps/ios/scripts/build_minirtc_ios.sh index fcef5d56..1d8c49a2 100755 --- a/apps/ios/scripts/build_minirtc_ios.sh +++ b/apps/ios/scripts/build_minirtc_ios.sh @@ -152,7 +152,7 @@ REQUIRED_LINKS=( nice glib-2.0 gobject-2.0 gmodule-2.0 gio-2.0 gthread-2.0 intl gupnp-igd-1.6 gupnp-1.6 gssdp-1.6 soup-3.0 nghttp2 sqlite3 psl xml2 ffi pcre2-8 pcre2-posix z ssl crypto srtp2 openfec opus yuv kcp - datachannel usrsctp openh264 dav1d SvtAv1Enc + datachannel usrsctp dav1d SvtAv1Enc ) if [[ "${MINIRTC_ENABLE_AOM}" == "true" ]]; then REQUIRED_LINKS+=(aom) @@ -180,12 +180,25 @@ MERGE_MANIFEST="${OUTPUT_LIBRARY}.inputs.sha256" TEMP_MANIFEST="${MERGE_MANIFEST}.tmp" trap 'rm -f "${TEMP_LIBRARY}" "${TEMP_MANIFEST}"' EXIT +# Check the actual archive, including when reusing cached build products. +verify_no_openh264() { + local symbols + symbols="$(DEVELOPER_DIR="${XMAKE_DEVELOPER_DIR}" xcrun nm -g "$1")" + if [[ "${symbols}" == *WelsCreateDecoder* || \ + "${symbols}" == *WelsCreateSVCEncoder* || \ + "${symbols}" == *WelsGetCodecVersion* ]]; then + print -u2 "OpenH264 symbols must not be present in the iOS native archive: $1" + exit 65 + fi +} + # Hash contents as well as paths so same-size archives replaced within the same # timestamp tick cannot leave a stale merged library. Preserve the output mtime # on no-op builds to avoid relinking the Xcode app. shasum -a 256 "${SCRIPT_DIR}/build_minirtc_ios.sh" "${MINIRTC_LIBRARY}" \ "${DEPENDENCY_ARCHIVES[@]}" "${WIRE_LIBRARY}" > "${TEMP_MANIFEST}" if [[ -f "${OUTPUT_LIBRARY}" ]] && cmp -s "${TEMP_MANIFEST}" "${MERGE_MANIFEST}"; then + verify_no_openh264 "${OUTPUT_LIBRARY}" print "Up to date: ${OUTPUT_LIBRARY}" exit 0 fi @@ -193,6 +206,7 @@ fi /usr/bin/libtool -static -o "${TEMP_LIBRARY}" \ "${MINIRTC_LIBRARY}" "${DEPENDENCY_ARCHIVES[@]}" \ "${WIRE_LIBRARY}" +verify_no_openh264 "${TEMP_LIBRARY}" mv -f "${TEMP_LIBRARY}" "${OUTPUT_LIBRARY}" mv -f "${TEMP_MANIFEST}" "${MERGE_MANIFEST}" diff --git a/deps/submodules/minirtc b/deps/submodules/minirtc index e4dcd826..74551f06 160000 --- a/deps/submodules/minirtc +++ b/deps/submodules/minirtc @@ -1 +1 @@ -Subproject commit e4dcd8260969e5ebfd3f8c6ccd2329502277931c +Subproject commit 74551f0629447d9c3920bc9728372197939f5505