@@ -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