Do not hold a codec in OnFrameRenderedListener

Doing so prevent Codec which is a big object with
JNI to be garbage collected.

As the codec can not be hold in the listener, there
is no way to call release, as it must be called on
the same codec.
As a result the release method is also removed.
The downside is that at runtime some callbacks may be
dropped but it should be a short transitive state.

This also simplifies lifecycle of the listener as
the client does not have to know if release needs
to be called or not.

An alternative would have been to hold a weak ref,
but I deemed it too complicated for the
runtime gain.

PiperOrigin-RevId: 290231659
This commit is contained in:
krocard 2020-01-17 09:57:01 +00:00 committed by Oliver Woodman
parent 2859a34027
commit 598538253a

View File

@ -564,7 +564,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
clearReportedVideoSize();
clearRenderedFirstFrame();
frameReleaseTimeHelper.disable();
releaseOnFrameRenderedListener();
tunnelingOnFrameRenderedListener = null;
try {
super.onDisabled();
} finally {
@ -1793,13 +1793,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
}
private void releaseOnFrameRenderedListener() {
if (tunnelingOnFrameRenderedListener != null) {
tunnelingOnFrameRenderedListener.release();
}
tunnelingOnFrameRenderedListener = null;
}
@TargetApi(23)
private final class OnFrameRenderedListenerV23
implements MediaCodec.OnFrameRenderedListener, Handler.Callback {
@ -1807,26 +1800,12 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
private static final int HANDLE_FRAME_RENDERED = 0;
private final Handler handler;
private final MediaCodec codec;
public OnFrameRenderedListenerV23(MediaCodec mediaCodec) {
public OnFrameRenderedListenerV23(MediaCodec codec) {
handler = Util.createHandler(/* callback= */ this);
codec = mediaCodec;
codec.setOnFrameRenderedListener(/* listener= */ this, handler);
}
/**
* Stop listening for the codec OnFrameRendered events and invalidate all queued such events.
*
* <p>Not required when switching one frame render listener for another and may cause overhead
* (MediaCodec calls native_enableOnFrameRenderedListener() twice then). The stale event logic
* prevents issues for a listener switch.
*/
public void release() {
codec.setOnFrameRenderedListener(null, null);
handler.removeCallbacksAndMessages(null);
}
@Override
public void onFrameRendered(MediaCodec codec, long presentationTimeUs, long nanoTime) {
// Workaround bug in MediaCodec that causes deadlock if you call directly back into the