mirror of
https://github.com/samsonjs/media.git
synced 2026-04-04 11:05:47 +00:00
Cleanup tunneled onFrameRenderListener
Cleanup the handler to prevent stale messages and potential handler leaks
This commit is contained in:
parent
45013ece1e
commit
245c9fec5a
1 changed files with 46 additions and 2 deletions
|
|
@ -563,6 +563,9 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||
clearReportedVideoSize();
|
||||
clearRenderedFirstFrame();
|
||||
frameReleaseTimeHelper.disable();
|
||||
if (tunnelingOnFrameRenderedListener != null && getCodec() != null) {
|
||||
tunnelingOnFrameRenderedListener.destroyHandler(getCodec());
|
||||
}
|
||||
tunnelingOnFrameRenderedListener = null;
|
||||
try {
|
||||
super.onDisabled();
|
||||
|
|
@ -687,6 +690,9 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||
}
|
||||
codec.configure(mediaFormat, surface, crypto, 0);
|
||||
if (Util.SDK_INT >= 23 && tunneling) {
|
||||
if (tunnelingOnFrameRenderedListener != null) {
|
||||
tunnelingOnFrameRenderedListener.destroyHandler(codec);
|
||||
}
|
||||
tunnelingOnFrameRenderedListener = new OnFrameRenderedListenerV23(codec);
|
||||
}
|
||||
}
|
||||
|
|
@ -1228,6 +1234,9 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||
MediaCodec codec = getCodec();
|
||||
// If codec is null then the listener will be instantiated in configureCodec.
|
||||
if (codec != null) {
|
||||
if (tunnelingOnFrameRenderedListener != null) {
|
||||
tunnelingOnFrameRenderedListener.destroyHandler(codec);
|
||||
}
|
||||
tunnelingOnFrameRenderedListener = new OnFrameRenderedListenerV23(codec);
|
||||
}
|
||||
}
|
||||
|
|
@ -1808,8 +1817,23 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||
@TargetApi(23)
|
||||
private final class OnFrameRenderedListenerV23 implements MediaCodec.OnFrameRenderedListener {
|
||||
|
||||
private final Handler handler;
|
||||
|
||||
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
|
||||
|
|
@ -1818,12 +1842,32 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||
// Stale event.
|
||||
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) {
|
||||
onProcessedTunneledEndOfStream();
|
||||
} else {
|
||||
onProcessedTunneledBuffer(presentationTimeUs);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue