Skip to content

Commit 7f18d76

Browse files
committed
Fix hardware stream downscaling lag
1 parent e1cf17e commit 7f18d76

1 file changed

Lines changed: 38 additions & 3 deletions

File tree

cli/XCWH264Encoder.m

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,11 @@ @interface XCWH264Encoder ()
477477
- (nullable CVPixelBufferRef)copySoftwareScaledPixelBuffer:(CVPixelBufferRef)pixelBuffer
478478
targetWidth:(int32_t)targetWidth
479479
targetHeight:(int32_t)targetHeight;
480+
- (BOOL)shouldUseSoftwareScalerForSourceWidth:(int32_t)sourceWidth
481+
sourceHeight:(int32_t)sourceHeight
482+
targetWidth:(int32_t)targetWidth
483+
targetHeight:(int32_t)targetHeight
484+
pixelFormat:(OSType)pixelFormat;
480485
- (nullable CVPixelBufferRef)copyPixelBufferFromScalingPoolWithWidth:(int32_t)targetWidth
481486
height:(int32_t)targetHeight
482487
pixelFormat:(OSType)pixelFormat;
@@ -715,7 +720,11 @@ - (uint64_t)initialHardwareFrameIntervalUsLocked {
715720
}
716721

717722
- (uint64_t)maximumHardwareFrameIntervalUsLocked {
718-
return _realtimeStreamMode ? XCWRealtimeMaximumFrameIntervalUs() : XCWLocalStreamMaximumFrameIntervalUs();
723+
if (_realtimeStreamMode) {
724+
uint64_t minimumFpsIntervalUs = (uint64_t)llround(1000000.0 / (double)XCWMinimumLocalStreamFrameRate);
725+
return MAX(XCWRealtimeMaximumFrameIntervalUs(), minimumFpsIntervalUs);
726+
}
727+
return XCWLocalStreamMaximumFrameIntervalUs();
719728
}
720729

721730
- (int32_t)expectedFrameRateLocked {
@@ -807,7 +816,7 @@ - (void)adaptSoftwarePacingForLatencyUs:(uint64_t)latencyUs {
807816
}
808817

809818
- (void)adaptHardwarePacingForLatencyUs:(uint64_t)latencyUs {
810-
if ((_encoderMode != XCWVideoEncoderModeAuto && _encoderMode != XCWVideoEncoderModeH264Hardware) || !_lowLatencyMode || latencyUs == 0) {
819+
if ((_encoderMode != XCWVideoEncoderModeAuto && _encoderMode != XCWVideoEncoderModeH264Hardware) || !_realtimeStreamMode || latencyUs == 0) {
811820
return;
812821
}
813822
if (_hardwareFrameIntervalUs == 0) {
@@ -1077,11 +1086,24 @@ - (nullable CVPixelBufferRef)copyScaledPixelBufferIfNeeded:(CVPixelBufferRef)pix
10771086
targetHeight:(int32_t)targetHeight {
10781087
int32_t sourceWidth = (int32_t)CVPixelBufferGetWidth(pixelBuffer);
10791088
int32_t sourceHeight = (int32_t)CVPixelBufferGetHeight(pixelBuffer);
1089+
OSType sourcePixelFormat = CVPixelBufferGetPixelFormatType(pixelBuffer);
10801090
BOOL shouldCopyStableRealtimeBuffer = _realtimeStreamMode || _lowLatencyMode;
10811091
if (sourceWidth == targetWidth && sourceHeight == targetHeight && !shouldCopyStableRealtimeBuffer) {
10821092
CVPixelBufferRetain(pixelBuffer);
10831093
return pixelBuffer;
10841094
}
1095+
if ([self shouldUseSoftwareScalerForSourceWidth:sourceWidth
1096+
sourceHeight:sourceHeight
1097+
targetWidth:targetWidth
1098+
targetHeight:targetHeight
1099+
pixelFormat:sourcePixelFormat]) {
1100+
CVPixelBufferRef scaledPixelBuffer = [self copySoftwareScaledPixelBuffer:pixelBuffer
1101+
targetWidth:targetWidth
1102+
targetHeight:targetHeight];
1103+
if (scaledPixelBuffer != NULL) {
1104+
return scaledPixelBuffer;
1105+
}
1106+
}
10851107

10861108
if (_pixelTransferSession == NULL) {
10871109
OSStatus sessionStatus = VTPixelTransferSessionCreate(kCFAllocatorDefault, &_pixelTransferSession);
@@ -1105,7 +1127,6 @@ - (nullable CVPixelBufferRef)copyScaledPixelBufferIfNeeded:(CVPixelBufferRef)pix
11051127
kVTScalingMode_Normal);
11061128
}
11071129

1108-
OSType sourcePixelFormat = CVPixelBufferGetPixelFormatType(pixelBuffer);
11091130
CVPixelBufferRef scaledPixelBuffer = [self copyPixelBufferFromScalingPoolWithWidth:targetWidth
11101131
height:targetHeight
11111132
pixelFormat:sourcePixelFormat];
@@ -1130,6 +1151,20 @@ - (nullable CVPixelBufferRef)copyScaledPixelBufferIfNeeded:(CVPixelBufferRef)pix
11301151
return scaledPixelBuffer;
11311152
}
11321153

1154+
- (BOOL)shouldUseSoftwareScalerForSourceWidth:(int32_t)sourceWidth
1155+
sourceHeight:(int32_t)sourceHeight
1156+
targetWidth:(int32_t)targetWidth
1157+
targetHeight:(int32_t)targetHeight
1158+
pixelFormat:(OSType)pixelFormat {
1159+
if (!_realtimeStreamMode || !XCWPixelFormatSupportsSoftwareScaling(pixelFormat)) {
1160+
return NO;
1161+
}
1162+
if (sourceWidth == targetWidth && sourceHeight == targetHeight) {
1163+
return NO;
1164+
}
1165+
return _encoderMode == XCWVideoEncoderModeAuto || _encoderMode == XCWVideoEncoderModeH264Hardware;
1166+
}
1167+
11331168
- (nullable CVPixelBufferRef)copySoftwareScaledPixelBuffer:(CVPixelBufferRef)pixelBuffer
11341169
targetWidth:(int32_t)targetWidth
11351170
targetHeight:(int32_t)targetHeight {

0 commit comments

Comments
 (0)