Commit 91517dc9 by andrewlewis Committed by Andrew Lewis

Split out extractor and common modules

PiperOrigin-RevId: 291378636
parent 7b63afb2
Showing with 1760 additions and 0 deletions
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
clarifying the distinction between `Format` and `MediaFormat`. clarifying the distinction between `Format` and `MediaFormat`.
* Move player message-related constants from `C` to `Renderer`, to avoid * Move player message-related constants from `C` to `Renderer`, to avoid
having the constants class depend on player/renderer classes. having the constants class depend on player/renderer classes.
* Split out `common` and `extractor` submodules.
* Text: * Text:
* Parse `<ruby>` and `<rt>` tags in WebVTT subtitles (rendering is coming * Parse `<ruby>` and `<rt>` tags in WebVTT subtitles (rendering is coming
later). later).
......
...@@ -18,8 +18,10 @@ if (gradle.ext.has('exoplayerModulePrefix')) { ...@@ -18,8 +18,10 @@ if (gradle.ext.has('exoplayerModulePrefix')) {
} }
include modulePrefix + 'library' include modulePrefix + 'library'
include modulePrefix + 'library-common'
include modulePrefix + 'library-core' include modulePrefix + 'library-core'
include modulePrefix + 'library-dash' include modulePrefix + 'library-dash'
include modulePrefix + 'library-extractor'
include modulePrefix + 'library-hls' include modulePrefix + 'library-hls'
include modulePrefix + 'library-smoothstreaming' include modulePrefix + 'library-smoothstreaming'
include modulePrefix + 'library-ui' include modulePrefix + 'library-ui'
...@@ -41,8 +43,10 @@ include modulePrefix + 'extension-jobdispatcher' ...@@ -41,8 +43,10 @@ include modulePrefix + 'extension-jobdispatcher'
include modulePrefix + 'extension-workmanager' include modulePrefix + 'extension-workmanager'
project(modulePrefix + 'library').projectDir = new File(rootDir, 'library/all') project(modulePrefix + 'library').projectDir = new File(rootDir, 'library/all')
project(modulePrefix + 'library-common').projectDir = new File(rootDir, 'library/common')
project(modulePrefix + 'library-core').projectDir = new File(rootDir, 'library/core') project(modulePrefix + 'library-core').projectDir = new File(rootDir, 'library/core')
project(modulePrefix + 'library-dash').projectDir = new File(rootDir, 'library/dash') project(modulePrefix + 'library-dash').projectDir = new File(rootDir, 'library/dash')
project(modulePrefix + 'library-extractor').projectDir = new File(rootDir, 'library/extractor')
project(modulePrefix + 'library-hls').projectDir = new File(rootDir, 'library/hls') project(modulePrefix + 'library-hls').projectDir = new File(rootDir, 'library/hls')
project(modulePrefix + 'library-smoothstreaming').projectDir = new File(rootDir, 'library/smoothstreaming') project(modulePrefix + 'library-smoothstreaming').projectDir = new File(rootDir, 'library/smoothstreaming')
project(modulePrefix + 'library-ui').projectDir = new File(rootDir, 'library/ui') project(modulePrefix + 'library-ui').projectDir = new File(rootDir, 'library/ui')
......
# ExoPlayer common library module #
Common code used by other ExoPlayer modules.
## Links ##
* [Javadoc][]: Note that this Javadoc is combined with that of other modules.
[Javadoc]: https://exoplayer.dev/doc/reference/index.html
// Copyright (C) 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.
apply from: '../../constants.gradle'
apply plugin: 'com.android.library'
android {
compileSdkVersion project.ext.compileSdkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
defaultConfig {
minSdkVersion project.ext.minSdkVersion
targetSdkVersion project.ext.targetSdkVersion
}
buildTypes {
debug {
testCoverageEnabled = true
}
}
testOptions.unitTests.includeAndroidResources = true
}
dependencies {
implementation 'androidx.annotation:annotation:' + androidxAnnotationVersion
compileOnly 'com.google.code.findbugs:jsr305:' + jsr305Version
compileOnly 'org.checkerframework:checker-qual:' + checkerframeworkVersion
compileOnly 'org.checkerframework:checker-compat-qual:' + checkerframeworkVersion
compileOnly 'org.jetbrains.kotlin:kotlin-annotations-jvm:' + kotlinAnnotationsVersion
testImplementation project(modulePrefix + 'testutils')
testImplementation 'org.robolectric:robolectric:' + robolectricVersion
}
ext {
javadocTitle = 'Common module'
}
apply from: '../../javadoc_library.gradle'
ext {
releaseArtifact = 'exoplayer-common'
releaseDescription = 'The ExoPlayer library common module.'
}
apply from: '../../publish.gradle'
# Proguard rules specific to the common module.
# Don't warn about checkerframework and Kotlin annotations
-dontwarn org.checkerframework.**
-dontwarn kotlin.annotations.jvm.**
-dontwarn javax.annotation.**
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.exoplayer2.common">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
</manifest>
/*
* Copyright (C) 2019 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.
*/
@NonNullApi
package com.google.android.exoplayer2.audio;
import com.google.android.exoplayer2.util.NonNullApi;
/*
* Copyright (C) 2019 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.
*/
@NonNullApi
package com.google.android.exoplayer2.decoder;
import com.google.android.exoplayer2.util.NonNullApi;
/*
* Copyright (C) 2019 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.
*/
@NonNullApi
package com.google.android.exoplayer2.drm;
import com.google.android.exoplayer2.util.NonNullApi;
/*
* Copyright (C) 2019 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.
*/
@NonNullApi
package com.google.android.exoplayer2.metadata;
import com.google.android.exoplayer2.util.NonNullApi;
/*
* Copyright (C) 2019 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.
*/
@NonNullApi
package com.google.android.exoplayer2;
import com.google.android.exoplayer2.util.NonNullApi;
/*
* Copyright (C) 2019 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.
*/
@NonNullApi
package com.google.android.exoplayer2.upstream;
import com.google.android.exoplayer2.util.NonNullApi;
/*
* Copyright (C) 2019 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.
*/
@NonNullApi
package com.google.android.exoplayer2.util;
/*
* Copyright (C) 2019 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.
*/
@NonNullApi
package com.google.android.exoplayer2.video;
import com.google.android.exoplayer2.util.NonNullApi;
../../proguard-rules.txt
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 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.
-->
<manifest package="com.google.android.exoplayer2.common">
<uses-sdk/>
</manifest>
/*
* Copyright (C) 2016 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;
import static com.google.common.truth.Truth.assertThat;
import android.annotation.SuppressLint;
import android.media.MediaCodec;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Unit test for {@link C}. */
@RunWith(AndroidJUnit4.class)
public class CTest {
@SuppressLint("InlinedApi")
@Test
public void testConstants() {
// Sanity check that constant values match those defined by the platform.
assertThat(C.BUFFER_FLAG_KEY_FRAME).isEqualTo(MediaCodec.BUFFER_FLAG_KEY_FRAME);
assertThat(C.BUFFER_FLAG_END_OF_STREAM).isEqualTo(MediaCodec.BUFFER_FLAG_END_OF_STREAM);
assertThat(C.CRYPTO_MODE_AES_CTR).isEqualTo(MediaCodec.CRYPTO_MODE_AES_CTR);
}
}
/*
* Copyright (C) 2016 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;
import static com.google.android.exoplayer2.C.WIDEVINE_UUID;
import static com.google.android.exoplayer2.util.MimeTypes.VIDEO_MP4;
import static com.google.android.exoplayer2.util.MimeTypes.VIDEO_WEBM;
import static com.google.common.truth.Truth.assertThat;
import android.os.Parcel;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.drm.DrmInitData;
import com.google.android.exoplayer2.metadata.Metadata;
import com.google.android.exoplayer2.metadata.id3.TextInformationFrame;
import com.google.android.exoplayer2.testutil.TestUtil;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.video.ColorInfo;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Unit test for {@link Format}. */
@RunWith(AndroidJUnit4.class)
public final class FormatTest {
private static final List<byte[]> initData;
static {
byte[] initData1 = new byte[] {1, 2, 3};
byte[] initData2 = new byte[] {4, 5, 6};
List<byte[]> initDataList = new ArrayList<>();
initDataList.add(initData1);
initDataList.add(initData2);
initData = Collections.unmodifiableList(initDataList);
}
@Test
public void testParcelable() {
DrmInitData.SchemeData drmData1 = new DrmInitData.SchemeData(WIDEVINE_UUID, VIDEO_MP4,
TestUtil.buildTestData(128, 1 /* data seed */));
DrmInitData.SchemeData drmData2 = new DrmInitData.SchemeData(C.UUID_NIL, VIDEO_WEBM,
TestUtil.buildTestData(128, 1 /* data seed */));
DrmInitData drmInitData = new DrmInitData(drmData1, drmData2);
byte[] projectionData = new byte[] {1, 2, 3};
Metadata metadata = new Metadata(
new TextInformationFrame("id1", "description1", "value1"),
new TextInformationFrame("id2", "description2", "value2"));
ColorInfo colorInfo = new ColorInfo(C.COLOR_SPACE_BT709,
C.COLOR_RANGE_LIMITED, C.COLOR_TRANSFER_SDR, new byte[] {1, 2, 3, 4, 5, 6, 7});
Format formatToParcel =
new Format(
"id",
"label",
C.SELECTION_FLAG_DEFAULT,
C.ROLE_FLAG_MAIN,
/* bitrate= */ 1024,
"codec",
metadata,
/* containerMimeType= */ MimeTypes.VIDEO_MP4,
/* sampleMimeType= */ MimeTypes.VIDEO_H264,
/* maxInputSize= */ 2048,
initData,
drmInitData,
Format.OFFSET_SAMPLE_RELATIVE,
/* width= */ 1920,
/* height= */ 1080,
/* frameRate= */ 24,
/* rotationDegrees= */ 90,
/* pixelWidthHeightRatio= */ 2,
projectionData,
C.STEREO_MODE_TOP_BOTTOM,
colorInfo,
/* channelCount= */ 6,
/* sampleRate= */ 44100,
C.ENCODING_PCM_24BIT,
/* encoderDelay= */ 1001,
/* encoderPadding= */ 1002,
"language",
/* accessibilityChannel= */ Format.NO_VALUE,
/* exoMediaCryptoType= */ null);
Parcel parcel = Parcel.obtain();
formatToParcel.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
Format formatFromParcel = Format.CREATOR.createFromParcel(parcel);
assertThat(formatFromParcel).isEqualTo(formatToParcel);
parcel.recycle();
}
}
/*
* Copyright (C) 2018 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.audio;
import static com.google.common.truth.Truth.assertThat;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.util.Util;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Unit tests for {@link Ac3Util}. */
@RunWith(AndroidJUnit4.class)
public final class Ac3UtilTest {
private static final int TRUEHD_SYNCFRAME_SAMPLE_COUNT = 40;
private static final byte[] TRUEHD_SYNCFRAME_HEADER =
Util.getBytesFromHexString("C07504D8F8726FBA0097C00FB7520000");
private static final byte[] TRUEHD_NON_SYNCFRAME_HEADER =
Util.getBytesFromHexString("A025048860224E6F6DEDB6D5B6DBAFE6");
@Test
public void testParseTrueHdSyncframeAudioSampleCount_nonSyncframe() {
assertThat(Ac3Util.parseTrueHdSyncframeAudioSampleCount(TRUEHD_NON_SYNCFRAME_HEADER))
.isEqualTo(0);
}
@Test
public void testParseTrueHdSyncframeAudioSampleCount_syncframe() {
assertThat(Ac3Util.parseTrueHdSyncframeAudioSampleCount(TRUEHD_SYNCFRAME_HEADER))
.isEqualTo(TRUEHD_SYNCFRAME_SAMPLE_COUNT);
}
}
/*
* Copyright (C) 2016 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.drm;
import static com.google.android.exoplayer2.C.PLAYREADY_UUID;
import static com.google.android.exoplayer2.C.UUID_NIL;
import static com.google.android.exoplayer2.C.WIDEVINE_UUID;
import static com.google.android.exoplayer2.util.MimeTypes.VIDEO_MP4;
import static com.google.common.truth.Truth.assertThat;
import android.os.Parcel;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
import com.google.android.exoplayer2.testutil.TestUtil;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Unit test for {@link DrmInitData}. */
@RunWith(AndroidJUnit4.class)
public class DrmInitDataTest {
private static final SchemeData DATA_1 = new SchemeData(WIDEVINE_UUID, VIDEO_MP4,
TestUtil.buildTestData(128, 1 /* data seed */));
private static final SchemeData DATA_2 = new SchemeData(PLAYREADY_UUID, VIDEO_MP4,
TestUtil.buildTestData(128, 2 /* data seed */));
private static final SchemeData DATA_1B = new SchemeData(WIDEVINE_UUID, VIDEO_MP4,
TestUtil.buildTestData(128, 1 /* data seed */));
private static final SchemeData DATA_2B = new SchemeData(PLAYREADY_UUID, VIDEO_MP4,
TestUtil.buildTestData(128, 2 /* data seed */));
private static final SchemeData DATA_UNIVERSAL = new SchemeData(C.UUID_NIL, VIDEO_MP4,
TestUtil.buildTestData(128, 3 /* data seed */));
@Test
public void testParcelable() {
DrmInitData drmInitDataToParcel = new DrmInitData(DATA_1, DATA_2);
Parcel parcel = Parcel.obtain();
drmInitDataToParcel.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
DrmInitData drmInitDataFromParcel = DrmInitData.CREATOR.createFromParcel(parcel);
assertThat(drmInitDataFromParcel).isEqualTo(drmInitDataToParcel);
parcel.recycle();
}
@Test
public void testEquals() {
DrmInitData drmInitData = new DrmInitData(DATA_1, DATA_2);
// Basic non-referential equality test.
DrmInitData testInitData = new DrmInitData(DATA_1, DATA_2);
assertThat(testInitData).isEqualTo(drmInitData);
assertThat(testInitData.hashCode()).isEqualTo(drmInitData.hashCode());
// Basic non-referential equality test with non-referential scheme data.
testInitData = new DrmInitData(DATA_1B, DATA_2B);
assertThat(testInitData).isEqualTo(drmInitData);
assertThat(testInitData.hashCode()).isEqualTo(drmInitData.hashCode());
// Passing the scheme data in reverse order shouldn't affect equality.
testInitData = new DrmInitData(DATA_2, DATA_1);
assertThat(testInitData).isEqualTo(drmInitData);
assertThat(testInitData.hashCode()).isEqualTo(drmInitData.hashCode());
// Ditto.
testInitData = new DrmInitData(DATA_2B, DATA_1B);
assertThat(testInitData).isEqualTo(drmInitData);
assertThat(testInitData.hashCode()).isEqualTo(drmInitData.hashCode());
// Different number of tuples should affect equality.
testInitData = new DrmInitData(DATA_1);
assertThat(drmInitData).isNotEqualTo(testInitData);
// Different data in one of the tuples should affect equality.
testInitData = new DrmInitData(DATA_1, DATA_UNIVERSAL);
assertThat(testInitData).isNotEqualTo(drmInitData);
}
@Test
@SuppressWarnings("deprecation")
public void testGetByUuid() {
// Basic matching.
DrmInitData testInitData = new DrmInitData(DATA_1, DATA_2);
assertThat(testInitData.get(WIDEVINE_UUID)).isEqualTo(DATA_1);
assertThat(testInitData.get(PLAYREADY_UUID)).isEqualTo(DATA_2);
assertThat(testInitData.get(UUID_NIL)).isNull();
// Basic matching including universal data.
testInitData = new DrmInitData(DATA_1, DATA_2, DATA_UNIVERSAL);
assertThat(testInitData.get(WIDEVINE_UUID)).isEqualTo(DATA_1);
assertThat(testInitData.get(PLAYREADY_UUID)).isEqualTo(DATA_2);
assertThat(testInitData.get(UUID_NIL)).isEqualTo(DATA_UNIVERSAL);
// Passing the scheme data in reverse order shouldn't affect equality.
testInitData = new DrmInitData(DATA_UNIVERSAL, DATA_2, DATA_1);
assertThat(testInitData.get(WIDEVINE_UUID)).isEqualTo(DATA_1);
assertThat(testInitData.get(PLAYREADY_UUID)).isEqualTo(DATA_2);
assertThat(testInitData.get(UUID_NIL)).isEqualTo(DATA_UNIVERSAL);
// Universal data should be returned in the absence of a specific match.
testInitData = new DrmInitData(DATA_1, DATA_UNIVERSAL);
assertThat(testInitData.get(WIDEVINE_UUID)).isEqualTo(DATA_1);
assertThat(testInitData.get(PLAYREADY_UUID)).isEqualTo(DATA_UNIVERSAL);
assertThat(testInitData.get(UUID_NIL)).isEqualTo(DATA_UNIVERSAL);
}
@Test
public void testGetByIndex() {
DrmInitData testInitData = new DrmInitData(DATA_1, DATA_2);
assertThat(getAllSchemeData(testInitData)).containsAtLeast(DATA_1, DATA_2);
}
@Test
@SuppressWarnings("deprecation")
public void testSchemeDatasWithSameUuid() {
DrmInitData testInitData = new DrmInitData(DATA_1, DATA_1B);
assertThat(testInitData.schemeDataCount).isEqualTo(2);
// Deprecated get method should return first entry.
assertThat(testInitData.get(WIDEVINE_UUID)).isEqualTo(DATA_1);
// Test retrieval of first and second entry.
assertThat(testInitData.get(0)).isEqualTo(DATA_1);
assertThat(testInitData.get(1)).isEqualTo(DATA_1B);
}
@Test
public void testSchemeDataMatches() {
assertThat(DATA_1.matches(WIDEVINE_UUID)).isTrue();
assertThat(DATA_1.matches(PLAYREADY_UUID)).isFalse();
assertThat(DATA_2.matches(UUID_NIL)).isFalse();
assertThat(DATA_2.matches(WIDEVINE_UUID)).isFalse();
assertThat(DATA_2.matches(PLAYREADY_UUID)).isTrue();
assertThat(DATA_2.matches(UUID_NIL)).isFalse();
assertThat(DATA_UNIVERSAL.matches(WIDEVINE_UUID)).isTrue();
assertThat(DATA_UNIVERSAL.matches(PLAYREADY_UUID)).isTrue();
assertThat(DATA_UNIVERSAL.matches(UUID_NIL)).isTrue();
}
private List<SchemeData> getAllSchemeData(DrmInitData drmInitData) {
ArrayList<SchemeData> schemeDatas = new ArrayList<>();
for (int i = 0; i < drmInitData.schemeDataCount; i++) {
schemeDatas.add(drmInitData.get(i));
}
return schemeDatas;
}
}
/*
* Copyright (C) 2019 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.metadata;
import static com.google.common.truth.Truth.assertThat;
import android.os.Parcel;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.metadata.id3.BinaryFrame;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Tests for {@link Metadata}. */
@RunWith(AndroidJUnit4.class)
public class MetadataTest {
@Test
public void testParcelable() {
Metadata metadataToParcel =
new Metadata(
new BinaryFrame("id1", new byte[] {1}), new BinaryFrame("id2", new byte[] {2}));
Parcel parcel = Parcel.obtain();
metadataToParcel.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
Metadata metadataFromParcel = Metadata.CREATOR.createFromParcel(parcel);
assertThat(metadataFromParcel).isEqualTo(metadataToParcel);
parcel.recycle();
}
}
/*
* Copyright (C) 2017 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.metadata.emsg;
import static com.google.android.exoplayer2.testutil.TestUtil.createByteArray;
import static com.google.android.exoplayer2.testutil.TestUtil.joinByteArrays;
import static com.google.common.truth.Truth.assertThat;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.metadata.Metadata;
import com.google.android.exoplayer2.metadata.MetadataInputBuffer;
import java.nio.ByteBuffer;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Test for {@link EventMessageDecoder}. */
@RunWith(AndroidJUnit4.class)
public final class EventMessageDecoderTest {
@Test
public void testDecodeEventMessage() {
byte[] rawEmsgBody =
joinByteArrays(
createByteArray(117, 114, 110, 58, 116, 101, 115, 116, 0), // scheme_id_uri = "urn:test"
createByteArray(49, 50, 51, 0), // value = "123"
createByteArray(0, 0, 11, 184), // event_duration_ms = 3000
createByteArray(0, 15, 67, 211), // id = 1000403
createByteArray(0, 1, 2, 3, 4)); // message_data = {0, 1, 2, 3, 4}
EventMessageDecoder decoder = new EventMessageDecoder();
MetadataInputBuffer buffer = new MetadataInputBuffer();
buffer.data = ByteBuffer.allocate(rawEmsgBody.length).put(rawEmsgBody);
Metadata metadata = decoder.decode(buffer);
assertThat(metadata.length()).isEqualTo(1);
EventMessage eventMessage = (EventMessage) metadata.get(0);
assertThat(eventMessage.schemeIdUri).isEqualTo("urn:test");
assertThat(eventMessage.value).isEqualTo("123");
assertThat(eventMessage.durationMs).isEqualTo(3000);
assertThat(eventMessage.id).isEqualTo(1000403);
assertThat(eventMessage.messageData).isEqualTo(new byte[]{0, 1, 2, 3, 4});
}
}
/*
* Copyright (C) 2017 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.metadata.emsg;
import static com.google.android.exoplayer2.testutil.TestUtil.createByteArray;
import static com.google.android.exoplayer2.testutil.TestUtil.joinByteArrays;
import static com.google.common.truth.Truth.assertThat;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.metadata.Metadata;
import com.google.android.exoplayer2.metadata.MetadataInputBuffer;
import java.io.IOException;
import java.nio.ByteBuffer;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Unit test for {@link EventMessageEncoder}. */
@RunWith(AndroidJUnit4.class)
public final class EventMessageEncoderTest {
private static final EventMessage DECODED_MESSAGE =
new EventMessage("urn:test", "123", 3000, 1000403, new byte[] {0, 1, 2, 3, 4});
private static final byte[] ENCODED_MESSAGE =
joinByteArrays(
createByteArray(117, 114, 110, 58, 116, 101, 115, 116, 0), // scheme_id_uri = "urn:test"
createByteArray(49, 50, 51, 0), // value = "123"
createByteArray(0, 0, 11, 184), // event_duration_ms = 3000
createByteArray(0, 15, 67, 211), // id = 1000403
createByteArray(0, 1, 2, 3, 4)); // message_data = {0, 1, 2, 3, 4}
@Test
public void testEncodeEventStream() throws IOException {
byte[] foo = new byte[] {1, 2, 3};
byte[] encodedByteArray = new EventMessageEncoder().encode(DECODED_MESSAGE);
assertThat(encodedByteArray).isEqualTo(ENCODED_MESSAGE);
}
@Test
public void testEncodeDecodeEventStream() throws IOException {
byte[] encodedByteArray = new EventMessageEncoder().encode(DECODED_MESSAGE);
MetadataInputBuffer buffer = new MetadataInputBuffer();
buffer.data = ByteBuffer.allocate(encodedByteArray.length).put(encodedByteArray);
EventMessageDecoder decoder = new EventMessageDecoder();
Metadata metadata = decoder.decode(buffer);
assertThat(metadata.length()).isEqualTo(1);
assertThat(metadata.get(0)).isEqualTo(DECODED_MESSAGE);
}
@Test
public void testEncodeEventStreamMultipleTimesWorkingCorrectly() throws IOException {
EventMessage eventMessage1 =
new EventMessage("urn:test", "123", 3000, 1000402, new byte[] {4, 3, 2, 1, 0});
byte[] expectedEmsgBody1 =
joinByteArrays(
createByteArray(117, 114, 110, 58, 116, 101, 115, 116, 0), // scheme_id_uri = "urn:test"
createByteArray(49, 50, 51, 0), // value = "123"
createByteArray(0, 0, 11, 184), // event_duration_ms = 3000
createByteArray(0, 15, 67, 210), // id = 1000402
createByteArray(4, 3, 2, 1, 0)); // message_data = {4, 3, 2, 1, 0}
EventMessageEncoder eventMessageEncoder = new EventMessageEncoder();
byte[] encodedByteArray = eventMessageEncoder.encode(DECODED_MESSAGE);
assertThat(encodedByteArray).isEqualTo(ENCODED_MESSAGE);
byte[] encodedByteArray1 = eventMessageEncoder.encode(eventMessage1);
assertThat(encodedByteArray1).isEqualTo(expectedEmsgBody1);
}
}
/*
* Copyright (C) 2017 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.metadata.emsg;
import static com.google.common.truth.Truth.assertThat;
import android.os.Parcel;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Test for {@link EventMessage}. */
@RunWith(AndroidJUnit4.class)
public final class EventMessageTest {
@Test
public void testEventMessageParcelable() {
EventMessage eventMessage =
new EventMessage("urn:test", "123", 3000, 1000403, new byte[] {0, 1, 2, 3, 4});
// Write to parcel.
Parcel parcel = Parcel.obtain();
eventMessage.writeToParcel(parcel, 0);
// Create from parcel.
parcel.setDataPosition(0);
EventMessage fromParcelEventMessage = EventMessage.CREATOR.createFromParcel(parcel);
// Assert equals.
assertThat(fromParcelEventMessage).isEqualTo(eventMessage);
}
}
/*
* Copyright (C) 2019 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.metadata.flac;
import static com.google.common.truth.Truth.assertThat;
import android.os.Parcel;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Test for {@link PictureFrame}. */
@RunWith(AndroidJUnit4.class)
public final class PictureFrameTest {
@Test
public void testParcelable() {
PictureFrame pictureFrameToParcel = new PictureFrame(0, "", "", 0, 0, 0, 0, new byte[0]);
Parcel parcel = Parcel.obtain();
pictureFrameToParcel.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
PictureFrame pictureFrameFromParcel = PictureFrame.CREATOR.createFromParcel(parcel);
assertThat(pictureFrameFromParcel).isEqualTo(pictureFrameToParcel);
parcel.recycle();
}
}
/*
* Copyright (C) 2019 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.metadata.flac;
import static com.google.common.truth.Truth.assertThat;
import android.os.Parcel;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Test for {@link VorbisComment}. */
@RunWith(AndroidJUnit4.class)
public final class VorbisCommentTest {
@Test
public void testParcelable() {
VorbisComment vorbisCommentFrameToParcel = new VorbisComment("key", "value");
Parcel parcel = Parcel.obtain();
vorbisCommentFrameToParcel.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
VorbisComment vorbisCommentFrameFromParcel = VorbisComment.CREATOR.createFromParcel(parcel);
assertThat(vorbisCommentFrameFromParcel).isEqualTo(vorbisCommentFrameToParcel);
parcel.recycle();
}
}
/*
* Copyright (C) 2017 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.metadata.id3;
import static com.google.common.truth.Truth.assertThat;
import android.os.Parcel;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Test for {@link ChapterFrame}. */
@RunWith(AndroidJUnit4.class)
public final class ChapterFrameTest {
@Test
public void testParcelable() {
Id3Frame[] subFrames = new Id3Frame[] {
new TextInformationFrame("TIT2", null, "title"),
new UrlLinkFrame("WXXX", "description", "url")
};
ChapterFrame chapterFrameToParcel = new ChapterFrame("id", 0, 1, 2, 3, subFrames);
Parcel parcel = Parcel.obtain();
chapterFrameToParcel.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
ChapterFrame chapterFrameFromParcel = ChapterFrame.CREATOR.createFromParcel(parcel);
assertThat(chapterFrameFromParcel).isEqualTo(chapterFrameToParcel);
parcel.recycle();
}
}
/*
* Copyright (C) 2017 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.metadata.id3;
import static com.google.common.truth.Truth.assertThat;
import android.os.Parcel;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Test for {@link ChapterTocFrame}. */
@RunWith(AndroidJUnit4.class)
public final class ChapterTocFrameTest {
@Test
public void testParcelable() {
String[] children = new String[] {"child0", "child1"};
Id3Frame[] subFrames = new Id3Frame[] {
new TextInformationFrame("TIT2", null, "title"),
new UrlLinkFrame("WXXX", "description", "url")
};
ChapterTocFrame chapterTocFrameToParcel = new ChapterTocFrame("id", false, true, children,
subFrames);
Parcel parcel = Parcel.obtain();
chapterTocFrameToParcel.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
ChapterTocFrame chapterTocFrameFromParcel = ChapterTocFrame.CREATOR.createFromParcel(parcel);
assertThat(chapterTocFrameFromParcel).isEqualTo(chapterTocFrameToParcel);
parcel.recycle();
}
}
/*
* Copyright (C) 2018 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.metadata.id3;
import static com.google.common.truth.Truth.assertThat;
import android.os.Parcel;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Test for {@link MlltFrame}. */
@RunWith(AndroidJUnit4.class)
public final class MlltFrameTest {
@Test
public void testParcelable() {
MlltFrame mlltFrameToParcel =
new MlltFrame(
/* mpegFramesBetweenReference= */ 1,
/* bytesBetweenReference= */ 1,
/* millisecondsBetweenReference= */ 1,
/* bytesDeviations= */ new int[] {1, 2},
/* millisecondsDeviations= */ new int[] {1, 2});
Parcel parcel = Parcel.obtain();
mlltFrameToParcel.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
MlltFrame mlltFrameFromParcel = MlltFrame.CREATOR.createFromParcel(parcel);
assertThat(mlltFrameFromParcel).isEqualTo(mlltFrameToParcel);
parcel.recycle();
}
}
/*
* Copyright (C) 2019 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.upstream;
import static com.google.common.truth.Truth.assertThat;
import static junit.framework.TestCase.fail;
import android.net.Uri;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Unit tests for {@link DataSpec}. */
@RunWith(AndroidJUnit4.class)
public class DataSpecTest {
@Test
public void createDataSpec_withDefaultValues_setsEmptyHttpRequestParameters() {
Uri uri = Uri.parse("www.google.com");
DataSpec dataSpec = new DataSpec(uri);
assertThat(dataSpec.httpRequestHeaders.isEmpty()).isTrue();
dataSpec = new DataSpec(uri, /*flags= */ 0);
assertThat(dataSpec.httpRequestHeaders.isEmpty()).isTrue();
dataSpec =
new DataSpec(
uri,
/* httpMethod= */ 0,
/* httpBody= */ new byte[] {0, 0, 0, 0},
/* absoluteStreamPosition= */ 0,
/* position= */ 0,
/* length= */ 1,
/* key= */ "key",
/* flags= */ 0);
assertThat(dataSpec.httpRequestHeaders.isEmpty()).isTrue();
}
@Test
public void createDataSpec_setsHttpRequestParameters() {
Map<String, String> httpRequestParameters = new HashMap<>();
httpRequestParameters.put("key1", "value1");
httpRequestParameters.put("key2", "value2");
httpRequestParameters.put("key3", "value3");
DataSpec dataSpec =
new DataSpec(
Uri.parse("www.google.com"),
/* httpMethod= */ 0,
/* httpBody= */ new byte[] {0, 0, 0, 0},
/* absoluteStreamPosition= */ 0,
/* position= */ 0,
/* length= */ 1,
/* key= */ "key",
/* flags= */ 0,
httpRequestParameters);
assertThat(dataSpec.httpRequestHeaders).isEqualTo(httpRequestParameters);
}
@Test
public void httpRequestParameters_areReadOnly() {
DataSpec dataSpec =
new DataSpec(
Uri.parse("www.google.com"),
/* httpMethod= */ 0,
/* httpBody= */ new byte[] {0, 0, 0, 0},
/* absoluteStreamPosition= */ 0,
/* position= */ 0,
/* length= */ 1,
/* key= */ "key",
/* flags= */ 0,
/* httpRequestHeaders= */ new HashMap<>());
try {
dataSpec.httpRequestHeaders.put("key", "value");
fail();
} catch (UnsupportedOperationException expected) {
// Expected
}
}
@Test
public void withUri_copiesHttpRequestHeaders() {
Map<String, String> httpRequestProperties = createRequestProperties(5);
DataSpec dataSpec = createDataSpecWithHeaders(httpRequestProperties);
DataSpec dataSpecCopy = dataSpec.withUri(Uri.parse("www.new-uri.com"));
assertThat(dataSpecCopy.httpRequestHeaders).isEqualTo(httpRequestProperties);
}
@Test
public void subrange_copiesHttpRequestHeaders() {
Map<String, String> httpRequestProperties = createRequestProperties(5);
DataSpec dataSpec = createDataSpecWithHeaders(httpRequestProperties);
DataSpec dataSpecCopy = dataSpec.subrange(2);
assertThat(dataSpecCopy.httpRequestHeaders).isEqualTo(httpRequestProperties);
}
@Test
public void subrange_withOffsetAndLength_copiesHttpRequestHeaders() {
Map<String, String> httpRequestProperties = createRequestProperties(5);
DataSpec dataSpec = createDataSpecWithHeaders(httpRequestProperties);
DataSpec dataSpecCopy = dataSpec.subrange(2, 2);
assertThat(dataSpecCopy.httpRequestHeaders).isEqualTo(httpRequestProperties);
}
@Test
public void withRequestHeaders_setsCorrectHeaders() {
Map<String, String> httpRequestProperties = createRequestProperties(5);
DataSpec dataSpec = createDataSpecWithHeaders(httpRequestProperties);
Map<String, String> newRequestHeaders = createRequestProperties(5, 10);
DataSpec dataSpecCopy = dataSpec.withRequestHeaders(newRequestHeaders);
assertThat(dataSpecCopy.httpRequestHeaders).isEqualTo(newRequestHeaders);
}
@Test
public void withAdditionalHeaders_setsCorrectHeaders() {
Map<String, String> httpRequestProperties = createRequestProperties(5);
DataSpec dataSpec = createDataSpecWithHeaders(httpRequestProperties);
Map<String, String> additionalHeaders = createRequestProperties(5, 10);
// additionalHeaders may overwrite a header key
String existingKey = httpRequestProperties.keySet().iterator().next();
additionalHeaders.put(existingKey, "overwritten");
Map<String, String> expectedHeaders = new HashMap<>(httpRequestProperties);
expectedHeaders.putAll(additionalHeaders);
DataSpec dataSpecCopy = dataSpec.withAdditionalHeaders(additionalHeaders);
assertThat(dataSpecCopy.httpRequestHeaders).isEqualTo(expectedHeaders);
}
private static Map<String, String> createRequestProperties(int howMany) {
return createRequestProperties(0, howMany);
}
private static Map<String, String> createRequestProperties(int from, int to) {
assertThat(from).isLessThan(to);
Map<String, String> httpRequestParameters = new HashMap<>();
for (int i = from; i < to; i++) {
httpRequestParameters.put("key-" + i, "value-" + i);
}
return httpRequestParameters;
}
private static DataSpec createDataSpecWithHeaders(Map<String, String> httpRequestProperties) {
return new DataSpec(
Uri.parse("www.google.com"),
/* httpMethod= */ 0,
/* httpBody= */ new byte[] {0, 0, 0, 0},
/* absoluteStreamPosition= */ 0,
/* position= */ 0,
/* length= */ 1,
/* key= */ "key",
/* flags= */ 0,
httpRequestProperties);
}
}
/*
* Copyright (C) 2019 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.util;
import static com.google.common.truth.Truth.assertThat;
import android.util.Pair;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Unit test for {@link CodecSpecificDataUtil}. */
@RunWith(AndroidJUnit4.class)
public class CodecSpecificDataUtilTest {
@Test
public void parseAlacAudioSpecificConfig() {
byte[] alacSpecificConfig =
new byte[] {
0, 0, 16, 0, // frameLength
0, // compatibleVersion
16, // bitDepth
40, 10, 14, // tuning parameters
2, // numChannels = 2
0, 0, // maxRun
0, 0, 64, 4, // maxFrameBytes
0, 46, -32, 0, // avgBitRate
0, 1, 119, 0, // sampleRate = 96000
};
Pair<Integer, Integer> sampleRateAndChannelCount =
CodecSpecificDataUtil.parseAlacAudioSpecificConfig(alacSpecificConfig);
assertThat(sampleRateAndChannelCount.first).isEqualTo(96000);
assertThat(sampleRateAndChannelCount.second).isEqualTo(2);
}
}
/*
* Copyright (C) 2018 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.util;
import static com.google.common.truth.Truth.assertThat;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Unit test for {@link MimeTypes}. */
@RunWith(AndroidJUnit4.class)
public final class MimeTypesTest {
@Test
public void testGetMediaMimeType_fromValidCodecs_returnsCorrectMimeType() {
assertThat(MimeTypes.getMediaMimeType("avc1")).isEqualTo(MimeTypes.VIDEO_H264);
assertThat(MimeTypes.getMediaMimeType("avc1.42E01E")).isEqualTo(MimeTypes.VIDEO_H264);
assertThat(MimeTypes.getMediaMimeType("avc1.42E01F")).isEqualTo(MimeTypes.VIDEO_H264);
assertThat(MimeTypes.getMediaMimeType("avc1.4D401F")).isEqualTo(MimeTypes.VIDEO_H264);
assertThat(MimeTypes.getMediaMimeType("avc1.4D4028")).isEqualTo(MimeTypes.VIDEO_H264);
assertThat(MimeTypes.getMediaMimeType("avc1.640028")).isEqualTo(MimeTypes.VIDEO_H264);
assertThat(MimeTypes.getMediaMimeType("avc1.640029")).isEqualTo(MimeTypes.VIDEO_H264);
assertThat(MimeTypes.getMediaMimeType("avc3")).isEqualTo(MimeTypes.VIDEO_H264);
assertThat(MimeTypes.getMediaMimeType("hev1")).isEqualTo(MimeTypes.VIDEO_H265);
assertThat(MimeTypes.getMediaMimeType("hvc1")).isEqualTo(MimeTypes.VIDEO_H265);
assertThat(MimeTypes.getMediaMimeType("vp08")).isEqualTo(MimeTypes.VIDEO_VP8);
assertThat(MimeTypes.getMediaMimeType("vp8")).isEqualTo(MimeTypes.VIDEO_VP8);
assertThat(MimeTypes.getMediaMimeType("vp09")).isEqualTo(MimeTypes.VIDEO_VP9);
assertThat(MimeTypes.getMediaMimeType("vp9")).isEqualTo(MimeTypes.VIDEO_VP9);
assertThat(MimeTypes.getMediaMimeType("ac-3")).isEqualTo(MimeTypes.AUDIO_AC3);
assertThat(MimeTypes.getMediaMimeType("dac3")).isEqualTo(MimeTypes.AUDIO_AC3);
assertThat(MimeTypes.getMediaMimeType("dec3")).isEqualTo(MimeTypes.AUDIO_E_AC3);
assertThat(MimeTypes.getMediaMimeType("ec-3")).isEqualTo(MimeTypes.AUDIO_E_AC3);
assertThat(MimeTypes.getMediaMimeType("ec+3")).isEqualTo(MimeTypes.AUDIO_E_AC3_JOC);
assertThat(MimeTypes.getMediaMimeType("dtsc")).isEqualTo(MimeTypes.AUDIO_DTS);
assertThat(MimeTypes.getMediaMimeType("dtse")).isEqualTo(MimeTypes.AUDIO_DTS);
assertThat(MimeTypes.getMediaMimeType("dtsh")).isEqualTo(MimeTypes.AUDIO_DTS_HD);
assertThat(MimeTypes.getMediaMimeType("dtsl")).isEqualTo(MimeTypes.AUDIO_DTS_HD);
assertThat(MimeTypes.getMediaMimeType("opus")).isEqualTo(MimeTypes.AUDIO_OPUS);
assertThat(MimeTypes.getMediaMimeType("vorbis")).isEqualTo(MimeTypes.AUDIO_VORBIS);
assertThat(MimeTypes.getMediaMimeType("mp4a")).isEqualTo(MimeTypes.AUDIO_AAC);
assertThat(MimeTypes.getMediaMimeType("mp4a.40.02")).isEqualTo(MimeTypes.AUDIO_AAC);
assertThat(MimeTypes.getMediaMimeType("mp4a.40.05")).isEqualTo(MimeTypes.AUDIO_AAC);
assertThat(MimeTypes.getMediaMimeType("mp4a.40.2")).isEqualTo(MimeTypes.AUDIO_AAC);
assertThat(MimeTypes.getMediaMimeType("mp4a.40.5")).isEqualTo(MimeTypes.AUDIO_AAC);
assertThat(MimeTypes.getMediaMimeType("mp4a.40.29")).isEqualTo(MimeTypes.AUDIO_AAC);
assertThat(MimeTypes.getMediaMimeType("mp4a.66")).isEqualTo(MimeTypes.AUDIO_AAC);
assertThat(MimeTypes.getMediaMimeType("mp4a.67")).isEqualTo(MimeTypes.AUDIO_AAC);
assertThat(MimeTypes.getMediaMimeType("mp4a.68")).isEqualTo(MimeTypes.AUDIO_AAC);
assertThat(MimeTypes.getMediaMimeType("mp4a.69")).isEqualTo(MimeTypes.AUDIO_MPEG);
assertThat(MimeTypes.getMediaMimeType("mp4a.6B")).isEqualTo(MimeTypes.AUDIO_MPEG);
assertThat(MimeTypes.getMediaMimeType("mp4a.a5")).isEqualTo(MimeTypes.AUDIO_AC3);
assertThat(MimeTypes.getMediaMimeType("mp4a.A5")).isEqualTo(MimeTypes.AUDIO_AC3);
assertThat(MimeTypes.getMediaMimeType("mp4a.a6")).isEqualTo(MimeTypes.AUDIO_E_AC3);
assertThat(MimeTypes.getMediaMimeType("mp4a.A6")).isEqualTo(MimeTypes.AUDIO_E_AC3);
assertThat(MimeTypes.getMediaMimeType("mp4a.A9")).isEqualTo(MimeTypes.AUDIO_DTS);
assertThat(MimeTypes.getMediaMimeType("mp4a.AC")).isEqualTo(MimeTypes.AUDIO_DTS);
assertThat(MimeTypes.getMediaMimeType("mp4a.AA")).isEqualTo(MimeTypes.AUDIO_DTS_HD);
assertThat(MimeTypes.getMediaMimeType("mp4a.AB")).isEqualTo(MimeTypes.AUDIO_DTS_HD);
assertThat(MimeTypes.getMediaMimeType("mp4a.AD")).isEqualTo(MimeTypes.AUDIO_OPUS);
}
@Test
public void testGetMimeTypeFromMp4ObjectType_forValidObjectType_returnsCorrectMimeType() {
assertThat(MimeTypes.getMimeTypeFromMp4ObjectType(0x60)).isEqualTo(MimeTypes.VIDEO_MPEG2);
assertThat(MimeTypes.getMimeTypeFromMp4ObjectType(0x61)).isEqualTo(MimeTypes.VIDEO_MPEG2);
assertThat(MimeTypes.getMimeTypeFromMp4ObjectType(0x20)).isEqualTo(MimeTypes.VIDEO_MP4V);
assertThat(MimeTypes.getMimeTypeFromMp4ObjectType(0x21)).isEqualTo(MimeTypes.VIDEO_H264);
assertThat(MimeTypes.getMimeTypeFromMp4ObjectType(0x23)).isEqualTo(MimeTypes.VIDEO_H265);
assertThat(MimeTypes.getMimeTypeFromMp4ObjectType(0x6B)).isEqualTo(MimeTypes.AUDIO_MPEG);
assertThat(MimeTypes.getMimeTypeFromMp4ObjectType(0x40)).isEqualTo(MimeTypes.AUDIO_AAC);
assertThat(MimeTypes.getMimeTypeFromMp4ObjectType(0x66)).isEqualTo(MimeTypes.AUDIO_AAC);
assertThat(MimeTypes.getMimeTypeFromMp4ObjectType(0x67)).isEqualTo(MimeTypes.AUDIO_AAC);
assertThat(MimeTypes.getMimeTypeFromMp4ObjectType(0x68)).isEqualTo(MimeTypes.AUDIO_AAC);
assertThat(MimeTypes.getMimeTypeFromMp4ObjectType(0xA5)).isEqualTo(MimeTypes.AUDIO_AC3);
assertThat(MimeTypes.getMimeTypeFromMp4ObjectType(0xA6)).isEqualTo(MimeTypes.AUDIO_E_AC3);
assertThat(MimeTypes.getMimeTypeFromMp4ObjectType(0xA9)).isEqualTo(MimeTypes.AUDIO_DTS);
assertThat(MimeTypes.getMimeTypeFromMp4ObjectType(0xAC)).isEqualTo(MimeTypes.AUDIO_DTS);
assertThat(MimeTypes.getMimeTypeFromMp4ObjectType(0xAA)).isEqualTo(MimeTypes.AUDIO_DTS_HD);
assertThat(MimeTypes.getMimeTypeFromMp4ObjectType(0xAB)).isEqualTo(MimeTypes.AUDIO_DTS_HD);
assertThat(MimeTypes.getMimeTypeFromMp4ObjectType(0xAD)).isEqualTo(MimeTypes.AUDIO_OPUS);
}
@Test
public void testGetMimeTypeFromMp4ObjectType_forInvalidObjectType_returnsNull() {
assertThat(MimeTypes.getMimeTypeFromMp4ObjectType(0)).isNull();
assertThat(MimeTypes.getMimeTypeFromMp4ObjectType(0x600)).isNull();
assertThat(MimeTypes.getMimeTypeFromMp4ObjectType(0x01)).isNull();
assertThat(MimeTypes.getMimeTypeFromMp4ObjectType(-1)).isNull();
}
}
/*
* Copyright (C) 2016 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.util;
import static com.google.android.exoplayer2.testutil.TestUtil.createByteArray;
import static com.google.common.truth.Truth.assertThat;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.nio.ByteBuffer;
import java.util.Arrays;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Tests for {@link NalUnitUtil}. */
@RunWith(AndroidJUnit4.class)
public final class NalUnitUtilTest {
private static final int TEST_PARTIAL_NAL_POSITION = 4;
private static final int TEST_NAL_POSITION = 10;
private static final byte[] SPS_TEST_DATA = createByteArray(0x00, 0x00, 0x01, 0x67, 0x4D, 0x40,
0x16, 0xEC, 0xA0, 0x50, 0x17, 0xFC, 0xB8, 0x08, 0x80, 0x00, 0x00, 0x03, 0x00, 0x80, 0x00,
0x00, 0x0F, 0x47, 0x8B, 0x16, 0xCB);
private static final int SPS_TEST_DATA_OFFSET = 3;
@Test
public void testFindNalUnit() {
byte[] data = buildTestData();
// Should find NAL unit.
int result = NalUnitUtil.findNalUnit(data, 0, data.length, null);
assertThat(result).isEqualTo(TEST_NAL_POSITION);
// Should find NAL unit whose prefix ends one byte before the limit.
result = NalUnitUtil.findNalUnit(data, 0, TEST_NAL_POSITION + 4, null);
assertThat(result).isEqualTo(TEST_NAL_POSITION);
// Shouldn't find NAL unit whose prefix ends at the limit (since the limit is exclusive).
result = NalUnitUtil.findNalUnit(data, 0, TEST_NAL_POSITION + 3, null);
assertThat(result).isEqualTo(TEST_NAL_POSITION + 3);
// Should find NAL unit whose prefix starts at the offset.
result = NalUnitUtil.findNalUnit(data, TEST_NAL_POSITION, data.length, null);
assertThat(result).isEqualTo(TEST_NAL_POSITION);
// Shouldn't find NAL unit whose prefix starts one byte past the offset.
result = NalUnitUtil.findNalUnit(data, TEST_NAL_POSITION + 1, data.length, null);
assertThat(result).isEqualTo(data.length);
}
@Test
public void testFindNalUnitWithPrefix() {
byte[] data = buildTestData();
// First byte of NAL unit in data1, rest in data2.
boolean[] prefixFlags = new boolean[3];
byte[] data1 = Arrays.copyOfRange(data, 0, TEST_NAL_POSITION + 1);
byte[] data2 = Arrays.copyOfRange(data, TEST_NAL_POSITION + 1, data.length);
int result = NalUnitUtil.findNalUnit(data1, 0, data1.length, prefixFlags);
assertThat(result).isEqualTo(data1.length);
result = NalUnitUtil.findNalUnit(data2, 0, data2.length, prefixFlags);
assertThat(result).isEqualTo(-1);
assertPrefixFlagsCleared(prefixFlags);
// First three bytes of NAL unit in data1, rest in data2.
prefixFlags = new boolean[3];
data1 = Arrays.copyOfRange(data, 0, TEST_NAL_POSITION + 3);
data2 = Arrays.copyOfRange(data, TEST_NAL_POSITION + 3, data.length);
result = NalUnitUtil.findNalUnit(data1, 0, data1.length, prefixFlags);
assertThat(result).isEqualTo(data1.length);
result = NalUnitUtil.findNalUnit(data2, 0, data2.length, prefixFlags);
assertThat(result).isEqualTo(-3);
assertPrefixFlagsCleared(prefixFlags);
// First byte of NAL unit in data1, second byte in data2, rest in data3.
prefixFlags = new boolean[3];
data1 = Arrays.copyOfRange(data, 0, TEST_NAL_POSITION + 1);
data2 = Arrays.copyOfRange(data, TEST_NAL_POSITION + 1, TEST_NAL_POSITION + 2);
byte[] data3 = Arrays.copyOfRange(data, TEST_NAL_POSITION + 2, data.length);
result = NalUnitUtil.findNalUnit(data1, 0, data1.length, prefixFlags);
assertThat(result).isEqualTo(data1.length);
result = NalUnitUtil.findNalUnit(data2, 0, data2.length, prefixFlags);
assertThat(result).isEqualTo(data2.length);
result = NalUnitUtil.findNalUnit(data3, 0, data3.length, prefixFlags);
assertThat(result).isEqualTo(-2);
assertPrefixFlagsCleared(prefixFlags);
// NAL unit split with one byte in four arrays.
prefixFlags = new boolean[3];
data1 = Arrays.copyOfRange(data, 0, TEST_NAL_POSITION + 1);
data2 = Arrays.copyOfRange(data, TEST_NAL_POSITION + 1, TEST_NAL_POSITION + 2);
data3 = Arrays.copyOfRange(data, TEST_NAL_POSITION + 2, TEST_NAL_POSITION + 3);
byte[] data4 = Arrays.copyOfRange(data, TEST_NAL_POSITION + 2, data.length);
result = NalUnitUtil.findNalUnit(data1, 0, data1.length, prefixFlags);
assertThat(result).isEqualTo(data1.length);
result = NalUnitUtil.findNalUnit(data2, 0, data2.length, prefixFlags);
assertThat(result).isEqualTo(data2.length);
result = NalUnitUtil.findNalUnit(data3, 0, data3.length, prefixFlags);
assertThat(result).isEqualTo(data3.length);
result = NalUnitUtil.findNalUnit(data4, 0, data4.length, prefixFlags);
assertThat(result).isEqualTo(-3);
assertPrefixFlagsCleared(prefixFlags);
// NAL unit entirely in data2. data1 ends with partial prefix.
prefixFlags = new boolean[3];
data1 = Arrays.copyOfRange(data, 0, TEST_PARTIAL_NAL_POSITION + 2);
data2 = Arrays.copyOfRange(data, TEST_PARTIAL_NAL_POSITION + 2, data.length);
result = NalUnitUtil.findNalUnit(data1, 0, data1.length, prefixFlags);
assertThat(result).isEqualTo(data1.length);
result = NalUnitUtil.findNalUnit(data2, 0, data2.length, prefixFlags);
assertThat(result).isEqualTo(4);
assertPrefixFlagsCleared(prefixFlags);
}
@Test
public void testParseSpsNalUnit() {
NalUnitUtil.SpsData data = NalUnitUtil.parseSpsNalUnit(SPS_TEST_DATA, SPS_TEST_DATA_OFFSET,
SPS_TEST_DATA.length);
assertThat(data.width).isEqualTo(640);
assertThat(data.height).isEqualTo(360);
assertThat(data.deltaPicOrderAlwaysZeroFlag).isFalse();
assertThat(data.frameMbsOnlyFlag).isTrue();
assertThat(data.frameNumLength).isEqualTo(4);
assertThat(data.picOrderCntLsbLength).isEqualTo(6);
assertThat(data.seqParameterSetId).isEqualTo(0);
assertThat(data.pixelWidthAspectRatio).isEqualTo(1.0f);
assertThat(data.picOrderCountType).isEqualTo(0);
assertThat(data.separateColorPlaneFlag).isFalse();
}
@Test
public void testUnescapeDoesNotModifyBuffersWithoutStartCodes() {
assertUnescapeDoesNotModify("");
assertUnescapeDoesNotModify("0000");
assertUnescapeDoesNotModify("172BF38A3C");
assertUnescapeDoesNotModify("000004");
}
@Test
public void testUnescapeModifiesBuffersWithStartCodes() {
assertUnescapeMatchesExpected("00000301", "000001");
assertUnescapeMatchesExpected("0000030200000300", "000002000000");
}
@Test
public void testDiscardToSps() {
assertDiscardToSpsMatchesExpected("", "");
assertDiscardToSpsMatchesExpected("00", "");
assertDiscardToSpsMatchesExpected("FFFF000001", "");
assertDiscardToSpsMatchesExpected("00000001", "");
assertDiscardToSpsMatchesExpected("00000001FF67", "");
assertDiscardToSpsMatchesExpected("00000001000167", "");
assertDiscardToSpsMatchesExpected("0000000167", "0000000167");
assertDiscardToSpsMatchesExpected("0000000167FF", "0000000167FF");
assertDiscardToSpsMatchesExpected("0000000167FF", "0000000167FF");
assertDiscardToSpsMatchesExpected("0000000167FF000000016700", "0000000167FF000000016700");
assertDiscardToSpsMatchesExpected("000000000167FF", "0000000167FF");
assertDiscardToSpsMatchesExpected("0001670000000167FF", "0000000167FF");
assertDiscardToSpsMatchesExpected("FF00000001660000000167FF", "0000000167FF");
}
private static byte[] buildTestData() {
byte[] data = new byte[20];
for (int i = 0; i < data.length; i++) {
data[i] = (byte) 0xFF;
}
// Insert an incomplete NAL unit start code.
data[TEST_PARTIAL_NAL_POSITION] = 0;
data[TEST_PARTIAL_NAL_POSITION + 1] = 0;
// Insert a complete NAL unit start code.
data[TEST_NAL_POSITION] = 0;
data[TEST_NAL_POSITION + 1] = 0;
data[TEST_NAL_POSITION + 2] = 1;
data[TEST_NAL_POSITION + 3] = 5;
return data;
}
private static void assertPrefixFlagsCleared(boolean[] flags) {
assertThat(flags[0] || flags[1] || flags[2]).isEqualTo(false);
}
private static void assertUnescapeDoesNotModify(String input) {
assertUnescapeMatchesExpected(input, input);
}
private static void assertUnescapeMatchesExpected(String input, String expectedOutput) {
byte[] bitstream = Util.getBytesFromHexString(input);
byte[] expectedOutputBitstream = Util.getBytesFromHexString(expectedOutput);
int count = NalUnitUtil.unescapeStream(bitstream, bitstream.length);
assertThat(count).isEqualTo(expectedOutputBitstream.length);
byte[] outputBitstream = new byte[count];
System.arraycopy(bitstream, 0, outputBitstream, 0, count);
assertThat(outputBitstream).isEqualTo(expectedOutputBitstream);
}
private static void assertDiscardToSpsMatchesExpected(String input, String expectedOutput) {
byte[] bitstream = Util.getBytesFromHexString(input);
byte[] expectedOutputBitstream = Util.getBytesFromHexString(expectedOutput);
ByteBuffer buffer = ByteBuffer.wrap(bitstream);
buffer.position(buffer.limit());
NalUnitUtil.discardToSps(buffer);
assertThat(Arrays.copyOf(buffer.array(), buffer.position())).isEqualTo(expectedOutputBitstream);
}
}
/*
* Copyright (C) 2016 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.util;
import static com.google.android.exoplayer2.testutil.TestUtil.createByteArray;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Tests for {@link ParsableNalUnitBitArray}. */
@RunWith(AndroidJUnit4.class)
public final class ParsableNalUnitBitArrayTest {
private static final byte[] NO_ESCAPING_TEST_DATA = createByteArray(0, 3, 0, 1, 3, 0, 0);
private static final byte[] ALL_ESCAPING_TEST_DATA = createByteArray(0, 0, 3, 0, 0, 3, 0, 0, 3);
private static final byte[] MIX_TEST_DATA = createByteArray(255, 0, 0, 3, 255, 0, 0, 127);
@Test
public void testReadNoEscaping() {
ParsableNalUnitBitArray array =
new ParsableNalUnitBitArray(NO_ESCAPING_TEST_DATA, 0, NO_ESCAPING_TEST_DATA.length);
assertThat(array.readBits(24)).isEqualTo(0x000300);
assertThat(array.readBits(7)).isEqualTo(0);
assertThat(array.readBit()).isTrue();
assertThat(array.readBits(24)).isEqualTo(0x030000);
assertThat(array.canReadBits(1)).isFalse();
assertThat(array.canReadBits(8)).isFalse();
}
@Test
public void testReadNoEscapingTruncated() {
ParsableNalUnitBitArray array = new ParsableNalUnitBitArray(NO_ESCAPING_TEST_DATA, 0, 4);
assertThat(array.canReadBits(32)).isTrue();
array.skipBits(32);
assertThat(array.canReadBits(1)).isFalse();
try {
array.readBit();
fail();
} catch (Exception e) {
// Expected.
}
}
@Test
public void testReadAllEscaping() {
ParsableNalUnitBitArray array =
new ParsableNalUnitBitArray(ALL_ESCAPING_TEST_DATA, 0, ALL_ESCAPING_TEST_DATA.length);
assertThat(array.canReadBits(48)).isTrue();
assertThat(array.canReadBits(49)).isFalse();
assertThat(array.readBits(15)).isEqualTo(0);
assertThat(array.readBit()).isFalse();
assertThat(array.readBits(17)).isEqualTo(0);
assertThat(array.readBits(15)).isEqualTo(0);
}
@Test
public void testReadMix() {
ParsableNalUnitBitArray array =
new ParsableNalUnitBitArray(MIX_TEST_DATA, 0, MIX_TEST_DATA.length);
assertThat(array.canReadBits(56)).isTrue();
assertThat(array.canReadBits(57)).isFalse();
assertThat(array.readBits(7)).isEqualTo(127);
assertThat(array.readBits(2)).isEqualTo(2);
assertThat(array.readBits(17)).isEqualTo(3);
assertThat(array.readBits(7)).isEqualTo(126);
assertThat(array.readBits(23)).isEqualTo(127);
assertThat(array.canReadBits(1)).isFalse();
}
@Test
public void testReadExpGolomb() {
ParsableNalUnitBitArray array = new ParsableNalUnitBitArray(createByteArray(0x9E), 0, 1);
assertThat(array.canReadExpGolombCodedNum()).isTrue();
assertThat(array.readUnsignedExpGolombCodedInt()).isEqualTo(0);
assertThat(array.readUnsignedExpGolombCodedInt()).isEqualTo(6);
assertThat(array.readUnsignedExpGolombCodedInt()).isEqualTo(0);
assertThat(array.canReadExpGolombCodedNum()).isFalse();
try {
array.readUnsignedExpGolombCodedInt();
fail();
} catch (Exception e) {
// Expected.
}
}
@Test
public void testReadExpGolombWithEscaping() {
ParsableNalUnitBitArray array =
new ParsableNalUnitBitArray(createByteArray(0, 0, 3, 128, 0), 0, 5);
assertThat(array.canReadExpGolombCodedNum()).isFalse();
array.skipBit();
assertThat(array.canReadExpGolombCodedNum()).isTrue();
assertThat(array.readUnsignedExpGolombCodedInt()).isEqualTo(32767);
assertThat(array.canReadBits(1)).isFalse();
}
@Test
public void testReset() {
ParsableNalUnitBitArray array = new ParsableNalUnitBitArray(createByteArray(0, 0), 0, 2);
assertThat(array.canReadExpGolombCodedNum()).isFalse();
assertThat(array.canReadBits(16)).isTrue();
assertThat(array.canReadBits(17)).isFalse();
array.reset(createByteArray(0, 0, 3, 0), 0, 4);
assertThat(array.canReadBits(24)).isTrue();
assertThat(array.canReadBits(25)).isFalse();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment