|
15 | 15 | */ |
16 | 16 | package androidx.media3.extractor.mp3; |
17 | 17 |
|
| 18 | +import static com.google.common.base.Preconditions.checkState; |
18 | 19 | import static com.google.common.collect.ImmutableList.toImmutableList; |
19 | 20 | import static com.google.common.truth.Truth.assertThat; |
20 | 21 | import static org.junit.Assume.assumeFalse; |
|
23 | 24 | import androidx.media3.common.C; |
24 | 25 | import androidx.media3.common.Format; |
25 | 26 | import androidx.media3.common.Metadata; |
| 27 | +import androidx.media3.common.util.Util; |
26 | 28 | import androidx.media3.extractor.Extractor; |
27 | 29 | import androidx.media3.extractor.MpegAudioUtil; |
28 | 30 | import androidx.media3.extractor.PositionHolder; |
|
37 | 39 | import androidx.test.core.app.ApplicationProvider; |
38 | 40 | import com.google.common.base.Ascii; |
39 | 41 | import com.google.common.collect.ImmutableList; |
| 42 | +import com.google.common.primitives.Bytes; |
40 | 43 | import com.google.testing.junit.testparameterinjector.TestParameter; |
41 | 44 | import com.google.testing.junit.testparameterinjector.TestParameterValuesProvider; |
| 45 | +import java.nio.ByteBuffer; |
42 | 46 | import org.junit.Test; |
43 | 47 | import org.junit.runner.RunWith; |
44 | 48 | import org.robolectric.RobolectricTestParameterInjector; |
@@ -129,14 +133,13 @@ public void mp3SampleWithInfoHeader_invalidDataSizeFallsBackToFrameBitrate() thr |
129 | 133 | byte[] fileBytes = |
130 | 134 | TestUtil.getByteArray( |
131 | 135 | ApplicationProvider.getApplicationContext(), "media/mp3/test-cbr-info-header.mp3"); |
132 | | - int infoTagOffset = indexOf(fileBytes, new byte[] {'I', 'n', 'f', 'o'}); |
133 | | - assertThat(infoTagOffset).isAtLeast(0); |
134 | | - int infoFramePosition = findMpegFramePositionBeforeTag(fileBytes, infoTagOffset); |
135 | | - assertThat(infoFramePosition).isNotEqualTo(C.INDEX_UNSET); |
| 136 | + int infoTagOffset = Bytes.indexOf(fileBytes, new byte[]{'I', 'n', 'f', 'o'}); |
| 137 | + checkState(infoTagOffset >= 0); |
| 138 | + ByteBuffer fileBytesBuffer = ByteBuffer.wrap(fileBytes); |
| 139 | + int infoFramePosition = findMpegFramePositionBeforeTag(fileBytesBuffer, infoTagOffset); |
136 | 140 | MpegAudioUtil.Header infoFrameHeader = new MpegAudioUtil.Header(); |
137 | | - assertThat(infoFrameHeader.setForHeaderData(readBigEndianInt(fileBytes, infoFramePosition))) |
138 | | - .isTrue(); |
139 | | - writeBigEndianInt(fileBytes, infoTagOffset + 12, infoFrameHeader.frameSize); |
| 141 | + checkState(infoFrameHeader.setForHeaderData(fileBytesBuffer.getInt(infoFramePosition))); |
| 142 | + fileBytesBuffer.putInt(infoTagOffset + 12, infoFrameHeader.frameSize); |
140 | 143 |
|
141 | 144 | FakeExtractorOutput output = |
142 | 145 | extractUntilSeekMap(new Mp3Extractor(), fileBytes, /* simulateUnknownLength= */ false); |
@@ -458,42 +461,15 @@ private static FakeExtractorOutput extractUntilSeekMap( |
458 | 461 | return output; |
459 | 462 | } |
460 | 463 |
|
461 | | - private static int findMpegFramePositionBeforeTag(byte[] data, int tagOffset) { |
| 464 | + private static int findMpegFramePositionBeforeTag(ByteBuffer data, int tagOffset) { |
462 | 465 | for (int tagOffsetFromFrameStart : new int[] {13, 21, 36}) { |
463 | 466 | int framePosition = tagOffset - tagOffsetFromFrameStart; |
464 | 467 | if (framePosition >= 0 |
465 | | - && framePosition + 4 <= data.length |
466 | | - && new MpegAudioUtil.Header().setForHeaderData(readBigEndianInt(data, framePosition))) { |
| 468 | + && framePosition + 4 <= data.remaining() |
| 469 | + && new MpegAudioUtil.Header().setForHeaderData(data.getInt(framePosition))) { |
467 | 470 | return framePosition; |
468 | 471 | } |
469 | 472 | } |
470 | | - return C.INDEX_UNSET; |
471 | | - } |
472 | | - |
473 | | - private static int indexOf(byte[] data, byte[] target) { |
474 | | - for (int i = 0; i <= data.length - target.length; i++) { |
475 | | - boolean matches = true; |
476 | | - for (int j = 0; j < target.length; j++) { |
477 | | - matches &= data[i + j] == target[j]; |
478 | | - } |
479 | | - if (matches) { |
480 | | - return i; |
481 | | - } |
482 | | - } |
483 | | - return C.INDEX_UNSET; |
484 | | - } |
485 | | - |
486 | | - private static int readBigEndianInt(byte[] data, int offset) { |
487 | | - return ((data[offset] & 0xFF) << 24) |
488 | | - | ((data[offset + 1] & 0xFF) << 16) |
489 | | - | ((data[offset + 2] & 0xFF) << 8) |
490 | | - | (data[offset + 3] & 0xFF); |
491 | | - } |
492 | | - |
493 | | - private static void writeBigEndianInt(byte[] data, int offset, int value) { |
494 | | - data[offset] = (byte) (value >> 24); |
495 | | - data[offset + 1] = (byte) (value >> 16); |
496 | | - data[offset + 2] = (byte) (value >> 8); |
497 | | - data[offset + 3] = (byte) value; |
| 473 | + throw new IllegalArgumentException("No tag found in " + Util.toHexString(data.array())); |
498 | 474 | } |
499 | 475 | } |
0 commit comments