diff --git a/library/extractor/src/test/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4ExtractorNoSniffingTest.java b/library/extractor/src/test/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4ExtractorNoSniffingTest.java new file mode 100644 index 0000000000..969c9b8d5a --- /dev/null +++ b/library/extractor/src/test/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4ExtractorNoSniffingTest.java @@ -0,0 +1,66 @@ +/* + * Copyright 2020 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 com.google.android.exoplayer2.extractor.mp4; + +import com.google.android.exoplayer2.C; +import com.google.android.exoplayer2.Format; +import com.google.android.exoplayer2.testutil.ExtractorAsserts; +import com.google.android.exoplayer2.util.MimeTypes; +import java.util.List; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.ParameterizedRobolectricTestRunner; +import org.robolectric.ParameterizedRobolectricTestRunner.Parameter; +import org.robolectric.ParameterizedRobolectricTestRunner.Parameters; + +/** + * Tests for {@link FragmentedMp4Extractor} that test behaviours where sniffing must not be tested. + */ +@RunWith(ParameterizedRobolectricTestRunner.class) +public class FragmentedMp4ExtractorNoSniffingTest { + + @Parameters(name = "{0}") + public static List params() { + return ExtractorAsserts.configsNoSniffing(); + } + + @Parameter public ExtractorAsserts.SimulationConfig simulationConfig; + + @Test + public void sampleWithSideLoadedTrack() throws Exception { + // Sideloaded tracks are generally used in Smooth Streaming, where the MP4 files do not contain + // any ftyp box and are not sniffed. + Track sideloadedTrack = + new Track( + /* id= */ 1, + /* type= */ C.TRACK_TYPE_VIDEO, + /* timescale= */ 30_000, + /* movieTimescale= */ 1000, + /* durationUs= */ C.TIME_UNSET, + new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_H264).build(), + /* sampleTransformation= */ Track.TRANSFORMATION_NONE, + /* sampleDescriptionEncryptionBoxes= */ null, + /* nalUnitLengthFieldLength= */ 4, + /* editListDurations= */ null, + /* editListMediaTimes= */ null); + ExtractorAsserts.assertBehavior( + () -> + new FragmentedMp4Extractor( + /* flags= */ 0, /* timestampAdjuster= */ null, sideloadedTrack), + "media/mp4/sample_fragmented_sideloaded_track.mp4", + simulationConfig); + } +} diff --git a/library/extractor/src/test/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4ExtractorTest.java b/library/extractor/src/test/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4ExtractorTest.java index e8ab027e9b..bb640a7ac3 100644 --- a/library/extractor/src/test/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4ExtractorTest.java +++ b/library/extractor/src/test/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4ExtractorTest.java @@ -28,7 +28,7 @@ import org.robolectric.ParameterizedRobolectricTestRunner; import org.robolectric.ParameterizedRobolectricTestRunner.Parameter; import org.robolectric.ParameterizedRobolectricTestRunner.Parameters; -/** Unit test for {@link FragmentedMp4Extractor}. */ +/** Tests for {@link FragmentedMp4Extractor} that test behaviours where sniffing must be tested. */ @RunWith(ParameterizedRobolectricTestRunner.class) public final class FragmentedMp4ExtractorTest { diff --git a/testdata/src/test/assets/extractordumps/mp4/sample_fragmented_sideloaded_track.mp4.0.dump b/testdata/src/test/assets/extractordumps/mp4/sample_fragmented_sideloaded_track.mp4.0.dump new file mode 100644 index 0000000000..f90492cfa1 --- /dev/null +++ b/testdata/src/test/assets/extractordumps/mp4/sample_fragmented_sideloaded_track.mp4.0.dump @@ -0,0 +1,131 @@ +seekMap: + isSeekable = false + duration = UNSET TIME + getPosition(0) = [[timeUs=0, position=0]] +numberOfTracks = 1 +track 0: + total output bytes = 85933 + sample count = 30 + format 0: + sampleMimeType = video/avc + sample 0: + time = 66733 + flags = 1 + data = length 38070, hash B58E1AEE + sample 1: + time = 200199 + flags = 0 + data = length 8340, hash 8AC449FF + sample 2: + time = 133466 + flags = 0 + data = length 1295, hash C0DA5090 + sample 3: + time = 100100 + flags = 0 + data = length 469, hash D6E0A200 + sample 4: + time = 166832 + flags = 0 + data = length 564, hash E5F56C5B + sample 5: + time = 333666 + flags = 0 + data = length 6075, hash 8756E49E + sample 6: + time = 266933 + flags = 0 + data = length 847, hash DCC2B618 + sample 7: + time = 233566 + flags = 0 + data = length 455, hash B9CCE047 + sample 8: + time = 300299 + flags = 0 + data = length 467, hash 69806D94 + sample 9: + time = 467133 + flags = 0 + data = length 4549, hash 3944F501 + sample 10: + time = 400399 + flags = 0 + data = length 1087, hash 491BF106 + sample 11: + time = 367033 + flags = 0 + data = length 380, hash 5FED016A + sample 12: + time = 433766 + flags = 0 + data = length 455, hash 8A0610 + sample 13: + time = 600599 + flags = 0 + data = length 5190, hash B9031D8 + sample 14: + time = 533866 + flags = 0 + data = length 1071, hash 684E7DC8 + sample 15: + time = 500500 + flags = 0 + data = length 653, hash 8494F326 + sample 16: + time = 567232 + flags = 0 + data = length 485, hash 2CCC85F4 + sample 17: + time = 734066 + flags = 0 + data = length 4884, hash D16B6A96 + sample 18: + time = 667333 + flags = 0 + data = length 997, hash 164FF210 + sample 19: + time = 633966 + flags = 0 + data = length 640, hash F664125B + sample 20: + time = 700699 + flags = 0 + data = length 491, hash B5930C7C + sample 21: + time = 867533 + flags = 0 + data = length 2989, hash 92CF4FCF + sample 22: + time = 800799 + flags = 0 + data = length 838, hash 294A3451 + sample 23: + time = 767433 + flags = 0 + data = length 544, hash FCCE2DE6 + sample 24: + time = 834166 + flags = 0 + data = length 329, hash A654FFA1 + sample 25: + time = 1000999 + flags = 0 + data = length 1517, hash 5F7EBF8B + sample 26: + time = 934266 + flags = 0 + data = length 803, hash 7A5C4C1D + sample 27: + time = 900900 + flags = 0 + data = length 415, hash B31BBC3B + sample 28: + time = 967632 + flags = 0 + data = length 415, hash 850DFEA3 + sample 29: + time = 1034366 + flags = 0 + data = length 619, hash AB5E56CA +tracksEnded = true diff --git a/testdata/src/test/assets/extractordumps/mp4/sample_fragmented_sideloaded_track.mp4.unknown_length.dump b/testdata/src/test/assets/extractordumps/mp4/sample_fragmented_sideloaded_track.mp4.unknown_length.dump new file mode 100644 index 0000000000..f90492cfa1 --- /dev/null +++ b/testdata/src/test/assets/extractordumps/mp4/sample_fragmented_sideloaded_track.mp4.unknown_length.dump @@ -0,0 +1,131 @@ +seekMap: + isSeekable = false + duration = UNSET TIME + getPosition(0) = [[timeUs=0, position=0]] +numberOfTracks = 1 +track 0: + total output bytes = 85933 + sample count = 30 + format 0: + sampleMimeType = video/avc + sample 0: + time = 66733 + flags = 1 + data = length 38070, hash B58E1AEE + sample 1: + time = 200199 + flags = 0 + data = length 8340, hash 8AC449FF + sample 2: + time = 133466 + flags = 0 + data = length 1295, hash C0DA5090 + sample 3: + time = 100100 + flags = 0 + data = length 469, hash D6E0A200 + sample 4: + time = 166832 + flags = 0 + data = length 564, hash E5F56C5B + sample 5: + time = 333666 + flags = 0 + data = length 6075, hash 8756E49E + sample 6: + time = 266933 + flags = 0 + data = length 847, hash DCC2B618 + sample 7: + time = 233566 + flags = 0 + data = length 455, hash B9CCE047 + sample 8: + time = 300299 + flags = 0 + data = length 467, hash 69806D94 + sample 9: + time = 467133 + flags = 0 + data = length 4549, hash 3944F501 + sample 10: + time = 400399 + flags = 0 + data = length 1087, hash 491BF106 + sample 11: + time = 367033 + flags = 0 + data = length 380, hash 5FED016A + sample 12: + time = 433766 + flags = 0 + data = length 455, hash 8A0610 + sample 13: + time = 600599 + flags = 0 + data = length 5190, hash B9031D8 + sample 14: + time = 533866 + flags = 0 + data = length 1071, hash 684E7DC8 + sample 15: + time = 500500 + flags = 0 + data = length 653, hash 8494F326 + sample 16: + time = 567232 + flags = 0 + data = length 485, hash 2CCC85F4 + sample 17: + time = 734066 + flags = 0 + data = length 4884, hash D16B6A96 + sample 18: + time = 667333 + flags = 0 + data = length 997, hash 164FF210 + sample 19: + time = 633966 + flags = 0 + data = length 640, hash F664125B + sample 20: + time = 700699 + flags = 0 + data = length 491, hash B5930C7C + sample 21: + time = 867533 + flags = 0 + data = length 2989, hash 92CF4FCF + sample 22: + time = 800799 + flags = 0 + data = length 838, hash 294A3451 + sample 23: + time = 767433 + flags = 0 + data = length 544, hash FCCE2DE6 + sample 24: + time = 834166 + flags = 0 + data = length 329, hash A654FFA1 + sample 25: + time = 1000999 + flags = 0 + data = length 1517, hash 5F7EBF8B + sample 26: + time = 934266 + flags = 0 + data = length 803, hash 7A5C4C1D + sample 27: + time = 900900 + flags = 0 + data = length 415, hash B31BBC3B + sample 28: + time = 967632 + flags = 0 + data = length 415, hash 850DFEA3 + sample 29: + time = 1034366 + flags = 0 + data = length 619, hash AB5E56CA +tracksEnded = true diff --git a/testdata/src/test/assets/media/mp4/sample_fragmented_sideloaded_track.mp4 b/testdata/src/test/assets/media/mp4/sample_fragmented_sideloaded_track.mp4 new file mode 100644 index 0000000000..c17251b005 Binary files /dev/null and b/testdata/src/test/assets/media/mp4/sample_fragmented_sideloaded_track.mp4 differ diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/ExtractorAsserts.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/ExtractorAsserts.java index 73664b44a8..17f6c8f7ab 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/ExtractorAsserts.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/ExtractorAsserts.java @@ -61,6 +61,25 @@ public final class ExtractorAsserts { new Object[] {new SimulationConfig(false, false, false, false)}); } + /** + * Returns a list of arrays containing {@link SimulationConfig} objects to exercise different + * extractor paths in which the input is not sniffed. + * + *

This is intended to be used from tests using {@code ParameterizedRobolectricTestRunner} or + * {@code org.junit.runners.Parameterized}. + */ + public static List configsNoSniffing() { + return Arrays.asList( + new Object[] {new SimulationConfig(false, false, false, false)}, + new Object[] {new SimulationConfig(false, false, false, true)}, + new Object[] {new SimulationConfig(false, false, true, false)}, + new Object[] {new SimulationConfig(false, false, true, true)}, + new Object[] {new SimulationConfig(false, true, false, false)}, + new Object[] {new SimulationConfig(false, true, false, true)}, + new Object[] {new SimulationConfig(false, true, true, false)}, + new Object[] {new SimulationConfig(false, true, true, true)}); + } + /** A config of different environments to simulate and extractor behaviours to test. */ public static class SimulationConfig {