|
34 | 34 | static const uint64_t XCWLowLatencySoftwareMaximumFrameIntervalUs = 133333; |
35 | 35 | static const uint64_t XCWLowLatencySoftwareFrameIntervalStepUs = 11111; |
36 | 36 | static const NSUInteger XCWLowLatencySoftwareHealthyFrameWindow = 8; |
37 | | -static const uint64_t XCWRealtimeHardwareInitialFrameIntervalUs = 33333; |
38 | | -static const uint64_t XCWRealtimeHardwareMinimumFrameIntervalUs = 33333; |
39 | | -static const uint64_t XCWRealtimeHardwareMaximumFrameIntervalUs = 66667; |
40 | 37 | static const uint64_t XCWRealtimeHardwareFrameIntervalStepUs = 5556; |
41 | 38 | static const NSUInteger XCWRealtimeHardwareHealthyFrameWindow = 6; |
42 | 39 |
|
@@ -308,7 +305,7 @@ static CGSize XCWScaledDimensionsForSourceSize(int32_t width, int32_t height, XC |
308 | 305 | ? XCWRealtimeMaximumEncodedDimension() |
309 | 306 | : XCWMaximumEncodedDimension; |
310 | 307 | if (mode == XCWVideoEncoderModeH264Software && lowLatencyMode) { |
311 | | - maximumDimension = XCWMaximumLowLatencySoftwareEncodedDimension; |
| 308 | + maximumDimension = MIN(maximumDimension, XCWMaximumLowLatencySoftwareEncodedDimension); |
312 | 309 | } else if (mode == XCWVideoEncoderModeH264Software && !realtimeStreamMode) { |
313 | 310 | maximumDimension = XCWMaximumSoftwareEncodedDimension; |
314 | 311 | } |
@@ -492,7 +489,7 @@ - (instancetype)initWithOutputHandler:(XCWH264EncoderOutputHandler)outputHandler |
492 | 489 | _realtimeStreamMode = XCWRealtimeStreamModeFromEnvironment() || _lowLatencyMode; |
493 | 490 | _codecType = XCWVideoCodecTypeForMode(_encoderMode); |
494 | 491 | _softwareFrameIntervalUs = [self initialSoftwareFrameIntervalUsLocked]; |
495 | | - _realtimeHardwareFrameIntervalUs = XCWRealtimeHardwareInitialFrameIntervalUs; |
| 492 | + _realtimeHardwareFrameIntervalUs = XCWRealtimeFrameIntervalUs(); |
496 | 493 | return self; |
497 | 494 | } |
498 | 495 |
|
@@ -535,6 +532,19 @@ - (void)requestKeyFrame { |
535 | 532 | }); |
536 | 533 | } |
537 | 534 |
|
| 535 | +- (void)reconfigureForStreamQualityChange { |
| 536 | + dispatch_async(_queue, ^{ |
| 537 | + [self invalidateCompressionSessionLocked]; |
| 538 | + self->_needsKeyFrame = YES; |
| 539 | + self->_softwareFrameIntervalUs = [self initialSoftwareFrameIntervalUsLocked]; |
| 540 | + self->_softwarePacedFrameCount = 0; |
| 541 | + self->_softwareHealthyFrameCount = 0; |
| 542 | + self->_realtimeHardwareFrameIntervalUs = XCWRealtimeFrameIntervalUs(); |
| 543 | + self->_realtimeHardwarePacedFrameCount = 0; |
| 544 | + self->_realtimeHardwareHealthyFrameCount = 0; |
| 545 | + }); |
| 546 | +} |
| 547 | + |
538 | 548 | - (NSDictionary *)statsRepresentation { |
539 | 549 | __block NSUInteger inputFrameCount = 0; |
540 | 550 | __block NSUInteger pendingReplacementCount = 0; |
@@ -642,7 +652,7 @@ - (BOOL)shouldPaceRealtimeHardwareFrameAtTimeUs:(uint64_t)nowUs { |
642 | 652 | return NO; |
643 | 653 | } |
644 | 654 | if (_realtimeHardwareFrameIntervalUs == 0) { |
645 | | - _realtimeHardwareFrameIntervalUs = XCWRealtimeHardwareInitialFrameIntervalUs; |
| 655 | + _realtimeHardwareFrameIntervalUs = XCWRealtimeFrameIntervalUs(); |
646 | 656 | } |
647 | 657 | if (_lastRealtimeHardwareSubmissionUs == 0) { |
648 | 658 | return NO; |
@@ -717,28 +727,30 @@ - (void)adaptRealtimeHardwarePacingForLatencyUs:(uint64_t)latencyUs { |
717 | 727 | return; |
718 | 728 | } |
719 | 729 | if (_realtimeHardwareFrameIntervalUs == 0) { |
720 | | - _realtimeHardwareFrameIntervalUs = XCWRealtimeHardwareInitialFrameIntervalUs; |
| 730 | + _realtimeHardwareFrameIntervalUs = XCWRealtimeFrameIntervalUs(); |
721 | 731 | } |
722 | 732 |
|
| 733 | + uint64_t minimumIntervalUs = XCWRealtimeFrameIntervalUs(); |
| 734 | + uint64_t maximumIntervalUs = XCWRealtimeMaximumFrameIntervalUs(); |
723 | 735 | if (latencyUs > _realtimeHardwareFrameIntervalUs) { |
724 | 736 | uint64_t nextIntervalUs = _realtimeHardwareFrameIntervalUs + XCWRealtimeHardwareFrameIntervalStepUs; |
725 | 737 | uint64_t latencyBoundIntervalUs = latencyUs + XCWRealtimeHardwareFrameIntervalStepUs; |
726 | 738 | if (nextIntervalUs < latencyBoundIntervalUs) { |
727 | 739 | nextIntervalUs = latencyBoundIntervalUs; |
728 | 740 | } |
729 | | - _realtimeHardwareFrameIntervalUs = MIN(nextIntervalUs, XCWRealtimeHardwareMaximumFrameIntervalUs); |
| 741 | + _realtimeHardwareFrameIntervalUs = MIN(nextIntervalUs, maximumIntervalUs); |
730 | 742 | _realtimeHardwareHealthyFrameCount = 0; |
731 | 743 | return; |
732 | 744 | } |
733 | 745 |
|
734 | 746 | if (latencyUs < _realtimeHardwareFrameIntervalUs && |
735 | | - _realtimeHardwareFrameIntervalUs > XCWRealtimeHardwareMinimumFrameIntervalUs) { |
| 747 | + _realtimeHardwareFrameIntervalUs > minimumIntervalUs) { |
736 | 748 | _realtimeHardwareHealthyFrameCount += 1; |
737 | 749 | if (_realtimeHardwareHealthyFrameCount >= XCWRealtimeHardwareHealthyFrameWindow) { |
738 | 750 | uint64_t nextIntervalUs = _realtimeHardwareFrameIntervalUs > XCWRealtimeHardwareFrameIntervalStepUs |
739 | 751 | ? _realtimeHardwareFrameIntervalUs - XCWRealtimeHardwareFrameIntervalStepUs |
740 | | - : XCWRealtimeHardwareMinimumFrameIntervalUs; |
741 | | - _realtimeHardwareFrameIntervalUs = MAX(nextIntervalUs, XCWRealtimeHardwareMinimumFrameIntervalUs); |
| 752 | + : minimumIntervalUs; |
| 753 | + _realtimeHardwareFrameIntervalUs = MAX(nextIntervalUs, minimumIntervalUs); |
742 | 754 | _realtimeHardwareHealthyFrameCount = 0; |
743 | 755 | } |
744 | 756 | return; |
|
0 commit comments