Skip to content

Commit c0d0c0a

Browse files
andrewlewisicbaker
authored andcommitted
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
1 parent 00a5b33 commit c0d0c0a

File tree

1 file changed

+29
-17
lines changed

1 file changed

+29
-17
lines changed

libraries/transformer/src/main/java/androidx/media3/transformer/FrameworkMuxer.java

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -194,24 +194,8 @@ public void release(boolean forCancellation) throws MuxerException {
194194

195195
isStarted = false;
196196
try {
197-
mediaMuxer.stop();
197+
stopMuxer(mediaMuxer);
198198
} catch (RuntimeException e) {
199-
if (SDK_INT < 30) {
200-
// Set the muxer state to stopped even if mediaMuxer.stop() failed so that
201-
// mediaMuxer.release() doesn't attempt to stop the muxer and therefore doesn't throw the
202-
// same exception without releasing its resources. This is already implemented in MediaMuxer
203-
// from API level 30.
204-
try {
205-
Field muxerStoppedStateField = MediaMuxer.class.getDeclaredField("MUXER_STATE_STOPPED");
206-
muxerStoppedStateField.setAccessible(true);
207-
int muxerStoppedState = castNonNull((Integer) muxerStoppedStateField.get(mediaMuxer));
208-
Field muxerStateField = MediaMuxer.class.getDeclaredField("mState");
209-
muxerStateField.setAccessible(true);
210-
muxerStateField.set(mediaMuxer, muxerStoppedState);
211-
} catch (Exception reflectionException) {
212-
// Do nothing.
213-
}
214-
}
215199
// It doesn't matter that stopping the muxer throws if the transformation is being cancelled.
216200
if (!forCancellation) {
217201
throw new MuxerException("Failed to stop the muxer", e);
@@ -239,4 +223,32 @@ private static int mimeTypeToMuxerOutputFormat(String mimeType) {
239223
throw new IllegalArgumentException("Unsupported output MIME type: " + mimeType);
240224
}
241225
}
226+
227+
// Accesses MediaMuxer state via reflection to ensure that muxer resources can be released even
228+
// if stopping fails.
229+
@SuppressLint("PrivateApi")
230+
private static void stopMuxer(MediaMuxer mediaMuxer) {
231+
try {
232+
mediaMuxer.stop();
233+
} catch (RuntimeException e) {
234+
if (SDK_INT < 30) {
235+
// Set the muxer state to stopped even if mediaMuxer.stop() failed so that
236+
// mediaMuxer.release() doesn't attempt to stop the muxer and therefore doesn't throw the
237+
// same exception without releasing its resources. This is already implemented in MediaMuxer
238+
// from API level 30. See also b/80338884.
239+
try {
240+
Field muxerStoppedStateField = MediaMuxer.class.getDeclaredField("MUXER_STATE_STOPPED");
241+
muxerStoppedStateField.setAccessible(true);
242+
int muxerStoppedState = castNonNull((Integer) muxerStoppedStateField.get(mediaMuxer));
243+
Field muxerStateField = MediaMuxer.class.getDeclaredField("mState");
244+
muxerStateField.setAccessible(true);
245+
muxerStateField.set(mediaMuxer, muxerStoppedState);
246+
} catch (Exception reflectionException) {
247+
// Do nothing.
248+
}
249+
}
250+
// Rethrow the original error.
251+
throw e;
252+
}
253+
}
242254
}

0 commit comments

Comments
 (0)