[fix] use VideoToolbox exclusively for iOS H.264

This commit is contained in:
dijunkun
2026-09-27 20:53:12 +08:00
parent 52f6f23f93
commit e65a30e969
7 changed files with 28 additions and 73 deletions
@@ -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<NSString *> *)remoteIDs
subscribe:(BOOL)subscribe
@@ -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) {
@@ -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
@@ -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)
+10 -5
View File
@@ -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)
+15 -1
View File
@@ -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}"