mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Send decode-only Opus samples in bypass mode for seekPreRoll skip
As Opus decoders skip some bytes prior to playback during a seek, the renderer for bypass playback should send samples to the decoder even if they would be decode-only. #minor-release PiperOrigin-RevId: 574494666 (cherry picked from commit 00193e0304a5ea2c20012fabf77f82f29e218372)
This commit is contained in:
parent
fe60d0d7b4
commit
111ac63695
@ -2279,7 +2279,10 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||
// Process any batched data.
|
||||
checkState(!outputStreamEnded);
|
||||
if (bypassBatchBuffer.hasSamples()) {
|
||||
boolean isDecodeOnly = bypassBatchBuffer.getLastSampleTimeUs() < getLastResetPositionUs();
|
||||
boolean isDecodeOnly =
|
||||
bypassBatchBuffer.getLastSampleTimeUs() < getLastResetPositionUs()
|
||||
&& (outputFormat == null
|
||||
|| !Objects.equals(outputFormat.sampleMimeType, MimeTypes.AUDIO_OPUS));
|
||||
if (processOutputBuffer(
|
||||
positionUs,
|
||||
elapsedRealtimeUs,
|
||||
|
@ -15,7 +15,7 @@
|
||||
*/
|
||||
package androidx.media3.exoplayer.e2etest;
|
||||
|
||||
import static androidx.media3.common.TrackSelectionParameters.AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED;
|
||||
import static androidx.media3.common.TrackSelectionParameters.AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_REQUIRED;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.annotation.Nullable;
|
||||
@ -40,12 +40,13 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class OggOpusPlaybackTest {
|
||||
public final class OggOpusPlaybackTest {
|
||||
|
||||
public static final String INPUT_FILE = "bear.opus";
|
||||
|
||||
@ -53,25 +54,31 @@ public class OggOpusPlaybackTest {
|
||||
public ShadowMediaCodecConfig mediaCodecConfig =
|
||||
ShadowMediaCodecConfig.forAllSupportedMimeTypes();
|
||||
|
||||
@Test
|
||||
public void checkOggOpusEncodings() throws Exception {
|
||||
Context applicationContext = ApplicationProvider.getApplicationContext();
|
||||
OffloadRenderersFactory offloadRenderersFactory =
|
||||
new OffloadRenderersFactory(applicationContext);
|
||||
DefaultTrackSelector trackSelector = new DefaultTrackSelector(applicationContext);
|
||||
public FakeClock fakeClock;
|
||||
public OffloadRenderersFactory offloadRenderersFactory;
|
||||
public DefaultTrackSelector trackSelector;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
fakeClock = new FakeClock(/* isAutoAdvancing= */ true);
|
||||
offloadRenderersFactory =
|
||||
new OffloadRenderersFactory(ApplicationProvider.getApplicationContext());
|
||||
trackSelector = new DefaultTrackSelector(ApplicationProvider.getApplicationContext());
|
||||
trackSelector.setParameters(
|
||||
trackSelector
|
||||
.buildUponParameters()
|
||||
.setAudioOffloadPreferences(
|
||||
new AudioOffloadPreferences.Builder()
|
||||
.setAudioOffloadMode(AUDIO_OFFLOAD_MODE_ENABLED)
|
||||
.setIsGaplessSupportRequired(false)
|
||||
.setIsSpeedChangeSupportRequired(false)
|
||||
.setAudioOffloadMode(AUDIO_OFFLOAD_MODE_REQUIRED)
|
||||
.build())
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void oggOpusPlayback_generatesCorrectOggOpusEncodings() throws Exception {
|
||||
ExoPlayer player =
|
||||
new ExoPlayer.Builder(applicationContext, offloadRenderersFactory)
|
||||
.setClock(new FakeClock(/* isAutoAdvancing= */ true))
|
||||
new ExoPlayer.Builder(ApplicationProvider.getApplicationContext(), offloadRenderersFactory)
|
||||
.setClock(fakeClock)
|
||||
.setTrackSelector(trackSelector)
|
||||
.build();
|
||||
player.setMediaItem(MediaItem.fromUri("asset:///media/ogg/" + INPUT_FILE));
|
||||
@ -82,12 +89,33 @@ public class OggOpusPlaybackTest {
|
||||
player.release();
|
||||
|
||||
DumpFileAsserts.assertOutput(
|
||||
applicationContext,
|
||||
ApplicationProvider.getApplicationContext(),
|
||||
offloadRenderersFactory,
|
||||
"playbackdumps/ogg/" + INPUT_FILE + ".oggOpus.dump");
|
||||
}
|
||||
|
||||
private static class OffloadRenderersFactory extends DefaultRenderersFactory
|
||||
@Test
|
||||
public void oggOpusPlayback_withSeek_generatesCorrectOggOpusEncodings() throws Exception {
|
||||
ExoPlayer player =
|
||||
new ExoPlayer.Builder(ApplicationProvider.getApplicationContext(), offloadRenderersFactory)
|
||||
.setClock(fakeClock)
|
||||
.setTrackSelector(trackSelector)
|
||||
.build();
|
||||
player.setMediaItem(MediaItem.fromUri("asset:///media/ogg/" + INPUT_FILE));
|
||||
player.prepare();
|
||||
player.seekTo(/* positionMs= */ 1415);
|
||||
player.play();
|
||||
|
||||
TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_ENDED);
|
||||
player.release();
|
||||
|
||||
DumpFileAsserts.assertOutput(
|
||||
ApplicationProvider.getApplicationContext(),
|
||||
offloadRenderersFactory,
|
||||
"playbackdumps/ogg/" + INPUT_FILE + ".oggOpusWithSeek.dump");
|
||||
}
|
||||
|
||||
private static final class OffloadRenderersFactory extends DefaultRenderersFactory
|
||||
implements Dumper.Dumpable {
|
||||
|
||||
private DumpingAudioSink dumpingAudioSink;
|
||||
@ -117,7 +145,8 @@ public class OggOpusPlaybackTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static class DumpingAudioSink extends ForwardingAudioSink implements Dumper.Dumpable {
|
||||
private static final class DumpingAudioSink extends ForwardingAudioSink
|
||||
implements Dumper.Dumpable {
|
||||
/** All handleBuffer interactions recorded with this audio sink. */
|
||||
private final List<CapturedInputBuffer> capturedInteractions;
|
||||
|
||||
@ -174,10 +203,9 @@ public class OggOpusPlaybackTest {
|
||||
buffer.position(originalPosition);
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
|
||||
/** Data record */
|
||||
private static class CapturedInputBuffer {
|
||||
private static final class CapturedInputBuffer {
|
||||
private final byte[] contents;
|
||||
|
||||
private CapturedInputBuffer(byte[] contents) {
|
||||
@ -185,3 +213,4 @@ public class OggOpusPlaybackTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
SinkDump (OggOpus):
|
||||
buffers.length = 6
|
||||
buffers[0] = length 207, hash D462AF66
|
||||
buffers[1] = length 3891, hash FE9EE7C1
|
||||
buffers[2] = length 3732, hash C2249BC1
|
||||
buffers[3] = length 3731, hash A9384B0F
|
||||
buffers[4] = length 4091, hash 9631FA86
|
||||
buffers[5] = length 776, hash 4BC27E65
|
Loading…
x
Reference in New Issue
Block a user