From 72f26d79f6f74e20f346fd400de4c4babe59ca5c Mon Sep 17 00:00:00 2001 From: Colin Kho Date: Thu, 5 Sep 2024 22:51:49 -0700 Subject: [PATCH 1/8] Added a forwarding class for Renderer to support composing custom behavior on Metadata & Text Renderers --- .../media3/exoplayer/ForwardingRenderer.java | 156 ++++++++++++++++++ .../audio/ForwardingRendererTest.java | 27 +++ 2 files changed, 183 insertions(+) create mode 100644 libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ForwardingRenderer.java create mode 100644 libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/ForwardingRendererTest.java diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ForwardingRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ForwardingRenderer.java new file mode 100644 index 0000000000..8996384c43 --- /dev/null +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ForwardingRenderer.java @@ -0,0 +1,156 @@ +package androidx.media3.exoplayer; + +import androidx.annotation.Nullable; +import androidx.media3.common.C; +import androidx.media3.common.Format; +import androidx.media3.common.Timeline; +import androidx.media3.common.util.Clock; +import androidx.media3.exoplayer.analytics.PlayerId; +import androidx.media3.exoplayer.source.MediaSource; +import androidx.media3.exoplayer.source.SampleStream; +import java.io.IOException; + +/** An overridable {@link ForwardingRenderer} implementation forwarding all methods to another renderer. */ +public class ForwardingRenderer implements Renderer { + + private final Renderer renderer; + + public ForwardingRenderer(Renderer renderer) { + this.renderer = renderer; + } + + @Override + public void handleMessage(@MessageType int messageType, @Nullable Object message) + throws ExoPlaybackException { + renderer.handleMessage(messageType, message); + } + + @Override + public String getName() { + return renderer.getName(); + } + + @Override + @C.TrackType + public int getTrackType() { + return renderer.getTrackType(); + } + + @Override + public RendererCapabilities getCapabilities() { + return renderer.getCapabilities(); + } + + @Override + public void init(int index, PlayerId playerId, Clock clock) { + renderer.init(index, playerId, clock); + } + + @Nullable + @Override + public MediaClock getMediaClock() { + return renderer.getMediaClock(); + } + + @Override + public @State int getState() { + return renderer.getState(); + } + + @Override + public void enable( + RendererConfiguration configuration, + Format[] formats, + SampleStream stream, + long positionUs, + boolean joining, + boolean mayRenderStartOfStream, + long startPositionUs, + long offsetUs, + MediaSource.MediaPeriodId mediaPeriodId) throws ExoPlaybackException { + renderer.enable(configuration, formats, stream, positionUs, joining, + mayRenderStartOfStream, startPositionUs, offsetUs, mediaPeriodId); + } + + @Override + public void start() throws ExoPlaybackException { + renderer.start(); + } + + @Override + public void replaceStream(Format[] formats, SampleStream stream, long startPositionUs, + long offsetUs, MediaSource.MediaPeriodId mediaPeriodId) throws ExoPlaybackException { + renderer.replaceStream(formats, stream, startPositionUs, offsetUs, mediaPeriodId); + } + + @Nullable + @Override + public SampleStream getStream() { + return renderer.getStream(); + } + + @Override + public boolean hasReadStreamToEnd() { + return renderer.hasReadStreamToEnd(); + } + + @Override + public long getReadingPositionUs() { + return renderer.getReadingPositionUs(); + } + + @Override + public void setCurrentStreamFinal() { + renderer.setCurrentStreamFinal(); + } + + @Override + public boolean isCurrentStreamFinal() { + return renderer.isCurrentStreamFinal(); + } + + @Override + public void maybeThrowStreamError() throws IOException { + renderer.maybeThrowStreamError(); + } + + @Override + public void resetPosition(long positionUs) throws ExoPlaybackException { + renderer.resetPosition(positionUs); + } + + @Override + public void setTimeline(Timeline timeline) { + + } + + @Override + public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException { + renderer.render(positionUs, elapsedRealtimeUs); + } + + @Override + public boolean isReady() { + return renderer.isReady(); + } + + @Override + public boolean isEnded() { + return renderer.isEnded(); + } + + @Override + public void stop() { + renderer.stop(); + } + + @Override + public void disable() { + renderer.disable(); + } + + @Override + public void reset() { + renderer.reset(); + } +} diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/ForwardingRendererTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/ForwardingRendererTest.java new file mode 100644 index 0000000000..ed65e25137 --- /dev/null +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/ForwardingRendererTest.java @@ -0,0 +1,27 @@ +package androidx.media3.exoplayer.audio; + +import static com.google.common.truth.Truth.assertThat; + +import androidx.media3.exoplayer.ForwardingRenderer; +import androidx.media3.exoplayer.Renderer; +import androidx.media3.test.utils.TestUtil; +import java.lang.reflect.Method; +import java.util.List; +import org.junit.Test; + +public class ForwardingRendererTest { + @Test + public void forwardingRenderer_overridesAllMethods() throws NoSuchMethodException { + // Check with reflection that ForwardingRenderer overrides all Renderer methods. + List methods = TestUtil.getPublicMethods(Renderer.class); + for (Method method : methods) { + if (!method.isDefault()) { + assertThat( + ForwardingRenderer.class + .getDeclaredMethod(method.getName(), method.getParameterTypes()) + .getDeclaringClass()) + .isEqualTo(ForwardingRenderer.class); + } + } + } +} From 72e39c91c47830b52daf1ac21fd124879491ba16 Mon Sep 17 00:00:00 2001 From: Colin Kho Date: Fri, 6 Sep 2024 10:06:54 -0700 Subject: [PATCH 2/8] Denote ForwardingRenderer as subject to change --- .../main/java/androidx/media3/exoplayer/ForwardingRenderer.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ForwardingRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ForwardingRenderer.java index 8996384c43..3c1b36976c 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ForwardingRenderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ForwardingRenderer.java @@ -5,12 +5,14 @@ import androidx.media3.common.C; import androidx.media3.common.Format; import androidx.media3.common.Timeline; import androidx.media3.common.util.Clock; +import androidx.media3.common.util.UnstableApi; import androidx.media3.exoplayer.analytics.PlayerId; import androidx.media3.exoplayer.source.MediaSource; import androidx.media3.exoplayer.source.SampleStream; import java.io.IOException; /** An overridable {@link ForwardingRenderer} implementation forwarding all methods to another renderer. */ +@UnstableApi public class ForwardingRenderer implements Renderer { private final Renderer renderer; From 62aef96b7dc6fbc638c4a4da27a16f40b08981fa Mon Sep 17 00:00:00 2001 From: Colin Kho Date: Fri, 6 Sep 2024 10:11:35 -0700 Subject: [PATCH 3/8] Format code using google java format --- .../media3/exoplayer/ForwardingRenderer.java | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ForwardingRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ForwardingRenderer.java index 3c1b36976c..2d543dd4a3 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ForwardingRenderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ForwardingRenderer.java @@ -11,7 +11,10 @@ import androidx.media3.exoplayer.source.MediaSource; import androidx.media3.exoplayer.source.SampleStream; import java.io.IOException; -/** An overridable {@link ForwardingRenderer} implementation forwarding all methods to another renderer. */ +/** + * An overridable {@link ForwardingRenderer} implementation forwarding all methods to another + * renderer. + */ @UnstableApi public class ForwardingRenderer implements Renderer { @@ -69,9 +72,18 @@ public class ForwardingRenderer implements Renderer { boolean mayRenderStartOfStream, long startPositionUs, long offsetUs, - MediaSource.MediaPeriodId mediaPeriodId) throws ExoPlaybackException { - renderer.enable(configuration, formats, stream, positionUs, joining, - mayRenderStartOfStream, startPositionUs, offsetUs, mediaPeriodId); + MediaSource.MediaPeriodId mediaPeriodId) + throws ExoPlaybackException { + renderer.enable( + configuration, + formats, + stream, + positionUs, + joining, + mayRenderStartOfStream, + startPositionUs, + offsetUs, + mediaPeriodId); } @Override @@ -80,8 +92,13 @@ public class ForwardingRenderer implements Renderer { } @Override - public void replaceStream(Format[] formats, SampleStream stream, long startPositionUs, - long offsetUs, MediaSource.MediaPeriodId mediaPeriodId) throws ExoPlaybackException { + public void replaceStream( + Format[] formats, + SampleStream stream, + long startPositionUs, + long offsetUs, + MediaSource.MediaPeriodId mediaPeriodId) + throws ExoPlaybackException { renderer.replaceStream(formats, stream, startPositionUs, offsetUs, mediaPeriodId); } @@ -122,9 +139,7 @@ public class ForwardingRenderer implements Renderer { } @Override - public void setTimeline(Timeline timeline) { - - } + public void setTimeline(Timeline timeline) {} @Override public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException { From 8ca12338f699b66250d026aa4ab679c40bd73f61 Mon Sep 17 00:00:00 2001 From: Rohit Singh Date: Mon, 16 Sep 2024 12:31:42 +0100 Subject: [PATCH 4/8] Format with google-java-format --- .../media3/exoplayer/audio/ForwardingRendererTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/ForwardingRendererTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/ForwardingRendererTest.java index ed65e25137..f44bbefe2b 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/ForwardingRendererTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/ForwardingRendererTest.java @@ -17,9 +17,9 @@ public class ForwardingRendererTest { for (Method method : methods) { if (!method.isDefault()) { assertThat( - ForwardingRenderer.class - .getDeclaredMethod(method.getName(), method.getParameterTypes()) - .getDeclaringClass()) + ForwardingRenderer.class + .getDeclaredMethod(method.getName(), method.getParameterTypes()) + .getDeclaringClass()) .isEqualTo(ForwardingRenderer.class); } } From 3c6f1f1e77d0d0d6c62f8c4fe5fc51f0f7a823a8 Mon Sep 17 00:00:00 2001 From: Rohit Singh Date: Mon, 16 Sep 2024 12:36:03 +0100 Subject: [PATCH 5/8] Add copyright text and move test to correct package --- .../media3/exoplayer/ForwardingRenderer.java | 15 +++++++++++++++ .../{audio => }/ForwardingRendererTest.java | 17 ++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) rename libraries/exoplayer/src/test/java/androidx/media3/exoplayer/{audio => }/ForwardingRendererTest.java (57%) diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ForwardingRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ForwardingRenderer.java index 2d543dd4a3..5586984da0 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ForwardingRenderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ForwardingRenderer.java @@ -1,3 +1,18 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package androidx.media3.exoplayer; import androidx.annotation.Nullable; diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/ForwardingRendererTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ForwardingRendererTest.java similarity index 57% rename from libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/ForwardingRendererTest.java rename to libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ForwardingRendererTest.java index f44bbefe2b..1af6478a2e 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/ForwardingRendererTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ForwardingRendererTest.java @@ -1,4 +1,19 @@ -package androidx.media3.exoplayer.audio; +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package androidx.media3.exoplayer; import static com.google.common.truth.Truth.assertThat; From 99751757008b728dfcb14804d380a836d2fe8cef Mon Sep 17 00:00:00 2001 From: Rohit Singh Date: Mon, 16 Sep 2024 13:01:54 +0100 Subject: [PATCH 6/8] Forward default methods --- .../media3/exoplayer/ForwardingRenderer.java | 22 +++++++++++++++++++ .../exoplayer/ForwardingRendererTest.java | 18 +++++++-------- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ForwardingRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ForwardingRenderer.java index 5586984da0..f1e7a55ab0 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ForwardingRenderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ForwardingRenderer.java @@ -35,6 +35,7 @@ public class ForwardingRenderer implements Renderer { private final Renderer renderer; + /** Creates a new instance that forwards all operations to {@code renderer}. */ public ForwardingRenderer(Renderer renderer) { this.renderer = renderer; } @@ -133,6 +134,11 @@ public class ForwardingRenderer implements Renderer { return renderer.getReadingPositionUs(); } + @Override + public long getDurationToProgressUs(long positionUs, long elapsedRealtimeUs) { + return renderer.getDurationToProgressUs(positionUs, elapsedRealtimeUs); + } + @Override public void setCurrentStreamFinal() { renderer.setCurrentStreamFinal(); @@ -153,6 +159,17 @@ public class ForwardingRenderer implements Renderer { renderer.resetPosition(positionUs); } + @Override + public void setPlaybackSpeed(float currentPlaybackSpeed, float targetPlaybackSpeed) + throws ExoPlaybackException { + renderer.setPlaybackSpeed(currentPlaybackSpeed, targetPlaybackSpeed); + } + + @Override + public void enableMayRenderStartOfStream() { + renderer.enableMayRenderStartOfStream(); + } + @Override public void setTimeline(Timeline timeline) {} @@ -185,4 +202,9 @@ public class ForwardingRenderer implements Renderer { public void reset() { renderer.reset(); } + + @Override + public void release() { + renderer.release(); + } } diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ForwardingRendererTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ForwardingRendererTest.java index 1af6478a2e..93c27792c7 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ForwardingRendererTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ForwardingRendererTest.java @@ -17,26 +17,26 @@ package androidx.media3.exoplayer; import static com.google.common.truth.Truth.assertThat; -import androidx.media3.exoplayer.ForwardingRenderer; -import androidx.media3.exoplayer.Renderer; import androidx.media3.test.utils.TestUtil; +import androidx.test.ext.junit.runners.AndroidJUnit4; import java.lang.reflect.Method; import java.util.List; import org.junit.Test; +import org.junit.runner.RunWith; +/** Unit tests for {@link ForwardingRenderer}. */ +@RunWith(AndroidJUnit4.class) public class ForwardingRendererTest { @Test public void forwardingRenderer_overridesAllMethods() throws NoSuchMethodException { // Check with reflection that ForwardingRenderer overrides all Renderer methods. List methods = TestUtil.getPublicMethods(Renderer.class); for (Method method : methods) { - if (!method.isDefault()) { - assertThat( - ForwardingRenderer.class - .getDeclaredMethod(method.getName(), method.getParameterTypes()) - .getDeclaringClass()) - .isEqualTo(ForwardingRenderer.class); - } + assertThat( + ForwardingRenderer.class + .getDeclaredMethod(method.getName(), method.getParameterTypes()) + .getDeclaringClass()) + .isEqualTo(ForwardingRenderer.class); } } } From 11aea9b34b83e49348d20d213b34e0dd45aee3c3 Mon Sep 17 00:00:00 2001 From: Rohit Singh Date: Mon, 16 Sep 2024 13:15:40 +0100 Subject: [PATCH 7/8] Add RELEASENOTES --- RELEASENOTES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index b213d5a349..959ca6fc86 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -17,6 +17,9 @@ need to pass a value representing a specific duration from the default start position for which the corresponding media source has to be preloaded with this IntDef, instead of a position. + * Add `ForwardingRenderer` implementation that forwards all method calls + to another renderer + ([1703](https://github.com/androidx/media/pull/1703)). * Transformer: * Track Selection: * Extractors: From c8aa122e8ae9c1930b14e4898fb0fa310ec64cf7 Mon Sep 17 00:00:00 2001 From: Rohit Singh Date: Mon, 16 Sep 2024 13:22:29 +0100 Subject: [PATCH 8/8] Change from internal review --- .../media3/exoplayer/ForwardingRenderer.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ForwardingRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ForwardingRenderer.java index f1e7a55ab0..93408d9c2a 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ForwardingRenderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ForwardingRenderer.java @@ -26,10 +26,7 @@ import androidx.media3.exoplayer.source.MediaSource; import androidx.media3.exoplayer.source.SampleStream; import java.io.IOException; -/** - * An overridable {@link ForwardingRenderer} implementation forwarding all methods to another - * renderer. - */ +/** An overridable {@link Renderer} implementation forwarding all methods to another renderer. */ @UnstableApi public class ForwardingRenderer implements Renderer { @@ -52,8 +49,7 @@ public class ForwardingRenderer implements Renderer { } @Override - @C.TrackType - public int getTrackType() { + public @C.TrackType int getTrackType() { return renderer.getTrackType(); } @@ -171,7 +167,9 @@ public class ForwardingRenderer implements Renderer { } @Override - public void setTimeline(Timeline timeline) {} + public void setTimeline(Timeline timeline) { + renderer.setTimeline(timeline); + } @Override public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {