Changeset 278272 in webkit
- Timestamp:
- May 31, 2021 12:28:32 AM (14 months ago)
- Location:
- trunk/Source/ThirdParty/libwebrtc
- Files:
-
- 2 edited
-
ChangeLog (modified) (1 diff)
-
Source/webrtc/sdk/objc/components/video_codec/RTCVideoEncoderH264.mm (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/ThirdParty/libwebrtc/ChangeLog
r277785 r278272 1 2021-05-31 Youenn Fablet <youenn@apple.com> 2 3 Use tighter bitrate allocation rules for WebRTC H264 software encoder 4 https://bugs.webkit.org/show_bug.cgi?id=226319 5 <rdar://73150695> 6 7 Reviewed by Eric Carlson. 8 9 Software H264 encoder is sometimes overshooting target bitrate in which case WebRTC backend will start dropping frames. 10 The encoder might then think it is on target and will not try to increase compression. 11 This makes it possible to be locked in a very low frame rate but high quality image situation. 12 It is often better to preserve frame rate and lower quality, the application could always lower frame rate if desired. 13 14 To do so, we detect whether the encoder is using software code path or not. 15 If so, we compute the actual frame rate and compare it with the expected frame rate. 16 If the actual frame rate is twice smaller or even below, we enter in a low frame rate mode. 17 Otherwise, we are in a regular frame rate mode where we apply the normal bitrate rules. 18 In the low frame rate mode, we divide the target bitrate by 3 so as to quickly recover frame rate. 19 20 This works well in situations where motion increases from time to time. 21 It is still not perfect for instance in case the video is muted and gets unmuted or when the scene is completely still and suddenly large motion happens. 22 In those cases, frame rate is recovered after a minute or so according my testing. 23 24 * Source/webrtc/sdk/objc/components/video_codec/RTCVideoEncoderH264.mm: 25 (-[RTCVideoEncoderH264 initWithCodecInfo:]): 26 (-[RTCVideoEncoderH264 encode:codecSpecificInfo:frameTypes:]): 27 (-[RTCVideoEncoderH264 resetCompressionSessionWithPixelFormat:]): 28 (-[RTCVideoEncoderH264 setEncoderBitrateBps:frameRate:]): 29 (-[RTCVideoEncoderH264 updateBitRateAccordingActualFrameRate]): 30 1 31 2021-05-20 Youenn Fablet <youenn@apple.com> 2 32 -
trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/components/video_codec/RTCVideoEncoderH264.mm
r277785 r278272 36 36 #include "rtc_base/buffer.h" 37 37 #include "rtc_base/logging.h" 38 #include "rtc_base/system/arch.h" 38 39 #include "rtc_base/time_utils.h" 39 40 #include "sdk/objc/components/video_codec/nalu_rewriter.h" … … 61 62 rotation:(RTCVideoRotation)rotation 62 63 isKeyFrameRequired:(bool)isKeyFrameRequired; 63 64 - (void)updateBitRateAccordingActualFrameRate; 64 65 @end 65 66 … … 76 77 77 78 const OSType kNV12PixelFormat = kCVPixelFormatType_420YpCbCr8BiPlanarFullRange; 79 80 const int kBelowFrameRateThreshold = 2; 81 const int kBelowFrameRateBitRateDecrease = 3; 78 82 79 83 // Struct that we pass to the encoder per frame to encode. We receive it again … … 350 354 bool _isKeyFrameRequired; 351 355 bool _isH264LowLatencyEncoderEnabled; 356 bool _isUsingSoftwareEncoder; 357 bool _isBelowExpectedFrameRate; 358 uint32_t _frameCount; 359 int64_t _lastFrameRateEstimationTime; 352 360 } 353 361 … … 378 386 _isKeyFrameRequired = false; 379 387 _isH264LowLatencyEncoderEnabled = true; 380 388 _isUsingSoftwareEncoder = false; 389 _isBelowExpectedFrameRate = false; 390 _frameCount = 0; 391 _lastFrameRateEstimationTime = 0; 381 392 return self; 382 393 } … … 442 453 if (_disableEncoding) { 443 454 return WEBRTC_VIDEO_CODEC_ERROR; 455 } 456 if (_isUsingSoftwareEncoder) { 457 [self updateBitRateAccordingActualFrameRate]; 444 458 } 445 459 … … 752 766 &_vcpCompressionSession); 753 767 } 768 #elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) && !(ENABLE_VCP_FOR_H264_BASELINE) && defined(WEBRTC_ARCH_X86_FAMILY) 769 CFBooleanRef hwaccl_enabled = nullptr; 770 if (status == noErr) { 771 auto result = VTSessionCopyProperty(_vtCompressionSession, kVTCompressionPropertyKey_UsingHardwareAcceleratedVideoEncoder, nullptr, &hwaccl_enabled); 772 _isUsingSoftwareEncoder = result == noErr ? !CFBooleanGetValue(hwaccl_enabled) : _width <= 480 && _height <= 480; 773 } 754 774 #else 755 775 // Provided encoder should be good enough. … … 840 860 - (void)setEncoderBitrateBps:(uint32_t)bitrateBps frameRate:(uint32_t)frameRate { 841 861 if ([self hasCompressionSession]) { 842 SetVTSessionProperty(_vtCompressionSession, _vcpCompressionSession, kVTCompressionPropertyKey_AverageBitRate, bitrateBps); 862 auto actualTarget = _isBelowExpectedFrameRate ? bitrateBps / kBelowFrameRateBitRateDecrease : bitrateBps; 863 SetVTSessionProperty(_vtCompressionSession, _vcpCompressionSession, kVTCompressionPropertyKey_AverageBitRate, actualTarget); 843 864 844 865 // With zero |_maxAllowedFrameRate|, we fall back to automatic frame rate detection. … … 850 871 // TODO(tkchin): Add a helper method to set array value. 851 872 int64_t dataLimitBytesPerSecondValue = 852 static_cast<int64_t>( bitrateBps* kLimitToAverageBitRateFactor / 8);873 static_cast<int64_t>(_isBelowExpectedFrameRate ? actualTarget / 8 : actualTarget * kLimitToAverageBitRateFactor / 8); 853 874 CFNumberRef bytesPerSecond = 854 875 CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &dataLimitBytesPerSecondValue); … … 874 895 _encoderFrameRate = frameRate; 875 896 } 897 } 898 899 - (void)updateBitRateAccordingActualFrameRate { 900 _frameCount++; 901 auto currentTime = rtc::TimeMillis(); 902 if (!_lastFrameRateEstimationTime) { 903 _lastFrameRateEstimationTime = currentTime; 904 return; 905 } 906 907 auto timeDifference = currentTime - _lastFrameRateEstimationTime; 908 909 // Let's not check too often. 910 if (timeDifference < 1000) { 911 return; 912 } 913 914 auto frameRate = _frameCount * 1000 / timeDifference; 915 _lastFrameRateEstimationTime = currentTime; 916 _frameCount = 0; 917 918 bool isBelow = frameRate * kBelowFrameRateThreshold < _encoderFrameRate; 919 if (isBelow == _isBelowExpectedFrameRate) { 920 return; 921 } 922 923 _isBelowExpectedFrameRate = isBelow; 924 [self setEncoderBitrateBps:_encoderBitrateBps frameRate:_encoderFrameRate]; 876 925 } 877 926
Note: See TracChangeset
for help on using the changeset viewer.