Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash when playing another media on tvOS 15.2 #114

Closed
defagos opened this issue Feb 25, 2022 · 3 comments
Closed

Crash when playing another media on tvOS 15.2 #114

defagos opened this issue Feb 25, 2022 · 3 comments
Milestone

Comments

@defagos
Copy link
Member

defagos commented Feb 25, 2022

As described on Letterbox issue tracker, changing the media currently being played crashes on tvOS 15.2 due to an internal implementation change made by Apple.

Issue type

Crash

Description of the problem

Stack trace:

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x1c)
    frame #0: 0x00000001800a35bc libobjc.A.dylib`object_isClass + 16
    frame #1: 0x0000000181253f4c Foundation`KVO_IS_RETAINING_ALL_OBSERVERS_OF_THIS_OBJECT_IF_IT_CRASHES_AN_OBSERVER_WAS_OVERRELEASED_OR_SMASHED + 44
    frame #2: 0x0000000181253d60 Foundation`-[NSObject(NSKeyValueObservingPrivate) _changeValueForKeys:count:maybeOldValuesDict:maybeNewValuesDict:usingBlock:] + 268
    frame #3: 0x000000018125461c Foundation`-[NSObject(NSKeyValueObservingPrivate) _changeValueForKey:key:key:usingBlock:] + 68
    frame #4: 0x000000018124d1d4 Foundation`_NSSetObjectValueAndNotify + 284
    frame #5: 0x0000000194248a44 AVKit`-[AVInterstitialController dealloc] + 32
    frame #6: 0x00000001800c0954 libobjc.A.dylib`AutoreleasePoolPage::releaseUntil(objc_object**) + 204
    frame #7: 0x00000001800c0824 libobjc.A.dylib`objc_autoreleasePoolPop + 236
    frame #8: 0x0000000180745e10 CoreFoundation`_CFAutoreleasePoolPop + 28
    frame #9: 0x00000001806a470c CoreFoundation`__CFRunLoopPerCalloutARPEnd + 44
    frame #10: 0x000000018069f9c4 CoreFoundation`__CFRunLoopRun + 2516
    frame #11: 0x000000018069eae4 CoreFoundation`CFRunLoopRunSpecific + 572
    frame #12: 0x00000001835bd5ec GraphicsServices`GSEventRunModal + 160
    frame #13: 0x00000001adc2eac4 UIKitCore`-[UIApplication _run] + 992
    frame #14: 0x00000001adc335e0 UIKitCore`UIApplicationMain + 112
  * frame #15: 0x0000000100fdb6c8 SRGLetterbox-demo`main(argc=1, argv=0x000000016ee2daf0) at main.m:14:16
    frame #16: 0x0000000101671ca0 dyld_sim`start_sim + 20
    frame #17: 0x00000001017710f4 dyld`start + 520

Environment information

  • Library version: Tested with 6.2.1
  • tvOS version: 15.2 (works with the M1 15.0 simulator)
  • Device: Any

Reproducibility

Always reproducible

Code sample

Add to MediasViewController~tvos.m:

- (void)repeatWithController:(SRGMediaPlayerViewController *)playerViewController
{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSURL *URL = [NSURL URLWithString:@"https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_adv_example_hevc/master.m3u8"];
        [playerViewController.controller playURL:URL];
        [self repeatWithController:playerViewController];
    });
}

and call right after SRGMediaPlayerViewController presentation:

[self repeatWithController:playerViewController];

This periodically updates the media being played, which should usually be properly implemented with a custom AVPlayerViewController overlay. The above is sufficient to reproduce the issue, though.

Steps to reproduce

  1. Update the tvOS demo code as described above.
  2. Play some content with SRG Media Player on tvOS.
  3. Wait until the crash happens.
@defagos
Copy link
Member Author

defagos commented Feb 25, 2022

The issue arises because of internal changes made by Apple to AVPlayerViewController implementation in tvOS 15.2.

When playing another media, our current SRGMediaPlayerViewController implementation first resets the state (setting the player to nil first), then prepares playback (setting the player to a fresh AVPlayer instance). At the SRGMediaPlayerViewController level we track player changes with KVO and switch the player view controller player accordingly. Thus, with our current implementation, the AVPlayerViewController player instance is updated twice in a row when playing another media, the first time to nil, then to a new instance.

Before tvOS 15 this was not an issue. But since tvOS 15 switching the AVPlayerViewController player instance several times in a row can lead to crashes, likely because of an incorrect KVO implementation to track interstitials updates. This also means that the crash does not affect SRGMediaPlayerViewController on iOS, as interstitials are not available on this platform.

We can fix the crash by avoiding unnecessary player changes at SRGMediaPlayerController level so that KVObservation at SRGMediaPlayerViewController level minimizes updates as well. This requires two kinds of code changes:

  • Checking player / player view controller identity and avoiding player updates when nothing changed.
  • Adding a parameter to the -reset method so that resetting when switching to another media can be made without unnecessarily transitioning to a nil player.

This issue will be reported to Apple, though in the future we might switch to AVQueuePlayer. In this case a controller will always have one AVQueuePlayer instance, which should avoid this kind of problems.

Fix proposal available for review on feature/tvos15-crash-fix.

@defagos defagos added this to the 6.2.2 milestone Feb 28, 2022
@defagos
Copy link
Member Author

defagos commented Mar 1, 2022

Merged into develop.

@defagos defagos closed this as completed Mar 1, 2022
@defagos defagos changed the title Crash when playing another media on tvOS 15 Crash when playing another media on tvOS 15.2 Mar 2, 2022
@defagos
Copy link
Member Author

defagos commented Mar 2, 2022

I opened a dedicated radar.

When testing my sample code I also discovered that the player associated with AVPlayerViewController leaks on iOS after an update. The workaround applied for the crash does not help in fixing this issue so it should probably be reported separately to Apple.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant