Update CapturingAudioSink to dump after audio processors

This ensures data modifications like channel mapping or
bitrate changes are correctly captured in the dump files.

PiperOrigin-RevId: 732129701
This commit is contained in:
tonihei 2025-02-28 07:20:05 -08:00 committed by Copybara-Service
parent 2088697a19
commit 796df136d7
8 changed files with 226 additions and 209 deletions

View File

@ -29,7 +29,6 @@ import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.exoplayer.Renderer;
import androidx.media3.exoplayer.RenderersFactory;
import androidx.media3.exoplayer.audio.AudioSink;
import androidx.media3.exoplayer.audio.DefaultAudioSink;
import androidx.media3.exoplayer.source.MediaSource;
import androidx.media3.exoplayer.source.ProgressiveMediaSource;
import androidx.media3.extractor.mkv.MatroskaExtractor;
@ -67,9 +66,7 @@ public class FlacPlaybackTest {
}
private static void playAndAssertAudioSinkInput(String fileName) throws Exception {
CapturingAudioSink audioSink =
new CapturingAudioSink(
new DefaultAudioSink.Builder(ApplicationProvider.getApplicationContext()).build());
CapturingAudioSink audioSink = CapturingAudioSink.create();
TestPlaybackRunnable testPlaybackRunnable =
new TestPlaybackRunnable(

View File

@ -34,7 +34,6 @@ import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.exoplayer.Renderer;
import androidx.media3.exoplayer.RenderersFactory;
import androidx.media3.exoplayer.audio.AudioSink;
import androidx.media3.exoplayer.audio.DefaultAudioSink;
import androidx.media3.exoplayer.source.MediaSource;
import androidx.media3.exoplayer.source.ProgressiveMediaSource;
import androidx.media3.extractor.mp4.Mp4Extractor;
@ -63,9 +62,7 @@ public class IamfPlaybackTest {
}
private static void playAndAssertAudioSinkOutput(String fileName) throws Exception {
CapturingAudioSink audioSink =
new CapturingAudioSink(
new DefaultAudioSink.Builder(ApplicationProvider.getApplicationContext()).build());
CapturingAudioSink audioSink = CapturingAudioSink.create();
TestPlaybackRunnable testPlaybackRunnable =
new TestPlaybackRunnable(

View File

@ -29,7 +29,6 @@ import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.exoplayer.Renderer;
import androidx.media3.exoplayer.RenderersFactory;
import androidx.media3.exoplayer.audio.AudioSink;
import androidx.media3.exoplayer.audio.DefaultAudioSink;
import androidx.media3.exoplayer.source.MediaSource;
import androidx.media3.exoplayer.source.ProgressiveMediaSource;
import androidx.media3.extractor.mkv.MatroskaExtractor;
@ -74,9 +73,7 @@ public class OpusPlaybackTest {
}
private void playUri(String fileName) throws Exception {
CapturingAudioSink audioSink =
new CapturingAudioSink(
new DefaultAudioSink.Builder(ApplicationProvider.getApplicationContext()).build());
CapturingAudioSink audioSink = CapturingAudioSink.create();
TestPlaybackRunnable testPlaybackRunnable =
new TestPlaybackRunnable(

View File

@ -7,88 +7,88 @@ AudioSink:
sampleRate = 48000
buffer #0:
time = 1000000000000
data = 225023649
data = 1217833679
buffer #1:
time = 1000000096000
data = 455106306
data = 558614672
buffer #2:
time = 1000000192000
data = 2025727297
data = -709714787
buffer #3:
time = 1000000288000
data = 758514657
data = 1367870571
buffer #4:
time = 1000000384000
data = 1044986473
data = -141229457
buffer #5:
time = 1000000480000
data = -2030029695
data = 1287758361
buffer #6:
time = 1000000576000
data = 1907053281
data = 1125289147
buffer #7:
time = 1000000672000
data = -1974954431
data = -1677383475
buffer #8:
time = 1000000768000
data = -206248383
data = 2130742861
buffer #9:
time = 1000000864000
data = 1484984417
data = -1292320253
buffer #10:
time = 1000000960000
data = -1306117439
data = -456587163
buffer #11:
time = 1000001056000
data = 692829792
data = 748981534
buffer #12:
time = 1000001152000
data = 1070563058
data = 1550456016
buffer #13:
time = 1000001248000
data = -1444096479
data = 1657906039
buffer #14:
time = 1000001344000
data = 1753016419
data = -762677083
buffer #15:
time = 1000001440000
data = 1947797953
data = -1343810763
buffer #16:
time = 1000001536000
data = 266121411
data = 1137318783
buffer #17:
time = 1000001632000
data = 1275494369
data = -1891318229
buffer #18:
time = 1000001728000
data = 372077825
data = -472068495
buffer #19:
time = 1000001824000
data = -993079679
data = 832315001
buffer #20:
time = 1000001920000
data = 177307937
data = 2054935175
buffer #21:
time = 1000002016000
data = 2037083009
data = 57921641
buffer #22:
time = 1000002112000
data = -435776287
data = 2132759067
buffer #23:
time = 1000002208000
data = 1867447329
data = -1742540521
buffer #24:
time = 1000002304000
data = 1884495937
data = 1657024301
buffer #25:
time = 1000002400000
data = -804673375
data = -585080145
buffer #26:
time = 1000002496000
data = -588531007
data = 427271397
buffer #27:
time = 1000002592000
data = -1064642970
data = -364201340
buffer #28:
time = 1000002688000
data = -1771406207
data = -627965287

View File

@ -8,415 +8,415 @@ AudioSink:
outputChannels = [0, 2, 1, 5, 3, 4]
buffer #0:
time = 1000000000000
data = 376017869
data = 234043725
buffer #1:
time = 1000000021000
data = -1501081867
data = -580791691
buffer #2:
time = 1000000041000
data = -1886525659
data = -1973782107
buffer #3:
time = 1000000061000
data = 1927220572
data = 1529931548
buffer #4:
time = 1000000081000
data = 1788008940
data = -174178004
buffer #5:
time = 1000000101000
data = -15902575
data = 1892687377
buffer #6:
time = 1000000121000
data = -1301740855
data = -413626423
buffer #7:
time = 1000000141000
data = 621832609
data = -595815775
buffer #8:
time = 1000000161000
data = -1588303803
data = 1775558213
buffer #9:
time = 1000000181000
data = 423082548
data = 278415988
buffer #10:
time = 1000000201000
data = 808505936
data = -1167220656
buffer #11:
time = 1000000221000
data = -1092493157
data = 1786323675
buffer #12:
time = 1000000241000
data = -725659694
data = -1686815982
buffer #13:
time = 1000000261000
data = -722218981
data = -1503850981
buffer #14:
time = 1000000281000
data = 280616064
data = 1852969920
buffer #15:
time = 1000000301000
data = 1182192471
data = -714258025
buffer #16:
time = 1000000321000
data = 375143304
data = 358778760
buffer #17:
time = 1000000341000
data = -474611788
data = 1972203316
buffer #18:
time = 1000000361000
data = 315949873
data = -1724152783
buffer #19:
time = 1000000381000
data = -1751860033
data = -390156801
buffer #20:
time = 1000000401000
data = -2141575433
data = -1216014025
buffer #21:
time = 1000000421000
data = -1759699799
data = 1345693353
buffer #22:
time = 1000000441000
data = -1006359333
data = -89432933
buffer #23:
time = 1000000461000
data = -243379314
data = 1599421134
buffer #24:
time = 1000000481000
data = -1627306664
data = -401786024
buffer #25:
time = 1000000501000
data = -757395606
data = 1298478122
buffer #26:
time = 1000000521000
data = -903517963
data = -123106251
buffer #27:
time = 1000000541000
data = 758333744
data = 358397360
buffer #28:
time = 1000000561000
data = -353919780
data = 1606505052
buffer #29:
time = 1000000581000
data = 1573994512
data = 717118992
buffer #30:
time = 1000000601000
data = 454984797
data = 1863602589
buffer #31:
time = 1000000621000
data = 121370022
data = -1165998042
buffer #32:
time = 1000000641000
data = -1549807559
data = 1932879417
buffer #33:
time = 1000000661000
data = -660414046
data = -1589619358
buffer #34:
time = 1000000681000
data = -2068819284
data = 379595052
buffer #35:
time = 1000000701000
data = -1759557231
data = -2127236143
buffer #36:
time = 1000000721000
data = -216211463
data = 345678777
buffer #37:
time = 1000000741000
data = -270655305
data = 1810184887
buffer #38:
time = 1000000761000
data = 1904218932
data = -766380364
buffer #39:
time = 1000000781000
data = -457511627
data = 354834037
buffer #40:
time = 1000000801000
data = -916250571
data = 474011509
buffer #41:
time = 1000000821000
data = -1352402544
data = -1707332016
buffer #42:
time = 1000000841000
data = -1406715357
data = 623940003
buffer #43:
time = 1000000861000
data = -160423302
data = 606630394
buffer #44:
time = 1000000881000
data = -562315050
data = 1109677590
buffer #45:
time = 1000000901000
data = -1285137896
data = -1576058536
buffer #46:
time = 1000000921000
data = 967514144
data = -90398112
buffer #47:
time = 1000000941000
data = -443593130
data = 71274198
buffer #48:
time = 1000000961000
data = -2053337994
data = -40310602
buffer #49:
time = 1000000981000
data = 1306897911
data = 44086455
buffer #50:
time = 1000001001000
data = -629261608
data = -1138227688
buffer #51:
time = 1000001021000
data = -197988143
data = 2025948945
buffer #52:
time = 1000001041000
data = 1951060329
data = 1440259177
buffer #53:
time = 1000001061000
data = 1516494919
data = -436097337
buffer #54:
time = 1000001081000
data = 1742589018
data = 385994650
buffer #55:
time = 1000001101000
data = 1121562002
data = -266443246
buffer #56:
time = 1000001121000
data = -1596344281
data = -1024305689
buffer #57:
time = 1000001141000
data = -969305045
data = -135858773
buffer #58:
time = 1000001161000
data = 364275722
data = 146727818
buffer #59:
time = 1000001181000
data = -233188688
data = 376340976
buffer #60:
time = 1000001201000
data = -1021462703
data = 969373265
buffer #61:
time = 1000001221000
data = 1064140860
data = -515465348
buffer #62:
time = 1000001241000
data = -236898679
data = -1253635383
buffer #63:
time = 1000001261000
data = -359764648
data = 713564184
buffer #64:
time = 1000001281000
data = -1723302464
data = 1056000576
buffer #65:
time = 1000001301000
data = 2076862288
data = 657074448
buffer #66:
time = 1000001321000
data = 2015097443
data = -1985799133
buffer #67:
time = 1000001341000
data = -955703828
data = -1241236052
buffer #68:
time = 1000001361000
data = 1573244659
data = -1605806349
buffer #69:
time = 1000001381000
data = -1421036943
data = 210306417
buffer #70:
time = 1000001401000
data = 1938324900
data = -778696412
buffer #71:
time = 1000001421000
data = 1088878684
data = 1820998620
buffer #72:
time = 1000001441000
data = 1597579555
data = 989311075
buffer #73:
time = 1000001461000
data = 1497574278
data = 860171718
buffer #74:
time = 1000001481000
data = -1756604247
data = -880014935
buffer #75:
time = 1000001501000
data = 368515147
data = 847793035
buffer #76:
time = 1000001521000
data = 512395852
data = 556584524
buffer #77:
time = 1000001541000
data = 564365812
data = -1287767308
buffer #78:
time = 1000001561000
data = 1873249477
data = 69040581
buffer #79:
time = 1000001581000
data = -1781707030
data = -575644502
buffer #80:
time = 1000001601000
data = 1012903106
data = 914598210
buffer #81:
time = 1000001621000
data = -1092012755
data = -397437651
buffer #82:
time = 1000001641000
data = 952876824
data = -254851496
buffer #83:
time = 1000001661000
data = -1424480890
data = 268612998
buffer #84:
time = 1000001681000
data = 1120937431
data = -1839968489
buffer #85:
time = 1000001701000
data = -1626344703
data = -1180239423
buffer #86:
time = 1000001721000
data = 1882664532
data = 59669332
buffer #87:
time = 1000001741000
data = -1175892393
data = -752827753
buffer #88:
time = 1000001761000
data = 2077583079
data = 403856167
buffer #89:
time = 1000001781000
data = -581217660
data = -1344219772
buffer #90:
time = 1000001801000
data = 377904743
data = -668842457
buffer #91:
time = 1000001821000
data = -1084595157
data = 2137762795
buffer #92:
time = 1000001841000
data = 1289312847
data = 343637519
buffer #93:
time = 1000001861000
data = 318127398
data = -1010041242
buffer #94:
time = 1000001881000
data = -1054665983
data = -1157580159
buffer #95:
time = 1000001901000
data = 1311800220
data = -781028132
buffer #96:
time = 1000001921000
data = 1083373864
data = 2132511272
buffer #97:
time = 1000001941000
data = -1575279712
data = -1907272992
buffer #98:
time = 1000001961000
data = 1903786940
data = 2122082300
buffer #99:
time = 1000001981000
data = 968132978
data = -1245356046
buffer #100:
time = 1000002001000
data = 1732190865
data = 1089802641
buffer #101:
time = 1000002021000
data = 1820905719
data = -381766345
buffer #102:
time = 1000002041000
data = 377136640
data = 1096835328
buffer #103:
time = 1000002061000
data = -461752511
data = 461086145
buffer #104:
time = 1000002081000
data = -1669510266
data = 1210244742
buffer #105:
time = 1000002101000
data = 399842824
data = -1808225016
buffer #106:
time = 1000002121000
data = 939150450
data = 26455730
buffer #107:
time = 1000002141000
data = -739412407
data = -188835895
buffer #108:
time = 1000002161000
data = -1094682025
data = 914880535
buffer #109:
time = 1000002181000
data = 1243234514
data = -1300606574
buffer #110:
time = 1000002201000
data = -299900960
data = 159581216
buffer #111:
time = 1000002221000
data = 1491665369
data = 1023615129
buffer #112:
time = 1000002241000
data = 195073085
data = -306886339
buffer #113:
time = 1000002261000
data = -1719454940
data = 1911300580
buffer #114:
time = 1000002281000
data = -744492884
data = -1978405524
buffer #115:
time = 1000002301000
data = 821067246
data = -1342524498
buffer #116:
time = 1000002321000
data = -1434851338
data = 827121014
buffer #117:
time = 1000002341000
data = 779094816
data = 1603726752
buffer #118:
time = 1000002361000
data = -330715311
data = 1732693777
buffer #119:
time = 1000002381000
data = 1225236580
data = -2093029724
buffer #120:
time = 1000002401000
data = 1592040991
data = 618588511
buffer #121:
time = 1000002421000
data = -996563326
data = -894493310
buffer #122:
time = 1000002441000
data = -494589605
data = -687085349
buffer #123:
time = 1000002461000
data = -1330262588
data = 1776293124
buffer #124:
time = 1000002481000
data = -1486074683
data = -948910267
buffer #125:
time = 1000002501000
data = 484577868
data = 173765132
buffer #126:
time = 1000002521000
data = 273883133
data = 716041917
buffer #127:
time = 1000002541000
data = -11420506
data = -743302106
buffer #128:
time = 1000002561000
data = 1904154495
data = -373809025
buffer #129:
time = 1000002581000
data = 516576999
data = -1807281497
buffer #130:
time = 1000002601000
data = 845202278
data = 302220326
buffer #131:
time = 1000002621000
data = 178229514
data = -1322806518
buffer #132:
time = 1000002641000
data = 153624742
data = 1613246758
buffer #133:
time = 1000002661000
data = -26049833
data = -974733545
buffer #134:
time = 1000002681000
data = -1951469655
data = -2087482007
buffer #135:
time = 1000002701000
data = 1564577937
data = -724712367
buffer #136:
time = 1000002721000
data = -660822929
data = 1475344687
buffer #137:
time = 1000002741000
data = -1352825612
data = 47156

View File

@ -15,29 +15,51 @@
*/
package androidx.media3.test.utils;
import static androidx.media3.common.util.Assertions.checkNotNull;
import androidx.annotation.Nullable;
import androidx.media3.common.C;
import androidx.media3.common.Format;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.exoplayer.audio.AudioSink;
import androidx.media3.exoplayer.audio.DefaultAudioSink;
import androidx.media3.exoplayer.audio.ForwardingAudioSink;
import androidx.media3.exoplayer.audio.TeeAudioProcessor;
import androidx.test.core.app.ApplicationProvider;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/** A {@link ForwardingAudioSink} that captures configuration, discontinuity and buffer events. */
/**
* An {@link AudioSink} forwarding to {@link DefaultAudioSink} that captures configuration,
* discontinuity and buffer events.
*/
@UnstableApi
public final class CapturingAudioSink extends ForwardingAudioSink implements Dumper.Dumpable {
private final List<Dumper.Dumpable> interceptedData;
@Nullable private ByteBuffer currentBuffer;
private int bufferCount;
private long lastPresentationTimeUs;
public CapturingAudioSink(AudioSink sink) {
/** Creates the capturing audio sink. */
public static CapturingAudioSink create() {
InterceptingBufferSink interceptingBufferSink = new InterceptingBufferSink();
return new CapturingAudioSink(
new DefaultAudioSink.Builder(ApplicationProvider.getApplicationContext())
.setAudioProcessorChain(
new DefaultAudioSink.DefaultAudioProcessorChain(
new TeeAudioProcessor(interceptingBufferSink)))
.build(),
interceptingBufferSink);
}
private CapturingAudioSink(AudioSink sink, InterceptingBufferSink interceptingBufferSink) {
super(sink);
interceptedData = new ArrayList<>();
interceptingBufferSink.setCapturingAudioSink(this);
}
@Override
@ -63,30 +85,13 @@ public final class CapturingAudioSink extends ForwardingAudioSink implements Dum
public boolean handleBuffer(
ByteBuffer buffer, long presentationTimeUs, int encodedAccessUnitCount)
throws InitializationException, WriteException {
// handleBuffer is called repeatedly with the same buffer until it's been fully consumed by the
// sink. We only want to dump each buffer once, and we need to do so before the sink being
// forwarded to has a chance to modify its position.
if (buffer != currentBuffer) {
interceptedData.add(new DumpableBuffer(bufferCount++, buffer, presentationTimeUs));
currentBuffer = buffer;
lastPresentationTimeUs = presentationTimeUs;
if (!buffer.hasRemaining()) {
// Empty buffers are not processed any further and need to be intercepted here.
// TODO: b/174737370 - Output audio bytes in Robolectric to avoid this situation.
interceptedData.add(new DumpableBuffer(bufferCount++, buffer, lastPresentationTimeUs));
}
boolean fullyConsumed = super.handleBuffer(buffer, presentationTimeUs, encodedAccessUnitCount);
if (fullyConsumed) {
currentBuffer = null;
}
return fullyConsumed;
}
@Override
public void flush() {
currentBuffer = null;
super.flush();
}
@Override
public void reset() {
currentBuffer = null;
super.reset();
return super.handleBuffer(buffer, presentationTimeUs, encodedAccessUnitCount);
}
@Override
@ -101,6 +106,29 @@ public final class CapturingAudioSink extends ForwardingAudioSink implements Dum
dumper.endBlock();
}
private static final class InterceptingBufferSink implements TeeAudioProcessor.AudioBufferSink {
private @MonotonicNonNull CapturingAudioSink capturingAudioSink;
public void setCapturingAudioSink(CapturingAudioSink capturingAudioSink) {
this.capturingAudioSink = capturingAudioSink;
}
@Override
public void flush(int sampleRateHz, int channelCount, @C.PcmEncoding int encoding) {}
@Override
public void handleBuffer(ByteBuffer buffer) {
checkNotNull(capturingAudioSink)
.interceptedData
.add(
new DumpableBuffer(
capturingAudioSink.bufferCount++,
buffer,
capturingAudioSink.lastPresentationTimeUs));
}
}
private static final class DumpableConfiguration implements Dumper.Dumpable {
private final @C.PcmEncoding int inputPcmEncoding;

View File

@ -37,7 +37,6 @@ import androidx.media3.exoplayer.DefaultRenderersFactory;
import androidx.media3.exoplayer.Renderer;
import androidx.media3.exoplayer.RenderersFactory;
import androidx.media3.exoplayer.audio.AudioRendererEventListener;
import androidx.media3.exoplayer.audio.DefaultAudioSink;
import androidx.media3.exoplayer.audio.MediaCodecAudioRenderer;
import androidx.media3.exoplayer.image.ImageDecoder;
import androidx.media3.exoplayer.image.ImageOutput;
@ -89,7 +88,7 @@ public class CapturingRenderersFactory implements RenderersFactory, Dumper.Dumpa
public CapturingRenderersFactory(Context context) {
this.context = context;
this.mediaCodecAdapterFactory = new CapturingMediaCodecAdapter.Factory(context);
this.audioSink = new CapturingAudioSink(new DefaultAudioSink.Builder(context).build());
this.audioSink = CapturingAudioSink.create();
this.imageOutput = new CapturingImageOutput();
this.imageDecoderFactory = ImageDecoder.Factory.DEFAULT;
this.textRendererFactory = TextRenderer::new;

View File

@ -27,7 +27,6 @@ import android.content.Context;
import androidx.media3.common.MediaItem;
import androidx.media3.common.Player;
import androidx.media3.exoplayer.audio.AudioSink;
import androidx.media3.exoplayer.audio.DefaultAudioSink;
import androidx.media3.test.utils.CapturingAudioSink;
import androidx.media3.test.utils.DumpFileAsserts;
import androidx.media3.test.utils.FakeClock;
@ -53,7 +52,7 @@ public final class CompositionPlayerAudioPlaybackTest {
@Before
public void setUp() throws Exception {
capturingAudioSink = new CapturingAudioSink(new DefaultAudioSink.Builder(context).build());
capturingAudioSink = CapturingAudioSink.create();
}
@Test