0

We're seeing a peculiar issue when attempting to re-encode videos, and it only seems to happen on the Nexus 5. We use MediaCodec to compress and re-encode videos clientside, and sometimes when the task is running on a Nexus 5 we get the following crash:

05-15 16:25:15.023 E/AndroidRuntime( 4716): FATAL EXCEPTION: FinalizerWatchdogDaemon
05-15 16:25:15.023 E/AndroidRuntime( 4716): java.util.concurrent.TimeoutException: android.graphics.SurfaceTexture.finalize() timed out after 10 seconds
05-15 16:25:15.023 E/AndroidRuntime( 4716):     at android.graphics.SurfaceTexture.nativeFinalize(Native Method)
05-15 16:25:15.023 E/AndroidRuntime( 4716):     at android.graphics.SurfaceTexture.finalize(SurfaceTexture.java:353)
05-15 16:25:15.023 E/AndroidRuntime( 4716):     at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:190)
05-15 16:25:15.023 E/AndroidRuntime( 4716):     at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:173)
05-15 16:25:15.023 E/AndroidRuntime( 4716):     at java.lang.Thread.run(Thread.java:818)    

Our code is relatively similar to to bigflake's DecodeEditEncodeTest (https://android.googlesource.com/platform/cts/+/jb-mr2-release/tests/tests/media/src/android/media/cts/DecodeEditEncodeTest.java), and we are also using their InputSurface, OutputSurface, and TextureRender classes (https://android.googlesource.com/platform/cts/+/jb-mr2-release/tests/tests/media/src/android/media/cts/). I am guessing that the issue occurs somewhere in OutputSurface or TextureRender as they're the classes that actually manipulate a surface texture.

The only reliable repro steps we can come up with is that it seems to happen somewhat randomly when several videos are queued to be re-encoded, even though the encoder only handles one video at a time.

Any help would be much appreciated.

gcgrant
  • 361
  • 5
  • 12

1 Answers1

2

The SurfaceTexture finalizer is hanging for some reason. The VM detects the stuck thread and throws an exception.

The SurfaceTexture finalizer is here, though it just calls nativeFinalize(), which you can see here. There isn't much going on -- just zeroing out fields and adjusting reference counts -- so it's unclear from the "Lollipop" sources why this would hang. "KitKat" and "Lollipop-mr1" look about the same.

What version of Android is running on that device?

fadden
  • 51,356
  • 5
  • 116
  • 166
  • Both devices we see this on are running 5.0, both Nexus 5s. I believe I've found a potential fix; in the `release()` call of OutputSurface, the line `mSurfaceTexture.release()` was commented out. Uncommenting this seems to have fixed the issue, and it makes sense to release the SurfaceTexture here. Now I'm just curious/cautious about why it was commented out in the first place. – gcgrant May 19 '15 at 14:59
  • Could be related to http://stackoverflow.com/questions/30172529/when-is-a-textureviews-consumer-side-closed, though the accepted answer there is specifically about the Camera. Something is not quite right in the platform if an explicit release of the SurfaceTexture is necessary. – fadden May 19 '15 at 15:34
  • Any ideas why we observed this only on the N5 and not any other devices running Lollipop? – gcgrant May 19 '15 at 20:02
  • I would guess it's a race that happens to lose on the N5. I don't really understand why it's getting stuck, so I don't have much to go on. The next step would be to get a native stack trace to see where exactly it's at; this used to be emitted automatically by Dalvik when finalizers got stuck, but I think that feature was removed (grumble grumble). You might be able to get this by having the app catch the exception with a global default handler and then send itself a couple of SIGTERMs to get a dump in logcat. (I haven't done this, but I think it'll work.) – fadden May 19 '15 at 22:59