From 71bfdd1bcebd4414c232cd5b5613b9153e2d216d Mon Sep 17 00:00:00 2001 From: michaelkatz Date: Wed, 6 Mar 2024 08:47:42 -0800 Subject: [PATCH] Start early-enabled renderers only after advancing the playing period Renderers may be enabled for subsequent media items as soon as the current media item's renderer's isEnded() returns true. When a renderer is being enabled and the player is 'playing', that renderer is also started. When playing a mixed playlist of images and content with audio & video, the player may skip some image items because the early-starting of the audio renderer causes a clock update. A solution is to only start the "early-enabled" renderers at the point of media transition and add a condition on DefaultMediaClock to use the standalone clock when reading-ahead and the renderer clock source is not in a started state. Issue: androidx/media#1017 PiperOrigin-RevId: 613231227 (cherry picked from commit 638b2a3c86f7362041b09faed7c3c09609e29118) --- RELEASENOTES.md | 3 + .../media3/exoplayer/DefaultMediaClock.java | 6 +- .../exoplayer/ExoPlayerImplInternal.java | 26 +- .../e2etest/PlaylistPlaybackTest.java | 41 ++ .../src/test/assets/media/png/media3test.png | Bin 0 -> 7256 bytes .../playlists/image_av_playlist.dump | 692 ++++++++++++++++++ 6 files changed, 761 insertions(+), 7 deletions(-) create mode 100644 libraries/test_data/src/test/assets/media/png/media3test.png create mode 100644 libraries/test_data/src/test/assets/playbackdumps/playlists/image_av_playlist.dump diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 49d102f5269..daacea1a5e5 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -7,6 +7,9 @@ is preloaded again. * Apply the correct corresponding `TrackSelectionResult` to the playing period in track reselection. + * Start early-enabled renderers only after advancing the playing period + when transitioning between media items + ([#1017](https://github.com/androidx/media/issues/1017)). * Transformer: * Add workaround for exception thrown due to `MediaMuxer` not supporting negative presentation timestamps before API 30. diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/DefaultMediaClock.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/DefaultMediaClock.java index 7677a0c5e69..6bfd495fd49 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/DefaultMediaClock.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/DefaultMediaClock.java @@ -15,6 +15,8 @@ */ package androidx.media3.exoplayer; +import static androidx.media3.exoplayer.Renderer.STATE_STARTED; + import androidx.annotation.Nullable; import androidx.media3.common.PlaybackException; import androidx.media3.common.PlaybackParameters; @@ -192,12 +194,14 @@ private void syncClocks(boolean isReadingAhead) { } private boolean shouldUseStandaloneClock(boolean isReadingAhead) { - // Use the standalone clock if the clock providing renderer is not set or has ended. Also use + // Use the standalone clock if the clock providing renderer is not set or has ended. Use the + // standalone clock if reading ahead and the renderer is not in a started state. Also use // the standalone clock if the renderer is not ready and we have finished reading the stream or // are reading ahead to avoid getting stuck if tracks in the current period have uneven // durations. See: https://github.com/google/ExoPlayer/issues/1874. return rendererClockSource == null || rendererClockSource.isEnded() + || (isReadingAhead && rendererClockSource.getState() != STATE_STARTED) || (!rendererClockSource.isReady() && (isReadingAhead || rendererClockSource.hasReadStreamToEnd())); } diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImplInternal.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImplInternal.java index 26e6b63274f..27e9ed1496c 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImplInternal.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImplInternal.java @@ -18,6 +18,9 @@ import static androidx.media3.common.util.Assertions.checkNotNull; import static androidx.media3.common.util.Util.castNonNull; import static androidx.media3.common.util.Util.msToUs; +import static androidx.media3.exoplayer.Renderer.STATE_DISABLED; +import static androidx.media3.exoplayer.Renderer.STATE_ENABLED; +import static androidx.media3.exoplayer.Renderer.STATE_STARTED; import static androidx.media3.exoplayer.audio.AudioSink.OFFLOAD_MODE_DISABLED; import static java.lang.Math.max; import static java.lang.Math.min; @@ -76,6 +79,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; @@ -1777,7 +1781,7 @@ private void maybeTriggerPendingMessages(long oldPeriodPositionUs, long newPerio } private void ensureStopped(Renderer renderer) { - if (renderer.getState() == Renderer.STATE_STARTED) { + if (renderer.getState() == STATE_STARTED) { renderer.stop(); } } @@ -2319,6 +2323,16 @@ private void maybeUpdatePlayingPeriod() throws ExoPlaybackException { Player.DISCONTINUITY_REASON_AUTO_TRANSITION); resetPendingPauseAtEndOfPeriod(); updatePlaybackPositions(); + if (playbackInfo.playbackState == Player.STATE_READY) { + for (int i = 0; i < renderers.length; i++) { + if (renderers[i].getState() == STATE_ENABLED + && queue.getPlayingPeriod() != null + && Objects.equals( + renderers[i].getStream(), queue.getPlayingPeriod().sampleStreams[i])) { + renderers[i].start(); + } + } + } allowRenderersToRenderStartOfStreams(); advancedPlayingPeriod = true; } @@ -2665,7 +2679,7 @@ private void enableRenderer(int rendererIndex, boolean wasRendererEnabled, long return; } MediaPeriodHolder periodHolder = queue.getReadingPeriod(); - boolean mayRenderStartOfStream = periodHolder == queue.getPlayingPeriod(); + boolean arePlayingAndReadingTheSamePeriod = periodHolder == queue.getPlayingPeriod(); TrackSelectorResult trackSelectorResult = periodHolder.getTrackSelectorResult(); RendererConfiguration rendererConfiguration = trackSelectorResult.rendererConfigurations[rendererIndex]; @@ -2684,7 +2698,7 @@ private void enableRenderer(int rendererIndex, boolean wasRendererEnabled, long periodHolder.sampleStreams[rendererIndex], rendererPositionUs, joining, - mayRenderStartOfStream, + /* mayRenderStartOfStream= */ arePlayingAndReadingTheSamePeriod, startPositionUs, periodHolder.getRendererOffset(), periodHolder.info.id); @@ -2703,8 +2717,8 @@ public void onWakeup() { }); mediaClock.onRendererEnabled(renderer); - // Start the renderer if playing. - if (playing) { + // Start the renderer if playing and the Playing and Reading periods are the same. + if (playing && arePlayingAndReadingTheSamePeriod) { renderer.start(); } } @@ -3224,7 +3238,7 @@ private static Format[] getFormats(ExoTrackSelection newSelection) { } private static boolean isRendererEnabled(Renderer renderer) { - return renderer.getState() != Renderer.STATE_DISABLED; + return renderer.getState() != STATE_DISABLED; } private static final class SeekPosition { diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/e2etest/PlaylistPlaybackTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/e2etest/PlaylistPlaybackTest.java index 5fcebe2c6d2..7c5d0dfb11a 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/e2etest/PlaylistPlaybackTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/e2etest/PlaylistPlaybackTest.java @@ -15,6 +15,9 @@ */ package androidx.media3.exoplayer.e2etest; +import static com.google.common.truth.Truth.assertThat; +import static org.robolectric.annotation.GraphicsMode.Mode.NATIVE; + import android.content.Context; import android.graphics.SurfaceTexture; import android.net.Uri; @@ -23,6 +26,7 @@ import androidx.media3.common.MediaItem; import androidx.media3.common.MimeTypes; import androidx.media3.common.Player; +import androidx.media3.common.util.Clock; import androidx.media3.exoplayer.ExoPlayer; import androidx.media3.exoplayer.source.DefaultMediaSourceFactory; import androidx.media3.exoplayer.source.MediaSource; @@ -38,9 +42,11 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.robolectric.annotation.GraphicsMode; /** End-to-end tests for playlists. */ @RunWith(AndroidJUnit4.class) +@GraphicsMode(value = NATIVE) public final class PlaylistPlaybackTest { @Rule @@ -141,4 +147,39 @@ public void test_subtitle() throws Exception { DumpFileAsserts.assertOutput( applicationContext, playbackOutput, "playbackdumps/playlists/playlist_with_subtitles.dump"); } + + @Test + public void testPlaylist_withImageAndAudioVideoItems_rendersExpectedContent() throws Exception { + Context applicationContext = ApplicationProvider.getApplicationContext(); + CapturingRenderersFactory renderersFactory = new CapturingRenderersFactory(applicationContext); + Clock clock = new FakeClock(/* isAutoAdvancing= */ true); + ExoPlayer player = + new ExoPlayer.Builder(applicationContext, renderersFactory).setClock(clock).build(); + PlaybackOutput playbackOutput = PlaybackOutput.register(player, renderersFactory); + long durationMs = 5 * C.MILLIS_PER_SECOND; + player.setMediaItems( + ImmutableList.of( + new MediaItem.Builder() + .setUri("asset:///media/png/media3test.png") + .setImageDurationMs(durationMs) + .build(), + new MediaItem.Builder() + .setUri("asset:///media/png/media3test.png") + .setImageDurationMs(durationMs) + .build(), + MediaItem.fromUri("asset:///media/mp4/sample.mp4"))); + player.prepare(); + + TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_READY); + long playerStartedMs = clock.elapsedRealtime(); + player.play(); + TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_ENDED); + long playbackDurationMs = clock.elapsedRealtime() - playerStartedMs; + player.release(); + + // Playback duration should be greater than the sum of the image item durations. + assertThat(playbackDurationMs).isGreaterThan(durationMs * 2); + DumpFileAsserts.assertOutput( + applicationContext, playbackOutput, "playbackdumps/playlists/image_av_playlist.dump"); + } } diff --git a/libraries/test_data/src/test/assets/media/png/media3test.png b/libraries/test_data/src/test/assets/media/png/media3test.png new file mode 100644 index 0000000000000000000000000000000000000000..9432c93ec8ab13be3fbde2cb2d715b524d089f93 GIT binary patch literal 7256 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 WC8th5j|=#t0wgc3B2^_}68t}G!@bi0 literal 0 HcmV?d00001 diff --git a/libraries/test_data/src/test/assets/playbackdumps/playlists/image_av_playlist.dump b/libraries/test_data/src/test/assets/playbackdumps/playlists/image_av_playlist.dump new file mode 100644 index 00000000000..00d59671985 --- /dev/null +++ b/libraries/test_data/src/test/assets/playbackdumps/playlists/image_av_playlist.dump @@ -0,0 +1,692 @@ +MediaCodecAdapter (exotest.audio.aac): + inputBuffers: + count = 46 + input buffer #0: + timeUs = 1000010044000 + contents = length 23, hash 47DE9131 + input buffer #1: + timeUs = 1000010067219 + contents = length 6, hash 31EC5206 + input buffer #2: + timeUs = 1000010090439 + contents = length 148, hash 894A176B + input buffer #3: + timeUs = 1000010113659 + contents = length 189, hash CEF235A1 + input buffer #4: + timeUs = 1000010136879 + contents = length 205, hash BBF5F7B0 + input buffer #5: + timeUs = 1000010160099 + contents = length 210, hash F278B193 + input buffer #6: + timeUs = 1000010183319 + contents = length 210, hash 82DA1589 + input buffer #7: + timeUs = 1000010206539 + contents = length 207, hash 5BE231DF + input buffer #8: + timeUs = 1000010229759 + contents = length 225, hash 18819EE1 + input buffer #9: + timeUs = 1000010252979 + contents = length 215, hash CA7FA67B + input buffer #10: + timeUs = 1000010276199 + contents = length 211, hash 581A1C18 + input buffer #11: + timeUs = 1000010299419 + contents = length 216, hash ADB88187 + input buffer #12: + timeUs = 1000010322639 + contents = length 229, hash 2E8BA4DC + input buffer #13: + timeUs = 1000010345859 + contents = length 232, hash 22F0C510 + input buffer #14: + timeUs = 1000010369079 + contents = length 235, hash 867AD0DC + input buffer #15: + timeUs = 1000010392299 + contents = length 231, hash 84E823A8 + input buffer #16: + timeUs = 1000010415519 + contents = length 226, hash 1BEF3A95 + input buffer #17: + timeUs = 1000010438739 + contents = length 216, hash EAA345AE + input buffer #18: + timeUs = 1000010461959 + contents = length 229, hash 6957411F + input buffer #19: + timeUs = 1000010485179 + contents = length 219, hash 41275022 + input buffer #20: + timeUs = 1000010508399 + contents = length 241, hash 6495DF96 + input buffer #21: + timeUs = 1000010531619 + contents = length 228, hash 63D95906 + input buffer #22: + timeUs = 1000010554839 + contents = length 238, hash 34F676F9 + input buffer #23: + timeUs = 1000010578058 + contents = length 234, hash E5CBC045 + input buffer #24: + timeUs = 1000010601278 + contents = length 231, hash 5FC43661 + input buffer #25: + timeUs = 1000010624498 + contents = length 217, hash 682708ED + input buffer #26: + timeUs = 1000010647718 + contents = length 239, hash D43780FC + input buffer #27: + timeUs = 1000010670938 + contents = length 243, hash C5E17980 + input buffer #28: + timeUs = 1000010694158 + contents = length 231, hash AC5837BA + input buffer #29: + timeUs = 1000010717378 + contents = length 230, hash 169EE895 + input buffer #30: + timeUs = 1000010740598 + contents = length 238, hash C48FF3F1 + input buffer #31: + timeUs = 1000010763818 + contents = length 225, hash 531E4599 + input buffer #32: + timeUs = 1000010787038 + contents = length 232, hash CB3C6B8D + input buffer #33: + timeUs = 1000010810258 + contents = length 243, hash F8C94C7 + input buffer #34: + timeUs = 1000010833478 + contents = length 232, hash A646A7D0 + input buffer #35: + timeUs = 1000010856698 + contents = length 237, hash E8B787A5 + input buffer #36: + timeUs = 1000010879918 + contents = length 228, hash 3FA7A29F + input buffer #37: + timeUs = 1000010903138 + contents = length 235, hash B9B33B0A + input buffer #38: + timeUs = 1000010926358 + contents = length 264, hash 71A4869E + input buffer #39: + timeUs = 1000010949578 + contents = length 257, hash D049B54C + input buffer #40: + timeUs = 1000010972798 + contents = length 227, hash 66757231 + input buffer #41: + timeUs = 1000010996018 + contents = length 227, hash BD374F1B + input buffer #42: + timeUs = 1000011019238 + contents = length 235, hash 999477F6 + input buffer #43: + timeUs = 1000011042458 + contents = length 229, hash FFF98DF0 + input buffer #44: + timeUs = 1000011065678 + contents = length 6, hash 31B22286 + input buffer #45: + timeUs = 0 + flags = 4 + contents = length 0, hash 1 + outputBuffers: + count = 45 + output buffer #0: + timeUs = 1000010044000 + size = 0 + rendered = false + output buffer #1: + timeUs = 1000010067219 + size = 0 + rendered = false + output buffer #2: + timeUs = 1000010090439 + size = 0 + rendered = false + output buffer #3: + timeUs = 1000010113659 + size = 0 + rendered = false + output buffer #4: + timeUs = 1000010136879 + size = 0 + rendered = false + output buffer #5: + timeUs = 1000010160099 + size = 0 + rendered = false + output buffer #6: + timeUs = 1000010183319 + size = 0 + rendered = false + output buffer #7: + timeUs = 1000010206539 + size = 0 + rendered = false + output buffer #8: + timeUs = 1000010229759 + size = 0 + rendered = false + output buffer #9: + timeUs = 1000010252979 + size = 0 + rendered = false + output buffer #10: + timeUs = 1000010276199 + size = 0 + rendered = false + output buffer #11: + timeUs = 1000010299419 + size = 0 + rendered = false + output buffer #12: + timeUs = 1000010322639 + size = 0 + rendered = false + output buffer #13: + timeUs = 1000010345859 + size = 0 + rendered = false + output buffer #14: + timeUs = 1000010369079 + size = 0 + rendered = false + output buffer #15: + timeUs = 1000010392299 + size = 0 + rendered = false + output buffer #16: + timeUs = 1000010415519 + size = 0 + rendered = false + output buffer #17: + timeUs = 1000010438739 + size = 0 + rendered = false + output buffer #18: + timeUs = 1000010461959 + size = 0 + rendered = false + output buffer #19: + timeUs = 1000010485179 + size = 0 + rendered = false + output buffer #20: + timeUs = 1000010508399 + size = 0 + rendered = false + output buffer #21: + timeUs = 1000010531619 + size = 0 + rendered = false + output buffer #22: + timeUs = 1000010554839 + size = 0 + rendered = false + output buffer #23: + timeUs = 1000010578058 + size = 0 + rendered = false + output buffer #24: + timeUs = 1000010601278 + size = 0 + rendered = false + output buffer #25: + timeUs = 1000010624498 + size = 0 + rendered = false + output buffer #26: + timeUs = 1000010647718 + size = 0 + rendered = false + output buffer #27: + timeUs = 1000010670938 + size = 0 + rendered = false + output buffer #28: + timeUs = 1000010694158 + size = 0 + rendered = false + output buffer #29: + timeUs = 1000010717378 + size = 0 + rendered = false + output buffer #30: + timeUs = 1000010740598 + size = 0 + rendered = false + output buffer #31: + timeUs = 1000010763818 + size = 0 + rendered = false + output buffer #32: + timeUs = 1000010787038 + size = 0 + rendered = false + output buffer #33: + timeUs = 1000010810258 + size = 0 + rendered = false + output buffer #34: + timeUs = 1000010833478 + size = 0 + rendered = false + output buffer #35: + timeUs = 1000010856698 + size = 0 + rendered = false + output buffer #36: + timeUs = 1000010879918 + size = 0 + rendered = false + output buffer #37: + timeUs = 1000010903138 + size = 0 + rendered = false + output buffer #38: + timeUs = 1000010926358 + size = 0 + rendered = false + output buffer #39: + timeUs = 1000010949578 + size = 0 + rendered = false + output buffer #40: + timeUs = 1000010972798 + size = 0 + rendered = false + output buffer #41: + timeUs = 1000010996018 + size = 0 + rendered = false + output buffer #42: + timeUs = 1000011019238 + size = 0 + rendered = false + output buffer #43: + timeUs = 1000011042458 + size = 0 + rendered = false + output buffer #44: + timeUs = 1000011065678 + size = 0 + rendered = false +MediaCodecAdapter (exotest.video.avc): + inputBuffers: + count = 31 + input buffer #0: + timeUs = 1000010000000 + contents = length 36692, hash D216076E + input buffer #1: + timeUs = 1000010066733 + contents = length 5312, hash D45D3CA0 + input buffer #2: + timeUs = 1000010033366 + contents = length 599, hash 1BE7812D + input buffer #3: + timeUs = 1000010200200 + contents = length 7735, hash 4490F110 + input buffer #4: + timeUs = 1000010133466 + contents = length 987, hash 560B5036 + input buffer #5: + timeUs = 1000010100100 + contents = length 673, hash ED7CD8C7 + input buffer #6: + timeUs = 1000010166833 + contents = length 523, hash 3020DF50 + input buffer #7: + timeUs = 1000010333666 + contents = length 6061, hash 736C72B2 + input buffer #8: + timeUs = 1000010266933 + contents = length 992, hash FE132F23 + input buffer #9: + timeUs = 1000010233566 + contents = length 623, hash 5B2C1816 + input buffer #10: + timeUs = 1000010300300 + contents = length 421, hash 742E69C1 + input buffer #11: + timeUs = 1000010433766 + contents = length 4899, hash F72F86A1 + input buffer #12: + timeUs = 1000010400400 + contents = length 568, hash 519A8E50 + input buffer #13: + timeUs = 1000010367033 + contents = length 620, hash 3990AA39 + input buffer #14: + timeUs = 1000010567233 + contents = length 5450, hash F06EC4AA + input buffer #15: + timeUs = 1000010500500 + contents = length 1051, hash 92DFA63A + input buffer #16: + timeUs = 1000010467133 + contents = length 874, hash 69587FB4 + input buffer #17: + timeUs = 1000010533866 + contents = length 781, hash 36BE495B + input buffer #18: + timeUs = 1000010700700 + contents = length 4725, hash AC0C8CD3 + input buffer #19: + timeUs = 1000010633966 + contents = length 1022, hash 5D8BFF34 + input buffer #20: + timeUs = 1000010600600 + contents = length 790, hash 99413A99 + input buffer #21: + timeUs = 1000010667333 + contents = length 610, hash 5E129290 + input buffer #22: + timeUs = 1000010834166 + contents = length 2751, hash 769974CB + input buffer #23: + timeUs = 1000010767433 + contents = length 745, hash B78A477A + input buffer #24: + timeUs = 1000010734066 + contents = length 621, hash CF741E7A + input buffer #25: + timeUs = 1000010800800 + contents = length 505, hash 1DB4894E + input buffer #26: + timeUs = 1000010967633 + contents = length 1268, hash C15348DC + input buffer #27: + timeUs = 1000010900900 + contents = length 880, hash C2DE85D0 + input buffer #28: + timeUs = 1000010867533 + contents = length 530, hash C98BC6A8 + input buffer #29: + timeUs = 1000010934266 + contents = length 568, hash 4FE5C8EA + input buffer #30: + timeUs = 0 + flags = 4 + contents = length 0, hash 1 + outputBuffers: + count = 30 + output buffer #0: + timeUs = 1000010000000 + size = 36692 + rendered = false + output buffer #1: + timeUs = 1000010066733 + size = 5312 + rendered = false + output buffer #2: + timeUs = 1000010033366 + size = 599 + rendered = false + output buffer #3: + timeUs = 1000010200200 + size = 7735 + rendered = false + output buffer #4: + timeUs = 1000010133466 + size = 987 + rendered = false + output buffer #5: + timeUs = 1000010100100 + size = 673 + rendered = false + output buffer #6: + timeUs = 1000010166833 + size = 523 + rendered = false + output buffer #7: + timeUs = 1000010333666 + size = 6061 + rendered = false + output buffer #8: + timeUs = 1000010266933 + size = 992 + rendered = false + output buffer #9: + timeUs = 1000010233566 + size = 623 + rendered = false + output buffer #10: + timeUs = 1000010300300 + size = 421 + rendered = false + output buffer #11: + timeUs = 1000010433766 + size = 4899 + rendered = false + output buffer #12: + timeUs = 1000010400400 + size = 568 + rendered = false + output buffer #13: + timeUs = 1000010367033 + size = 620 + rendered = false + output buffer #14: + timeUs = 1000010567233 + size = 5450 + rendered = false + output buffer #15: + timeUs = 1000010500500 + size = 1051 + rendered = false + output buffer #16: + timeUs = 1000010467133 + size = 874 + rendered = false + output buffer #17: + timeUs = 1000010533866 + size = 781 + rendered = false + output buffer #18: + timeUs = 1000010700700 + size = 4725 + rendered = false + output buffer #19: + timeUs = 1000010633966 + size = 1022 + rendered = false + output buffer #20: + timeUs = 1000010600600 + size = 790 + rendered = false + output buffer #21: + timeUs = 1000010667333 + size = 610 + rendered = false + output buffer #22: + timeUs = 1000010834166 + size = 2751 + rendered = false + output buffer #23: + timeUs = 1000010767433 + size = 745 + rendered = false + output buffer #24: + timeUs = 1000010734066 + size = 621 + rendered = false + output buffer #25: + timeUs = 1000010800800 + size = 505 + rendered = false + output buffer #26: + timeUs = 1000010967633 + size = 1268 + rendered = false + output buffer #27: + timeUs = 1000010900900 + size = 880 + rendered = false + output buffer #28: + timeUs = 1000010867533 + size = 530 + rendered = false + output buffer #29: + timeUs = 1000010934266 + size = 568 + rendered = false +AudioSink: + buffer count = 45 + config: + pcmEncoding = 2 + channelCount = 1 + sampleRate = 44100 + buffer #0: + time = 1000010044000 + data = 1 + buffer #1: + time = 1000010067219 + data = 1 + buffer #2: + time = 1000010090439 + data = 1 + buffer #3: + time = 1000010113659 + data = 1 + buffer #4: + time = 1000010136879 + data = 1 + buffer #5: + time = 1000010160099 + data = 1 + buffer #6: + time = 1000010183319 + data = 1 + buffer #7: + time = 1000010206539 + data = 1 + buffer #8: + time = 1000010229759 + data = 1 + buffer #9: + time = 1000010252979 + data = 1 + buffer #10: + time = 1000010276199 + data = 1 + buffer #11: + time = 1000010299419 + data = 1 + buffer #12: + time = 1000010322639 + data = 1 + buffer #13: + time = 1000010345859 + data = 1 + buffer #14: + time = 1000010369079 + data = 1 + buffer #15: + time = 1000010392299 + data = 1 + buffer #16: + time = 1000010415519 + data = 1 + buffer #17: + time = 1000010438739 + data = 1 + buffer #18: + time = 1000010461959 + data = 1 + buffer #19: + time = 1000010485179 + data = 1 + buffer #20: + time = 1000010508399 + data = 1 + buffer #21: + time = 1000010531619 + data = 1 + buffer #22: + time = 1000010554839 + data = 1 + buffer #23: + time = 1000010578058 + data = 1 + buffer #24: + time = 1000010601278 + data = 1 + buffer #25: + time = 1000010624498 + data = 1 + buffer #26: + time = 1000010647718 + data = 1 + buffer #27: + time = 1000010670938 + data = 1 + buffer #28: + time = 1000010694158 + data = 1 + buffer #29: + time = 1000010717378 + data = 1 + buffer #30: + time = 1000010740598 + data = 1 + buffer #31: + time = 1000010763818 + data = 1 + buffer #32: + time = 1000010787038 + data = 1 + buffer #33: + time = 1000010810258 + data = 1 + buffer #34: + time = 1000010833478 + data = 1 + buffer #35: + time = 1000010856698 + data = 1 + buffer #36: + time = 1000010879918 + data = 1 + buffer #37: + time = 1000010903138 + data = 1 + buffer #38: + time = 1000010926358 + data = 1 + buffer #39: + time = 1000010949578 + data = 1 + buffer #40: + time = 1000010972798 + data = 1 + buffer #41: + time = 1000010996018 + data = 1 + buffer #42: + time = 1000011019238 + data = 1 + buffer #43: + time = 1000011042458 + data = 1 + buffer #44: + time = 1000011065678 + data = 1 +ImageOutput: + rendered image count = 2 + image output #1: + presentationTimeUs = 0 + bitmap hash = -389047680 + image output #2: + presentationTimeUs = 0 + bitmap hash = -389047680