Skip to content

Commit 694e8cf

Browse files
fix(ios): resolve critical memory leak in video recording (flutter-webrtc#1960)
Issue flutter-webrtc#1959 Fixed memory leaks in FlutterRTCMediaRecorder that caused dramatic memory growth during video recording, leading to app crashes. The renderFrame: method was creating Core Foundation objects (CMVideoFormatDescriptionRef and CMSampleBufferRef) 30-60 times per second without releasing them, causing memory to accumulate rapidly. Changes: - Added CFRelease() calls for formatDescription and outBuffer - Added NULL initialization and error checking for Core Foundation objects - Ensured proper cleanup on error paths - Removed platform-specific conditional for pixel buffer release This prevents memory from growing unbounded during recording sessions.
1 parent 149c238 commit 694e8cf

File tree

1 file changed

+24
-6
lines changed

1 file changed

+24
-6
lines changed

common/darwin/Classes/FlutterRTCMediaRecorder.m

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,16 @@ - (void)renderFrame:(nullable RTCVideoFrame *)frame {
110110
pixelBufferRef = [FlutterRTCFrameCapturer convertToCVPixelBuffer:frame];
111111
shouldRelease = true;
112112
}
113-
CMVideoFormatDescriptionRef formatDescription;
113+
CMVideoFormatDescriptionRef formatDescription = NULL;
114114
OSStatus status = CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, pixelBufferRef, &formatDescription);
115+
116+
if (status != noErr || formatDescription == NULL) {
117+
NSLog(@"Failed to create format description: %d", (int)status);
118+
if (shouldRelease) {
119+
CVPixelBufferRelease(pixelBufferRef);
120+
}
121+
return;
122+
}
115123

116124
CMSampleTimingInfo timingInfo;
117125

@@ -123,7 +131,7 @@ - (void)renderFrame:(nullable RTCVideoFrame *)frame {
123131
timingInfo.presentationTimeStamp = CMTimeMake(frameTime, 1000000);
124132
framesCount++;
125133

126-
CMSampleBufferRef outBuffer;
134+
CMSampleBufferRef outBuffer = NULL;
127135

128136
status = CMSampleBufferCreateReadyWithImageBuffer(
129137
kCFAllocatorDefault,
@@ -133,14 +141,24 @@ - (void)renderFrame:(nullable RTCVideoFrame *)frame {
133141
&outBuffer
134142
);
135143

136-
if (![self.writerInput appendSampleBuffer:outBuffer]) {
137-
NSLog(@"Frame not appended %@", self.assetWriter.error);
144+
if (status == noErr && outBuffer != NULL) {
145+
if (![self.writerInput appendSampleBuffer:outBuffer]) {
146+
NSLog(@"Frame not appended %@", self.assetWriter.error);
147+
}
148+
} else {
149+
NSLog(@"Failed to create sample buffer: %d", (int)status);
150+
}
151+
152+
// Release Core Foundation objects to prevent memory leaks
153+
if (outBuffer != NULL) {
154+
CFRelease(outBuffer);
155+
}
156+
if (formatDescription != NULL) {
157+
CFRelease(formatDescription);
138158
}
139-
#if TARGET_OS_IPHONE
140159
if (shouldRelease) {
141160
CVPixelBufferRelease(pixelBufferRef);
142161
}
143-
#endif
144162
}
145163

146164
- (void)stop:(FlutterResult _Nonnull) result {

0 commit comments

Comments
 (0)