mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-10-31 02:49:35 +08:00
Compare commits
3
Commits
v1.5.3
...
e894f4a763
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e894f4a763 | ||
|
|
e65a30e969 | ||
|
|
52f6f23f93 |
@@ -988,7 +988,7 @@ int GuiApplication::Run() {
|
|||||||
strncpy(signal_server_ip_self_, config_center_->GetSignalServerHost().c_str(),
|
strncpy(signal_server_ip_self_, config_center_->GetSignalServerHost().c_str(),
|
||||||
sizeof(signal_server_ip_self_) - 1);
|
sizeof(signal_server_ip_self_) - 1);
|
||||||
const int signal_port = config_center_->GetSignalServerPort();
|
const int signal_port = config_center_->GetSignalServerPort();
|
||||||
if (signal_port > 0) {
|
if (signal_port > 0 && signal_port <= 65535) {
|
||||||
std::snprintf(signal_server_port_self_, sizeof(signal_server_port_self_),
|
std::snprintf(signal_server_port_self_, sizeof(signal_server_port_self_),
|
||||||
"%d", signal_port);
|
"%d", signal_port);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -903,12 +903,15 @@ void ScreenCapturerSckImpl::StartOrReconfigureCapturer() {
|
|||||||
// method is still running on another thread.
|
// method is still running on another thread.
|
||||||
std::mutex _capturer_lock;
|
std::mutex _capturer_lock;
|
||||||
ScreenCapturerSckImpl *_capturer;
|
ScreenCapturerSckImpl *_capturer;
|
||||||
|
dispatch_queue_t _completion_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)initWithCapturer:(ScreenCapturerSckImpl *)capturer {
|
- (instancetype)initWithCapturer:(ScreenCapturerSckImpl *)capturer {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if (self) {
|
if (self) {
|
||||||
_capturer = capturer;
|
_capturer = capturer;
|
||||||
|
_completion_queue = dispatch_queue_create("CrossDesk.ScreenCaptureKit.Completions",
|
||||||
|
DISPATCH_QUEUE_SERIAL);
|
||||||
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(privacyCoversChanged:)
|
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(privacyCoversChanged:)
|
||||||
name:@"CrossDeskPrivacyCoversChanged" object:nil];
|
name:@"CrossDeskPrivacyCoversChanged" object:nil];
|
||||||
}
|
}
|
||||||
@@ -922,18 +925,25 @@ void ScreenCapturerSckImpl::StartOrReconfigureCapturer() {
|
|||||||
- (void)configurationFinished:(SCStream*)stream generation:(uint64_t)generation
|
- (void)configurationFinished:(SCStream*)stream generation:(uint64_t)generation
|
||||||
revision:(uint64_t)revision complete:(BOOL)complete
|
revision:(uint64_t)revision complete:(BOOL)complete
|
||||||
configuration:(SCStreamConfiguration*)configuration error:(NSError*)error {
|
configuration:(SCStreamConfiguration*)configuration error:(NSError*)error {
|
||||||
std::lock_guard<std::mutex> lock(_capturer_lock);
|
// SCK may call a completion inline (notably updateContentFilter when nothing
|
||||||
if (_capturer)
|
// changed). The caller can still hold both _capturer_lock and the capturer's
|
||||||
_capturer->ConfigurationFinished(stream, generation, revision, complete, configuration, error);
|
// state lock. Always defer before acquiring either lock, including errors.
|
||||||
|
// The block retains this helper; releaseCapturer revokes queued callbacks
|
||||||
|
// before the C++ capturer is destroyed.
|
||||||
|
dispatch_async(_completion_queue, ^{
|
||||||
|
std::lock_guard<std::mutex> lock(self->_capturer_lock);
|
||||||
|
if (self->_capturer)
|
||||||
|
self->_capturer->ConfigurationFinished(stream, generation, revision, complete,
|
||||||
|
configuration, error);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
- (void)onShareableContentCreated:(SCShareableContent *)content generation:(uint64_t)generation
|
- (void)onShareableContentCreated:(SCShareableContent *)content generation:(uint64_t)generation
|
||||||
revision:(uint64_t)revision {
|
revision:(uint64_t)revision {
|
||||||
std::lock_guard<std::mutex> lock(_capturer_lock);
|
dispatch_async(_completion_queue, ^{
|
||||||
if (_capturer) {
|
std::lock_guard<std::mutex> lock(self->_capturer_lock);
|
||||||
_capturer->OnShareableContentCreated(content, generation, revision);
|
if (self->_capturer)
|
||||||
} else {
|
self->_capturer->OnShareableContentCreated(content, generation, revision);
|
||||||
LOG_ERROR("Invalid capturer");
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)stream:(SCStream *)stream
|
- (void)stream:(SCStream *)stream
|
||||||
@@ -971,8 +981,10 @@ void ScreenCapturerSckImpl::StartOrReconfigureCapturer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)stream:(SCStream*)stream didStopWithError:(NSError*)error {
|
- (void)stream:(SCStream*)stream didStopWithError:(NSError*)error {
|
||||||
std::lock_guard<std::mutex> lock(_capturer_lock);
|
dispatch_async(_completion_queue, ^{
|
||||||
if (_capturer) _capturer->CaptureStopped(stream, error);
|
std::lock_guard<std::mutex> lock(self->_capturer_lock);
|
||||||
|
if (self->_capturer) self->_capturer->CaptureStopped(stream, error);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -100,7 +100,6 @@ typedef NS_ENUM(NSInteger, CrossDeskVideoAdaptationPolicy) {
|
|||||||
|
|
||||||
- (void)configureWithSignalHost:(NSString *)host
|
- (void)configureWithSignalHost:(NSString *)host
|
||||||
signalPort:(NSInteger)signalPort;
|
signalPort:(NSInteger)signalPort;
|
||||||
- (void)setHardwareAccelerationEnabled:(BOOL)enabled;
|
|
||||||
- (void)setVideoAdaptationPolicy:(CrossDeskVideoAdaptationPolicy)policy;
|
- (void)setVideoAdaptationPolicy:(CrossDeskVideoAdaptationPolicy)policy;
|
||||||
- (void)requestPresenceForRemoteIDs:(NSArray<NSString *> *)remoteIDs
|
- (void)requestPresenceForRemoteIDs:(NSArray<NSString *> *)remoteIDs
|
||||||
subscribe:(BOOL)subscribe
|
subscribe:(BOOL)subscribe
|
||||||
|
|||||||
@@ -75,7 +75,6 @@ struct RTCState {
|
|||||||
CallbackContext controller_context;
|
CallbackContext controller_context;
|
||||||
std::string signal_host;
|
std::string signal_host;
|
||||||
int signal_port = 0;
|
int signal_port = 0;
|
||||||
bool hardware_acceleration = true;
|
|
||||||
VideoDegradationPreference video_adaptation_policy =
|
VideoDegradationPreference video_adaptation_policy =
|
||||||
VideoDegradationPreference::MaintainResolution;
|
VideoDegradationPreference::MaintainResolution;
|
||||||
bool identity_ready = false;
|
bool identity_ready = false;
|
||||||
@@ -332,7 +331,8 @@ Params MakeParams(const RTCState &state, const std::string &user_id,
|
|||||||
state.signal_host);
|
state.signal_host);
|
||||||
params.signal_server_port = state.signal_port;
|
params.signal_server_port = state.signal_port;
|
||||||
CopyCString(params.log_path, sizeof(params.log_path), state.log_path);
|
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.native_video_output = true;
|
||||||
params.av1_encoding = false;
|
params.av1_encoding = false;
|
||||||
params.turn_mode = TurnMode::TurnAutoUdpTcp;
|
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 {
|
- (void)setVideoAdaptationPolicy:(CrossDeskVideoAdaptationPolicy)policy {
|
||||||
dispatch_async(_rtcQueue, ^{
|
dispatch_async(_rtcQueue, ^{
|
||||||
switch (policy) {
|
switch (policy) {
|
||||||
|
|||||||
@@ -686,22 +686,6 @@ private struct ServerSettingsView: View {
|
|||||||
.font(.footnote)
|
.font(.footnote)
|
||||||
.foregroundStyle(.secondary)
|
.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("画面偏好") {
|
Section("画面偏好") {
|
||||||
Picker("偏好模式", selection: $session.videoAdaptationPolicy) {
|
Picker("偏好模式", selection: $session.videoAdaptationPolicy) {
|
||||||
ForEach(VideoAdaptationPolicy.allCases) { policy in
|
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 {
|
enum VideoAdaptationPolicy: String, CaseIterable, Identifiable {
|
||||||
case frameRatePriority
|
case frameRatePriority
|
||||||
case qualityPriority
|
case qualityPriority
|
||||||
@@ -361,9 +324,6 @@ final class RemoteSessionModel: NSObject, ObservableObject, CrossDeskRTCBridgeDe
|
|||||||
@Published var mouseControlMode = MouseControlMode.saved {
|
@Published var mouseControlMode = MouseControlMode.saved {
|
||||||
didSet { mouseControlMode.save() }
|
didSet { mouseControlMode.save() }
|
||||||
}
|
}
|
||||||
@Published var videoCodecMode = VideoCodecMode.saved {
|
|
||||||
didSet { videoCodecMode.save() }
|
|
||||||
}
|
|
||||||
@Published var videoAdaptationPolicy = VideoAdaptationPolicy.saved {
|
@Published var videoAdaptationPolicy = VideoAdaptationPolicy.saved {
|
||||||
didSet { videoAdaptationPolicy.save() }
|
didSet { videoAdaptationPolicy.save() }
|
||||||
}
|
}
|
||||||
@@ -467,7 +427,6 @@ final class RemoteSessionModel: NSObject, ObservableObject, CrossDeskRTCBridgeDe
|
|||||||
} else if signalConnected {
|
} else if signalConnected {
|
||||||
signalStatus = "已连接服务器"
|
signalStatus = "已连接服务器"
|
||||||
}
|
}
|
||||||
bridge.setHardwareAccelerationEnabled(videoCodecMode == .hardware)
|
|
||||||
bridge.setVideoAdaptationPolicy(videoAdaptationPolicy.bridgeValue)
|
bridge.setVideoAdaptationPolicy(videoAdaptationPolicy.bridgeValue)
|
||||||
bridge.configure(withSignalHost: host,
|
bridge.configure(withSignalHost: host,
|
||||||
signalPort: signal)
|
signalPort: signal)
|
||||||
|
|||||||
+10
-5
@@ -56,11 +56,16 @@ the desktop-compatible `DisplayN`, `control_audio`, `mouse`, `keyboard`,
|
|||||||
|
|
||||||
## Video codecs
|
## Video codecs
|
||||||
|
|
||||||
Every iOS build includes VideoToolbox, OpenH264, dav1d, and SVT-AV1. H.264 uses
|
Every iOS build includes VideoToolbox, dav1d, and SVT-AV1. H.264 uses
|
||||||
VideoToolbox by default; choose software processing under **设置 → 视频编解码 →
|
VideoToolbox exclusively; OpenH264 is excluded from the iOS dependencies and
|
||||||
处理方式** (Settings → Video codec → Processing mode) to use OpenH264 for H.264.
|
native archive. The hardware/software processing setting has been removed,
|
||||||
The change takes effect on the next connection. AV1 encoding uses SVT-AV1 and AV1 decoding
|
and preferences saved by older versions are no longer read. H.264 codec
|
||||||
uses dav1d; VideoToolbox AV1 hardware decoding is currently unsupported.
|
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,
|
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)
|
set the `MINIRTC_ENABLE_AOM` environment variable (or Xcode user-defined build setting)
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ REQUIRED_LINKS=(
|
|||||||
nice glib-2.0 gobject-2.0 gmodule-2.0 gio-2.0 gthread-2.0 intl
|
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
|
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
|
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
|
if [[ "${MINIRTC_ENABLE_AOM}" == "true" ]]; then
|
||||||
REQUIRED_LINKS+=(aom)
|
REQUIRED_LINKS+=(aom)
|
||||||
@@ -180,12 +180,25 @@ MERGE_MANIFEST="${OUTPUT_LIBRARY}.inputs.sha256"
|
|||||||
TEMP_MANIFEST="${MERGE_MANIFEST}.tmp"
|
TEMP_MANIFEST="${MERGE_MANIFEST}.tmp"
|
||||||
trap 'rm -f "${TEMP_LIBRARY}" "${TEMP_MANIFEST}"' EXIT
|
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
|
# 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
|
# timestamp tick cannot leave a stale merged library. Preserve the output mtime
|
||||||
# on no-op builds to avoid relinking the Xcode app.
|
# on no-op builds to avoid relinking the Xcode app.
|
||||||
shasum -a 256 "${SCRIPT_DIR}/build_minirtc_ios.sh" "${MINIRTC_LIBRARY}" \
|
shasum -a 256 "${SCRIPT_DIR}/build_minirtc_ios.sh" "${MINIRTC_LIBRARY}" \
|
||||||
"${DEPENDENCY_ARCHIVES[@]}" "${WIRE_LIBRARY}" > "${TEMP_MANIFEST}"
|
"${DEPENDENCY_ARCHIVES[@]}" "${WIRE_LIBRARY}" > "${TEMP_MANIFEST}"
|
||||||
if [[ -f "${OUTPUT_LIBRARY}" ]] && cmp -s "${TEMP_MANIFEST}" "${MERGE_MANIFEST}"; then
|
if [[ -f "${OUTPUT_LIBRARY}" ]] && cmp -s "${TEMP_MANIFEST}" "${MERGE_MANIFEST}"; then
|
||||||
|
verify_no_openh264 "${OUTPUT_LIBRARY}"
|
||||||
print "Up to date: ${OUTPUT_LIBRARY}"
|
print "Up to date: ${OUTPUT_LIBRARY}"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
@@ -193,6 +206,7 @@ fi
|
|||||||
/usr/bin/libtool -static -o "${TEMP_LIBRARY}" \
|
/usr/bin/libtool -static -o "${TEMP_LIBRARY}" \
|
||||||
"${MINIRTC_LIBRARY}" "${DEPENDENCY_ARCHIVES[@]}" \
|
"${MINIRTC_LIBRARY}" "${DEPENDENCY_ARCHIVES[@]}" \
|
||||||
"${WIRE_LIBRARY}"
|
"${WIRE_LIBRARY}"
|
||||||
|
verify_no_openh264 "${TEMP_LIBRARY}"
|
||||||
mv -f "${TEMP_LIBRARY}" "${OUTPUT_LIBRARY}"
|
mv -f "${TEMP_LIBRARY}" "${OUTPUT_LIBRARY}"
|
||||||
mv -f "${TEMP_MANIFEST}" "${MERGE_MANIFEST}"
|
mv -f "${TEMP_MANIFEST}" "${MERGE_MANIFEST}"
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
Submodule deps/submodules/minirtc updated: e4dcd82609...74551f0629
Reference in New Issue
Block a user