From e61e96b352c980fea6c3965f7d54a9c2e6b3169d Mon Sep 17 00:00:00 2001 From: Acaki Date: Sat, 12 Jul 2025 15:33:14 +0800 Subject: [PATCH] fix: background stream issues --- VoidLink/Stream/VideoDecoderRenderer.m | 25 +++++++++---------- .../StreamFrameViewController.m | 2 +- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/VoidLink/Stream/VideoDecoderRenderer.m b/VoidLink/Stream/VideoDecoderRenderer.m index 246194ef..c29cfbe7 100644 --- a/VoidLink/Stream/VideoDecoderRenderer.m +++ b/VoidLink/Stream/VideoDecoderRenderer.m @@ -39,10 +39,12 @@ extern int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size, - (void)reinitializeDisplayLayer { - CALayer *oldLayer = _displayLayer; - - _displayLayer = [[AVSampleBufferDisplayLayer alloc] init]; - _displayLayer.backgroundColor = [UIColor blackColor].CGColor; + if (_displayLayer == nil) { + _displayLayer = [[AVSampleBufferDisplayLayer alloc] init]; + _displayLayer.backgroundColor = [UIColor blackColor].CGColor; + _displayLayer.videoGravity = AVLayerVideoGravityResize; + [_view.layer addSublayer:_displayLayer]; + } // Ensure the AVSampleBufferDisplayLayer is sized to preserve the aspect ratio // of the video stream. We used to use AVLayerVideoGravityResizeAspect, but that @@ -55,22 +57,17 @@ extern int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size, } else { videoSize = CGSizeMake(_view.bounds.size.width, _view.bounds.size.width / _streamAspectRatio); } + + [CATransaction begin]; + [CATransaction setDisableActions:YES]; _displayLayer.position = CGPointMake(CGRectGetMidX(_view.bounds), CGRectGetMidY(_view.bounds)); _displayLayer.bounds = CGRectMake(0, 0, videoSize.width, videoSize.height); - _displayLayer.videoGravity = AVLayerVideoGravityResize; + [CATransaction commit]; // Hide the layer until we get an IDR frame. This ensures we // can see the loading progress label as the stream is starting. _displayLayer.hidden = YES; - if (oldLayer != nil) { - // Switch out the old display layer with the new one - [_view.layer replaceSublayer:oldLayer with:_displayLayer]; - } - else { - [_view.layer addSublayer:_displayLayer]; - } - if (formatDesc != nil) { CFRelease(formatDesc); formatDesc = nil; @@ -525,6 +522,8 @@ int DrSubmitDecodeUnit(PDECODE_UNIT decodeUnit); if (_displayLayer.status == AVQueuedSampleBufferRenderingStatusFailed) { Log(LOG_E, @"Display layer rendering failed: %@", _displayLayer.error); + [self->_displayLayer flushAndRemoveImage]; + // Recreate the display layer. We are already on the main thread, // so this is safe to do right here. [self reinitializeDisplayLayer]; diff --git a/VoidLink/ViewControllers/StreamFrameViewController.m b/VoidLink/ViewControllers/StreamFrameViewController.m index 37014faf..8b27b85c 100644 --- a/VoidLink/ViewControllers/StreamFrameViewController.m +++ b/VoidLink/ViewControllers/StreamFrameViewController.m @@ -889,7 +889,7 @@ #if !TARGET_OS_TV // Terminate the stream if the app is inactive for 60 seconds Log(LOG_I, @"Starting inactivity termination timer"); - _inactivityTimer = [NSTimer scheduledTimerWithTimeInterval:60 + _inactivityTimer = [NSTimer scheduledTimerWithTimeInterval:1800 target:self selector:@selector(inactiveTimerExpired:) userInfo:nil