From a99ab62241b19df55fd7743258e280e11abda28e Mon Sep 17 00:00:00 2001 From: krocard Date: Thu, 16 Jan 2020 17:13:51 +0000 Subject: [PATCH] Tunneling timestamp use Message instead of Runnable This avoids allocating a Runnable. PiperOrigin-RevId: 290079660 --- .../exoplayer2/util/ParsableBitArray.java | 2 +- .../google/android/exoplayer2/util/Util.java | 12 +++++++++ .../video/MediaCodecVideoRenderer.java | 27 ++++++++++++++++--- .../android/exoplayer2/util/UtilTest.java | 25 +++++++++++++++++ 4 files changed, 62 insertions(+), 4 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/util/ParsableBitArray.java b/library/core/src/main/java/com/google/android/exoplayer2/util/ParsableBitArray.java index 1d8c3021a5..fc1bc653c6 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/util/ParsableBitArray.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/util/ParsableBitArray.java @@ -195,7 +195,7 @@ public final class ParsableBitArray { if (numBits <= 32) { return Util.toUnsignedLong(readBits(numBits)); } - return Util.toUnsignedLong(readBits(numBits - 32)) << 32 | Util.toUnsignedLong(readBits(32)); + return Util.toLong(readBits(numBits - 32), readBits(32)); } /** diff --git a/library/core/src/main/java/com/google/android/exoplayer2/util/Util.java b/library/core/src/main/java/com/google/android/exoplayer2/util/Util.java index 65ffcf351e..b258e49835 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/util/Util.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/util/Util.java @@ -1229,6 +1229,18 @@ public final class Util { return x & 0xFFFFFFFFL; } + /** + * Return the long that is composed of the bits of the 2 specified integers. + * + * @param mostSignificantBits The 32 most significant bits of the long to return. + * @param leastSignificantBits The 32 least significant bits of the long to return. + * @return a long where its 32 most significant bits are {@code mostSignificantBits} bits and its + * 32 least significant bits are {@code leastSignificantBits}. + */ + public static long toLong(int mostSignificantBits, int leastSignificantBits) { + return (toUnsignedLong(mostSignificantBits) << 32) | toUnsignedLong(leastSignificantBits); + } + /** * Returns a byte array containing values parsed from the hex string provided. * diff --git a/library/core/src/main/java/com/google/android/exoplayer2/video/MediaCodecVideoRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/video/MediaCodecVideoRenderer.java index 1370e2580f..96d4752cd7 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/video/MediaCodecVideoRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/video/MediaCodecVideoRenderer.java @@ -26,6 +26,7 @@ import android.media.MediaCrypto; import android.media.MediaFormat; import android.os.Bundle; import android.os.Handler; +import android.os.Message; import android.os.SystemClock; import android.util.Pair; import android.view.Surface; @@ -1800,13 +1801,16 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { } @TargetApi(23) - private final class OnFrameRenderedListenerV23 implements MediaCodec.OnFrameRenderedListener { + private final class OnFrameRenderedListenerV23 + implements MediaCodec.OnFrameRenderedListener, Handler.Callback { + + private static final int HANDLE_FRAME_RENDERED = 0; private final Handler handler; private final MediaCodec codec; public OnFrameRenderedListenerV23(MediaCodec mediaCodec) { - handler = Util.createHandler(); + handler = Util.createHandler(/* callback= */ this); codec = mediaCodec; codec.setOnFrameRenderedListener(/* listener= */ this, handler); } @@ -1833,12 +1837,29 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { // // The workaround queues the event for subsequent processing, where the lock will not be held. if (Util.SDK_INT < 30) { - handler.postAtFrontOfQueue(() -> handleFrameRendered(presentationTimeUs)); + Message message = + Message.obtain( + handler, + /* what= */ HANDLE_FRAME_RENDERED, + /* arg1= */ (int) (presentationTimeUs >> 32), + /* arg2= */ (int) presentationTimeUs); + handler.sendMessageAtFrontOfQueue(message); } else { handleFrameRendered(presentationTimeUs); } } + @Override + public boolean handleMessage(Message message) { + switch (message.what) { + case HANDLE_FRAME_RENDERED: + handleFrameRendered(Util.toLong(message.arg1, message.arg2)); + return true; + default: + return false; + } + } + private void handleFrameRendered(long presentationTimeUs) { if (this != tunnelingOnFrameRenderedListener) { // Stale event. diff --git a/library/core/src/test/java/com/google/android/exoplayer2/util/UtilTest.java b/library/core/src/test/java/com/google/android/exoplayer2/util/UtilTest.java index 3a972db4b5..07334872e1 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/util/UtilTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/util/UtilTest.java @@ -235,6 +235,31 @@ public class UtilTest { assertThat(result).isEqualTo(0xF5D67F23L); } + @Test + public void testToLongZeroValue() { + assertThat(Util.toLong(0, 0)).isEqualTo(0); + } + + @Test + public void testToLongValue() { + assertThat(Util.toLong(1, -4)).isEqualTo(0x1FFFFFFFCL); + } + + @Test + public void testToLongBigValue() { + assertThat(Util.toLong(0x7ABCDEF, 0x12345678)).isEqualTo(0x7ABCDEF_12345678L); + } + + @Test + public void testToLongMaxValue() { + assertThat(Util.toLong(0x0FFFFFFF, 0xFFFFFFFF)).isEqualTo(0x0FFFFFFF_FFFFFFFFL); + } + + @Test + public void testToLongBigNegativeValue() { + assertThat(Util.toLong(0xFEDCBA, 0x87654321)).isEqualTo(0xFEDCBA_87654321L); + } + @Test public void testGetCodecsOfType() { assertThat(getCodecsOfType(null, C.TRACK_TYPE_VIDEO)).isNull();