mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Create audio offload failure recovery playback tests
These audio offload failure recovery tests model the DefaultAudioSink failing at audio track init and write operations in offload mode. Playback should recover and try again as DefaultAudioSink will disable offload mode. PiperOrigin-RevId: 610372935
This commit is contained in:
parent
a5f3db4cfe
commit
a45e734bb0
@ -0,0 +1,405 @@
|
||||
/*
|
||||
* Copyright (C) 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
|
||||
*
|
||||
* http://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.e2etest;
|
||||
|
||||
import static androidx.media3.common.TrackSelectionParameters.AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.AudioTrack;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.Format;
|
||||
import androidx.media3.common.MediaItem;
|
||||
import androidx.media3.common.MimeTypes;
|
||||
import androidx.media3.common.Player;
|
||||
import androidx.media3.common.TrackSelectionParameters;
|
||||
import androidx.media3.exoplayer.DefaultRenderersFactory;
|
||||
import androidx.media3.exoplayer.ExoPlayer;
|
||||
import androidx.media3.exoplayer.audio.AudioOffloadSupport;
|
||||
import androidx.media3.exoplayer.audio.AudioSink;
|
||||
import androidx.media3.exoplayer.audio.DefaultAudioSink;
|
||||
import androidx.media3.exoplayer.audio.ForwardingAudioSink;
|
||||
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector;
|
||||
import androidx.media3.test.utils.DumpFileAsserts;
|
||||
import androidx.media3.test.utils.Dumper;
|
||||
import androidx.media3.test.utils.FakeClock;
|
||||
import androidx.media3.test.utils.robolectric.ShadowMediaCodecConfig;
|
||||
import androidx.media3.test.utils.robolectric.TestPlayerRunHelper;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
/** End-to-end tests of playback with recovery from offload failure. */
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class EndToEndOffloadFailureRecoveryTest {
|
||||
public static final String INPUT_FILE = "bear.opus";
|
||||
|
||||
@Rule
|
||||
public ShadowMediaCodecConfig mediaCodecConfig =
|
||||
ShadowMediaCodecConfig.forAllSupportedMimeTypes();
|
||||
|
||||
public FakeClock fakeClock;
|
||||
public DefaultTrackSelector trackSelector;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
fakeClock = new FakeClock(/* isAutoAdvancing= */ true);
|
||||
trackSelector = new DefaultTrackSelector(ApplicationProvider.getApplicationContext());
|
||||
trackSelector.setParameters(
|
||||
trackSelector
|
||||
.buildUponParameters()
|
||||
.setAudioOffloadPreferences(
|
||||
new TrackSelectionParameters.AudioOffloadPreferences.Builder()
|
||||
.setAudioOffloadMode(AUDIO_OFFLOAD_MODE_ENABLED)
|
||||
.build())
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void oggOpusPlayback_recoversFromAudioTrackOffloadInitFailure_generatesDecodedContent()
|
||||
throws Exception {
|
||||
OffloadInitFailureRenderersFactory offloadInitFailureRenderersFactory =
|
||||
new OffloadInitFailureRenderersFactory(ApplicationProvider.getApplicationContext());
|
||||
ExoPlayer player =
|
||||
new ExoPlayer.Builder(
|
||||
ApplicationProvider.getApplicationContext(), offloadInitFailureRenderersFactory)
|
||||
.setClock(fakeClock)
|
||||
.setTrackSelector(trackSelector)
|
||||
.build();
|
||||
player.setMediaItem(MediaItem.fromUri("asset:///media/ogg/" + INPUT_FILE));
|
||||
player.prepare();
|
||||
player.play();
|
||||
|
||||
TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_ENDED);
|
||||
player.release();
|
||||
|
||||
DumpFileAsserts.assertOutput(
|
||||
ApplicationProvider.getApplicationContext(),
|
||||
offloadInitFailureRenderersFactory,
|
||||
"playbackdumps/offloadRecovery/" + INPUT_FILE + ".offloadInitFailureRecovery.dump");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void oggOpusPlayback_recoversFromAudioTrackOffloadWriteFailure_generatesCorrectContent()
|
||||
throws Exception {
|
||||
OffloadWriteFailureRenderersFactory offloadWriteFailureRenderersFactory =
|
||||
new OffloadWriteFailureRenderersFactory(ApplicationProvider.getApplicationContext());
|
||||
ExoPlayer player =
|
||||
new ExoPlayer.Builder(
|
||||
ApplicationProvider.getApplicationContext(), offloadWriteFailureRenderersFactory)
|
||||
.setClock(fakeClock)
|
||||
.setTrackSelector(trackSelector)
|
||||
.build();
|
||||
player.setMediaItem(MediaItem.fromUri("asset:///media/ogg/" + INPUT_FILE));
|
||||
player.prepare();
|
||||
player.play();
|
||||
|
||||
TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_ENDED);
|
||||
player.release();
|
||||
|
||||
DumpFileAsserts.assertOutput(
|
||||
ApplicationProvider.getApplicationContext(),
|
||||
offloadWriteFailureRenderersFactory,
|
||||
"playbackdumps/offloadRecovery/" + INPUT_FILE + ".offloadWriteFailureRecovery.dump");
|
||||
}
|
||||
|
||||
private static class OffloadRenderersFactory extends DefaultRenderersFactory
|
||||
implements Dumper.Dumpable {
|
||||
|
||||
protected DumpingAudioSink dumpingAudioSink;
|
||||
|
||||
/**
|
||||
* @param context A {@link Context}.
|
||||
*/
|
||||
public OffloadRenderersFactory(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AudioSink buildAudioSink(
|
||||
Context context, boolean enableFloatOutput, boolean enableAudioTrackPlaybackParams) {
|
||||
dumpingAudioSink =
|
||||
new DumpingAudioSink(
|
||||
new DefaultAudioSink.Builder(context)
|
||||
.setEnableFloatOutput(enableFloatOutput)
|
||||
.setEnableAudioTrackPlaybackParams(enableAudioTrackPlaybackParams)
|
||||
.build());
|
||||
return dumpingAudioSink;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(Dumper dumper) {
|
||||
dumpingAudioSink.dump(dumper);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class OffloadInitFailureRenderersFactory extends OffloadRenderersFactory {
|
||||
|
||||
/**
|
||||
* @param context A {@link Context}.
|
||||
*/
|
||||
public OffloadInitFailureRenderersFactory(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AudioSink buildAudioSink(
|
||||
Context context, boolean enableFloatOutput, boolean enableAudioTrackPlaybackParams) {
|
||||
dumpingAudioSink =
|
||||
new DumpingAudioSinkWithOffloadInitFailure(
|
||||
new DefaultAudioSink.Builder(context)
|
||||
.setEnableFloatOutput(enableFloatOutput)
|
||||
.setEnableAudioTrackPlaybackParams(enableAudioTrackPlaybackParams)
|
||||
.build());
|
||||
return dumpingAudioSink;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class OffloadWriteFailureRenderersFactory extends OffloadRenderersFactory {
|
||||
|
||||
/**
|
||||
* @param context A {@link Context}.
|
||||
*/
|
||||
public OffloadWriteFailureRenderersFactory(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AudioSink buildAudioSink(
|
||||
Context context, boolean enableFloatOutput, boolean enableAudioTrackPlaybackParams) {
|
||||
dumpingAudioSink =
|
||||
new DumpingAudioSinkWithOffloadWriteFailure(
|
||||
new DefaultAudioSink.Builder(context)
|
||||
.setEnableFloatOutput(enableFloatOutput)
|
||||
.setEnableAudioTrackPlaybackParams(enableAudioTrackPlaybackParams)
|
||||
.build());
|
||||
return dumpingAudioSink;
|
||||
}
|
||||
}
|
||||
|
||||
/** A dumping audio sink that fails to initialize for offloaded playback. */
|
||||
private static class DumpingAudioSink extends ForwardingAudioSink implements Dumper.Dumpable {
|
||||
/** All handleBuffer interactions recorded with this audio sink. */
|
||||
protected final List<DumpingAudioSink.CapturedInputBuffer> capturedInteractions;
|
||||
|
||||
/**
|
||||
* If offload mode should be not supported until next {@linkplain
|
||||
* DumpingAudioSink#configure(Format, int, int[]) configure} call.
|
||||
*/
|
||||
protected boolean offloadDisabledUntilNextConfiguration;
|
||||
|
||||
/** If audio sink has been configured for offloaded playback. */
|
||||
protected boolean isOffloadMode;
|
||||
|
||||
/** The {@link Format input format} for the audio sink. */
|
||||
@Nullable protected Format inputFormat;
|
||||
|
||||
public DumpingAudioSink(AudioSink sink) {
|
||||
super(sink);
|
||||
this.capturedInteractions = new ArrayList<>();
|
||||
this.isOffloadMode = false;
|
||||
this.offloadDisabledUntilNextConfiguration = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(
|
||||
Format inputFormat, int specifiedBufferSize, @Nullable int[] outputChannels) {
|
||||
// Bypass configure of base DefaultAudioSink
|
||||
isOffloadMode = !Objects.equals(inputFormat.sampleMimeType, MimeTypes.AUDIO_RAW);
|
||||
offloadDisabledUntilNextConfiguration = false;
|
||||
this.inputFormat = inputFormat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsFormat(Format format) {
|
||||
return Objects.equals(format.sampleMimeType, MimeTypes.AUDIO_RAW);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AudioOffloadSupport getFormatOffloadSupport(Format format) {
|
||||
if (offloadDisabledUntilNextConfiguration) {
|
||||
return AudioOffloadSupport.DEFAULT_UNSUPPORTED;
|
||||
}
|
||||
return new AudioOffloadSupport.Builder()
|
||||
.setIsFormatSupported(true)
|
||||
.setIsGaplessSupported(false)
|
||||
.setIsSpeedChangeSupported(false)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Captures audio data in {@link DumpingAudioSink}.
|
||||
*
|
||||
* @param buffer The buffer containing audio data.
|
||||
* @param presentationTimeUs The presentation timestamp of the buffer in microseconds.
|
||||
* @param encodedAccessUnitCount The number of encoded access units in the buffer, or 1 if the
|
||||
* buffer contains PCM audio. This allows batching multiple encoded access units in one
|
||||
* buffer.
|
||||
* @return {@code True} if buffer successfully written.
|
||||
*/
|
||||
@Override
|
||||
public boolean handleBuffer(
|
||||
ByteBuffer buffer, long presentationTimeUs, int encodedAccessUnitCount)
|
||||
throws InitializationException, WriteException {
|
||||
capturedInteractions.add(
|
||||
new DumpingAudioSink.CapturedInputBuffer(
|
||||
peekBytes(buffer, 0, buffer.limit() - buffer.position())));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
offloadDisabledUntilNextConfiguration = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(Dumper dumper) {
|
||||
dumper.startBlock("SinkDump (OggOpus)");
|
||||
dumper.add("buffers.length", capturedInteractions.size());
|
||||
for (int i = 0; i < capturedInteractions.size(); i++) {
|
||||
dumper.add("buffers[" + i + "]", capturedInteractions.get(i).contents);
|
||||
}
|
||||
dumper.endBlock();
|
||||
}
|
||||
|
||||
protected byte[] peekBytes(ByteBuffer buffer, int offset, int size) {
|
||||
int originalPosition = buffer.position();
|
||||
buffer.position(offset);
|
||||
byte[] bytes = new byte[size];
|
||||
buffer.get(bytes);
|
||||
buffer.position(originalPosition);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/** Data record. */
|
||||
private static final class CapturedInputBuffer {
|
||||
private final byte[] contents;
|
||||
|
||||
private CapturedInputBuffer(byte[] contents) {
|
||||
this.contents = contents;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class DumpingAudioSinkWithOffloadInitFailure extends DumpingAudioSink {
|
||||
|
||||
public DumpingAudioSinkWithOffloadInitFailure(AudioSink sink) {
|
||||
super(sink);
|
||||
}
|
||||
|
||||
/**
|
||||
* Captures audio data in {@link DumpingAudioSink}.
|
||||
*
|
||||
* <p>Method throws {@code InitializationException} when called if sink is configured for
|
||||
* offloaded playback.
|
||||
*
|
||||
* @param buffer The buffer containing audio data.
|
||||
* @param presentationTimeUs The presentation timestamp of the buffer in microseconds.
|
||||
* @param encodedAccessUnitCount The number of encoded access units in the buffer, or 1 if the
|
||||
* buffer contains PCM audio. This allows batching multiple encoded access units in one
|
||||
* buffer.
|
||||
* @return {@code True} if buffer successfully written.
|
||||
* @throws InitializationException if configured for offloaded audio playback.
|
||||
*/
|
||||
@Override
|
||||
public boolean handleBuffer(
|
||||
ByteBuffer buffer, long presentationTimeUs, int encodedAccessUnitCount)
|
||||
throws InitializationException {
|
||||
if (isOffloadMode) {
|
||||
// Models that AudioTrack initialization throws error if configured for offloaded playback.
|
||||
offloadDisabledUntilNextConfiguration = true;
|
||||
assertThat(inputFormat).isNotNull();
|
||||
throw new InitializationException(
|
||||
AudioTrack.STATE_UNINITIALIZED,
|
||||
/* sampleRate= */ 48_000,
|
||||
/* channelConfig= */ 0,
|
||||
/* bufferSize= */ C.LENGTH_UNSET,
|
||||
inputFormat,
|
||||
/* isRecoverable= */ true,
|
||||
/* audioTrackException= */ null);
|
||||
}
|
||||
capturedInteractions.add(
|
||||
new DumpingAudioSink.CapturedInputBuffer(
|
||||
peekBytes(buffer, 0, buffer.limit() - buffer.position())));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A dumping audio sink that starts failing for offloaded playback after two successful writes.
|
||||
*/
|
||||
private static final class DumpingAudioSinkWithOffloadWriteFailure extends DumpingAudioSink {
|
||||
|
||||
private int writeCounter;
|
||||
private boolean hasThrownWriteException;
|
||||
|
||||
public DumpingAudioSinkWithOffloadWriteFailure(AudioSink sink) {
|
||||
super(sink);
|
||||
this.writeCounter = 0;
|
||||
this.hasThrownWriteException = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Captures audio data in {@link DumpingAudioSink}.
|
||||
*
|
||||
* <p>Method throws {@code WriteException} when called if sink is configured for offloaded
|
||||
* playback and after two successful writes.
|
||||
*
|
||||
* @param buffer The buffer containing audio data.
|
||||
* @param presentationTimeUs The presentation timestamp of the buffer in microseconds.
|
||||
* @param encodedAccessUnitCount The number of encoded access units in the buffer, or 1 if the
|
||||
* buffer contains PCM audio. This allows batching multiple encoded access units in one
|
||||
* buffer.
|
||||
* @return {@code True} if buffer successfully written.
|
||||
* @throws WriteException if configured for offloaded audio playback.
|
||||
*/
|
||||
@Override
|
||||
public boolean handleBuffer(
|
||||
ByteBuffer buffer, long presentationTimeUs, int encodedAccessUnitCount)
|
||||
throws WriteException {
|
||||
if (isOffloadMode && writeCounter > 1) {
|
||||
// Models that AudioTrack write throws error if configured for offloaded playback.
|
||||
if (hasThrownWriteException) {
|
||||
assertThat(offloadDisabledUntilNextConfiguration).isFalse();
|
||||
offloadDisabledUntilNextConfiguration = true;
|
||||
}
|
||||
hasThrownWriteException = true;
|
||||
assertThat(inputFormat).isNotNull();
|
||||
throw new WriteException(
|
||||
AudioTrack.ERROR_DEAD_OBJECT, inputFormat, /* isRecoverable= */ true);
|
||||
}
|
||||
capturedInteractions.add(
|
||||
new DumpingAudioSink.CapturedInputBuffer(
|
||||
peekBytes(buffer, 0, buffer.limit() - buffer.position())));
|
||||
writeCounter++;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
super.reset();
|
||||
writeCounter = 0;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,277 @@
|
||||
SinkDump (OggOpus):
|
||||
buffers.length = 275
|
||||
buffers[0] = length 0, hash 1
|
||||
buffers[1] = length 0, hash 1
|
||||
buffers[2] = length 0, hash 1
|
||||
buffers[3] = length 0, hash 1
|
||||
buffers[4] = length 0, hash 1
|
||||
buffers[5] = length 0, hash 1
|
||||
buffers[6] = length 0, hash 1
|
||||
buffers[7] = length 0, hash 1
|
||||
buffers[8] = length 0, hash 1
|
||||
buffers[9] = length 0, hash 1
|
||||
buffers[10] = length 0, hash 1
|
||||
buffers[11] = length 0, hash 1
|
||||
buffers[12] = length 0, hash 1
|
||||
buffers[13] = length 0, hash 1
|
||||
buffers[14] = length 0, hash 1
|
||||
buffers[15] = length 0, hash 1
|
||||
buffers[16] = length 0, hash 1
|
||||
buffers[17] = length 0, hash 1
|
||||
buffers[18] = length 0, hash 1
|
||||
buffers[19] = length 0, hash 1
|
||||
buffers[20] = length 0, hash 1
|
||||
buffers[21] = length 0, hash 1
|
||||
buffers[22] = length 0, hash 1
|
||||
buffers[23] = length 0, hash 1
|
||||
buffers[24] = length 0, hash 1
|
||||
buffers[25] = length 0, hash 1
|
||||
buffers[26] = length 0, hash 1
|
||||
buffers[27] = length 0, hash 1
|
||||
buffers[28] = length 0, hash 1
|
||||
buffers[29] = length 0, hash 1
|
||||
buffers[30] = length 0, hash 1
|
||||
buffers[31] = length 0, hash 1
|
||||
buffers[32] = length 0, hash 1
|
||||
buffers[33] = length 0, hash 1
|
||||
buffers[34] = length 0, hash 1
|
||||
buffers[35] = length 0, hash 1
|
||||
buffers[36] = length 0, hash 1
|
||||
buffers[37] = length 0, hash 1
|
||||
buffers[38] = length 0, hash 1
|
||||
buffers[39] = length 0, hash 1
|
||||
buffers[40] = length 0, hash 1
|
||||
buffers[41] = length 0, hash 1
|
||||
buffers[42] = length 0, hash 1
|
||||
buffers[43] = length 0, hash 1
|
||||
buffers[44] = length 0, hash 1
|
||||
buffers[45] = length 0, hash 1
|
||||
buffers[46] = length 0, hash 1
|
||||
buffers[47] = length 0, hash 1
|
||||
buffers[48] = length 0, hash 1
|
||||
buffers[49] = length 0, hash 1
|
||||
buffers[50] = length 0, hash 1
|
||||
buffers[51] = length 0, hash 1
|
||||
buffers[52] = length 0, hash 1
|
||||
buffers[53] = length 0, hash 1
|
||||
buffers[54] = length 0, hash 1
|
||||
buffers[55] = length 0, hash 1
|
||||
buffers[56] = length 0, hash 1
|
||||
buffers[57] = length 0, hash 1
|
||||
buffers[58] = length 0, hash 1
|
||||
buffers[59] = length 0, hash 1
|
||||
buffers[60] = length 0, hash 1
|
||||
buffers[61] = length 0, hash 1
|
||||
buffers[62] = length 0, hash 1
|
||||
buffers[63] = length 0, hash 1
|
||||
buffers[64] = length 0, hash 1
|
||||
buffers[65] = length 0, hash 1
|
||||
buffers[66] = length 0, hash 1
|
||||
buffers[67] = length 0, hash 1
|
||||
buffers[68] = length 0, hash 1
|
||||
buffers[69] = length 0, hash 1
|
||||
buffers[70] = length 0, hash 1
|
||||
buffers[71] = length 0, hash 1
|
||||
buffers[72] = length 0, hash 1
|
||||
buffers[73] = length 0, hash 1
|
||||
buffers[74] = length 0, hash 1
|
||||
buffers[75] = length 0, hash 1
|
||||
buffers[76] = length 0, hash 1
|
||||
buffers[77] = length 0, hash 1
|
||||
buffers[78] = length 0, hash 1
|
||||
buffers[79] = length 0, hash 1
|
||||
buffers[80] = length 0, hash 1
|
||||
buffers[81] = length 0, hash 1
|
||||
buffers[82] = length 0, hash 1
|
||||
buffers[83] = length 0, hash 1
|
||||
buffers[84] = length 0, hash 1
|
||||
buffers[85] = length 0, hash 1
|
||||
buffers[86] = length 0, hash 1
|
||||
buffers[87] = length 0, hash 1
|
||||
buffers[88] = length 0, hash 1
|
||||
buffers[89] = length 0, hash 1
|
||||
buffers[90] = length 0, hash 1
|
||||
buffers[91] = length 0, hash 1
|
||||
buffers[92] = length 0, hash 1
|
||||
buffers[93] = length 0, hash 1
|
||||
buffers[94] = length 0, hash 1
|
||||
buffers[95] = length 0, hash 1
|
||||
buffers[96] = length 0, hash 1
|
||||
buffers[97] = length 0, hash 1
|
||||
buffers[98] = length 0, hash 1
|
||||
buffers[99] = length 0, hash 1
|
||||
buffers[100] = length 0, hash 1
|
||||
buffers[101] = length 0, hash 1
|
||||
buffers[102] = length 0, hash 1
|
||||
buffers[103] = length 0, hash 1
|
||||
buffers[104] = length 0, hash 1
|
||||
buffers[105] = length 0, hash 1
|
||||
buffers[106] = length 0, hash 1
|
||||
buffers[107] = length 0, hash 1
|
||||
buffers[108] = length 0, hash 1
|
||||
buffers[109] = length 0, hash 1
|
||||
buffers[110] = length 0, hash 1
|
||||
buffers[111] = length 0, hash 1
|
||||
buffers[112] = length 0, hash 1
|
||||
buffers[113] = length 0, hash 1
|
||||
buffers[114] = length 0, hash 1
|
||||
buffers[115] = length 0, hash 1
|
||||
buffers[116] = length 0, hash 1
|
||||
buffers[117] = length 0, hash 1
|
||||
buffers[118] = length 0, hash 1
|
||||
buffers[119] = length 0, hash 1
|
||||
buffers[120] = length 0, hash 1
|
||||
buffers[121] = length 0, hash 1
|
||||
buffers[122] = length 0, hash 1
|
||||
buffers[123] = length 0, hash 1
|
||||
buffers[124] = length 0, hash 1
|
||||
buffers[125] = length 0, hash 1
|
||||
buffers[126] = length 0, hash 1
|
||||
buffers[127] = length 0, hash 1
|
||||
buffers[128] = length 0, hash 1
|
||||
buffers[129] = length 0, hash 1
|
||||
buffers[130] = length 0, hash 1
|
||||
buffers[131] = length 0, hash 1
|
||||
buffers[132] = length 0, hash 1
|
||||
buffers[133] = length 0, hash 1
|
||||
buffers[134] = length 0, hash 1
|
||||
buffers[135] = length 0, hash 1
|
||||
buffers[136] = length 0, hash 1
|
||||
buffers[137] = length 0, hash 1
|
||||
buffers[138] = length 0, hash 1
|
||||
buffers[139] = length 0, hash 1
|
||||
buffers[140] = length 0, hash 1
|
||||
buffers[141] = length 0, hash 1
|
||||
buffers[142] = length 0, hash 1
|
||||
buffers[143] = length 0, hash 1
|
||||
buffers[144] = length 0, hash 1
|
||||
buffers[145] = length 0, hash 1
|
||||
buffers[146] = length 0, hash 1
|
||||
buffers[147] = length 0, hash 1
|
||||
buffers[148] = length 0, hash 1
|
||||
buffers[149] = length 0, hash 1
|
||||
buffers[150] = length 0, hash 1
|
||||
buffers[151] = length 0, hash 1
|
||||
buffers[152] = length 0, hash 1
|
||||
buffers[153] = length 0, hash 1
|
||||
buffers[154] = length 0, hash 1
|
||||
buffers[155] = length 0, hash 1
|
||||
buffers[156] = length 0, hash 1
|
||||
buffers[157] = length 0, hash 1
|
||||
buffers[158] = length 0, hash 1
|
||||
buffers[159] = length 0, hash 1
|
||||
buffers[160] = length 0, hash 1
|
||||
buffers[161] = length 0, hash 1
|
||||
buffers[162] = length 0, hash 1
|
||||
buffers[163] = length 0, hash 1
|
||||
buffers[164] = length 0, hash 1
|
||||
buffers[165] = length 0, hash 1
|
||||
buffers[166] = length 0, hash 1
|
||||
buffers[167] = length 0, hash 1
|
||||
buffers[168] = length 0, hash 1
|
||||
buffers[169] = length 0, hash 1
|
||||
buffers[170] = length 0, hash 1
|
||||
buffers[171] = length 0, hash 1
|
||||
buffers[172] = length 0, hash 1
|
||||
buffers[173] = length 0, hash 1
|
||||
buffers[174] = length 0, hash 1
|
||||
buffers[175] = length 0, hash 1
|
||||
buffers[176] = length 0, hash 1
|
||||
buffers[177] = length 0, hash 1
|
||||
buffers[178] = length 0, hash 1
|
||||
buffers[179] = length 0, hash 1
|
||||
buffers[180] = length 0, hash 1
|
||||
buffers[181] = length 0, hash 1
|
||||
buffers[182] = length 0, hash 1
|
||||
buffers[183] = length 0, hash 1
|
||||
buffers[184] = length 0, hash 1
|
||||
buffers[185] = length 0, hash 1
|
||||
buffers[186] = length 0, hash 1
|
||||
buffers[187] = length 0, hash 1
|
||||
buffers[188] = length 0, hash 1
|
||||
buffers[189] = length 0, hash 1
|
||||
buffers[190] = length 0, hash 1
|
||||
buffers[191] = length 0, hash 1
|
||||
buffers[192] = length 0, hash 1
|
||||
buffers[193] = length 0, hash 1
|
||||
buffers[194] = length 0, hash 1
|
||||
buffers[195] = length 0, hash 1
|
||||
buffers[196] = length 0, hash 1
|
||||
buffers[197] = length 0, hash 1
|
||||
buffers[198] = length 0, hash 1
|
||||
buffers[199] = length 0, hash 1
|
||||
buffers[200] = length 0, hash 1
|
||||
buffers[201] = length 0, hash 1
|
||||
buffers[202] = length 0, hash 1
|
||||
buffers[203] = length 0, hash 1
|
||||
buffers[204] = length 0, hash 1
|
||||
buffers[205] = length 0, hash 1
|
||||
buffers[206] = length 0, hash 1
|
||||
buffers[207] = length 0, hash 1
|
||||
buffers[208] = length 0, hash 1
|
||||
buffers[209] = length 0, hash 1
|
||||
buffers[210] = length 0, hash 1
|
||||
buffers[211] = length 0, hash 1
|
||||
buffers[212] = length 0, hash 1
|
||||
buffers[213] = length 0, hash 1
|
||||
buffers[214] = length 0, hash 1
|
||||
buffers[215] = length 0, hash 1
|
||||
buffers[216] = length 0, hash 1
|
||||
buffers[217] = length 0, hash 1
|
||||
buffers[218] = length 0, hash 1
|
||||
buffers[219] = length 0, hash 1
|
||||
buffers[220] = length 0, hash 1
|
||||
buffers[221] = length 0, hash 1
|
||||
buffers[222] = length 0, hash 1
|
||||
buffers[223] = length 0, hash 1
|
||||
buffers[224] = length 0, hash 1
|
||||
buffers[225] = length 0, hash 1
|
||||
buffers[226] = length 0, hash 1
|
||||
buffers[227] = length 0, hash 1
|
||||
buffers[228] = length 0, hash 1
|
||||
buffers[229] = length 0, hash 1
|
||||
buffers[230] = length 0, hash 1
|
||||
buffers[231] = length 0, hash 1
|
||||
buffers[232] = length 0, hash 1
|
||||
buffers[233] = length 0, hash 1
|
||||
buffers[234] = length 0, hash 1
|
||||
buffers[235] = length 0, hash 1
|
||||
buffers[236] = length 0, hash 1
|
||||
buffers[237] = length 0, hash 1
|
||||
buffers[238] = length 0, hash 1
|
||||
buffers[239] = length 0, hash 1
|
||||
buffers[240] = length 0, hash 1
|
||||
buffers[241] = length 0, hash 1
|
||||
buffers[242] = length 0, hash 1
|
||||
buffers[243] = length 0, hash 1
|
||||
buffers[244] = length 0, hash 1
|
||||
buffers[245] = length 0, hash 1
|
||||
buffers[246] = length 0, hash 1
|
||||
buffers[247] = length 0, hash 1
|
||||
buffers[248] = length 0, hash 1
|
||||
buffers[249] = length 0, hash 1
|
||||
buffers[250] = length 0, hash 1
|
||||
buffers[251] = length 0, hash 1
|
||||
buffers[252] = length 0, hash 1
|
||||
buffers[253] = length 0, hash 1
|
||||
buffers[254] = length 0, hash 1
|
||||
buffers[255] = length 0, hash 1
|
||||
buffers[256] = length 0, hash 1
|
||||
buffers[257] = length 0, hash 1
|
||||
buffers[258] = length 0, hash 1
|
||||
buffers[259] = length 0, hash 1
|
||||
buffers[260] = length 0, hash 1
|
||||
buffers[261] = length 0, hash 1
|
||||
buffers[262] = length 0, hash 1
|
||||
buffers[263] = length 0, hash 1
|
||||
buffers[264] = length 0, hash 1
|
||||
buffers[265] = length 0, hash 1
|
||||
buffers[266] = length 0, hash 1
|
||||
buffers[267] = length 0, hash 1
|
||||
buffers[268] = length 0, hash 1
|
||||
buffers[269] = length 0, hash 1
|
||||
buffers[270] = length 0, hash 1
|
||||
buffers[271] = length 0, hash 1
|
||||
buffers[272] = length 0, hash 1
|
||||
buffers[273] = length 0, hash 1
|
||||
buffers[274] = length 0, hash 1
|
@ -0,0 +1,279 @@
|
||||
SinkDump (OggOpus):
|
||||
buffers.length = 277
|
||||
buffers[0] = length 4137, hash 9776A1C3
|
||||
buffers[1] = length 3848, hash B3105060
|
||||
buffers[2] = length 0, hash 1
|
||||
buffers[3] = length 0, hash 1
|
||||
buffers[4] = length 0, hash 1
|
||||
buffers[5] = length 0, hash 1
|
||||
buffers[6] = length 0, hash 1
|
||||
buffers[7] = length 0, hash 1
|
||||
buffers[8] = length 0, hash 1
|
||||
buffers[9] = length 0, hash 1
|
||||
buffers[10] = length 0, hash 1
|
||||
buffers[11] = length 0, hash 1
|
||||
buffers[12] = length 0, hash 1
|
||||
buffers[13] = length 0, hash 1
|
||||
buffers[14] = length 0, hash 1
|
||||
buffers[15] = length 0, hash 1
|
||||
buffers[16] = length 0, hash 1
|
||||
buffers[17] = length 0, hash 1
|
||||
buffers[18] = length 0, hash 1
|
||||
buffers[19] = length 0, hash 1
|
||||
buffers[20] = length 0, hash 1
|
||||
buffers[21] = length 0, hash 1
|
||||
buffers[22] = length 0, hash 1
|
||||
buffers[23] = length 0, hash 1
|
||||
buffers[24] = length 0, hash 1
|
||||
buffers[25] = length 0, hash 1
|
||||
buffers[26] = length 0, hash 1
|
||||
buffers[27] = length 0, hash 1
|
||||
buffers[28] = length 0, hash 1
|
||||
buffers[29] = length 0, hash 1
|
||||
buffers[30] = length 0, hash 1
|
||||
buffers[31] = length 0, hash 1
|
||||
buffers[32] = length 0, hash 1
|
||||
buffers[33] = length 0, hash 1
|
||||
buffers[34] = length 0, hash 1
|
||||
buffers[35] = length 0, hash 1
|
||||
buffers[36] = length 0, hash 1
|
||||
buffers[37] = length 0, hash 1
|
||||
buffers[38] = length 0, hash 1
|
||||
buffers[39] = length 0, hash 1
|
||||
buffers[40] = length 0, hash 1
|
||||
buffers[41] = length 0, hash 1
|
||||
buffers[42] = length 0, hash 1
|
||||
buffers[43] = length 0, hash 1
|
||||
buffers[44] = length 0, hash 1
|
||||
buffers[45] = length 0, hash 1
|
||||
buffers[46] = length 0, hash 1
|
||||
buffers[47] = length 0, hash 1
|
||||
buffers[48] = length 0, hash 1
|
||||
buffers[49] = length 0, hash 1
|
||||
buffers[50] = length 0, hash 1
|
||||
buffers[51] = length 0, hash 1
|
||||
buffers[52] = length 0, hash 1
|
||||
buffers[53] = length 0, hash 1
|
||||
buffers[54] = length 0, hash 1
|
||||
buffers[55] = length 0, hash 1
|
||||
buffers[56] = length 0, hash 1
|
||||
buffers[57] = length 0, hash 1
|
||||
buffers[58] = length 0, hash 1
|
||||
buffers[59] = length 0, hash 1
|
||||
buffers[60] = length 0, hash 1
|
||||
buffers[61] = length 0, hash 1
|
||||
buffers[62] = length 0, hash 1
|
||||
buffers[63] = length 0, hash 1
|
||||
buffers[64] = length 0, hash 1
|
||||
buffers[65] = length 0, hash 1
|
||||
buffers[66] = length 0, hash 1
|
||||
buffers[67] = length 0, hash 1
|
||||
buffers[68] = length 0, hash 1
|
||||
buffers[69] = length 0, hash 1
|
||||
buffers[70] = length 0, hash 1
|
||||
buffers[71] = length 0, hash 1
|
||||
buffers[72] = length 0, hash 1
|
||||
buffers[73] = length 0, hash 1
|
||||
buffers[74] = length 0, hash 1
|
||||
buffers[75] = length 0, hash 1
|
||||
buffers[76] = length 0, hash 1
|
||||
buffers[77] = length 0, hash 1
|
||||
buffers[78] = length 0, hash 1
|
||||
buffers[79] = length 0, hash 1
|
||||
buffers[80] = length 0, hash 1
|
||||
buffers[81] = length 0, hash 1
|
||||
buffers[82] = length 0, hash 1
|
||||
buffers[83] = length 0, hash 1
|
||||
buffers[84] = length 0, hash 1
|
||||
buffers[85] = length 0, hash 1
|
||||
buffers[86] = length 0, hash 1
|
||||
buffers[87] = length 0, hash 1
|
||||
buffers[88] = length 0, hash 1
|
||||
buffers[89] = length 0, hash 1
|
||||
buffers[90] = length 0, hash 1
|
||||
buffers[91] = length 0, hash 1
|
||||
buffers[92] = length 0, hash 1
|
||||
buffers[93] = length 0, hash 1
|
||||
buffers[94] = length 0, hash 1
|
||||
buffers[95] = length 0, hash 1
|
||||
buffers[96] = length 0, hash 1
|
||||
buffers[97] = length 0, hash 1
|
||||
buffers[98] = length 0, hash 1
|
||||
buffers[99] = length 0, hash 1
|
||||
buffers[100] = length 0, hash 1
|
||||
buffers[101] = length 0, hash 1
|
||||
buffers[102] = length 0, hash 1
|
||||
buffers[103] = length 0, hash 1
|
||||
buffers[104] = length 0, hash 1
|
||||
buffers[105] = length 0, hash 1
|
||||
buffers[106] = length 0, hash 1
|
||||
buffers[107] = length 0, hash 1
|
||||
buffers[108] = length 0, hash 1
|
||||
buffers[109] = length 0, hash 1
|
||||
buffers[110] = length 0, hash 1
|
||||
buffers[111] = length 0, hash 1
|
||||
buffers[112] = length 0, hash 1
|
||||
buffers[113] = length 0, hash 1
|
||||
buffers[114] = length 0, hash 1
|
||||
buffers[115] = length 0, hash 1
|
||||
buffers[116] = length 0, hash 1
|
||||
buffers[117] = length 0, hash 1
|
||||
buffers[118] = length 0, hash 1
|
||||
buffers[119] = length 0, hash 1
|
||||
buffers[120] = length 0, hash 1
|
||||
buffers[121] = length 0, hash 1
|
||||
buffers[122] = length 0, hash 1
|
||||
buffers[123] = length 0, hash 1
|
||||
buffers[124] = length 0, hash 1
|
||||
buffers[125] = length 0, hash 1
|
||||
buffers[126] = length 0, hash 1
|
||||
buffers[127] = length 0, hash 1
|
||||
buffers[128] = length 0, hash 1
|
||||
buffers[129] = length 0, hash 1
|
||||
buffers[130] = length 0, hash 1
|
||||
buffers[131] = length 0, hash 1
|
||||
buffers[132] = length 0, hash 1
|
||||
buffers[133] = length 0, hash 1
|
||||
buffers[134] = length 0, hash 1
|
||||
buffers[135] = length 0, hash 1
|
||||
buffers[136] = length 0, hash 1
|
||||
buffers[137] = length 0, hash 1
|
||||
buffers[138] = length 0, hash 1
|
||||
buffers[139] = length 0, hash 1
|
||||
buffers[140] = length 0, hash 1
|
||||
buffers[141] = length 0, hash 1
|
||||
buffers[142] = length 0, hash 1
|
||||
buffers[143] = length 0, hash 1
|
||||
buffers[144] = length 0, hash 1
|
||||
buffers[145] = length 0, hash 1
|
||||
buffers[146] = length 0, hash 1
|
||||
buffers[147] = length 0, hash 1
|
||||
buffers[148] = length 0, hash 1
|
||||
buffers[149] = length 0, hash 1
|
||||
buffers[150] = length 0, hash 1
|
||||
buffers[151] = length 0, hash 1
|
||||
buffers[152] = length 0, hash 1
|
||||
buffers[153] = length 0, hash 1
|
||||
buffers[154] = length 0, hash 1
|
||||
buffers[155] = length 0, hash 1
|
||||
buffers[156] = length 0, hash 1
|
||||
buffers[157] = length 0, hash 1
|
||||
buffers[158] = length 0, hash 1
|
||||
buffers[159] = length 0, hash 1
|
||||
buffers[160] = length 0, hash 1
|
||||
buffers[161] = length 0, hash 1
|
||||
buffers[162] = length 0, hash 1
|
||||
buffers[163] = length 0, hash 1
|
||||
buffers[164] = length 0, hash 1
|
||||
buffers[165] = length 0, hash 1
|
||||
buffers[166] = length 0, hash 1
|
||||
buffers[167] = length 0, hash 1
|
||||
buffers[168] = length 0, hash 1
|
||||
buffers[169] = length 0, hash 1
|
||||
buffers[170] = length 0, hash 1
|
||||
buffers[171] = length 0, hash 1
|
||||
buffers[172] = length 0, hash 1
|
||||
buffers[173] = length 0, hash 1
|
||||
buffers[174] = length 0, hash 1
|
||||
buffers[175] = length 0, hash 1
|
||||
buffers[176] = length 0, hash 1
|
||||
buffers[177] = length 0, hash 1
|
||||
buffers[178] = length 0, hash 1
|
||||
buffers[179] = length 0, hash 1
|
||||
buffers[180] = length 0, hash 1
|
||||
buffers[181] = length 0, hash 1
|
||||
buffers[182] = length 0, hash 1
|
||||
buffers[183] = length 0, hash 1
|
||||
buffers[184] = length 0, hash 1
|
||||
buffers[185] = length 0, hash 1
|
||||
buffers[186] = length 0, hash 1
|
||||
buffers[187] = length 0, hash 1
|
||||
buffers[188] = length 0, hash 1
|
||||
buffers[189] = length 0, hash 1
|
||||
buffers[190] = length 0, hash 1
|
||||
buffers[191] = length 0, hash 1
|
||||
buffers[192] = length 0, hash 1
|
||||
buffers[193] = length 0, hash 1
|
||||
buffers[194] = length 0, hash 1
|
||||
buffers[195] = length 0, hash 1
|
||||
buffers[196] = length 0, hash 1
|
||||
buffers[197] = length 0, hash 1
|
||||
buffers[198] = length 0, hash 1
|
||||
buffers[199] = length 0, hash 1
|
||||
buffers[200] = length 0, hash 1
|
||||
buffers[201] = length 0, hash 1
|
||||
buffers[202] = length 0, hash 1
|
||||
buffers[203] = length 0, hash 1
|
||||
buffers[204] = length 0, hash 1
|
||||
buffers[205] = length 0, hash 1
|
||||
buffers[206] = length 0, hash 1
|
||||
buffers[207] = length 0, hash 1
|
||||
buffers[208] = length 0, hash 1
|
||||
buffers[209] = length 0, hash 1
|
||||
buffers[210] = length 0, hash 1
|
||||
buffers[211] = length 0, hash 1
|
||||
buffers[212] = length 0, hash 1
|
||||
buffers[213] = length 0, hash 1
|
||||
buffers[214] = length 0, hash 1
|
||||
buffers[215] = length 0, hash 1
|
||||
buffers[216] = length 0, hash 1
|
||||
buffers[217] = length 0, hash 1
|
||||
buffers[218] = length 0, hash 1
|
||||
buffers[219] = length 0, hash 1
|
||||
buffers[220] = length 0, hash 1
|
||||
buffers[221] = length 0, hash 1
|
||||
buffers[222] = length 0, hash 1
|
||||
buffers[223] = length 0, hash 1
|
||||
buffers[224] = length 0, hash 1
|
||||
buffers[225] = length 0, hash 1
|
||||
buffers[226] = length 0, hash 1
|
||||
buffers[227] = length 0, hash 1
|
||||
buffers[228] = length 0, hash 1
|
||||
buffers[229] = length 0, hash 1
|
||||
buffers[230] = length 0, hash 1
|
||||
buffers[231] = length 0, hash 1
|
||||
buffers[232] = length 0, hash 1
|
||||
buffers[233] = length 0, hash 1
|
||||
buffers[234] = length 0, hash 1
|
||||
buffers[235] = length 0, hash 1
|
||||
buffers[236] = length 0, hash 1
|
||||
buffers[237] = length 0, hash 1
|
||||
buffers[238] = length 0, hash 1
|
||||
buffers[239] = length 0, hash 1
|
||||
buffers[240] = length 0, hash 1
|
||||
buffers[241] = length 0, hash 1
|
||||
buffers[242] = length 0, hash 1
|
||||
buffers[243] = length 0, hash 1
|
||||
buffers[244] = length 0, hash 1
|
||||
buffers[245] = length 0, hash 1
|
||||
buffers[246] = length 0, hash 1
|
||||
buffers[247] = length 0, hash 1
|
||||
buffers[248] = length 0, hash 1
|
||||
buffers[249] = length 0, hash 1
|
||||
buffers[250] = length 0, hash 1
|
||||
buffers[251] = length 0, hash 1
|
||||
buffers[252] = length 0, hash 1
|
||||
buffers[253] = length 0, hash 1
|
||||
buffers[254] = length 0, hash 1
|
||||
buffers[255] = length 0, hash 1
|
||||
buffers[256] = length 0, hash 1
|
||||
buffers[257] = length 0, hash 1
|
||||
buffers[258] = length 0, hash 1
|
||||
buffers[259] = length 0, hash 1
|
||||
buffers[260] = length 0, hash 1
|
||||
buffers[261] = length 0, hash 1
|
||||
buffers[262] = length 0, hash 1
|
||||
buffers[263] = length 0, hash 1
|
||||
buffers[264] = length 0, hash 1
|
||||
buffers[265] = length 0, hash 1
|
||||
buffers[266] = length 0, hash 1
|
||||
buffers[267] = length 0, hash 1
|
||||
buffers[268] = length 0, hash 1
|
||||
buffers[269] = length 0, hash 1
|
||||
buffers[270] = length 0, hash 1
|
||||
buffers[271] = length 0, hash 1
|
||||
buffers[272] = length 0, hash 1
|
||||
buffers[273] = length 0, hash 1
|
||||
buffers[274] = length 0, hash 1
|
||||
buffers[275] = length 0, hash 1
|
||||
buffers[276] = length 0, hash 1
|
Loading…
x
Reference in New Issue
Block a user