Title: [281868] trunk/Source
Revision
281868
Author
[email protected]
Date
2021-09-01 13:02:04 -0700 (Wed, 01 Sep 2021)

Log Message

[WebRTC] Leak or over-release of CFPixelBufferRef returned from webrtc::createPixelBufferFromFrame()
<https://webkit.org/b/229661>
<rdar://problem/82507827>

Reviewed by Eric Carlson.

Source/ThirdParty/libwebrtc:

* Configurations/libwebrtc.iOS.exp:
* Configurations/libwebrtc.iOSsim.exp:
* Configurations/libwebrtc.mac.exp:
- Update export symbol for rename from pixelBufferFromFrame() to
  createPixelBufferFromFrame().

* Source/webrtc/sdk/WebKit/WebKitDecoderReceiver.cpp:
(webrtc::WebKitDecoderReceiver::Decoded):
- Update to call renamed createPixelBufferFromFrame() function.
  This method already released the returned CFPixelBufferRef, so
  it did not require any more changes.  Also, its functor
  returned a +1 retained CFPixelBufferRef, so it did not need to
  change, either.

* Source/webrtc/sdk/WebKit/WebKitUtilities.h:
- Include <CoreFoundation/CFBase.h> for CF_RETURNS_RETAINED.
(webrtc::createPixelBufferFromFrame):
- Name const std::function<>& as `createPixelBuffer` to describe
  its behavior.
- Add CF_RETURNS_RETAINED to describe memory management of the
  returned object.
* Source/webrtc/sdk/WebKit/WebKitUtilities.mm:
(webrtc::pixelBufferFromFrame):
- Rename to createPixelBufferFromFrame().
(webrtc::createPixelBufferFromFrame):
- Rename from pixelBufferFromFrame().
- Rename const std::function<>& argument to `createPixelBuffer`
  to describe its behavior of returning a +1 retained
  CVPixelBufferRef.
- Fix last return statement to return a +1 retained
  CFPixelBufferRef if it is not nullptr.

* WebKit/libwebrtc.diff:
- Update diff for WebKitUtilities.{h|mm}.

Source/WebCore:

* platform/mediastream/mac/RealtimeIncomingVideoSourceCocoa.mm:
(WebCore::RealtimeIncomingVideoSourceCocoa::pixelBufferFromVideoFrame):
- Use adoptCF() to prevent a leak since
  webrtc::createPixelBufferFromFrame() always returns a +1
  retained CVPixelBufferRef now.
- Change the functor to return a +1 retained CVPixelBufferRef.

Source/WebKit:

* WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp:
(WebKit::LibWebRTCCodecs::encodeFrame):
- Use adoptCF() to prevent a leak since
  webrtc::createPixelBufferFromFrame() always returns a +1
  retained CVPixelBufferRef now.
- Change the functor to return a +1 retained CVPixelBufferRef.
- Reuse `pixelBuffer` to store the converted CVPixelBufferRef
  since this object needs to be kept alive until after the
  send() method is called.

Modified Paths

Diff

Modified: trunk/Source/ThirdParty/libwebrtc/ChangeLog (281867 => 281868)


--- trunk/Source/ThirdParty/libwebrtc/ChangeLog	2021-09-01 19:50:04 UTC (rev 281867)
+++ trunk/Source/ThirdParty/libwebrtc/ChangeLog	2021-09-01 20:02:04 UTC (rev 281868)
@@ -1,3 +1,46 @@
+2021-09-01  David Kilzer  <[email protected]>
+
+        [WebRTC] Leak or over-release of CFPixelBufferRef returned from webrtc::createPixelBufferFromFrame()
+        <https://webkit.org/b/229661>
+        <rdar://problem/82507827>
+
+        Reviewed by Eric Carlson.
+
+        * Configurations/libwebrtc.iOS.exp:
+        * Configurations/libwebrtc.iOSsim.exp:
+        * Configurations/libwebrtc.mac.exp:
+        - Update export symbol for rename from pixelBufferFromFrame() to
+          createPixelBufferFromFrame().
+
+        * Source/webrtc/sdk/WebKit/WebKitDecoderReceiver.cpp:
+        (webrtc::WebKitDecoderReceiver::Decoded):
+        - Update to call renamed createPixelBufferFromFrame() function.
+          This method already released the returned CFPixelBufferRef, so
+          it did not require any more changes.  Also, its functor
+          returned a +1 retained CFPixelBufferRef, so it did not need to
+          change, either.
+
+        * Source/webrtc/sdk/WebKit/WebKitUtilities.h:
+        - Include <CoreFoundation/CFBase.h> for CF_RETURNS_RETAINED.
+        (webrtc::createPixelBufferFromFrame):
+        - Name const std::function<>& as `createPixelBuffer` to describe
+          its behavior.
+        - Add CF_RETURNS_RETAINED to describe memory management of the
+          returned object.
+        * Source/webrtc/sdk/WebKit/WebKitUtilities.mm:
+        (webrtc::pixelBufferFromFrame):
+        - Rename to createPixelBufferFromFrame().
+        (webrtc::createPixelBufferFromFrame):
+        - Rename from pixelBufferFromFrame().
+        - Rename const std::function<>& argument to `createPixelBuffer`
+          to describe its behavior of returning a +1 retained
+          CVPixelBufferRef.
+        - Fix last return statement to return a +1 retained
+          CFPixelBufferRef if it is not nullptr.
+
+        * WebKit/libwebrtc.diff:
+        - Update diff for WebKitUtilities.{h|mm}.
+
 2021-08-19  Youenn Fablet  <[email protected]>
 
         Add support for RTCDtlsTransport

Modified: trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.iOS.exp (281867 => 281868)


--- trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.iOS.exp	2021-09-01 19:50:04 UTC (rev 281867)
+++ trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.iOS.exp	2021-09-01 20:02:04 UTC (rev 281868)
@@ -97,6 +97,7 @@
 __ZN6webrtc32CreateBuiltinAudioEncoderFactoryEv
 __ZN6webrtc27SessionDescriptionInterface16RemoveCandidatesERKNSt3__16vectorIN7cricket9CandidateENS1_9allocatorIS4_EEEE
 __ZNK6webrtc21IceCandidateInterface10server_urlEv
+__ZN6webrtc18pixelBufferToFrameEP10__CVBuffer
 __ZN6webrtc20setApplicationStatusEb
 __ZN6webrtc26createWebKitDecoderFactoryENS_10WebKitH265ENS_9WebKitVP9ENS_12WebKitVP9VTBE
 __ZN6webrtc26createWebKitEncoderFactoryENS_10WebKitH265ENS_9WebKitVP9ENS_20WebKitH264LowLatencyE
@@ -103,8 +104,7 @@
 __ZN6webrtc29setH264HardwareEncoderAllowedEb
 __ZN6webrtc24registerWebKitVP8DecoderEv
 __ZN6webrtc24registerWebKitVP9DecoderEv
-__ZN6webrtc20pixelBufferFromFrameERKNS_10VideoFrameERKNSt3__18functionIFP10__CVBuffermmNS_10BufferTypeEEEE
-__ZN6webrtc18pixelBufferToFrameEP10__CVBuffer
+__ZN6webrtc26createPixelBufferFromFrameERKNS_10VideoFrameERKNSt3__18functionIFP10__CVBuffermmNS_10BufferTypeEEEE
 __ZN3rtc24BasicPacketSocketFactory19CreateAsyncResolverEv
 __ZN3rtc24BasicPacketSocketFactoryC2Ev
 __ZN3rtc24BasicPacketSocketFactoryD2Ev

Modified: trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.iOSsim.exp (281867 => 281868)


--- trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.iOSsim.exp	2021-09-01 19:50:04 UTC (rev 281867)
+++ trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.iOSsim.exp	2021-09-01 20:02:04 UTC (rev 281868)
@@ -97,6 +97,7 @@
 __ZN6webrtc32CreateBuiltinAudioEncoderFactoryEv
 __ZN6webrtc27SessionDescriptionInterface16RemoveCandidatesERKNSt3__16vectorIN7cricket9CandidateENS1_9allocatorIS4_EEEE
 __ZNK6webrtc21IceCandidateInterface10server_urlEv
+__ZN6webrtc18pixelBufferToFrameEP10__CVBuffer
 __ZN6webrtc20setApplicationStatusEb
 __ZN6webrtc26createWebKitDecoderFactoryENS_10WebKitH265ENS_9WebKitVP9ENS_12WebKitVP9VTBE
 __ZN6webrtc26createWebKitEncoderFactoryENS_10WebKitH265ENS_9WebKitVP9ENS_20WebKitH264LowLatencyE
@@ -103,8 +104,7 @@
 __ZN6webrtc29setH264HardwareEncoderAllowedEb
 __ZN6webrtc24registerWebKitVP8DecoderEv
 __ZN6webrtc24registerWebKitVP9DecoderEv
-__ZN6webrtc20pixelBufferFromFrameERKNS_10VideoFrameERKNSt3__18functionIFP10__CVBuffermmNS_10BufferTypeEEEE
-__ZN6webrtc18pixelBufferToFrameEP10__CVBuffer
+__ZN6webrtc26createPixelBufferFromFrameERKNS_10VideoFrameERKNSt3__18functionIFP10__CVBuffermmNS_10BufferTypeEEEE
 __ZN3rtc24BasicPacketSocketFactory19CreateAsyncResolverEv
 __ZN3rtc24BasicPacketSocketFactoryC2Ev
 __ZN3rtc24BasicPacketSocketFactoryD2Ev

Modified: trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.mac.exp (281867 => 281868)


--- trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.mac.exp	2021-09-01 19:50:04 UTC (rev 281867)
+++ trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.mac.exp	2021-09-01 20:02:04 UTC (rev 281868)
@@ -97,6 +97,7 @@
 __ZN6webrtc32CreateBuiltinAudioEncoderFactoryEv
 __ZN6webrtc27SessionDescriptionInterface16RemoveCandidatesERKNSt3__16vectorIN7cricket9CandidateENS1_9allocatorIS4_EEEE
 __ZNK6webrtc21IceCandidateInterface10server_urlEv
+__ZN6webrtc18pixelBufferToFrameEP10__CVBuffer
 __ZN6webrtc20setApplicationStatusEb
 __ZN6webrtc26createWebKitDecoderFactoryENS_10WebKitH265ENS_9WebKitVP9ENS_12WebKitVP9VTBE
 __ZN6webrtc26createWebKitEncoderFactoryENS_10WebKitH265ENS_9WebKitVP9ENS_20WebKitH264LowLatencyE
@@ -103,8 +104,7 @@
 __ZN6webrtc29setH264HardwareEncoderAllowedEb
 __ZN6webrtc24registerWebKitVP8DecoderEv
 __ZN6webrtc24registerWebKitVP9DecoderEv
-__ZN6webrtc20pixelBufferFromFrameERKNS_10VideoFrameERKNSt3__18functionIFP10__CVBuffermmNS_10BufferTypeEEEE
-__ZN6webrtc18pixelBufferToFrameEP10__CVBuffer
+__ZN6webrtc26createPixelBufferFromFrameERKNS_10VideoFrameERKNSt3__18functionIFP10__CVBuffermmNS_10BufferTypeEEEE
 __ZN3rtc24BasicPacketSocketFactory19CreateAsyncResolverEv
 __ZN3rtc24BasicPacketSocketFactoryC2Ev
 __ZN3rtc24BasicPacketSocketFactoryD2Ev

Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/WebKitDecoderReceiver.cpp (281867 => 281868)


--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/WebKitDecoderReceiver.cpp	2021-09-01 19:50:04 UTC (rev 281867)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/WebKitDecoderReceiver.cpp	2021-09-01 20:02:04 UTC (rev 281868)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2020-2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -160,7 +160,7 @@
 
 int32_t WebKitDecoderReceiver::Decoded(VideoFrame& frame)
 {
-    auto pixelBuffer = pixelBufferFromFrame(frame, [this](size_t width, size_t height, BufferType type) -> CVPixelBufferRef {
+    auto pixelBuffer = createPixelBufferFromFrame(frame, [this](size_t width, size_t height, BufferType type) -> CVPixelBufferRef {
         auto pixelBufferPool = this->pixelBufferPool(width, height, type == BufferType::I010);
         if (!pixelBufferPool)
             return nullptr;

Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/WebKitUtilities.h (281867 => 281868)


--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/WebKitUtilities.h	2021-09-01 19:50:04 UTC (rev 281867)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/WebKitUtilities.h	2021-09-01 20:02:04 UTC (rev 281868)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2018-2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -27,6 +27,7 @@
 
 #include "api/video/video_frame_buffer.h"
 #include "api/scoped_refptr.h"
+#include <CoreFoundation/CFBase.h>
 #include <functional>
 
 using CVPixelBufferRef = struct __CVBuffer*;
@@ -46,7 +47,7 @@
 bool isH264HardwareEncoderAllowed();
 
 enum class BufferType { I420, I010 };
-CVPixelBufferRef pixelBufferFromFrame(const VideoFrame&, const std::function<CVPixelBufferRef(size_t, size_t, BufferType)>&);
+CVPixelBufferRef createPixelBufferFromFrame(const VideoFrame&, const std::function<CVPixelBufferRef(size_t, size_t, BufferType)>& createPixelBuffer) CF_RETURNS_RETAINED;
 rtc::scoped_refptr<webrtc::VideoFrameBuffer> pixelBufferToFrame(CVPixelBufferRef);
 
 }

Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/WebKitUtilities.mm (281867 => 281868)


--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/WebKitUtilities.mm	2021-09-01 19:50:04 UTC (rev 281867)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/WebKitUtilities.mm	2021-09-01 20:02:04 UTC (rev 281868)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2018-2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -144,7 +144,7 @@
     return true;
 }
 
-CVPixelBufferRef pixelBufferFromFrame(const VideoFrame& frame, const std::function<CVPixelBufferRef(size_t, size_t, BufferType)>& makePixelBuffer)
+CVPixelBufferRef createPixelBufferFromFrame(const VideoFrame& frame, const std::function<CVPixelBufferRef(size_t, size_t, BufferType)>& createPixelBuffer)
 {
     auto buffer = frame.video_frame_buffer();
     if (buffer->type() != VideoFrameBuffer::Type::kNative) {
@@ -154,7 +154,7 @@
             return nullptr;
         }
 
-        auto pixelBuffer = makePixelBuffer(buffer->width(), buffer->height(), type == VideoFrameBuffer::Type::kI420 ? BufferType::I420 : BufferType::I010);
+        auto pixelBuffer = createPixelBuffer(buffer->width(), buffer->height(), type == VideoFrameBuffer::Type::kI420 ? BufferType::I420 : BufferType::I010);
         if (!pixelBuffer) {
             RTC_LOG(WARNING) << "Pixel buffer creation failed.";
             return nullptr;
@@ -172,7 +172,7 @@
         return nullptr;
 
     auto *rtcPixelBuffer = (RTCCVPixelBuffer *)frameBuffer;
-    return rtcPixelBuffer.pixelBuffer;
+    return CVPixelBufferRetain(rtcPixelBuffer.pixelBuffer);
 }
 
 }

Modified: trunk/Source/ThirdParty/libwebrtc/WebKit/libwebrtc.diff (281867 => 281868)


--- trunk/Source/ThirdParty/libwebrtc/WebKit/libwebrtc.diff	2021-09-01 19:50:04 UTC (rev 281867)
+++ trunk/Source/ThirdParty/libwebrtc/WebKit/libwebrtc.diff	2021-09-01 20:02:04 UTC (rev 281868)
@@ -944,9 +944,9 @@
 index 00000000000..ef1456eddd3
 --- /dev/null
 +++ b/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/WebKitUtilities.h
-@@ -0,0 +1,54 @@
+@@ -0,0 +1,53 @@
 +/*
-+ * Copyright (C) 2018 Apple Inc. All rights reserved.
++ * Copyright (C) 2018-2021 Apple Inc. All rights reserved.
 + *
 + * Redistribution and use in source and binary forms, with or without
 + * modification, are permitted provided that the following conditions
@@ -973,29 +973,28 @@
 +#pragma once
 +
 +#include "api/video/video_frame_buffer.h"
-+#include "rtc_base/scoped_ref_ptr.h"
-+#include "webrtc/media/engine/webrtcvideodecoderfactory.h"
-+#include "webrtc/media/engine/webrtcvideoencoderfactory.h"
++#include "api/scoped_refptr.h"
++#include <CoreFoundation/CFBase.h>
++#include <functional>
 +
-+typedef struct __CVBuffer* CVPixelBufferRef;
++using CVPixelBufferRef = struct __CVBuffer*;
 +
 +namespace webrtc {
 +
-+class VideoDecoderFactory;
-+class VideoEncoderFactory;
 +class VideoFrame;
 +
-+enum class WebKitCodecSupport { H264, H264AndVP8 };
++enum class WebKitH265 { Off, On };
++enum class WebKitVP9 { Off, Profile0, Profile0And2 };
++enum class WebKitVP9VTB { Off, On };
++enum class WebKitH264LowLatency { Off, On };
 +
-+std::unique_ptr<webrtc::VideoEncoderFactory> createWebKitEncoderFactory(WebKitCodecSupport);
-+std::unique_ptr<webrtc::VideoDecoderFactory> createWebKitDecoderFactory(WebKitCodecSupport);
-+
 +void setApplicationStatus(bool isActive);
 +
 +void setH264HardwareEncoderAllowed(bool);
 +bool isH264HardwareEncoderAllowed();
 +
-+CVPixelBufferRef pixelBufferFromFrame(const VideoFrame&, const std::function<CVPixelBufferRef(size_t, size_t)>&);
++enum class BufferType { I420, I010 };
++CVPixelBufferRef createPixelBufferFromFrame(const VideoFrame&, const std::function<CVPixelBufferRef(size_t, size_t, BufferType)>& createPixelBuffer) CF_RETURNS_RETAINED;
 +rtc::scoped_refptr<webrtc::VideoFrameBuffer> pixelBufferToFrame(CVPixelBufferRef);
 +
 +}
@@ -1004,9 +1003,9 @@
 index 00000000000..65eefa36f2d
 --- /dev/null
 +++ b/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/WebKitUtilities.mm
-@@ -0,0 +1,185 @@
+@@ -0,0 +1,178 @@
 +/*
-+ * Copyright (C) 2018 Apple Inc. All rights reserved.
++ * Copyright (C) 2018-2021 Apple Inc. All rights reserved.
 + *
 + * Redistribution and use in source and binary forms, with or without
 + * modification, are permitted provided that the following conditions
@@ -1032,68 +1031,15 @@
 +
 +#include "WebKitUtilities.h"
 +
-+//#include "Common/RTCUIApplicationStatusObserver.h"
-+#import "WebRTC/RTCVideoCodecH264.h"
-+
 +#include "api/video/video_frame.h"
 +#include "native/src/objc_frame_buffer.h"
++#include "rtc_base/logging.h"
 +#include "third_party/libyuv/include/libyuv/convert_from.h"
-+#include "webrtc/rtc_base/checks.h"
-+#include "Framework/Headers/WebRTC/RTCVideoCodecFactory.h"
-+#include "Framework/Headers/WebRTC/RTCVideoFrame.h"
++#include "libyuv/cpu_id.h"
++#include "libyuv/row.h"
 +#include "Framework/Headers/WebRTC/RTCVideoFrameBuffer.h"
-+#include "Framework/Native/api/video_decoder_factory.h"
-+#include "Framework/Native/api/video_encoder_factory.h"
-+/*
-+#if !defined(WEBRTC_IOS)
-+__attribute__((objc_runtime_name("WK_RTCUIApplicationStatusObserver")))
-+@interface RTCUIApplicationStatusObserver : NSObject
++#include "third_party/libyuv/include/libyuv.h"
 +
-++ (instancetype)sharedInstance;
-++ (void)prepareForUse;
-+
-+- (BOOL)isApplicationActive;
-+
-+@end
-+#endif
-+
-+@implementation RTCUIApplicationStatusObserver {
-+    BOOL _isActive;
-+}
-+
-++ (instancetype)sharedInstance {
-+    static id sharedInstance;
-+    static dispatch_once_t onceToken;
-+    dispatch_once(&onceToken, ^{
-+        sharedInstance = [[self alloc] init];
-+    });
-+
-+    return sharedInstance;
-+}
-+
-++ (void)prepareForUse {
-+    __unused RTCUIApplicationStatusObserver *observer = [self sharedInstance];
-+}
-+
-+- (id)init {
-+    _isActive = YES;
-+    return self;
-+}
-+
-+- (void)setActive {
-+    _isActive = YES;
-+}
-+
-+- (void)setInactive {
-+    _isActive = NO;
-+}
-+
-+- (BOOL)isApplicationActive {
-+    return _isActive;
-+}
-+
-+@end
-+*/
 +namespace webrtc {
 +
 +void setApplicationStatus(bool isActive)
@@ -1106,33 +1052,6 @@
 + */
 +}
 +
-+std::unique_ptr<webrtc::VideoEncoderFactory> createWebKitEncoderFactory(WebKitCodecSupport codecSupport)
-+{
-+#if ENABLE_VCP_ENCODER
-+    static std::once_flag onceFlag;
-+    std::call_once(onceFlag, [] {
-+        webrtc::VPModuleInitialize();
-+    });
-+#endif
-+    return ObjCToNativeVideoEncoderFactory(codecSupport == WebKitCodecSupport::H264AndVP8 ? [[RTCDefaultVideoEncoderFactory alloc] init] : [[RTCVideoEncoderFactoryH264 alloc] init]);
-+}
-+
-+std::unique_ptr<webrtc::VideoDecoderFactory> createWebKitDecoderFactory(WebKitCodecSupport codecSupport)
-+{
-+    return ObjCToNativeVideoDecoderFactory(codecSupport == WebKitCodecSupport::H264AndVP8 ? [[RTCDefaultVideoDecoderFactory alloc] init] : [[RTCVideoDecoderFactoryH264 alloc] init]);
-+}
-+
-+static bool h264HardwareEncoderAllowed = true;
-+void setH264HardwareEncoderAllowed(bool allowed)
-+{
-+    h264HardwareEncoderAllowed = allowed;
-+}
-+
-+bool isH264HardwareEncoderAllowed()
-+{
-+    return h264HardwareEncoderAllowed;
-+}
-+
 +rtc::scoped_refptr<webrtc::VideoFrameBuffer> pixelBufferToFrame(CVPixelBufferRef pixelBuffer)
 +{
 +    RTCCVPixelBuffer *frameBuffer = [[RTCCVPixelBuffer alloc] initWithPixelBuffer:pixelBuffer];
@@ -1139,7 +1058,7 @@
 +    return new rtc::RefCountedObject<ObjCFrameBuffer>(frameBuffer);
 +}
 +
-+static bool CopyVideoFrameToPixelBuffer(const rtc::scoped_refptr<webrtc::I420BufferInterface>& frame, CVPixelBufferRef pixel_buffer) {
++static bool CopyVideoFrameToPixelBuffer(const webrtc::I420BufferInterface* frame, CVPixelBufferRef pixel_buffer) {
 +    RTC_DCHECK(pixel_buffer);
 +    RTC_DCHECK(CVPixelBufferGetPixelFormatType(pixel_buffer) == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange || CVPixelBufferGetPixelFormatType(pixel_buffer) == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange);
 +    RTC_DCHECK_EQ(CVPixelBufferGetHeightOfPlane(pixel_buffer, 0), static_cast<size_t>(frame->height()));
@@ -1148,12 +1067,27 @@
 +    if (CVPixelBufferLockBaseAddress(pixel_buffer, 0) != kCVReturnSuccess)
 +        return false;
 +
++    auto src_width_y = frame->width();
++    auto src_height_y = frame->height();
++    auto src_width_uv = frame->ChromaWidth();
++    auto src_height_uv = frame->ChromaHeight();
++
 +    uint8_t* dst_y = reinterpret_cast<uint8_t*>(CVPixelBufferGetBaseAddressOfPlane(pixel_buffer, 0));
 +    int dst_stride_y = CVPixelBufferGetBytesPerRowOfPlane(pixel_buffer, 0);
++    auto dst_width_y = CVPixelBufferGetWidthOfPlane(pixel_buffer, 0);
++    auto dst_height_y = CVPixelBufferGetHeightOfPlane(pixel_buffer, 0);
 +
 +    uint8_t* dst_uv = reinterpret_cast<uint8_t*>(CVPixelBufferGetBaseAddressOfPlane(pixel_buffer, 1));
 +    int dst_stride_uv = CVPixelBufferGetBytesPerRowOfPlane(pixel_buffer, 1);
++    auto dst_width_uv = CVPixelBufferGetWidthOfPlane(pixel_buffer, 1);
++    auto dst_height_uv = CVPixelBufferGetHeightOfPlane(pixel_buffer, 1);
 +
++    if (src_width_y != dst_width_y
++        || src_height_y != dst_height_y
++        || src_width_uv != dst_width_uv
++        || src_height_uv != dst_height_uv)
++        return false;
++
 +    int result = libyuv::I420ToNV12(
 +        frame->DataY(), frame->StrideY(),
 +        frame->DataU(), frame->StrideU(),
@@ -1169,24 +1103,82 @@
 +    return true;
 +}
 +
++static bool CopyVideoFrameToPixelBuffer(const webrtc::I010BufferInterface* frame, CVPixelBufferRef pixel_buffer)
++{
++    RTC_DCHECK(pixel_buffer);
++    RTC_DCHECK(CVPixelBufferGetPixelFormatType(pixel_buffer) == kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange || CVPixelBufferGetPixelFormatType(pixel_buffer) == kCVPixelFormatType_420YpCbCr10BiPlanarFullRange);
++    RTC_DCHECK_EQ(CVPixelBufferGetHeightOfPlane(pixel_buffer, 0), static_cast<size_t>(frame->height()));
++    RTC_DCHECK_EQ(CVPixelBufferGetWidthOfPlane(pixel_buffer, 0), static_cast<size_t>(frame->width()));
 +
-+CVPixelBufferRef pixelBufferFromFrame(const VideoFrame& frame, const std::function<CVPixelBufferRef(size_t, size_t)>& makePixelBuffer)
++    if (CVPixelBufferLockBaseAddress(pixel_buffer, 0) != kCVReturnSuccess)
++        return false;
++
++    auto src_y = const_cast<uint16_t*>(frame->DataY());
++    auto src_u = const_cast<uint16_t*>(frame->DataU());
++    auto src_v = const_cast<uint16_t*>(frame->DataV());
++    auto src_width_y = frame->width();
++    auto src_height_y = frame->height();
++    auto src_stride_y = frame->StrideY();
++    auto src_width_uv = frame->ChromaWidth();
++    auto src_height_uv = frame->ChromaHeight();
++    auto src_stride_u = frame->StrideU();
++    auto src_stride_v = frame->StrideV();
++
++    auto* dst_y = reinterpret_cast<uint16_t*>(CVPixelBufferGetBaseAddressOfPlane(pixel_buffer, 0));
++    auto dst_stride_y = CVPixelBufferGetBytesPerRowOfPlane(pixel_buffer, 0) / 2;
++    auto dst_width_y = CVPixelBufferGetWidthOfPlane(pixel_buffer, 0);
++    auto dst_height_y = CVPixelBufferGetHeightOfPlane(pixel_buffer, 0);
++
++    auto* dst_uv = reinterpret_cast<uint16_t*>(CVPixelBufferGetBaseAddressOfPlane(pixel_buffer, 1));
++    auto dst_stride_uv = CVPixelBufferGetBytesPerRowOfPlane(pixel_buffer, 1) / 2;
++    auto dst_width_uv = CVPixelBufferGetWidthOfPlane(pixel_buffer, 1);
++    auto dst_height_uv = CVPixelBufferGetHeightOfPlane(pixel_buffer, 1);
++
++    if (src_width_y != dst_width_y
++        || src_height_y != dst_height_y
++        || src_width_uv != dst_width_uv
++        || src_height_uv != dst_height_uv)
++        return false;
++
++    libyuv::I010ToP010(src_y, src_stride_y,
++                       src_u, src_stride_u,
++                       src_v, src_stride_v,
++                       dst_y, dst_stride_y, dst_uv, dst_stride_uv,
++                       src_width_y, src_height_y);
++
++    CVPixelBufferUnlockBaseAddress(pixel_buffer, 0);
++    return true;
++}
++
++CVPixelBufferRef createPixelBufferFromFrame(const VideoFrame& frame, const std::function<CVPixelBufferRef(size_t, size_t, BufferType)>& createPixelBuffer)
 +{
-+    if (frame.video_frame_buffer()->type() != VideoFrameBuffer::Type::kNative) {
-+        rtc::scoped_refptr<const I420BufferInterface> buffer = frame.video_frame_buffer()->GetI420();
++    auto buffer = frame.video_frame_buffer();
++    if (buffer->type() != VideoFrameBuffer::Type::kNative) {
++        auto type = buffer->type();
++        if (type != VideoFrameBuffer::Type::kI420 && type != VideoFrameBuffer::Type::kI010) {
++            RTC_LOG(WARNING) << "Video frame buffer type is not expected.";
++            return nullptr;
++        }
 +
-+        auto pixelBuffer = makePixelBuffer(buffer->width(), buffer->height());
-+        if (pixelBuffer)
-+            CopyVideoFrameToPixelBuffer(frame.video_frame_buffer()->GetI420(), pixelBuffer);
++        auto pixelBuffer = createPixelBuffer(buffer->width(), buffer->height(), type == VideoFrameBuffer::Type::kI420 ? BufferType::I420 : BufferType::I010);
++        if (!pixelBuffer) {
++            RTC_LOG(WARNING) << "Pixel buffer creation failed.";
++            return nullptr;
++        }
++
++        if (type == VideoFrameBuffer::Type::kI420)
++            CopyVideoFrameToPixelBuffer(buffer->GetI420(), pixelBuffer);
++        else
++            CopyVideoFrameToPixelBuffer(buffer->GetI010(), pixelBuffer);
 +        return pixelBuffer;
 +    }
 +
-+    auto *frameBuffer = static_cast<ObjCFrameBuffer*>(frame.video_frame_buffer().get())->wrapped_frame_buffer();
++    auto *frameBuffer = static_cast<ObjCFrameBuffer*>(buffer.get())->wrapped_frame_buffer();
 +    if (![frameBuffer isKindOfClass:[RTCCVPixelBuffer class]])
 +        return nullptr;
 +
 +    auto *rtcPixelBuffer = (RTCCVPixelBuffer *)frameBuffer;
-+    return rtcPixelBuffer.pixelBuffer;
++    return rtcPixelBuffer.pixelBuffer ? CVPixelBufferRetain(rtcPixelBuffer.pixelBuffer) : nullptr;
 +}
 +
 +}

Modified: trunk/Source/WebCore/ChangeLog (281867 => 281868)


--- trunk/Source/WebCore/ChangeLog	2021-09-01 19:50:04 UTC (rev 281867)
+++ trunk/Source/WebCore/ChangeLog	2021-09-01 20:02:04 UTC (rev 281868)
@@ -1,3 +1,18 @@
+2021-09-01  David Kilzer  <[email protected]>
+
+        [WebRTC] Leak or over-release of CFPixelBufferRef returned from webrtc::createPixelBufferFromFrame()
+        <https://webkit.org/b/229661>
+        <rdar://problem/82507827>
+
+        Reviewed by Eric Carlson.
+
+        * platform/mediastream/mac/RealtimeIncomingVideoSourceCocoa.mm:
+        (WebCore::RealtimeIncomingVideoSourceCocoa::pixelBufferFromVideoFrame):
+        - Use adoptCF() to prevent a leak since
+          webrtc::createPixelBufferFromFrame() always returns a +1
+          retained CVPixelBufferRef now.
+        - Change the functor to return a +1 retained CVPixelBufferRef.
+
 2021-09-01  Fujii Hironori  <[email protected]>
 
         REGRESSION(r280928) The smooth keyboard scrolling is unconditionally enabled for PageUp and PageDown keys

Modified: trunk/Source/WebCore/platform/mediastream/mac/RealtimeIncomingVideoSourceCocoa.mm (281867 => 281868)


--- trunk/Source/WebCore/platform/mediastream/mac/RealtimeIncomingVideoSourceCocoa.mm	2021-09-01 19:50:04 UTC (rev 281867)
+++ trunk/Source/WebCore/platform/mediastream/mac/RealtimeIncomingVideoSourceCocoa.mm	2021-09-01 20:02:04 UTC (rev 281868)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -117,8 +117,7 @@
         return m_blackFrame.get();
     }
 
-    RetainPtr<CVPixelBufferRef> newPixelBuffer;
-    return webrtc::pixelBufferFromFrame(frame, [this, &newPixelBuffer](size_t width, size_t height, webrtc::BufferType bufferType) -> CVPixelBufferRef {
+    return adoptCF(webrtc::createPixelBufferFromFrame(frame, [this](size_t width, size_t height, webrtc::BufferType bufferType) -> CVPixelBufferRef {
         auto pixelBufferPool = this->pixelBufferPool(width, height, bufferType);
         if (!pixelBufferPool)
             return nullptr;
@@ -130,9 +129,8 @@
             ERROR_LOG_IF(loggerPtr(), LOGIDENTIFIER, "Failed creating a pixel buffer with error ", status);
             return nullptr;
         }
-        newPixelBuffer = adoptCF(pixelBuffer);
-        return newPixelBuffer.get();
-    });
+        return pixelBuffer;
+    }));
 }
 
 void RealtimeIncomingVideoSourceCocoa::OnFrame(const webrtc::VideoFrame& frame)

Modified: trunk/Source/WebKit/ChangeLog (281867 => 281868)


--- trunk/Source/WebKit/ChangeLog	2021-09-01 19:50:04 UTC (rev 281867)
+++ trunk/Source/WebKit/ChangeLog	2021-09-01 20:02:04 UTC (rev 281868)
@@ -1,3 +1,21 @@
+2021-09-01  David Kilzer  <[email protected]>
+
+        [WebRTC] Leak or over-release of CFPixelBufferRef returned from webrtc::createPixelBufferFromFrame()
+        <https://webkit.org/b/229661>
+        <rdar://problem/82507827>
+
+        Reviewed by Eric Carlson.
+
+        * WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp:
+        (WebKit::LibWebRTCCodecs::encodeFrame):
+        - Use adoptCF() to prevent a leak since
+          webrtc::createPixelBufferFromFrame() always returns a +1
+          retained CVPixelBufferRef now.
+        - Change the functor to return a +1 retained CVPixelBufferRef.
+        - Reuse `pixelBuffer` to store the converted CVPixelBufferRef
+          since this object needs to be kept alive until after the
+          send() method is called.
+
 2021-09-01  Chris Dumez  <[email protected]>
 
         Add support for ServiceWorkerGlobalScope.serviceWorker

Modified: trunk/Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp (281867 => 281868)


--- trunk/Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp	2021-09-01 19:50:04 UTC (rev 281867)
+++ trunk/Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp	2021-09-01 20:02:04 UTC (rev 281868)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2020-2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -431,8 +431,7 @@
     if (!encoder.connection)
         return WEBRTC_VIDEO_CODEC_ERROR;
 
-    RetainPtr<CVPixelBufferRef> newPixelBuffer;
-    auto pixelBuffer = webrtc::pixelBufferFromFrame(frame, [&newPixelBuffer](size_t width, size_t height, webrtc::BufferType bufferType) -> CVPixelBufferRef {
+    auto pixelBuffer = adoptCF(webrtc::createPixelBufferFromFrame(frame, [](size_t width, size_t height, webrtc::BufferType bufferType) -> CVPixelBufferRef {
         OSType poolBufferType;
         switch (bufferType) {
         case webrtc::BufferType::I420:
@@ -445,18 +444,17 @@
         if (!pixelBufferPool)
             return nullptr;
 
-        newPixelBuffer = WebCore::createPixelBufferFromPool(pixelBufferPool);
-        return newPixelBuffer.get();
-    });
+        return WebCore::createPixelBufferFromPool(pixelBufferPool).leakRef();
+    }));
 
     if (!pixelBuffer)
         return WEBRTC_VIDEO_CODEC_ERROR;
 
-    auto sample = RemoteVideoSample::create(pixelBuffer, MediaTime(frame.timestamp_us() * 1000, 1000000), toMediaSampleVideoRotation(frame.rotation()));
+    auto sample = RemoteVideoSample::create(pixelBuffer.get(), MediaTime(frame.timestamp_us() * 1000, 1000000), toMediaSampleVideoRotation(frame.rotation()));
     if (!sample) {
         // FIXME: Optimize this code path, currently we have non BGRA for muted frames at least.
-        newPixelBuffer = convertToBGRA(pixelBuffer);
-        sample = RemoteVideoSample::create(newPixelBuffer.get(), MediaTime(frame.timestamp_us() * 1000, 1000000), toMediaSampleVideoRotation(frame.rotation()));
+        pixelBuffer = convertToBGRA(pixelBuffer.get());
+        sample = RemoteVideoSample::create(pixelBuffer.get(), MediaTime(frame.timestamp_us() * 1000, 1000000), toMediaSampleVideoRotation(frame.rotation()));
     }
 
     encoder.connection->send(Messages::LibWebRTCCodecsProxy::EncodeFrame { encoder.identifier, *sample, frame.timestamp(), shouldEncodeAsKeyFrame }, 0);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to