millicast / millicast-player-unreal-engine-plugin

Millicast Player plugin for Unreal Engine
Other
19 stars 15 forks source link

In UE 5.1, quitting the game while the stream is being received results in a crash #36

Closed adrian-j-programmer closed 1 year ago

adrian-j-programmer commented 1 year ago

This does not occur when PIE is stopped, only when a standalone application is closed.

dzeitman commented 1 year ago

@adrian-j-programmer - Please expand a little deeper on this issue. On the surface, it sounds like you may need to add methods to gracefully close the stream before closing the scene/level and or application.
Some resources for events: Player Plugin: In the Subscriber's component, you can connect several events received from the Dolby.io Real-time Streaming media server. https://docs.dolby.io/streaming-apis/docs/player-plugin

adrian-j-programmer commented 1 year ago

There are two crash callstacks we are seeing with this behavior. The first one is a crash coming from the Unsubscribe method in the millicast subscriber component [Project]!UMillicastSubscriberComponent::Unsubscribe() [/project/Plugins/MillicastPlayer/Source/MillicastPlayer/Private/Components/MillicastSubscriberComponent.cpp:100] The second callstack is coming from the game thread task that gets queued to process incoming video data. What we see is that in some cases, by the time this game thread task is executed, the this pointer can no longer be valid.

dbaldassi commented 1 year ago

I will investigate this today

dbaldassi commented 1 year ago

I'm able to reproduce it. For the second call stack, when it crash in the in the OnFrame function, I can fix it by making a weak capture of this pointer to check if it is still valid. For the first one, it just hangs and then crash, this might be some clean up issue in webrtc threads.

dbaldassi commented 1 year ago

Seems that just adding a weak capture solves the issue. I've pushed it in e80d759

dbaldassi commented 1 year ago

@adrian-j-programmer can you confirm this is solved for you ?

adrian-j-programmer commented 1 year ago

We still experience this crash with the fix applied @dbaldassi

dbaldassi commented 1 year ago

For both callstack, or only one now ?

adrian-j-programmer commented 1 year ago

I'm only seeing this one now:

[REDACTED]!UMillicastSubscriberComponent::~UMillicastSubscriberComponent() [/project/Plugins/MillicastPlayer/Source/MillicastPlayer/Private/Components/MillicastSubscriberComponent.cpp:42]," [REDACTED]!UMillicastSubscriberComponent::~UMillicastSubscriberComponent() [/project/Plugins/MillicastPlayer/Source/MillicastPlayer/Private/Components/MillicastSubscriberComponent.cpp:42]"
2022-12-01T17:00:53.894Z,"0x0000000005bfc81a [REDACTED]!bool FAsyncPurge::TickDestroyObjects<false>(bool, float, double)()"," [REDACTED]!bool FAsyncPurge::TickDestroyObjects<false>(bool, float, double)()"
2022-12-01T17:00:53.894Z,"0x0000000005bfc11f [REDACTED]!FAsyncPurge::TickPurge(bool, float, double)()"," [REDACTED]!FAsyncPurge::TickPurge(bool, float, double)()"
2022-12-01T17:00:53.894Z,"0x0000000005bd5b86 [REDACTED]!IncrementalPurgeGarbage(bool, double)()"," [REDACTED]!IncrementalPurgeGarbage(bool, double)()"
dbaldassi commented 1 year ago

Hi @adrian-j-programmer, I am not able to reproduce this crash on my side. I have tried to run the packaged game in debug and shipping, in the editor in multiplayer and solo. My steps are :

adrian-j-programmer commented 1 year ago

We are using the patch commit already, just double-checked. I can't think of anything else you might wanna try here. It looks like it's not dependent on how long the client has been run (and millicast subscribed) before shutdown, so I'm not really sure what's going on... If you add in some logging, I'll integrate this change asap so we can get more data.

dbaldassi commented 1 year ago

I have added logs the plugin, can you send me the log file corresponding to this issue ?

adrian-j-programmer commented 1 year ago

Posting for visibility here. The issue is caused by the destructor of the UMillicastSubscriberComponent calling the Unsubscribe method. Inside the Unsubscribe method, all cached media tracks are iterated through and cleared. This causes a crash if the destructor of the component was run as part of the garbage collection job. In this case, the tracks might have already been cleared by GC, so accessing their pointers leads to a crash.

dbaldassi commented 1 year ago

Actually, the tracks have been added to root, so I don't think they are cleared by the GC before calling the RemoveToRoot method

rweber89 commented 1 year ago

@adrian-j-programmer could you please check if this is still an issue for you? There is a potential fix on the dev branch