statsOverlay for frame interpolation
This commit is contained in:
@@ -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" : {
|
||||
|
||||
@@ -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(¤tVideoStats, 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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -40,6 +40,7 @@ typedef struct {
|
||||
int totalFrames;
|
||||
int receivedFrames;
|
||||
int networkDroppedFrames;
|
||||
int interpolatedFrames;
|
||||
int totalHostProcessingLatency;
|
||||
int framesWithHostProcessingLatency;
|
||||
int maxHostProcessingLatency;
|
||||
|
||||
@@ -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模式"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user