Skip to content

Commit 3a5a91e

Browse files
authored
fix: hold weak ref of RendererDelegate in async task (#2265) (#2271)
1 parent 755e0dd commit 3a5a91e

File tree

1 file changed

+22
-8
lines changed

1 file changed

+22
-8
lines changed

shared/darwin/TextureRenderer.mm

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#import <AgoraRtcWrapper/iris_rtc_rendering_cxx.h>
66
#import <Foundation/Foundation.h>
77

8+
#import <memory.h>
89
#import <stdio.h>
910

1011
using namespace agora::iris;
@@ -26,7 +27,8 @@ @interface TextureRender ()
2627
@end
2728

2829
namespace {
29-
class RendererDelegate : public agora::iris::VideoFrameObserverDelegate {
30+
class RendererDelegate : public std::enable_shared_from_this<RendererDelegate>,
31+
public agora::iris::VideoFrameObserverDelegate {
3032
public:
3133
RendererDelegate(void *renderer)
3234
: renderer_(((__bridge TextureRender *)renderer)), pre_width_(0),
@@ -40,6 +42,8 @@ void OnVideoFrameReceived(const void *videoFrame,
4042
return;
4143
}
4244

45+
std::weak_ptr<RendererDelegate> self_weak = shared_from_this();
46+
4347
agora::media::base::VideoFrame *vf =
4448
(agora::media::base::VideoFrame *)videoFrame;
4549

@@ -61,8 +65,14 @@ void OnVideoFrameReceived(const void *videoFrame,
6165
// copy the width and height to local variables.
6266
int temp_width = vf->width;
6367
int temp_height = vf->height;
68+
6469
dispatch_async(dispatch_get_main_queue(), ^{
65-
TextureRender *strongRenderer = renderer_;
70+
std::shared_ptr<RendererDelegate> self_strong = self_weak.lock();
71+
if (!self_strong) {
72+
return;
73+
}
74+
75+
TextureRender *strongRenderer = self_strong->renderer_;
6676
if (!strongRenderer) {
6777
return;
6878
}
@@ -93,7 +103,12 @@ void OnVideoFrameReceived(const void *videoFrame,
93103

94104
// notify new frame available on main thread
95105
dispatch_async(dispatch_get_main_queue(), ^{
96-
TextureRender *strongRenderer = renderer_;
106+
std::shared_ptr<RendererDelegate> self_strong = self_weak.lock();
107+
if (!self_strong) {
108+
return;
109+
}
110+
111+
TextureRender *strongRenderer = self_strong->renderer_;
97112
if (!strongRenderer) {
98113
return;
99114
}
@@ -111,7 +126,7 @@ void OnVideoFrameReceived(const void *videoFrame,
111126

112127
@interface TextureRender ()
113128

114-
@property(nonatomic) RendererDelegate *delegate;
129+
@property(nonatomic) std::shared_ptr<RendererDelegate> delegate;
115130

116131
@end
117132

@@ -133,7 +148,7 @@ @implementation TextureRender
133148
self.textureId]
134149
binaryMessenger:messenger];
135150

136-
self.delegate = new ::RendererDelegate((__bridge void *)self);
151+
self.delegate = std::make_shared<::RendererDelegate>((__bridge void *)self);
137152
self.latestPixelBuffer = nil;
138153
self.pixelBufferSynchronizationQueue = dispatch_queue_create(
139154
[[NSString stringWithFormat:@"io.agora.flutter.render_%lld", _textureId]
@@ -163,7 +178,7 @@ - (void)updateData:(NSNumber *)uid
163178
agora::media::base::VIDEO_MODULE_POSITION::POSITION_PRE_RENDERER;
164179

165180
self.delegateId = self.irisRtcRendering->AddVideoFrameObserverDelegate(
166-
config, self.delegate);
181+
config, self.delegate.get());
167182
}
168183

169184
- (CVPixelBufferRef _Nullable)copyPixelBuffer {
@@ -184,8 +199,7 @@ - (void)dispose {
184199
self.irisRtcRendering = nil;
185200
}
186201
if (self.delegate) {
187-
delete self.delegate;
188-
self.delegate = nil;
202+
self.delegate.reset();
189203
}
190204
if (self.textureRegistry) {
191205
[self.textureRegistry unregisterTexture:self.textureId];

0 commit comments

Comments
 (0)