From 0490839fce92af15dabd32e6d8be64ffd3fbc47f Mon Sep 17 00:00:00 2001 From: andrewlewis Date: Tue, 22 Feb 2022 13:46:05 +0000 Subject: [PATCH] Suppress framework muxer lint warning We need to access internal state to work around resources not being released on old API versions. Add a reference to the bug about this and suppress the lint warning. #minor-release PiperOrigin-RevId: 430190794 --- .../media3/transformer/FrameworkMuxer.java | 46 ++++++++++++------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/FrameworkMuxer.java b/libraries/transformer/src/main/java/androidx/media3/transformer/FrameworkMuxer.java index 214d7b121f..1c433356d4 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/FrameworkMuxer.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/FrameworkMuxer.java @@ -209,24 +209,8 @@ import java.nio.ByteBuffer; isStarted = false; try { - mediaMuxer.stop(); + stopMuxer(mediaMuxer); } catch (RuntimeException e) { - if (SDK_INT < 30) { - // Set the muxer state to stopped even if mediaMuxer.stop() failed so that - // mediaMuxer.release() doesn't attempt to stop the muxer and therefore doesn't throw the - // same exception without releasing its resources. This is already implemented in MediaMuxer - // from API level 30. - try { - Field muxerStoppedStateField = MediaMuxer.class.getDeclaredField("MUXER_STATE_STOPPED"); - muxerStoppedStateField.setAccessible(true); - int muxerStoppedState = castNonNull((Integer) muxerStoppedStateField.get(mediaMuxer)); - Field muxerStateField = MediaMuxer.class.getDeclaredField("mState"); - muxerStateField.setAccessible(true); - muxerStateField.set(mediaMuxer, muxerStoppedState); - } catch (Exception reflectionException) { - // Do nothing. - } - } // It doesn't matter that stopping the muxer throws if the transformation is being cancelled. if (!forCancellation) { throw new MuxerException("Failed to stop the muxer", e); @@ -254,4 +238,32 @@ import java.nio.ByteBuffer; throw new IllegalArgumentException("Unsupported output MIME type: " + mimeType); } } + + // Accesses MediaMuxer state via reflection to ensure that muxer resources can be released even + // if stopping fails. + @SuppressLint("PrivateApi") + private static void stopMuxer(MediaMuxer mediaMuxer) { + try { + mediaMuxer.stop(); + } catch (RuntimeException e) { + if (SDK_INT < 30) { + // Set the muxer state to stopped even if mediaMuxer.stop() failed so that + // mediaMuxer.release() doesn't attempt to stop the muxer and therefore doesn't throw the + // same exception without releasing its resources. This is already implemented in MediaMuxer + // from API level 30. See also b/80338884. + try { + Field muxerStoppedStateField = MediaMuxer.class.getDeclaredField("MUXER_STATE_STOPPED"); + muxerStoppedStateField.setAccessible(true); + int muxerStoppedState = castNonNull((Integer) muxerStoppedStateField.get(mediaMuxer)); + Field muxerStateField = MediaMuxer.class.getDeclaredField("mState"); + muxerStateField.setAccessible(true); + muxerStateField.set(mediaMuxer, muxerStoppedState); + } catch (Exception reflectionException) { + // Do nothing. + } + } + // Rethrow the original error. + throw e; + } + } }