mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +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();
|
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 {
|
||||||
}
|
}
|
||||||
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 {
|
||||||
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 {
|
||||||
@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 {
|
||||||
// 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue