From cca2c0e6bbcb749b98c4aa104ad84aae809e0656 Mon Sep 17 00:00:00 2001 From: Mike Woodworth Date: Sat, 19 Nov 2022 22:46:00 -0800 Subject: [PATCH] fixes crash caused by race derefing pixelbufferpool ivar while being destroyed and replaced by format change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit removes cached pixelbufferpool and instead retrieves current pool from the compressionSession each time (as recommended by apple docs) Bug: webrtc:14688 Change-Id: I2244e69e7f32b912021db0905b9d5867d0bf6357 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/284240 Reviewed-by: Kári Helgason Commit-Queue: Kári Helgason Cr-Commit-Position: refs/heads/main@{#38920} --- AUTHORS | 1 + .../video_codec/RTCVideoEncoderH264.mm | 29 ++++++++++++------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/AUTHORS b/AUTHORS index bd7ab248c2..f79b6adc32 100644 --- a/AUTHORS +++ b/AUTHORS @@ -86,6 +86,7 @@ Miguel Paris Mike Gilbert Mike Wei Min Wang +Mike Woodworth Mo Zanaty Nico Schlumprecht Niek van der Maas diff --git a/sdk/objc/components/video_codec/RTCVideoEncoderH264.mm b/sdk/objc/components/video_codec/RTCVideoEncoderH264.mm index 7dbbfaf019..2160d79ae5 100644 --- a/sdk/objc/components/video_codec/RTCVideoEncoderH264.mm +++ b/sdk/objc/components/video_codec/RTCVideoEncoderH264.mm @@ -129,7 +129,14 @@ bool CopyVideoFrameToNV12PixelBuffer(id frameBuffe return true; } -CVPixelBufferRef CreatePixelBuffer(CVPixelBufferPoolRef pixel_buffer_pool) { +CVPixelBufferRef CreatePixelBuffer(VTCompressionSessionRef compression_session) { + if (!compression_session) { + RTC_LOG(LS_ERROR) << "Failed to get compression session."; + return nullptr; + } + CVPixelBufferPoolRef pixel_buffer_pool = + VTCompressionSessionGetPixelBufferPool(compression_session); + if (!pixel_buffer_pool) { RTC_LOG(LS_ERROR) << "Failed to get pixel buffer pool."; return nullptr; @@ -323,7 +330,6 @@ NSUInteger GetMaxSampleRate(const webrtc::H264ProfileLevelId &profile_level_id) int32_t _width; int32_t _height; VTCompressionSessionRef _compressionSession; - CVPixelBufferPoolRef _pixelBufferPool; RTCVideoCodecMode _mode; webrtc::H264BitstreamParser _h264BitstreamParser; @@ -412,7 +418,7 @@ NSUInteger GetMaxSampleRate(const webrtc::H264ProfileLevelId &profile_level_id) CVBufferRetain(pixelBuffer); } else { // Cropping required, we need to crop and scale to a new pixel buffer. - pixelBuffer = CreatePixelBuffer(_pixelBufferPool); + pixelBuffer = CreatePixelBuffer(_compressionSession); if (!pixelBuffer) { return WEBRTC_VIDEO_CODEC_ERROR; } @@ -437,7 +443,8 @@ NSUInteger GetMaxSampleRate(const webrtc::H264ProfileLevelId &profile_level_id) // We did not have a native frame buffer RTC_DCHECK_EQ(frame.width, _width); RTC_DCHECK_EQ(frame.height, _height); - pixelBuffer = CreatePixelBuffer(_pixelBufferPool); + + pixelBuffer = CreatePixelBuffer(_compressionSession); if (!pixelBuffer) { return WEBRTC_VIDEO_CODEC_ERROR; } @@ -574,8 +581,15 @@ NSUInteger GetMaxSampleRate(const webrtc::H264ProfileLevelId &profile_level_id) if (_compressionSession) { // The pool attribute `kCVPixelBufferPixelFormatTypeKey` can contain either an array of pixel // formats or a single pixel format. + + CVPixelBufferPoolRef pixelBufferPool = + VTCompressionSessionGetPixelBufferPool(_compressionSession); + if (!pixelBufferPool) { + return NO; + } + NSDictionary *poolAttributes = - (__bridge NSDictionary *)CVPixelBufferPoolGetPixelBufferAttributes(_pixelBufferPool); + (__bridge NSDictionary *)CVPixelBufferPoolGetPixelBufferAttributes(pixelBufferPool); id pixelFormats = [poolAttributes objectForKey:(__bridge NSString *)kCVPixelBufferPixelFormatTypeKey]; NSArray *compressionSessionPixelFormats = nil; @@ -655,10 +669,6 @@ NSUInteger GetMaxSampleRate(const webrtc::H264ProfileLevelId &profile_level_id) #endif [self configureCompressionSession]; - // The pixel buffer pool is dependent on the compression session so if the session is reset, the - // pool should be reset as well. - _pixelBufferPool = VTCompressionSessionGetPixelBufferPool(_compressionSession); - return WEBRTC_VIDEO_CODEC_OK; } @@ -689,7 +699,6 @@ NSUInteger GetMaxSampleRate(const webrtc::H264ProfileLevelId &profile_level_id) VTCompressionSessionInvalidate(_compressionSession); CFRelease(_compressionSession); _compressionSession = nullptr; - _pixelBufferPool = nullptr; } }