diff --git a/VoidLink/Base.lproj/iPad.storyboard b/VoidLink/Base.lproj/iPad.storyboard index d8a56a06..db043bfb 100644 --- a/VoidLink/Base.lproj/iPad.storyboard +++ b/VoidLink/Base.lproj/iPad.storyboard @@ -368,7 +368,7 @@ - + @@ -3216,19 +3216,19 @@ - + - + - + - + diff --git a/VoidLink/Base.lproj/iPhone.storyboard b/VoidLink/Base.lproj/iPhone.storyboard index 026ed9a5..b612e756 100644 --- a/VoidLink/Base.lproj/iPhone.storyboard +++ b/VoidLink/Base.lproj/iPhone.storyboard @@ -1925,7 +1925,7 @@ - + @@ -3106,16 +3106,16 @@ - + - + - + - + diff --git a/VoidLink/Localization/Localizable.xcstrings b/VoidLink/Localization/Localizable.xcstrings index f71a2a3b..313166b6 100644 --- a/VoidLink/Localization/Localizable.xcstrings +++ b/VoidLink/Localization/Localizable.xcstrings @@ -3577,7 +3577,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "- 关闭 = 无帧步进控制,即为之前的“最低延迟”.\n\n- 传统模式,相当于之前的“最高流畅度” (尽管已经不是最流畅的选项)." + "value" : "- 关闭 = 无帧步进控制,即为moonlight的“最低延迟”.\n\n- 传统模式,相当于之前的“最高流畅度” (尽管已经不是最流畅的选项)." } }, "zh-Hant" : { @@ -4481,6 +4481,29 @@ } } }, + "lowest latency" : { + "extractionState" : "manual", + "localizations" : { + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "最低延迟" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "最低延遲" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "最低延遲" + } + } + } + }, "Manual_Add_Host_Fail" : { "extractionState" : "manual", "localizations" : { diff --git a/VoidLink/Stream/StreamManager.m b/VoidLink/Stream/StreamManager.m index 5e42dc16..29f54e1e 100644 --- a/VoidLink/Stream/StreamManager.m +++ b/VoidLink/Stream/StreamManager.m @@ -115,6 +115,7 @@ } - (void) setNeedRequeuing:(bool)needRequeuing{ + if (_videoRenderer.queueSize==0) return; [_videoRenderer.frameQueue clear]; _videoRenderer.needRequeuing = needRequeuing; } diff --git a/VoidLink/Stream/VideoDecoderRenderer.h b/VoidLink/Stream/VideoDecoderRenderer.h index fcc10e7c..3dc14832 100644 --- a/VoidLink/Stream/VideoDecoderRenderer.h +++ b/VoidLink/Stream/VideoDecoderRenderer.h @@ -20,6 +20,7 @@ @property (atomic, readonly) PlotMetrics frameQueueMetrics; @property (atomic, assign) bool needRequeuing; @property (nonatomic, strong) FrameQueue* frameQueue; +@property (atomic, readonly) int32_t queueSize; @property (nonatomic, strong, readonly) AVSampleBufferDisplayLayer *displayLayer; diff --git a/VoidLink/Stream/VideoDecoderRenderer.m b/VoidLink/Stream/VideoDecoderRenderer.m index b7d6595d..3c3c6e5c 100644 --- a/VoidLink/Stream/VideoDecoderRenderer.m +++ b/VoidLink/Stream/VideoDecoderRenderer.m @@ -52,7 +52,6 @@ extern int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size, VTDecompressionSessionRef _decompressionSession; CADisplayLink *_displayLink; - uint8_t queueSize; NSInteger _maxRefreshRate; RenderingBackend _renderingBackend; @@ -145,13 +144,13 @@ extern int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size, _asyncFrameDequeue = tempSettings.asyncFrameDequeue; NSLog(@"_asyncFrameDequeue %d", _asyncFrameDequeue); _enableTimebase = false; - queueSize = tempSettings.frameQueueSize.intValue; - _needRequeuing = true; + _queueSize = tempSettings.frameQueueSize.intValue; + _needRequeuing = _queueSize>0; isIPhone = [Utils isIPhone]; _frameQueue = [FrameQueue sharedInstance]; [_frameQueue start]; - [_frameQueue setHighWaterMark:(int)[tempSettings.frameQueueSize integerValue]]; + [_frameQueue setHighWaterMark:MAX(1, _queueSize)]; [self reinitializeDisplayLayer]; // NSTimeInterval interval = 1.0/tempSettings.framerate.intValue; @@ -310,8 +309,8 @@ int DrSubmitDecodeUnit(PDECODE_UNIT decodeUnit); waitFor = 0.0f; } */ - - if(_needRequeuing ? _frameQueue.count>queueSize-1 : true){ + + if(_needRequeuing ? _frameQueue.count>MAX(_queueSize-1,0) : true){ // if(true){ _needRequeuing = false; if(_asyncFrameDequeue){ diff --git a/VoidLink/ViewControllers/MainFrameViewController.m b/VoidLink/ViewControllers/MainFrameViewController.m index d1622d6b..0d1ed02e 100644 --- a/VoidLink/ViewControllers/MainFrameViewController.m +++ b/VoidLink/ViewControllers/MainFrameViewController.m @@ -1170,7 +1170,7 @@ static NSMutableSet* hostList; self.navigationItem.leftBarButtonItems = @[_settingsButton]; if(streamFrameViewController.streamMan){ - NSLog(@"setNeedRequeuing %f", CACurrentMediaTime()); + // NSLog(@"setNeedRequeuing %f", CACurrentMediaTime()); double delayInSeconds = 0.1; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); dispatch_after(popTime, dispatch_get_main_queue(), ^{ diff --git a/VoidLink/ViewControllers/SettingsViewController.m b/VoidLink/ViewControllers/SettingsViewController.m index 51173ccc..9c887e00 100644 --- a/VoidLink/ViewControllers/SettingsViewController.m +++ b/VoidLink/ViewControllers/SettingsViewController.m @@ -1994,7 +1994,7 @@ BOOL isCustomResolution(int resolutionSelected) { [self updateBitrateText]; [self updateResolutionDisplayLabel]; - [self.frameQueueSizeSlider setMinimumValue:1]; + [self.frameQueueSizeSlider setMinimumValue:0]; [self.frameQueueSizeSlider setMaximumValue:5]; [self.frameQueueSizeSlider setValue:self->tempSettings.frameQueueSize.intValue]; [self.frameQueueSizeSlider addTarget:self action:@selector(frameQueueSizeSliderMoved:) forControlEvents:UIControlEventValueChanged]; @@ -3381,7 +3381,8 @@ BOOL isCustomResolution(int resolutionSelected) { - (void) frameQueueSizeSliderMoved:(UISlider* )sender { assert(self.frameQueueSizeSlider.value >= 0 && self.frameQueueSizeSlider.value <= 5); - [self findDynamicLabelFromStack:_frameQueueSizeStack].text = [NSString stringWithFormat:@" %d ", (int)self.frameQueueSizeSlider.value]; + int queueSize = self.frameQueueSizeSlider.value; + [self findDynamicLabelFromStack:_frameQueueSizeStack].text = queueSize==0 ? [LocalizationHelper localizedStringForKey:@"lowest latency"] : [NSString stringWithFormat: @" %d ", queueSize]; } - (void) enableGraphsChanged:(UISwitch* )sender {