diff --git a/VoidLink/Base.lproj/iPad.storyboard b/VoidLink/Base.lproj/iPad.storyboard index ca845a1f..5a849bcc 100644 --- a/VoidLink/Base.lproj/iPad.storyboard +++ b/VoidLink/Base.lproj/iPad.storyboard @@ -2011,16 +2011,16 @@ - + - + + + + + + + + + + + + + + + @@ -2177,6 +2197,8 @@ + + diff --git a/VoidLink/Base.lproj/iPhone.storyboard b/VoidLink/Base.lproj/iPhone.storyboard index 1ebffc39..8c90783f 100644 --- a/VoidLink/Base.lproj/iPhone.storyboard +++ b/VoidLink/Base.lproj/iPhone.storyboard @@ -2867,16 +2867,16 @@ - + - + + + + + + + + + + + + + + + @@ -3022,6 +3042,8 @@ + + diff --git a/VoidLink/Database/DataManager.h b/VoidLink/Database/DataManager.h index 4fd98485..14436263 100644 --- a/VoidLink/Database/DataManager.h +++ b/VoidLink/Database/DataManager.h @@ -156,6 +156,7 @@ typedef NS_ENUM(NSInteger, PencilTickMode) { controllerGyroSwitchMode:(NSInteger)controllerGyroSwitchMode enableFrameTimebase:(BOOL)enableFrameTimebase asyncFrameDequeue:(BOOL)asyncFrameDequeue + sdrPerformanceWorkaround:(BOOL)sdrPerformanceWorkaround backgroundSessionTimer:(NSInteger)backgroundSessionTimer; - (NSArray*) getHosts; diff --git a/VoidLink/Database/DataManager.m b/VoidLink/Database/DataManager.m index da3ee11f..a7796e9f 100644 --- a/VoidLink/Database/DataManager.m +++ b/VoidLink/Database/DataManager.m @@ -128,6 +128,7 @@ controllerGyroSwitchMode:(NSInteger)controllerGyroSwitchMode enableFrameTimebase:(BOOL)enableFrameTimebase asyncFrameDequeue:(BOOL)asyncFrameDequeue + sdrPerformanceWorkaround:(BOOL)sdrPerformanceWorkaround backgroundSessionTimer:(NSInteger)backgroundSessionTimer{ __block Settings* settingsToSave = settings; @@ -165,6 +166,7 @@ settingsToSave.useBuiltinMic = useBuiltinMic; settingsToSave.preferredCodec = preferredCodec; settingsToSave.enableYUV444 = enableYUV444; + settingsToSave.sdrPerformanceWorkaround = sdrPerformanceWorkaround; settingsToSave.enablePIP = enablePIP; settingsToSave.fullColorRange = fullColorRange; settingsToSave.enableHdr = enableHdr; diff --git a/VoidLink/Database/TemporarySettings.h b/VoidLink/Database/TemporarySettings.h index 426c835c..a5ee5362 100644 --- a/VoidLink/Database/TemporarySettings.h +++ b/VoidLink/Database/TemporarySettings.h @@ -53,6 +53,7 @@ CODEC_PREF_AV1, } preferredCodec; @property (nonatomic) BOOL enableYUV444; +@property (nonatomic) BOOL sdrPerformanceWorkaround; @property (nonatomic) BOOL enablePIP; @property (nonatomic) BOOL fullColorRange; @property (nonatomic) BOOL reverseMouseWheelDirection; diff --git a/VoidLink/Database/TemporarySettings.m b/VoidLink/Database/TemporarySettings.m index 08953585..9bf2d0a1 100644 --- a/VoidLink/Database/TemporarySettings.m +++ b/VoidLink/Database/TemporarySettings.m @@ -88,6 +88,7 @@ self.audioConfig = settings.audioConfig; self.preferredCodec = settings.preferredCodec; self.enableYUV444 = settings.enableYUV444; + self.sdrPerformanceWorkaround = settings.sdrPerformanceWorkaround; self.enablePIP = settings.enablePIP; self.fullColorRange = settings.fullColorRange; self.frameQueueSize = settings.frameQueueSize; diff --git a/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents b/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents index 2657fdb4..383019b0 100644 --- a/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents +++ b/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents @@ -89,6 +89,7 @@ + diff --git a/VoidLink/Stream/VideoDecoderRenderer.m b/VoidLink/Stream/VideoDecoderRenderer.m index a3bdf51f..1d6b6a6d 100644 --- a/VoidLink/Stream/VideoDecoderRenderer.m +++ b/VoidLink/Stream/VideoDecoderRenderer.m @@ -127,7 +127,7 @@ extern int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size, _vtq = dispatch_queue_create("com.moonlight.VideoDecoderRenderer.VTDecoder", dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INTERACTIVE, 0)); - _view = view; + _view = (StreamView*) view; _callbacks = callbacks; _streamAspectRatio = aspectRatio; _maxRefreshRate = [[UIScreen mainScreen] maximumFramesPerSecond]; @@ -137,8 +137,8 @@ extern int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size, TemporarySettings* tempSettings = [dataMan getSettings]; _framePacingMode = tempSettings.framePacingMode.integerValue; - _enableTimebase = tempSettings.enableFrameTimebase; _asyncFrameDequeue = tempSettings.asyncFrameDequeue; + _enableTimebase = false; _frameQueue = [FrameQueue sharedInstance]; [_frameQueue start]; diff --git a/VoidLink/Utility/Utils.h b/VoidLink/Utility/Utils.h index 1616bf92..647b87b7 100644 --- a/VoidLink/Utility/Utils.h +++ b/VoidLink/Utility/Utils.h @@ -31,6 +31,8 @@ FOUNDATION_EXPORT NSString *const deviceName; + (NSString*) addressPortStringToAddress:(NSString*)addressPort; + (unsigned short) addressPortStringToPort:(NSString*)addressPort; + (NSString*) addressAndPortToAddressPortString:(NSString*)address port:(unsigned short)port; ++ (bool)hdrSupported; ++ (bool)needUpdateDefaultSettings; #if !TARGET_OS_TV + (void) launchUrl:(NSString*)urlString; diff --git a/VoidLink/Utility/Utils.m b/VoidLink/Utility/Utils.m index 8f50b618..9d5d700f 100644 --- a/VoidLink/Utility/Utils.m +++ b/VoidLink/Utility/Utils.m @@ -11,6 +11,8 @@ #include #include #include +#import +#import #import "LocalizationHelper.h" @implementation Utils @@ -149,6 +151,22 @@ NSString *const deviceName = @"roth"; } } ++ (bool)hdrSupported{ + return VTIsHardwareDecodeSupported(kCMVideoCodecType_HEVC) && (AVPlayer.availableHDRModes & AVPlayerHDRModeHDR10); +} + ++ (bool)needUpdateDefaultSettings { + NSString *key = @"needUpdateDefaultSettings20260207"; + BOOL updatedBefore = [[NSUserDefaults standardUserDefaults] boolForKey:key]; + + if (!updatedBefore) { + [[NSUserDefaults standardUserDefaults] setBool:YES forKey:key]; + [[NSUserDefaults standardUserDefaults] synchronize]; + return YES; + } + return NO; +} + @end @implementation NSString (NSStringWithTrim) diff --git a/VoidLink/ViewControllers/MainFrameViewController.m b/VoidLink/ViewControllers/MainFrameViewController.m index bbbbde35..18b2d4f0 100644 --- a/VoidLink/ViewControllers/MainFrameViewController.m +++ b/VoidLink/ViewControllers/MainFrameViewController.m @@ -876,7 +876,8 @@ static NSMutableSet* hostList; _streamConfig.supportedVideoFormats |= VIDEO_FORMAT_AV1_HIGH8_444; } else { - _streamConfig.supportedVideoFormats |= VIDEO_FORMAT_AV1_MAIN8; + if(streamSettings.sdrPerformanceWorkaround && [Utils hdrSupported]) _streamConfig.supportedVideoFormats |= VIDEO_FORMAT_AV1_MAIN10; // 8bit performance degradation workaround for av1 + else _streamConfig.supportedVideoFormats |= VIDEO_FORMAT_AV1_MAIN8; } } #endif @@ -886,10 +887,13 @@ static NSMutableSet* hostList; case CODEC_PREF_HEVC: if (VTIsHardwareDecodeSupported(kCMVideoCodecType_HEVC)) { if (streamSettings.enableYUV444) { - _streamConfig.supportedVideoFormats |= VIDEO_FORMAT_H265_REXT8_444; + if(streamSettings.sdrPerformanceWorkaround && [Utils hdrSupported]) _streamConfig.supportedVideoFormats |= VIDEO_FORMAT_H265_REXT10_444; // 8bit performance degradation workaround + else _streamConfig.supportedVideoFormats |= VIDEO_FORMAT_H265_REXT8_444; } else { - _streamConfig.supportedVideoFormats |= VIDEO_FORMAT_H265; + // _streamConfig.supportedVideoFormats |= VIDEO_FORMAT_H265; + if(streamSettings.sdrPerformanceWorkaround && [Utils hdrSupported]) _streamConfig.supportedVideoFormats |= VIDEO_FORMAT_H265_MAIN10; // 8bit performance degradation workaround + else _streamConfig.supportedVideoFormats |= VIDEO_FORMAT_H265; } } // Fall-through @@ -905,8 +909,10 @@ static NSMutableSet* hostList; // HEVC is supported if the user wants it (or it's required by the chosen resolution) and the SoC supports it if ((_streamConfig.width > 4096 || _streamConfig.height > 4096 || streamSettings.enableHdr) && VTIsHardwareDecodeSupported(kCMVideoCodecType_HEVC)) { - _streamConfig.supportedVideoFormats |= VIDEO_FORMAT_H265; + if(streamSettings.sdrPerformanceWorkaround && [Utils hdrSupported]) _streamConfig.supportedVideoFormats |= VIDEO_FORMAT_H265_MAIN10; // 8bit performance degradation workaround + else _streamConfig.supportedVideoFormats |= VIDEO_FORMAT_H265; + // HEVC Main10 is supported if the user wants it and the display supports it if (streamSettings.enableHdr && (AVPlayer.availableHDRModes & AVPlayerHDRModeHDR10) != 0) { if (streamSettings.enableYUV444) { @@ -1568,6 +1574,28 @@ static NSMutableSet* hostList; } } +- (void)changeDefaultSettings{ + if(![Utils needUpdateDefaultSettings]) return; + DataManager* dataMan = [[DataManager alloc] init]; + Settings* settings = [dataMan retrieveSettings]; + switch ([UIDevice currentDevice].userInterfaceIdiom) { + case UIUserInterfaceIdiomPad: + settings.sdrPerformanceWorkaround = true; + settings.framePacingMode = @(FramePacingModeQueue); + break; + case UIUserInterfaceIdiomPhone: + settings.sdrPerformanceWorkaround = false; + settings.framePacingMode = @(FramePacingModeLegacy); + break; + default: + settings.sdrPerformanceWorkaround = true; + break; + } + if([UIScreen mainScreen].maximumFramesPerSecond > 110) settings.asyncFrameDequeue = false; + if([UIScreen mainScreen].maximumFramesPerSecond < 65) settings.asyncFrameDequeue = true; + [dataMan saveData]; +} + - (void)viewDidLoad{ [super viewDidLoad]; diff --git a/VoidLink/ViewControllers/SettingsViewController.h b/VoidLink/ViewControllers/SettingsViewController.h index 5a3b7ab3..701946f0 100644 --- a/VoidLink/ViewControllers/SettingsViewController.h +++ b/VoidLink/ViewControllers/SettingsViewController.h @@ -249,6 +249,10 @@ @property (weak, nonatomic) IBOutlet UIStackView *asyncFrameDequeueStack; @property (weak, nonatomic) IBOutlet UISwitch *asyncFrameDequeueSwitch; +@property (weak, nonatomic) IBOutlet UIStackView *sdrPerformanceWorkaroundStack; +@property (weak, nonatomic) IBOutlet UISwitch *sdrPerformanceWorkaroundSwitch; + + @property (strong, nonatomic) IBOutlet UIStackView *testStack; diff --git a/VoidLink/ViewControllers/SettingsViewController.m b/VoidLink/ViewControllers/SettingsViewController.m index bdd7dae9..50199c87 100644 --- a/VoidLink/ViewControllers/SettingsViewController.m +++ b/VoidLink/ViewControllers/SettingsViewController.m @@ -18,8 +18,6 @@ #import "OSCProfilesManager.h" #import -#import -#import #import "LocalizationHelper.h" @@ -788,15 +786,12 @@ BOOL isCustomResolution(int resolutionSelected) { [self addSetting:self.fpsStack ofId:@"fpsStack" withInfoTag:NO withDynamicLabel:NO to:videoSection]; [self addSetting:self.bitrateStack ofId:@"bitrateStack" withInfoTag:YES withDynamicLabel:YES to:videoSection]; [self addSetting:self.codecStack ofId:@"codecStack" withInfoTag:NO withDynamicLabel:NO to:videoSection]; - [self addSetting:self.hdrStack ofId:@"hdrStack" withInfoTag:![self hdrSupported] withDynamicLabel:NO to:videoSection]; + [self addSetting:self.hdrStack ofId:@"hdrStack" withInfoTag:![Utils hdrSupported] withDynamicLabel:NO to:videoSection]; [self addSetting:self.yuv444Stack ofId:@"yuv444Stack" withInfoTag:YES withDynamicLabel:NO to:videoSection]; [self addSetting:self.fullColorRangeStack ofId:@"fullColorRangeStack" withInfoTag:NO withDynamicLabel:NO to:videoSection]; [self addSetting:self.pipStack ofId:@"pipStack" withInfoTag:YES withDynamicLabel:NO to:videoSection]; [self addSetting:self.framePacingStack ofId:@"framePacingStack" withInfoTag:YES withDynamicLabel:NO to:videoSection]; [self addSetting:self.frameQueueSizeStack ofId:@"frameQueueSizeStack" withInfoTag:NO withDynamicLabel:YES to:videoSection]; - [self addSetting:self.frameTimebaseStack ofId:@"frameTimebaseStack" withInfoTag:NO withDynamicLabel:NO to:videoSection]; - [self addSetting:self.asyncFrameDequeueStack ofId:@"asyncFrameDequeueStack" withInfoTag:NO withDynamicLabel:NO to:videoSection]; - [videoSection addToParentStack:_parentStack]; // [videoSection setExpanded:NO]; @@ -975,7 +970,10 @@ BOOL isCustomResolution(int resolutionSelected) { [self addSetting:self.relativeTouchSlideThresholdStack ofId:@"relativeTouchSlideThresholdStack" withInfoTag:YES withDynamicLabel:YES to:experimentalSection]; [self addSetting:self.singleTapSensitivityStack ofId:@"singleTapSensitivityStack" withInfoTag:NO withDynamicLabel:YES to:experimentalSection]; [self addSetting:self.leftClickDelayStack ofId:@"leftClickDelayStack" withInfoTag:NO withDynamicLabel:YES to:experimentalSection]; + [self addSetting:self.sdrPerformanceWorkaroundStack ofId:@"sdrPerformanceWorkaroundStack" withInfoTag:NO withDynamicLabel:NO to:experimentalSection]; [self addSetting:self.renderingBackendStack ofId:@"renderingBackendStack" withInfoTag:YES withDynamicLabel:NO to:experimentalSection]; + // [self addSetting:self.frameTimebaseStack ofId:@"frameTimebaseStack" withInfoTag:NO withDynamicLabel:NO to:videoSection]; + [self addSetting:self.asyncFrameDequeueStack ofId:@"asyncFrameDequeueStack" withInfoTag:NO withDynamicLabel:NO to:experimentalSection]; [self addSetting:self.performanceGraphStack ofId:@"performanceGraphStack" withInfoTag:YES withDynamicLabel:NO to:experimentalSection]; [self addDynamicLabelForStack:self.graphOpacityStack]; @@ -1855,12 +1853,13 @@ BOOL isCustomResolution(int resolutionSelected) { } }]; - if (![self hdrSupported]) { + if (![Utils hdrSupported]) { [self.hdrSwitch setOn:NO]; [self.hdrSwitch setEnabled:NO]; } else { [self.hdrSwitch setOn:self->tempSettings.enableHdr]; + [self.hdrSwitch addTarget:self action:@selector(hdrSwitchFlipped:) forControlEvents:UIControlEventValueChanged]; } // Initialize codec-dependent switches together @@ -1888,8 +1887,9 @@ BOOL isCustomResolution(int resolutionSelected) { [self.framePacingModeSelector addTarget:self action:@selector(framePacingModeChanged:) forControlEvents:UIControlEventValueChanged]; [self framePacingModeChanged:self.framePacingModeSelector]; - [self.frameTimebaseSwitch setOn:self->tempSettings.enableFrameTimebase]; + // [self.frameTimebaseSwitch setOn:self->tempSettings.enableFrameTimebase]; [self.asyncFrameDequeueSwitch setOn:self->tempSettings.asyncFrameDequeue]; + [self.sdrPerformanceWorkaroundSwitch setOn:self->tempSettings.sdrPerformanceWorkaround]; [self renderingBackendChanged:self.renderingBackendSelector]; // Update PiP and frame pacing state based on current selection @@ -2223,6 +2223,14 @@ BOOL isCustomResolution(int resolutionSelected) { [self presentViewController:alertController animated:YES completion:nil]; } +- (void)hdrSwitchFlipped:(UISwitch* )sender{ + /* + if(!sender.isOn + && [Utils hdrSupported] + && ![self isIPhone]) [self.sdrPerformanceWorkaroundSwitch setOn:true]; + */ +} + - (bool)isOswEnabled{ return [self isNotNativeTouchOnly] && self.onScreenWidgetSelector.selectedSegmentIndex != OnScreenControlsLevelOff; } @@ -2308,8 +2316,8 @@ BOOL isCustomResolution(int resolutionSelected) { - (void)framePacingModeChanged:(UISegmentedControl *)sender { // Hide frame queue size for Off and Legacy modes [self setHidden:(sender.selectedSegmentIndex == FramePacingModeOff || sender.selectedSegmentIndex == FramePacingModeLegacy) forStack:self.frameQueueSizeStack]; - [self setHidden:(sender.selectedSegmentIndex != FramePacingModeQueue) forStack:self.frameTimebaseStack]; - [self setHidden:(sender.selectedSegmentIndex != FramePacingModeQueue) forStack:self.frameTimebaseStack]; + // [self setHidden:(sender.selectedSegmentIndex != FramePacingModeQueue) forStack:self.frameTimebaseStack]; + [self setHidden:(sender.selectedSegmentIndex != FramePacingModeQueue) forStack:self.asyncFrameDequeueStack]; if(sender.selectedSegmentIndex == FramePacingModeOff || sender.selectedSegmentIndex == FramePacingModeLegacy){ [self.enableGraphsSwitch setOn:NO]; @@ -3502,6 +3510,7 @@ BOOL isCustomResolution(int resolutionSelected) { BOOL useBuiltinMic = self.useBuiltinMicSwitch.isOn; uint32_t preferredCodec = [self getChosenCodecPreference]; BOOL enableYUV444 = self.yuv444Switch.isOn; + BOOL sdrPerformanceWorkaround = self.sdrPerformanceWorkaroundSwitch.isOn; BOOL enablePIP = self.pipSwitch.isOn; BOOL fullColorRange = self.fullColorRangeSwitch.isOn; BOOL btMouseSupport = self.citrixX1MouseSwitch.isOn; @@ -3540,7 +3549,7 @@ BOOL isCustomResolution(int resolutionSelected) { CGFloat controllerMousePointerVelocity = self.controllerMouseVelocitySlider.value; CGFloat controllerMouseExpo = self.controllerMouseExpoSlider.value; NSInteger controllerGyroSwitchMode = self.controllerGyroSwitchButtonSetter.selectedSegmentIndex; - BOOL enableFrameTimebase = self.frameTimebaseSwitch.isOn; + BOOL enableFrameTimebase = false; BOOL asyncFrameDequeue = self.asyncFrameDequeueSwitch.isOn; NSInteger backgroundSessionTimer = self.backgroundSessionTimerSlider.value == self.backgroundSessionTimerSlider.maximumValue ? (uint32_t) INT16_MAX : (uint32_t)self.backgroundSessionTimerSlider.value; @@ -3616,6 +3625,7 @@ BOOL isCustomResolution(int resolutionSelected) { controllerGyroSwitchMode:controllerGyroSwitchMode enableFrameTimebase:enableFrameTimebase asyncFrameDequeue:asyncFrameDequeue + sdrPerformanceWorkaround:sdrPerformanceWorkaround backgroundSessionTimer:backgroundSessionTimer]; } @@ -3661,12 +3671,12 @@ BOOL isCustomResolution(int resolutionSelected) { [self.hdrSwitch setEnabled:NO]; } else { // Only enable HDR if the device supports it - if ([self hdrSupported]) { + if ([Utils hdrSupported]) { [self.hdrSwitch setEnabled:YES]; } } - if(![self hdrSupported]) [self.hdrSwitch setOn:NO animated:NO]; + if(![Utils hdrSupported]) [self.hdrSwitch setOn:NO animated:NO]; } @end diff --git a/VoidLink/ViewControllers/StreamFrameViewController.m b/VoidLink/ViewControllers/StreamFrameViewController.m index e82efc87..9ae5438c 100644 --- a/VoidLink/ViewControllers/StreamFrameViewController.m +++ b/VoidLink/ViewControllers/StreamFrameViewController.m @@ -1324,6 +1324,19 @@ if(strcmp(stageName, "mic stream unsupported or unintialized")==0){ _micStreamInitialized = false; } + + // 8bit 444 degration workaround + if(strcmp(stageName, "video stream establishment")==0){ + if(!_settings.enableHdr + && _settings.sdrPerformanceWorkaround + && [Utils hdrSupported]){ + dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)); + dispatch_after(delay, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + NSArray* hdrCommand = [CommandManager.shared extractKeyStringsFrom:@"WIN+ALT+B"]; + [CommandManager.shared sendKeyComboCommandWithKeyboardCmdStrings:hdrCommand delay:0.15 index:0]; + }); + } + } } - (void) stageFailed:(const char*)stageName withError:(int)errorCode portTestFlags:(int)portTestFlags { diff --git a/VoidLink/mul.lproj/iPad.xcstrings b/VoidLink/mul.lproj/iPad.xcstrings index d0ccd2b6..dcf37ecc 100644 --- a/VoidLink/mul.lproj/iPad.xcstrings +++ b/VoidLink/mul.lproj/iPad.xcstrings @@ -5641,14 +5641,62 @@ } } }, - "X0u-7f-F86.text" : { - "comment" : "Class = \"UILabel\"; text = \"Async Deueue\"; ObjectID = \"X0u-7f-F86\";", + "WWl-77-twB.text" : { + "comment" : "Class = \"UILabel\"; text = \"SDR Performance Workaround\"; ObjectID = \"WWl-77-twB\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Async Deueue" + "value" : "SDR Performance Workaround" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "SDR性能优化路径" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "SDR效能優化路徑" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "SDR效能優化路徑" + } + } + } + }, + "X0u-7f-F86.text" : { + "comment" : "Class = \"UILabel\"; text = \"Async Frame Dequeue\"; ObjectID = \"X0u-7f-F86\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Async Frame Dequeue" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "异步帧出队" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "非同步取幀" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "非同步取幀" } } } diff --git a/VoidLink/mul.lproj/iPhone.xcstrings b/VoidLink/mul.lproj/iPhone.xcstrings index 4629eea9..24ddf9a7 100644 --- a/VoidLink/mul.lproj/iPhone.xcstrings +++ b/VoidLink/mul.lproj/iPhone.xcstrings @@ -2024,13 +2024,31 @@ } }, "e1n-pw-04X.text" : { - "comment" : "Class = \"UILabel\"; text = \"Async Deueue\"; ObjectID = \"e1n-pw-04X\";", + "comment" : "Class = \"UILabel\"; text = \"Async Frame Deueue\"; ObjectID = \"e1n-pw-04X\";", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", - "value" : "Async Deueue" + "value" : "Async Frame Deueue" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "异步帧出队" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "非同步取幀" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "非同步取幀" } } } @@ -2197,6 +2215,36 @@ } } }, + "F8d-OQ-PsH.text" : { + "comment" : "Class = \"UILabel\"; text = \"SDR Performance Workaround\"; ObjectID = \"F8d-OQ-PsH\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "SDR Performance Workaround" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "SDR性能优化路径" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "SDR效能優化路徑" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "SDR效能優化路徑" + } + } + } + }, "f46-Pt-0Pv.text" : { "comment" : "Class = \"UILabel\"; text = \"Profile:\"; ObjectID = \"f46-Pt-0Pv\";", "extractionState" : "extracted_with_value",