diff --git a/library/core/src/main/java/com/google/android/exoplayer2/C.java b/library/core/src/main/java/com/google/android/exoplayer2/C.java index 19545fe0c3..75f1263a31 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/C.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/C.java @@ -977,52 +977,36 @@ public final class C { public static final int NETWORK_TYPE_OTHER = 8; /** - * Adaptation set's role descriptor value (ISO 23009-1) + * Adaptation set's role and accessibility descriptor value. */ @Documented @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ROLE_UNSET, - ROLE_MAIN, - ROLE_ALTERNATE, - ROLE_SUPPLEMENTARY, - ROLE_COMMENTARY, - ROLE_DUB, - ROLE_EMERGENCY, - ROLE_CAPTION, - ROLE_SIGN + @IntDef( + flag = true, + value = { + ROLE_FLAGS_MAIN, + ROLE_FLAGS_ALTERNATE, + ROLE_FLAGS_SUPPLEMENTARY, + ROLE_FLAGS_COMMENTARY, + ROLE_FLAGS_DUB, + ROLE_FLAGS_EMERGENCY, + ROLE_FLAGS_CAPTION, + ROLE_FLAGS_SIGN, + ROLE_FLAGS_ENHANCED_AUDIO_INTELLIGIBILITY, + ROLE_FLAGS_DESCRIPTION }) - public @interface Role {} + public @interface RoleFlags {} - public static final int ROLE_UNSET = -1; - public static final int ROLE_MAIN = 0; - public static final int ROLE_ALTERNATE = 1; - public static final int ROLE_SUPPLEMENTARY = 2; - public static final int ROLE_COMMENTARY = 3; - public static final int ROLE_DUB = 4; - public static final int ROLE_EMERGENCY = 5; - public static final int ROLE_CAPTION = 6; - public static final int ROLE_SIGN = 7; - - /** - * Adaptation set's accessibility descriptor value (ISO 23009-1) - */ - @Documented - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ACCESSIBILITY_UNSET, - ACCESSIBILITY_ENHANCED_AUDIO_INTELLIGIBILITY, - ACCESSIBILITY_DESCRIPTION, - ACCESSIBILITY_CAPTION, - ACCESSIBILITY_SIGN - }) - public @interface Accessibility {} - - public static final int ACCESSIBILITY_UNSET = -1; - public static final int ACCESSIBILITY_ENHANCED_AUDIO_INTELLIGIBILITY = 1; - public static final int ACCESSIBILITY_DESCRIPTION = 2; - public static final int ACCESSIBILITY_CAPTION = 3; - public static final int ACCESSIBILITY_SIGN = 4; + public static final int ROLE_FLAGS_MAIN = 1; + public static final int ROLE_FLAGS_ALTERNATE = 1 << 1; + public static final int ROLE_FLAGS_SUPPLEMENTARY = 1 << 2; + public static final int ROLE_FLAGS_COMMENTARY = 1 << 3; + public static final int ROLE_FLAGS_DUB = 1 << 4; + public static final int ROLE_FLAGS_EMERGENCY = 1 << 5; + public static final int ROLE_FLAGS_CAPTION = 1 << 6; + public static final int ROLE_FLAGS_SIGN = 1 << 7; + public static final int ROLE_FLAGS_ENHANCED_AUDIO_INTELLIGIBILITY = 1 << 8; + public static final int ROLE_FLAGS_DESCRIPTION = 1 << 9; /** * Converts a time in microseconds to the corresponding time in milliseconds, preserving diff --git a/library/core/src/main/java/com/google/android/exoplayer2/Format.java b/library/core/src/main/java/com/google/android/exoplayer2/Format.java index 43ca19e444..509ef8011f 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/Format.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/Format.java @@ -51,15 +51,9 @@ public final class Format implements Parcelable { /** Track selection flags. **/ @C.SelectionFlags public final int selectionFlags; - /** Track role descriptor value, or {@link C#ROLE_UNSET} if unknown or not applicable. **/ - @C.Role - public final int role; - /** - * Track accessibility descriptor value, or {@link C#ACCESSIBILITY_UNSET} if unknown - * or not applicable. - */ - @C.Accessibility - public final int accessibility; + /** Track role and accessibility descriptor values. **/ + @C.RoleFlags + public final int roleFlags; /** * The average bandwidth in bits per second, or {@link #NO_VALUE} if unknown or not applicable. */ @@ -189,8 +183,7 @@ public final class Format implements Parcelable { float frameRate, @Nullable List initializationData, @C.SelectionFlags int selectionFlags, - @C.Role int role, - @C.Accessibility int accessibility) { + @C.RoleFlags int roleFlags) { return createVideoContainerFormat( id, /* label= */ null, @@ -203,8 +196,7 @@ public final class Format implements Parcelable { frameRate, initializationData, selectionFlags, - role, - accessibility); + roleFlags); } public static Format createVideoContainerFormat( @@ -219,8 +211,7 @@ public final class Format implements Parcelable { float frameRate, @Nullable List initializationData, @C.SelectionFlags int selectionFlags, - @C.Role int role, - @C.Accessibility int accessibility) { + @C.RoleFlags int roleFlags) { return new Format( id, label, @@ -245,8 +236,7 @@ public final class Format implements Parcelable { selectionFlags, /* language= */ null, /* accessibilityChannel= */ NO_VALUE, - role, - accessibility, + roleFlags, OFFSET_SAMPLE_RELATIVE, initializationData, /* drmInitData= */ null, @@ -350,8 +340,7 @@ public final class Format implements Parcelable { /* selectionFlags= */ 0, /* language= */ null, /* accessibilityChannel= */ NO_VALUE, - /* role= */ C.ROLE_UNSET, - /* accessibility= */ C.ACCESSIBILITY_UNSET, + /* roleFlags= */ 0, OFFSET_SAMPLE_RELATIVE, initializationData, drmInitData, @@ -372,8 +361,7 @@ public final class Format implements Parcelable { @Nullable List initializationData, @C.SelectionFlags int selectionFlags, @Nullable String language, - @C.Role int role, - @C.Accessibility int accessibility) { + @C.RoleFlags int roleFlags) { return createAudioContainerFormat( id, /* label= */ null, @@ -386,8 +374,7 @@ public final class Format implements Parcelable { initializationData, selectionFlags, language, - role, - accessibility); + roleFlags); } public static Format createAudioContainerFormat( @@ -402,8 +389,7 @@ public final class Format implements Parcelable { @Nullable List initializationData, @C.SelectionFlags int selectionFlags, @Nullable String language, - @C.Role int role, - @C.Accessibility int accessibility) { + @C.RoleFlags int roleFlags) { return new Format( id, label, @@ -428,8 +414,7 @@ public final class Format implements Parcelable { selectionFlags, language, /* accessibilityChannel= */ NO_VALUE, - role, - accessibility, + roleFlags, OFFSET_SAMPLE_RELATIVE, initializationData, /* drmInitData= */ null, @@ -534,8 +519,7 @@ public final class Format implements Parcelable { selectionFlags, language, /* accessibilityChannel= */ NO_VALUE, - /* role= */ C.ROLE_UNSET, - /* accessibility= */ C.ACCESSIBILITY_UNSET, + /* roleFlags= */ 0, OFFSET_SAMPLE_RELATIVE, initializationData, drmInitData, @@ -583,8 +567,7 @@ public final class Format implements Parcelable { selectionFlags, language, /* accessibilityChannel= */ NO_VALUE, - /* role= */ C.ROLE_UNSET, - /* accessibility= */ C.ACCESSIBILITY_UNSET); + /* roleFlags= */ 0); } public static Format createTextContainerFormat( @@ -597,8 +580,7 @@ public final class Format implements Parcelable { @C.SelectionFlags int selectionFlags, @Nullable String language, int accessibilityChannel, - @C.Role int role, - @C.Accessibility int accessibility) { + @C.RoleFlags int roleFlags) { return new Format( id, label, @@ -623,8 +605,7 @@ public final class Format implements Parcelable { selectionFlags, language, accessibilityChannel, - role, - accessibility, + roleFlags, OFFSET_SAMPLE_RELATIVE, /* initializationData= */ null, /* drmInitData= */ null, @@ -737,8 +718,7 @@ public final class Format implements Parcelable { selectionFlags, language, accessibilityChannel, - /* role= */ C.ROLE_UNSET, - /* accessibility= */ C.ACCESSIBILITY_UNSET, + /* roleFlags= */ 0, subsampleOffsetUs, initializationData, drmInitData, @@ -780,8 +760,7 @@ public final class Format implements Parcelable { selectionFlags, language, /* accessibilityChannel= */ NO_VALUE, - /* role= */ C.ROLE_UNSET, - /* accessibility= */ C.ACCESSIBILITY_UNSET, + /* roleFlags= */ 0, OFFSET_SAMPLE_RELATIVE, initializationData, drmInitData, @@ -843,8 +822,7 @@ public final class Format implements Parcelable { selectionFlags, language, /* accessibilityChannel= */ NO_VALUE, - /* role= */ C.ROLE_UNSET, - /* accessibility= */ C.ACCESSIBILITY_UNSET, + /* roleFlags= */ 0, OFFSET_SAMPLE_RELATIVE, /* initializationData= */ null, /* drmInitData= */ null, @@ -877,8 +855,7 @@ public final class Format implements Parcelable { /* selectionFlags= */ 0, /* language= */ null, /* accessibilityChannel= */ NO_VALUE, - /* role= */ C.ROLE_UNSET, - /* accessibility= */ C.ACCESSIBILITY_UNSET, + /* roleFlags= */ 0, subsampleOffsetUs, /* initializationData= */ null, /* drmInitData= */ null, @@ -915,8 +892,7 @@ public final class Format implements Parcelable { /* selectionFlags= */ 0, /* language= */ null, /* accessibilityChannel= */ NO_VALUE, - /* role= */ C.ROLE_UNSET, - /* accessibility= */ C.ACCESSIBILITY_UNSET, + /* roleFlags= */ 0, OFFSET_SAMPLE_RELATIVE, /* initializationData= */ null, drmInitData, @@ -947,8 +923,7 @@ public final class Format implements Parcelable { @C.SelectionFlags int selectionFlags, @Nullable String language, int accessibilityChannel, - @C.Role int role, - @C.Accessibility int accessibility, + @C.RoleFlags int roleFlags, long subsampleOffsetUs, @Nullable List initializationData, @Nullable DrmInitData drmInitData, @@ -977,8 +952,7 @@ public final class Format implements Parcelable { this.selectionFlags = selectionFlags; this.language = Util.normalizeLanguageCode(language); this.accessibilityChannel = accessibilityChannel; - this.role = role; - this.accessibility = accessibility; + this.roleFlags = roleFlags; this.subsampleOffsetUs = subsampleOffsetUs; this.initializationData = initializationData == null ? Collections.emptyList() : initializationData; @@ -1012,8 +986,7 @@ public final class Format implements Parcelable { selectionFlags = in.readInt(); language = in.readString(); accessibilityChannel = in.readInt(); - role = in.readInt(); - accessibility = in.readInt(); + roleFlags = in.readInt(); subsampleOffsetUs = in.readLong(); int initializationDataSize = in.readInt(); initializationData = new ArrayList<>(initializationDataSize); @@ -1049,8 +1022,7 @@ public final class Format implements Parcelable { selectionFlags, language, accessibilityChannel, - role, - accessibility, + roleFlags, subsampleOffsetUs, initializationData, drmInitData, @@ -1082,8 +1054,7 @@ public final class Format implements Parcelable { selectionFlags, language, accessibilityChannel, - role, - accessibility, + roleFlags, subsampleOffsetUs, initializationData, drmInitData, @@ -1124,8 +1095,7 @@ public final class Format implements Parcelable { selectionFlags, language, accessibilityChannel, - role, - accessibility, + roleFlags, subsampleOffsetUs, initializationData, drmInitData, @@ -1197,8 +1167,7 @@ public final class Format implements Parcelable { selectionFlags, language, accessibilityChannel, - role, - accessibility, + roleFlags, subsampleOffsetUs, initializationData, drmInitData, @@ -1230,8 +1199,7 @@ public final class Format implements Parcelable { selectionFlags, language, accessibilityChannel, - role, - accessibility, + roleFlags, subsampleOffsetUs, initializationData, drmInitData, @@ -1263,8 +1231,7 @@ public final class Format implements Parcelable { selectionFlags, language, accessibilityChannel, - role, - accessibility, + roleFlags, subsampleOffsetUs, initializationData, drmInitData, @@ -1296,8 +1263,7 @@ public final class Format implements Parcelable { selectionFlags, language, accessibilityChannel, - role, - accessibility, + roleFlags, subsampleOffsetUs, initializationData, drmInitData, @@ -1329,8 +1295,7 @@ public final class Format implements Parcelable { selectionFlags, language, accessibilityChannel, - role, - accessibility, + roleFlags, subsampleOffsetUs, initializationData, drmInitData, @@ -1362,8 +1327,7 @@ public final class Format implements Parcelable { selectionFlags, language, accessibilityChannel, - role, - accessibility, + roleFlags, subsampleOffsetUs, initializationData, drmInitData, @@ -1395,8 +1359,7 @@ public final class Format implements Parcelable { selectionFlags, language, accessibilityChannel, - role, - accessibility, + roleFlags, subsampleOffsetUs, initializationData, drmInitData, @@ -1506,8 +1469,7 @@ public final class Format implements Parcelable { && Util.areEqual(label, other.label) && Util.areEqual(language, other.language) && accessibilityChannel == other.accessibilityChannel - && Util.areEqual(role, other.role) - && Util.areEqual(accessibility, other.accessibility) + && roleFlags == other.roleFlags && Util.areEqual(containerMimeType, other.containerMimeType) && Util.areEqual(sampleMimeType, other.sampleMimeType) && Util.areEqual(codecs, other.codecs) @@ -1609,8 +1571,7 @@ public final class Format implements Parcelable { dest.writeInt(selectionFlags); dest.writeString(language); dest.writeInt(accessibilityChannel); - dest.writeInt(role); - dest.writeInt(accessibility); + dest.writeInt(roleFlags); dest.writeLong(subsampleOffsetUs); int initializationDataSize = initializationData.size(); dest.writeInt(initializationDataSize); diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java index 462ebc6300..0a629b3d19 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java @@ -588,8 +588,9 @@ public class DashManifestParser extends DefaultHandler List supplementalProperties) { String sampleMimeType = getSampleMimeType(containerMimeType, codecs); if (sampleMimeType != null) { - int role = parseRole(roleDescriptors); - int accessibility = parseAccessibility(accessibilityDescriptors); + @C.RoleFlags int role = parseRole(roleDescriptors); + @C.RoleFlags int accessibility = parseAccessibility(accessibilityDescriptors); + @C.RoleFlags int roleFlags = role | accessibility; if (MimeTypes.AUDIO_E_AC3.equals(sampleMimeType)) { sampleMimeType = parseEac3SupplementalProperties(supplementalProperties); } @@ -606,8 +607,7 @@ public class DashManifestParser extends DefaultHandler frameRate, /* initializationData= */ null, selectionFlags, - role, - accessibility); + roleFlags); } else if (MimeTypes.isAudio(sampleMimeType)) { return Format.createAudioContainerFormat( id, @@ -621,8 +621,7 @@ public class DashManifestParser extends DefaultHandler /* initializationData= */ null, selectionFlags, language, - role, - accessibility); + roleFlags); } else if (mimeTypeIsRawText(sampleMimeType)) { int accessibilityChannel; if (MimeTypes.APPLICATION_CEA608.equals(sampleMimeType)) { @@ -642,8 +641,7 @@ public class DashManifestParser extends DefaultHandler selectionFlags, language, accessibilityChannel, - role, - accessibility); + roleFlags); } } return Format.createContainerFormat( @@ -1070,66 +1068,83 @@ public class DashManifestParser extends DefaultHandler // Role and Accessibility parsing. - protected @C.Role int parseRole(List roleDescriptors) { + protected @C.RoleFlags int parseRole(List roleDescriptors) { + @C.RoleFlags int result = 0; for (int i = 0; i < roleDescriptors.size(); i++) { Descriptor descriptor = roleDescriptors.get(i); if ("urn:mpeg:dash:role:2011".equalsIgnoreCase(descriptor.schemeIdUri) && descriptor.value != null) { - switch (descriptor.value) { - case "main": - return C.ROLE_MAIN; - case "alternate": - return C.ROLE_ALTERNATE; - case "supplementary": - return C.ROLE_SUPPLEMENTARY; - case "commentary": - return C.ROLE_COMMENTARY; - case "dub": - return C.ROLE_DUB; - case "emergency": - return C.ROLE_EMERGENCY; - case "caption": - return C.ROLE_CAPTION; - case "sign": - return C.ROLE_SIGN; - default: - return C.ROLE_UNSET; - } + result |= parseRoleSchemeValue(descriptor.value); } } - return C.ROLE_UNSET; + return result; } - protected @C.Accessibility int parseAccessibility(List accessibilityDescriptors) { + protected @C.RoleFlags int parseAccessibility(List accessibilityDescriptors) { + @C.RoleFlags int result = 0; for (int i = 0; i < accessibilityDescriptors.size(); i++) { Descriptor descriptor = accessibilityDescriptors.get(i); if ("urn:mpeg:dash:role:2011".equalsIgnoreCase(descriptor.schemeIdUri) && descriptor.value != null) { - switch (descriptor.value){ - case "description": - return C.ACCESSIBILITY_DESCRIPTION; - case "enhanced-audio-intelligibility": - return C.ACCESSIBILITY_ENHANCED_AUDIO_INTELLIGIBILITY; - case "caption": - return C.ACCESSIBILITY_CAPTION; - case "sign": - return C.ACCESSIBILITY_SIGN; - default: - return C.ACCESSIBILITY_UNSET; - } + result |= parseRoleSchemeValue(descriptor.value); } - if ("urn:tva:metadata:cs:AudioPurposeCS:2007".equalsIgnoreCase(descriptor.schemeIdUri) && descriptor.value != null) { switch (descriptor.value){ - case "1": - return C.ACCESSIBILITY_ENHANCED_AUDIO_INTELLIGIBILITY; - case "2": - return C.ACCESSIBILITY_CAPTION; - default: - return C.ACCESSIBILITY_UNSET; + case "1": // Audio description for the visually impaired + result |= C.ROLE_FLAGS_DESCRIPTION; + break; + case "2": // Audio description for the hard of hearing + result |= C.ROLE_FLAGS_ENHANCED_AUDIO_INTELLIGIBILITY; + break; + case "3": // Supplemental commentary + result |= C.ROLE_FLAGS_SUPPLEMENTARY; + break; + case "4": // Director's commentary + result |= C.ROLE_FLAGS_COMMENTARY; + break; + case "6": // Main programme audio + result |= C.ROLE_FLAGS_MAIN; + break; } } } - return C.ACCESSIBILITY_UNSET; + return result; + } + + protected @C.RoleFlags int parseRoleSchemeValue(String value){ + @C.RoleFlags int result = 0; + switch (value) { + case "main": + result |= C.ROLE_FLAGS_MAIN; + break; + case "alternate": + result |= C.ROLE_FLAGS_ALTERNATE; + break; + case "supplementary": + result |= C.ROLE_FLAGS_SUPPLEMENTARY; + break; + case "commentary": + result |= C.ROLE_FLAGS_COMMENTARY; + break; + case "dub": + result |= C.ROLE_FLAGS_DUB; + break; + case "emergency": + result |= C.ROLE_FLAGS_EMERGENCY; + break; + case "caption": + result |= C.ROLE_FLAGS_CAPTION; + break; + case "sign": + result |= C.ROLE_FLAGS_SIGN; + break; + case "description": + result |= C.ROLE_FLAGS_DESCRIPTION; + break; + case "enhanced-audio-intelligibility": + result |= C.ROLE_FLAGS_ENHANCED_AUDIO_INTELLIGIBILITY; + break; + } + return result; } // Utility methods. diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaPeriod.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaPeriod.java index 61244f9a45..3465bfe6a9 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaPeriod.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaPeriod.java @@ -703,8 +703,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper variantFormat.frameRate, /* initializationData= */ null, variantFormat.selectionFlags, - /* role= */ C.ROLE_UNSET, - /* accessibility= */ C.ACCESSIBILITY_UNSET); + /* roleFlags= */ 0); } private static Format deriveAudioFormat( @@ -743,8 +742,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper /* initializationData= */ null, selectionFlags, language, - /* role= */ C.ROLE_UNSET, - /* accessibility= */ C.ACCESSIBILITY_UNSET); + /* roleFlags= */ 0); } } diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java index 7e273fbd3f..31528353ee 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java @@ -330,8 +330,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser { /* frameRate= */ Format.NO_VALUE, codecSpecificData, /* selectionFlags= */ 0, - /* role= */ C.ROLE_UNSET, - /* accessibility= */ C.ACCESSIBILITY_UNSET); + /* roleFlags= */ 0); } else if (type == C.TRACK_TYPE_AUDIO) { sampleMimeType = sampleMimeType == null ? MimeTypes.AUDIO_AAC : sampleMimeType; int channels = parseRequiredInt(parser, KEY_CHANNELS); @@ -708,8 +707,7 @@ public class SsManifestParser implements ParsingLoadable.Parser { codecSpecificData, /* selectionFlags= */ 0, language, - /* role= */ C.ROLE_UNSET, - /* accessibility= */ C.ACCESSIBILITY_UNSET); + /* roleFlags= */ 0); } else if (type == C.TRACK_TYPE_TEXT) { String language = (String) getNormalizedAttribute(KEY_LANGUAGE); format =