Commit 245c9fec by Steve Mayhew

Cleanup tunneled onFrameRenderListener

Cleanup the handler to prevent stale messages and potential handler leaks
parent 45013ece
...@@ -563,6 +563,9 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -563,6 +563,9 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
clearReportedVideoSize(); clearReportedVideoSize();
clearRenderedFirstFrame(); clearRenderedFirstFrame();
frameReleaseTimeHelper.disable(); frameReleaseTimeHelper.disable();
if (tunnelingOnFrameRenderedListener != null && getCodec() != null) {
tunnelingOnFrameRenderedListener.destroyHandler(getCodec());
}
tunnelingOnFrameRenderedListener = null; tunnelingOnFrameRenderedListener = null;
try { try {
super.onDisabled(); super.onDisabled();
...@@ -687,6 +690,9 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -687,6 +690,9 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
} }
codec.configure(mediaFormat, surface, crypto, 0); codec.configure(mediaFormat, surface, crypto, 0);
if (Util.SDK_INT >= 23 && tunneling) { if (Util.SDK_INT >= 23 && tunneling) {
if (tunnelingOnFrameRenderedListener != null) {
tunnelingOnFrameRenderedListener.destroyHandler(codec);
}
tunnelingOnFrameRenderedListener = new OnFrameRenderedListenerV23(codec); tunnelingOnFrameRenderedListener = new OnFrameRenderedListenerV23(codec);
} }
} }
...@@ -1228,6 +1234,9 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -1228,6 +1234,9 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
MediaCodec codec = getCodec(); MediaCodec codec = getCodec();
// If codec is null then the listener will be instantiated in configureCodec. // If codec is null then the listener will be instantiated in configureCodec.
if (codec != null) { if (codec != null) {
if (tunnelingOnFrameRenderedListener != null) {
tunnelingOnFrameRenderedListener.destroyHandler(codec);
}
tunnelingOnFrameRenderedListener = new OnFrameRenderedListenerV23(codec); tunnelingOnFrameRenderedListener = new OnFrameRenderedListenerV23(codec);
} }
} }
...@@ -1808,8 +1817,23 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -1808,8 +1817,23 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
@TargetApi(23) @TargetApi(23)
private final class OnFrameRenderedListenerV23 implements MediaCodec.OnFrameRenderedListener { private final class OnFrameRenderedListenerV23 implements MediaCodec.OnFrameRenderedListener {
private final Handler handler;
private OnFrameRenderedListenerV23(MediaCodec codec) { private OnFrameRenderedListenerV23(MediaCodec codec) {
codec.setOnFrameRenderedListener(/* listener= */ this, Util.createHandler()); handler = new Handler();
codec.setOnFrameRenderedListener(/* listener= */ this, handler);
}
/**
* Cleanup any messages pending for this listener before removing references to it
*
* @param codec optional, if the codec is still around it should be passed here
*/
void destroyHandler(@Nullable MediaCodec codec) {
if (codec != null) {
codec.setOnFrameRenderedListener(null, null);
}
handler.removeCallbacksAndMessages(null);
} }
@Override @Override
...@@ -1818,12 +1842,32 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -1818,12 +1842,32 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
// Stale event. // Stale event.
return; return;
} }
// Work around bug in MediaCodec that causes deadlocks if you call back a
// MediaCodec API that requires MediaCodec to use it's Looper, as it calls this
// listener method holding locks. This was fixed in:
// https://android-review.googlesource.com/1156807
//
// The work around simply queues the processing to a subsequent message, where
// the lock will not be held.
//
if (Util.SDK_INT < 30) {
handler.post(() -> {
if (this == tunnelingOnFrameRenderedListener) { // event not stale
handleFrameRendered(presentationTimeUs);
}
});
} else {
handleFrameRendered(presentationTimeUs);
}
}
private void handleFrameRendered(long presentationTimeUs) {
if (presentationTimeUs == TUNNELING_EOS_PRESENTATION_TIME_US) { if (presentationTimeUs == TUNNELING_EOS_PRESENTATION_TIME_US) {
onProcessedTunneledEndOfStream(); onProcessedTunneledEndOfStream();
} else { } else {
onProcessedTunneledBuffer(presentationTimeUs); onProcessedTunneledBuffer(presentationTimeUs);
} }
} }
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment