statsOverlay for frame interpolation

This commit is contained in:
True Zhuanjia
2026-08-11 13:32:24 +08:00
parent d28aa43319
commit 4214afd2b7
7 changed files with 235 additions and 182 deletions
+98 -161
View File
@@ -9350,138 +9350,6 @@
}
}
},
"Interpolation Resolution" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "插帧分辨率"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "影格插補解析度"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "影格插補解析度"
}
}
}
},
"Most devices currently support frame interpolation only for 8-bit YUV 4:2:0 SDR video. In this case, if HDR or YUV 4:4:4 is enabled, intermediate frames will still be generated in 8-bit YUV 4:2:0 SDR." : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "目前多数设备仅支持 8-bit YUV420 SDR 视频插帧。这种情况下,如果您打开了 HDR 或 YUV444 选项,中间帧将依然按 8-bit YUV420 SDR 格式生成。"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "目前多數裝置僅支援 8-bit YUV420 SDR 影片影格插補。在這種情況下,如果您開啟 HDR 或 YUV444 選項,中間影格仍會以 8-bit YUV420 SDR 格式產生。"
}
}
}
},
"Interpolation failed for an unknown reason." : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "未知原因导致的插帧失败"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "未知原因導致插幀失敗"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "未知原因導致插幀失敗"
}
}
}
},
"Interpolation overhead is too high. Falling back to normal mode." : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "插帧性能开销过大,回退普通模式"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "插幀效能開銷過大,回退至一般模式"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "插幀效能開銷過大,回退至一般模式"
}
}
}
},
"Interpolator error:" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "插帧器错误:"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "插幀器錯誤:"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "插幀器錯誤:"
}
}
}
},
"Interpolator started." : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "插帧器已启动。"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "插幀器已啟動。"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "插幀器已啟動。"
}
}
}
},
"framePacingStackTip" : {
"extractionState" : "manual",
"localizations" : {
@@ -11015,6 +10883,29 @@
}
}
},
"Interpolation Resolution" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "插帧分辨率"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "影格插補解析度"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "影格插補解析度"
}
}
}
},
"Interpolator error:" : {
"extractionState" : "manual",
"localizations" : {
@@ -12371,25 +12262,25 @@
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "\nHold up! \n\n- Standard render has better performance on most devices now.\n\n- The change takes effect the next time you start a stream. No app restart is needed.\n\n- Metal rendering is an experimental feature that may cause performance degradation on some devices.\n\n- Metal render currently is unable to handle HDR content correctly on most devices.\n\n- Metal rendering mode does not support PiP.\n\n- Tapping “Apply” means I acknowledge the above information."
"value" : "\nWait!\n\n- VoidLink's standard rendering mode already delivers extremely strong performance, on par with Metal rendering.\n\n- Metal rendering consumes more GPU resources and power, and on some devices it may result in reduced performance.\n\n- Metal render currently is unable to handle HDR content correctly on most devices.\n\n- Metal rendering mode does not support PiP.\n\n- Tapping “Apply” means I acknowledge the above information."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "\n等等!\n\n- 标准渲染模式目前在大多数设备上具有更好的性能。\n\n- 渲染模式的更改将在下次开始串流时生效,无需重启应用程序。\n\n- Metal 渲染是一项实验性功能,在某些设备上可能会导致性能下降。\n\n- Metal 渲染模式下不支持画中画。\n\n- 目前 Metal 渲染器在大多数设备上无法正确处理 HDR 内容。\n\n点击“应用”表示我已知晓并认可以上信息。"
"state" : "needs_review",
"value" : "\n等等!\n\n- VoidLink 标准渲染模式的性能已经非常强,与Metal 渲染处于同一水准。\n\n- Metal 渲染需消耗更多GPU资源和电量,在某些设备上可能会导致性能下降。\n\n- Metal 渲染模式下不支持画中画。\n\n- 目前 Metal 渲染器在大多数设备上无法正确处理 HDR 内容。\n\n点击“应用”表示我已知晓并认可以上信息。"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "\n等等!\n\n- 目前在大多数装置上,標準渲染模式具有较佳的效能。\n\n- 变更渲染模式将在下次开始串流时生效,无需重新启动应用程式。\n\n- Metal 渲染为实验性功能,可能在某些装置上造成效能下降。\n\n- Metal 渲染模式下不支援画中画。\n\n- Metal 渲染器目前在大多数装置上无法正确处理 HDR 内容。\n\n点选「套用」表示我已了解并同意上述说明。"
"value" : "\n等等!\n\n- VoidLink 標準渲染模式的效能已經非常強大,與 Metal 渲染處於同等水準。\n\n- Metal 渲染需要消耗更多 GPU 資源與電量,在部分裝置上可能反而會導致效能下降。\n\n- Metal 渲染模式下不支援画中画。\n\n- Metal 渲染器目前在大多数装置上无法正确处理 HDR 内容。\n\n点选「套用」表示我已了解并同意上述说明。"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "\n等等!\n\n- 目前在大多数装置上,標準渲染模式具有较佳的效能。\n\n- 变更渲染模式将在下次开始串流时生效,无需重新启动应用程式。\n\n- Metal 渲染为实验性功能,可能在某些装置上造成效能下降。\n\n- Metal 渲染模式下不支援画中画。\n\n- Metal 渲染器目前在大多数装置上无法正确处理 HDR 内容。\n\n点选「套用」表示我已了解并同意上述说明。"
"value" : "\n等等!\n\n- VoidLink 標準渲染模式的效能已經非常強大,與 Metal 渲染處於同等水準。\n\n- Metal 渲染需要消耗更多 GPU 資源與電量,在部分裝置上可能反而會導致效能下降。\n\n- Metal 渲染模式下不支援画中画。\n\n- Metal 渲染器目前在大多数装置上无法正确处理 HDR 内容。\n\n点选「套用」表示我已了解并同意上述说明。"
}
}
}
@@ -12567,6 +12458,23 @@
}
}
},
"Most devices currently support frame interpolation only for 8-bit YUV 4:2:0 SDR video. In this case, if HDR or YUV 4:4:4 is enabled, intermediate frames will still be generated in 8-bit YUV 4:2:0 SDR." : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "目前多数设备仅支持 8-bit YUV420 SDR 视频插帧。这种情况下,如果您打开了 HDR 或 YUV444 选项,中间帧将依然按 8-bit YUV420 SDR 格式生成。"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "目前多數裝置僅支援 8-bit YUV420 SDR 影片影格插補。在這種情況下,如果您開啟 HDR 或 YUV444 選項,中間影格仍會以 8-bit YUV420 SDR 格式產生。"
}
}
}
},
"Motion Control" : {
"extractionState" : "manual",
"localizations" : {
@@ -16482,6 +16390,29 @@
}
}
},
"Scaled Stream Resolution" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "串流分辨率缩放"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "串流解析度縮放"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "串流解析度縮放"
}
}
}
},
"screenRotationTIp" : {
"extractionState" : "manual",
"localizations" : {
@@ -17214,6 +17145,35 @@
}
}
},
"simplifiedOsdTextWithInterpolation" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "FPS: %6.2f+%.2f Dropped frames: %4.1f%% Bitrate: %5.1f Mbps Latency: %@"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "帧率: %6.2f+%.2f 丢帧: %4.1f%% 码率: %5.1f Mbps 延迟: %@"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "FPS: %6.2f+%.2f 掉幀: %4.1f%% 位元速率: %5.1f Mbps 延遲: %@"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "FPS: %6.2f+%.2f 掉幀: %4.1f%% 位元速率: %5.1f Mbps 延遲: %@"
}
}
}
},
"Size" : {
"extractionState" : "manual",
"localizations" : {
@@ -17387,29 +17347,6 @@
}
}
},
"Scaled Stream Resolution" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "串流分辨率缩放"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "串流解析度縮放"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "串流解析度縮放"
}
}
}
},
"Slow connection to PC, Reduce your bitrate" : {
"extractionState" : "manual",
"localizations" : {
@@ -20116,4 +20053,4 @@
}
},
"version" : "1.1"
}
}
+5
View File
@@ -43,6 +43,7 @@ static int activeVideoFormat;
static video_stats_t currentVideoStats;
static video_stats_t lastVideoStats;
static NSLock* videoStatsLock;
static uint64_t lastRenderedInterpolatedFrameCount;
static SDL_AudioDeviceID audioDevice;
static OPUS_MULTISTREAM_CONFIGURATION audioConfig;
@@ -73,6 +74,7 @@ int DrDecoderSetup(int videoFormat, int width, int height, int redrawRate, void*
Log(LOG_I, @"Active video format: 0x%x", activeVideoFormat);
memset(&currentVideoStats, 0, sizeof(currentVideoStats));
memset(&lastVideoStats, 0, sizeof(lastVideoStats));
lastRenderedInterpolatedFrameCount = [renderer renderedInterpolatedFrameCount];
bwTracker = [[BandwidthTracker alloc] initWithWindowSeconds:10 bucketIntervalMs:250];
return 0;
}
@@ -178,6 +180,9 @@ int DrSubmitDecodeUnit(PDECODE_UNIT decodeUnit)
// Flip stats roughly every second
if (now - currentVideoStats.startTime >= 1.0f) {
currentVideoStats.endTime = now;
uint64_t renderedInterpolatedFrameCount = [renderer renderedInterpolatedFrameCount];
currentVideoStats.interpolatedFrames = (int)(renderedInterpolatedFrameCount - lastRenderedInterpolatedFrameCount);
lastRenderedInterpolatedFrameCount = renderedInterpolatedFrameCount;
[videoStatsLock lock];
lastVideoStats = currentVideoStats;
+30 -13
View File
@@ -209,17 +209,38 @@
float scalePlotMetrics = stats.frameDropMetrics.nsamples > 0 ? ((float)stats.frameDropMetrics.nsamples / stats.totalFrames) : 1.0f;
fps = (stats.totalFrames - stats.networkDroppedFrames - (stats.frameDropMetrics.total / scalePlotMetrics)) / interval;
}
float interpolatedFps = stats.interpolatedFrames / interval;
NSString *renderingFpsString;
if (framePacingMode == FramePacingModeInterpolation) {
renderingFpsString = [NSString stringWithFormat:@"Rendering FPS: %dx%d %.2f+%.2f",
_config.width, _config.height, fps, interpolatedFps];
}
else {
renderingFpsString = [NSString stringWithFormat:@"Rendering FPS: %dx%d %.2f",
_config.width, _config.height, fps];
}
double avgVideoMbps = [_connection getBwTracker].averageMbps;
double peakVideoMbps = [_connection getBwTracker].peakMbps;
NSString* colorRange = _config.fullColorRange ? @"Full" : @"Limited";
if(overlayLevel == 1) return [LocalizationHelper localizedStringForKey:@"simplifiedOsdText",
fps,
stats.networkDroppedFrames / interval,
avgVideoMbps,
latencyString];
if (overlayLevel == 1) {
if (framePacingMode == FramePacingModeInterpolation) {
return [LocalizationHelper localizedStringForKey:@"simplifiedOsdTextWithInterpolation",
fps,
interpolatedFps,
stats.networkDroppedFrames / interval,
avgVideoMbps,
latencyString];
}
return [LocalizationHelper localizedStringForKey:@"simplifiedOsdText",
fps,
stats.networkDroppedFrames / interval,
avgVideoMbps,
latencyString];
}
else {
if (framePacingMode == FramePacingModeLegacy || framePacingMode == FramePacingModeOff) {
NSString* rendererWithPacing = stats.renderingBackendString;
@@ -231,15 +252,13 @@
}
}
return [LocalizationHelper localizedStringForKey:@"Video stream: %dx%d %.2f FPS (Codec: %@, %@)\n"
return [LocalizationHelper localizedStringForKey:@"%@ (Codec: %@, %@)\n"
"Bitrate: %.1f Mbps, Peak: %.1f\n"
"%@"
"Renderer: %@\n"
"Frames dropped by network: %.1f%%\n"
"Average network latency: %@",
_config.width,
_config.height,
fps,
renderingFpsString,
[_connection getActiveCodecName],
colorRange,
avgVideoMbps, peakVideoMbps,
@@ -253,16 +272,14 @@
rendererWithPacing = @"AVSampleBuffer (Queue Pacing)";
}
return [LocalizationHelper localizedStringForKey:@"Video stream: %dx%d %.2f FPS (Codec: %@, %@)\n"
return [LocalizationHelper localizedStringForKey:@"%@ (Codec: %@, %@)\n"
"Bitrate: %.1f Mbps, Peak: %.1f, Frames buffered: %.1f\n"
"%@"
"Renderer: %@\n"
"Frames dropped by network/pacing jitter: %.1f%% / %.1f%%\n"
"Average network latency: %@\n"
"Decode time: %.2f/%.2f/%.2f ms %@",
_config.width,
_config.height,
fps,
renderingFpsString,
[_connection getActiveCodecName],
colorRange,
avgVideoMbps, peakVideoMbps, stats.frameQueueMetrics.avg,
+1
View File
@@ -33,6 +33,7 @@
- (void)setHdrMode:(BOOL)enabled;
- (void)safeCopyMetricsTo:(PlotMetrics *)dst from:(PlotMetrics *)src;
- (void)getAllStats:(video_stats_t *)stats;
- (uint64_t)renderedInterpolatedFrameCount;
- (void)optimizeRefreshRate;
- (void)resetFramePacing;
+94 -2
View File
@@ -31,6 +31,7 @@
#include <libavutil/mem.h>
#include <mach/mach_time.h>
#include <math.h>
#include <stdatomic.h>
// Define for extra logging related to frame pacing
//#define DISPLAYLINK_VERBOSE
@@ -47,6 +48,7 @@ extern int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size,
- (void)stopFrameInterpolation;
- (NSInteger)displayLinkFrameRateForInterpolationEnabled:(BOOL)enabled;
- (void)restartDisplayLinkForInterpolationEnabled:(BOOL)enabled;
// - (void)logColorMetadataForFrameIfNeeded:(Frame *)frame;
@end
@implementation VideoDecoderRenderer {
@@ -69,6 +71,9 @@ extern int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size,
VTDecompressionSessionRef _decompressionSession;
FrameInterpolator *_frameInterpolator;
BOOL _frameInterpolationPaused;
BOOL _loggedSourceFrameColorMetadata;
BOOL _loggedInterpolatedFrameColorMetadata;
atomic_uint_fast64_t _renderedInterpolatedFrameCount;
CADisplayLink *_displayLink;
NSInteger _maxRefreshRate;
@@ -201,6 +206,7 @@ extern int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size,
_streamAspectRatio = aspectRatio;
_maxRefreshRate = [[UIScreen mainScreen] maximumFramesPerSecond];
_parameterSetBuffers = [[NSMutableArray alloc] init];
atomic_init(&_renderedInterpolatedFrameCount, 0);
DataManager* dataMan = [[DataManager alloc] init];
TemporarySettings* tempSettings = [dataMan getSettings];
@@ -638,6 +644,9 @@ int DrSubmitDecodeUnit(PDECODE_UNIT decodeUnit);
// Render frame at a specific targetTime
- (void)renderFrame:(Frame *)frame atTime:(CMTime)targetTime {
if (kEnableFrameInterpolation && self->_frameInterpolator != nil) {
// [self logColorMetadataForFrameIfNeeded:frame];
}
CMSampleBufferSetOutputPresentationTimeStamp(frame.sampleBuffer, targetTime);
if (_enableTimebase && [self->_displayLayer controlTimebase] == NULL) {
@@ -659,8 +668,15 @@ int DrSubmitDecodeUnit(PDECODE_UNIT decodeUnit);
Log(LOG_I, @"Setting timebase for stream to %d / %d", pts.value, pts.timescale);
}
if(appDidEnterBackgroundWithoutPip) [self->_displayLayer flush];
else [self->_displayLayer enqueueSampleBuffer:frame.sampleBuffer];
if(appDidEnterBackgroundWithoutPip) {
[self->_displayLayer flush];
}
else {
[self->_displayLayer enqueueSampleBuffer:frame.sampleBuffer];
if (kEnableFrameInterpolation && frame.isInterpolated) {
atomic_fetch_add_explicit(&_renderedInterpolatedFrameCount, 1, memory_order_relaxed);
}
}
#ifdef DISPLAYLINK_VERBOSE
// Some OS-level metrics I'm not sure what to do with
@@ -688,6 +704,78 @@ int DrSubmitDecodeUnit(PDECODE_UNIT decodeUnit);
}
}
/*
- (void)logColorMetadataForFrameIfNeeded:(Frame *)frame {
BOOL *logged = frame.isInterpolated ?
&_loggedInterpolatedFrameColorMetadata :
&_loggedSourceFrameColorMetadata;
if (*logged || frame.sampleBuffer == nil) {
return;
}
*logged = YES;
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(frame.sampleBuffer);
CMFormatDescriptionRef formatDescription = CMSampleBufferGetFormatDescription(frame.sampleBuffer);
if (imageBuffer == nil) {
Log(LOG_W, @"[FrameColor] %@ frame has no image buffer",
frame.isInterpolated ? @"interpolated" : @"source");
return;
}
OSType pixelFormat = CVPixelBufferGetPixelFormatType(imageBuffer);
char fourCC[5] = {
(char)((pixelFormat >> 24) & 0xff),
(char)((pixelFormat >> 16) & 0xff),
(char)((pixelFormat >> 8) & 0xff),
(char)(pixelFormat & 0xff),
'\0'
};
CFTypeRef bufferTransfer = CVBufferGetAttachment(
imageBuffer, kCVImageBufferTransferFunctionKey, NULL);
CFTypeRef bufferPrimaries = CVBufferGetAttachment(
imageBuffer, kCVImageBufferColorPrimariesKey, NULL);
CFTypeRef bufferMatrix = CVBufferGetAttachment(
imageBuffer, kCVImageBufferYCbCrMatrixKey, NULL);
CFTypeRef bufferMastering = CVBufferGetAttachment(
imageBuffer, kCVImageBufferMasteringDisplayColorVolumeKey, NULL);
CFTypeRef bufferContentLight = CVBufferGetAttachment(
imageBuffer, kCVImageBufferContentLightLevelInfoKey, NULL);
CFDictionaryRef extensions = formatDescription != nil ?
CMFormatDescriptionGetExtensions(formatDescription) : NULL;
CFTypeRef formatTransfer = extensions != NULL ?
CFDictionaryGetValue(extensions, kCMFormatDescriptionExtension_TransferFunction) : NULL;
CFTypeRef formatPrimaries = extensions != NULL ?
CFDictionaryGetValue(extensions, kCMFormatDescriptionExtension_ColorPrimaries) : NULL;
CFTypeRef formatMatrix = extensions != NULL ?
CFDictionaryGetValue(extensions, kCMFormatDescriptionExtension_YCbCrMatrix) : NULL;
CFTypeRef formatMastering = extensions != NULL ?
CFDictionaryGetValue(extensions, kCMFormatDescriptionExtension_MasteringDisplayColorVolume) : NULL;
CFTypeRef formatContentLight = extensions != NULL ?
CFDictionaryGetValue(extensions, kCMFormatDescriptionExtension_ContentLightLevelInfo) : NULL;
Log(LOG_I,
@"[FrameColor] %@ frame: %dx%d pixelFormat=%s (%u); "
"buffer transfer=%@ primaries=%@ matrix=%@ mastering=%@ contentLight=%@; "
"format transfer=%@ primaries=%@ matrix=%@ mastering=%@ contentLight=%@",
frame.isInterpolated ? @"interpolated" : @"source",
(int)CVPixelBufferGetWidth(imageBuffer),
(int)CVPixelBufferGetHeight(imageBuffer),
fourCC,
(unsigned int)pixelFormat,
(__bridge id)bufferTransfer,
(__bridge id)bufferPrimaries,
(__bridge id)bufferMatrix,
bufferMastering != NULL ? @"present" : @"nil",
bufferContentLight != NULL ? @"present" : @"nil",
(__bridge id)formatTransfer,
(__bridge id)formatPrimaries,
(__bridge id)formatMatrix,
formatMastering != NULL ? @"present" : @"nil",
formatContentLight != NULL ? @"present" : @"nil");
} */
- (void)stop{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[_displayLink invalidate];
@@ -1487,6 +1575,10 @@ int DrSubmitDecodeUnit(PDECODE_UNIT decodeUnit);
});
}
- (uint64_t)renderedInterpolatedFrameCount {
return atomic_load_explicit(&_renderedInterpolatedFrameCount, memory_order_relaxed);
}
// When streaming lower framerate content on a ProMotion display, the screen refresh rate can be
// reduced, optimizing battery life. Not currently used, it doesn't seem as reliable as I'd like.
- (void)optimizeRefreshRate {
+1
View File
@@ -40,6 +40,7 @@ typedef struct {
int totalFrames;
int receivedFrames;
int networkDroppedFrames;
int interpolatedFrames;
int totalHostProcessingLatency;
int framesWithHostProcessingLatency;
int maxHostProcessingLatency;
+6 -6
View File
@@ -2689,20 +2689,20 @@
},
"zh-Hans" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "悬停模式"
"state" : "translated",
"value" : "Pencil模式"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "懸停模式"
"state" : "translated",
"value" : "Pencil模式"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "懸停模式"
"state" : "translated",
"value" : "Pencil模式"
}
}
}