JDK-8156563 : JavaFX Ensemble8 media sample hang and crash
  • Type: Bug
  • Component: javafx
  • Sub-Component: media
  • Affected Version: 8u60,9
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2016-05-09
  • Updated: 2017-09-07
  • Resolved: 2016-09-13
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
8u152Fixed 9Fixed
In Jigsaw mode the advanced media sample exhibits a hang (repeatable) and a crash (not repeatable yet).

Mac OSX 10.11.5
Xcode 7.3.1

Ran with:

$JIGSAW_HOME/bin/java @build/xpatch.args -cp /Users/morris/jfx/9-dev/rt/apps/samples/Ensemble8/lib/lucene-core-3.2.0.jar:/Users/morris/jfx/9-dev/rt/apps/samples/Ensemble8/lib/lucene-grouping-3.2.0.jar:/Users/morris/jfx/9-dev/rt/apps/samples/Ensemble8/build/classes ensemble.EnsembleApp
Approved to backport to 8u-dev for 8u122.

agreed, will post sometime this week

I think this has baked long enough in 9 to warrant a backport to 8u. When you get a chance, please post an 8u webrev matching what you pushed to 9.

That's fine, especially considering we want this to have a little bake time in JDK 9 first.

Will get a 8u backport ready, but it won't be put up for review until after JO

changeset: http://hg.openjdk.java.net/openjfx/9-dev/rt/rev/1143dd8b53d8 user: ddehaven date: Tue Sep 13 07:33:27 2016 -0700 summary: 8156563: JavaFX Ensemble8 media sample hang and crash

Tested on OS X 10.9.5. Looks good. +1

Looks good. Approved.

Removed reference counting code as it's fragile, it now uses std::shared_ptr to manage shared C++ object lifecycles. Also removed the back reference to the AVFAudioProcessor in the audio tap context, with the addition of the AVFKernelProcessor pointers there's no need for it. Also removed the delay unit as it was not actually doing anything, and when hooked up did not have the desired effect (needs to be fixed under a different JBS ID).

Code review: http://cr.openjdk.java.net/~ddehaven/8156563/rt.0/

We should consider a backport to 8u.

BTW, the only "hang" I've seen is caused by buffering while seeking. I've not seen anything else that could qualify as a hang in Ensemble.

Ultimately, there were at least three places where crashes were happening: - The AU renderer continued rendering after the player was disposed, due to AVFAudioProcessor never being released due to a lingering reference in the audio tap code, this produced a rare crash in Apple's code largely due to timing of when the player gets disposed - The C++ objects used to interface with jfxmedia native were still in use by the AU render threads (which hadn't had a chance to shut down yet) although the associated Java object had been garbage collected. This was causing the VM to abort. This is an issue in the core JFXMedia native code that needs to be addressed - The audio kernel objects were being deleted while still in use by the AU render thread, unfortunately due to the AVFAudioProcessor object being released before the audio tap gets unprepared and finalized

Summary of proposed fixes: - Fix CJavaPlayerEventDispatcher: It currently uses a global reference to a Java object everywhere, this is a big NO-NO in JNI code. Fixed by a> setting the global ref to NULL when it's deleted, and b> Adding calls to NewLocalRef/DeleteLocalRef where it's actually needed. This makes it thread-safe. I will investigate the rest of the JNI code for similar misuse of global references. - Removed all strong references to AVFAudioProcessor except for the reference in the AVFMediaPlayer where it's needed. The only reference needed by the audio tap is converted to __weak, then made __strong when it's actually needed (only when the audio tap is prepared). This allows ARC to dealloc the object when it's no longer referenced anywhere, this also kicks off shutting down the audio tap. - Added reference counting to AVFKernelProcessor, since we cannot know the order in which objects that need access to it will be freed/deleted/dealloced this seems the easiest solution to guarantee they don't get deleted prematurely. - Made changes to the dispose sequence in AVFMediaPlayer, it now clears the spectrum callback and band buffers to prevent it from any future processing attempts.

I've fixed at least one crash and fix the fact that the audio tap was never being released (major leak!). There's still one more crash being caused by a C++ object being released while still in use in an AU render thread.

1. Run the Ensemble8 Advanced media sample. 2. Click ahead about to about 10% on the media timeline. 3. Click and slowly drag right on the media timeline. Note messages like: 2016-05-09 13:30:23.933 java[53416:218196] CMTimeMakeWithSeconds(5.785 seconds, timescale 1): warning: error of -0.785 introduced due to very low timescale 2016-05-09 13:30:23.956 java[53416:218196] CMTimeMakeWithSeconds(6.697 seconds, timescale 1): warning: error of -0.697 introduced due to very low timescale 2016-05-09 13:30:24.014 java[53416:218196] CMTimeMakeWithSeconds(12.172 seconds, timescale 1): warning: error of -0.172 introduced due to very low timescale Followed by a hang. The JVM crash happened after hitting the Mac OS X red close button.