fix: occasional crashes when put in foreground

This commit is contained in:
Acaki
2025-08-25 02:05:00 +08:00
parent c8f61b0b87
commit 0582655954
2 changed files with 43 additions and 31 deletions
+2
View File
@@ -43,4 +43,6 @@
frameType:(int)frameType
decodeStartTime:(CFTimeInterval)decodeStartTime;
- (void)invalidateDecompressionSession;
@end
+41 -31
View File
@@ -98,12 +98,14 @@ extern int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size,
_formatDescImageBuffer = nil;
}
if (_decompressionSession != nil){
VTDecompressionSessionWaitForAsynchronousFrames(_decompressionSession);
@synchronized(self) {
if (_decompressionSession != nil){
VTDecompressionSessionWaitForAsynchronousFrames(_decompressionSession);
VTDecompressionSessionInvalidate(_decompressionSession);
CFRelease(_decompressionSession);
_decompressionSession = nil;
VTDecompressionSessionInvalidate(_decompressionSession);
CFRelease(_decompressionSession);
_decompressionSession = nil;
}
}
}
@@ -174,6 +176,7 @@ extern int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size,
- (void)setupDecompressionSessionWithAttributes:(NSDictionary *)destinationPixelBufferAttributes {
// This method is called from within synchronized block, so no additional sync needed here
if (_decompressionSession != NULL) {
VTDecompressionSessionInvalidate(_decompressionSession);
CFRelease(_decompressionSession);
@@ -367,10 +370,12 @@ int DrSubmitDecodeUnit(PDECODE_UNIT decodeUnit);
[_displayLink invalidate];
}
if (_decompressionSession != NULL) {
VTDecompressionSessionInvalidate(_decompressionSession);
CFRelease(_decompressionSession);
_decompressionSession = nil;
@synchronized(self) {
if (_decompressionSession != NULL) {
VTDecompressionSessionInvalidate(_decompressionSession);
CFRelease(_decompressionSession);
_decompressionSession = nil;
}
}
}
@@ -845,28 +850,30 @@ int DrSubmitDecodeUnit(PDECODE_UNIT decodeUnit);
frameNumber:(int)frameNumber
frameType:(int)frameType
decodeStartTime:(CFTimeInterval)decodeStartTime {
// Check if we need to create/recreate the decompression session
BOOL needsNewSession = (frameType == FRAME_TYPE_IDR || _decompressionSession == nil);
// Synchronize access to decompression session to prevent race conditions during background/foreground transitions
@synchronized(self) {
// Check if we need to create/recreate the decompression session
BOOL needsNewSession = (frameType == FRAME_TYPE_IDR || _decompressionSession == nil);
// Also check if the session might have been invalidated by iOS during background
if (!needsNewSession && _decompressionSession != nil) {
Boolean isValid = VTDecompressionSessionCanAcceptFormatDescription(_decompressionSession, _formatDesc);
if (!isValid) {
Log(LOG_W, @"Decompression session is invalid, needs recreation");
needsNewSession = YES;
// Also check if the session might have been invalidated by iOS during background
if (!needsNewSession && _decompressionSession != nil) {
Boolean isValid = VTDecompressionSessionCanAcceptFormatDescription(_decompressionSession, _formatDesc);
if (!isValid) {
Log(LOG_W, @"Decompression session is invalid, needs recreation");
needsNewSession = YES;
}
}
}
if (needsNewSession) {
[self setupDecompressionSession];
}
if (needsNewSession) {
[self setupDecompressionSession];
}
if (_decompressionSession == nil) {
Log(LOG_E, @"Failed to create decompression session");
return kVTInvalidSessionErr;
}
if (_decompressionSession == nil) {
Log(LOG_E, @"Failed to create decompression session");
return kVTInvalidSessionErr;
}
OSStatus status = VTDecompressionSessionDecodeFrameWithOutputHandler(
OSStatus status = VTDecompressionSessionDecodeFrameWithOutputHandler(
_decompressionSession,
sampleBuffer,
0,
@@ -878,10 +885,12 @@ int DrSubmitDecodeUnit(PDECODE_UNIT decodeUnit);
if (status == kVTInvalidSessionErr) {
// The session was invalidated by the OS. Destroy our reference
// so it gets recreated on the next IDR frame.
if (self->_decompressionSession) {
VTDecompressionSessionInvalidate(self->_decompressionSession);
CFRelease(self->_decompressionSession);
self->_decompressionSession = nil;
@synchronized(self) {
if (self->_decompressionSession) {
VTDecompressionSessionInvalidate(self->_decompressionSession);
CFRelease(self->_decompressionSession);
self->_decompressionSession = nil;
}
}
}
LiRequestIdrFrame(); // Request an IDR to restart the stream
@@ -948,7 +957,8 @@ int DrSubmitDecodeUnit(PDECODE_UNIT decodeUnit);
});
});
return status;
return status;
}
}
- (void)setHdrMode:(BOOL)enabled {