From 06ed877845dbe971fc92df94872520119e8a9543 Mon Sep 17 00:00:00 2001 From: Arnold Szabo Date: Wed, 27 Feb 2019 23:53:52 +0200 Subject: [PATCH 1/5] Pass role and accessibility descriptor values from adaptation set to format --- .../com/google/android/exoplayer2/Format.java | 68 ++++++++++++++++++- .../dash/manifest/DashManifestParser.java | 44 +++++++++++- .../hls/playlist/HlsPlaylistParser.java | 4 +- 3 files changed, 111 insertions(+), 5 deletions(-) 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 8778a4244b..3ed5a99f23 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 @@ -167,6 +167,16 @@ public final class Format implements Parcelable { */ public final int accessibilityChannel; + /** + * The Role descriptor value. + */ + public final String role; + + /** + * The Accessibility descriptor value. + */ + public final String accessibility; + // Lazily initialized hashcode. private int hashCode; @@ -234,6 +244,8 @@ public final class Format implements Parcelable { selectionFlags, /* language= */ null, /* accessibilityChannel= */ NO_VALUE, + /* role= */ null, + /* accessibility= */ null, OFFSET_SAMPLE_RELATIVE, initializationData, /* drmInitData= */ null, @@ -337,6 +349,8 @@ public final class Format implements Parcelable { /* selectionFlags= */ 0, /* language= */ null, /* accessibilityChannel= */ NO_VALUE, + /* role= */ null, + /* accessibility= */ null, OFFSET_SAMPLE_RELATIVE, initializationData, drmInitData, @@ -407,6 +421,8 @@ public final class Format implements Parcelable { selectionFlags, language, /* accessibilityChannel= */ NO_VALUE, + /* role= */ null, + /* accessibility= */ null, OFFSET_SAMPLE_RELATIVE, initializationData, /* drmInitData= */ null, @@ -511,6 +527,8 @@ public final class Format implements Parcelable { selectionFlags, language, /* accessibilityChannel= */ NO_VALUE, + /* role= */ null, + /* accessibility= */ null, OFFSET_SAMPLE_RELATIVE, initializationData, drmInitData, @@ -557,7 +575,9 @@ public final class Format implements Parcelable { bitrate, selectionFlags, language, - /* accessibilityChannel= */ NO_VALUE); + /* accessibilityChannel= */ NO_VALUE, + /* role= */ null, + /* accessibility= */ null); } public static Format createTextContainerFormat( @@ -569,7 +589,9 @@ public final class Format implements Parcelable { int bitrate, @C.SelectionFlags int selectionFlags, @Nullable String language, - int accessibilityChannel) { + int accessibilityChannel, + @Nullable String role, + @Nullable String accessibility) { return new Format( id, label, @@ -594,6 +616,8 @@ public final class Format implements Parcelable { selectionFlags, language, accessibilityChannel, + role, + accessibility, OFFSET_SAMPLE_RELATIVE, /* initializationData= */ null, /* drmInitData= */ null, @@ -706,6 +730,8 @@ public final class Format implements Parcelable { selectionFlags, language, accessibilityChannel, + /* role= */ null, + /* accessibility= */ null, subsampleOffsetUs, initializationData, drmInitData, @@ -747,6 +773,8 @@ public final class Format implements Parcelable { selectionFlags, language, /* accessibilityChannel= */ NO_VALUE, + /* role= */ null, + /* accessibility= */ null, OFFSET_SAMPLE_RELATIVE, initializationData, drmInitData, @@ -808,6 +836,8 @@ public final class Format implements Parcelable { selectionFlags, language, /* accessibilityChannel= */ NO_VALUE, + /* role= */ null, + /* accessibility= */ null, OFFSET_SAMPLE_RELATIVE, /* initializationData= */ null, /* drmInitData= */ null, @@ -840,6 +870,8 @@ public final class Format implements Parcelable { /* selectionFlags= */ 0, /* language= */ null, /* accessibilityChannel= */ NO_VALUE, + /* role= */ null, + /* accessibility= */ null, subsampleOffsetUs, /* initializationData= */ null, /* drmInitData= */ null, @@ -876,6 +908,8 @@ public final class Format implements Parcelable { /* selectionFlags= */ 0, /* language= */ null, /* accessibilityChannel= */ NO_VALUE, + /* role= */ null, + /* accessibility= */ null, OFFSET_SAMPLE_RELATIVE, /* initializationData= */ null, drmInitData, @@ -906,6 +940,8 @@ public final class Format implements Parcelable { @C.SelectionFlags int selectionFlags, @Nullable String language, int accessibilityChannel, + @Nullable String role, + @Nullable String accessibility, long subsampleOffsetUs, @Nullable List initializationData, @Nullable DrmInitData drmInitData, @@ -934,6 +970,8 @@ public final class Format implements Parcelable { this.selectionFlags = selectionFlags; this.language = Util.normalizeLanguageCode(language); this.accessibilityChannel = accessibilityChannel; + this.role = role; + this.accessibility = accessibility; this.subsampleOffsetUs = subsampleOffsetUs; this.initializationData = initializationData == null ? Collections.emptyList() : initializationData; @@ -967,6 +1005,8 @@ public final class Format implements Parcelable { selectionFlags = in.readInt(); language = in.readString(); accessibilityChannel = in.readInt(); + role = in.readString(); + accessibility = in.readString(); subsampleOffsetUs = in.readLong(); int initializationDataSize = in.readInt(); initializationData = new ArrayList<>(initializationDataSize); @@ -1002,6 +1042,8 @@ public final class Format implements Parcelable { selectionFlags, language, accessibilityChannel, + role, + accessibility, subsampleOffsetUs, initializationData, drmInitData, @@ -1033,6 +1075,8 @@ public final class Format implements Parcelable { selectionFlags, language, accessibilityChannel, + role, + accessibility, subsampleOffsetUs, initializationData, drmInitData, @@ -1073,6 +1117,8 @@ public final class Format implements Parcelable { selectionFlags, language, accessibilityChannel, + role, + accessibility, subsampleOffsetUs, initializationData, drmInitData, @@ -1144,6 +1190,8 @@ public final class Format implements Parcelable { selectionFlags, language, accessibilityChannel, + role, + accessibility, subsampleOffsetUs, initializationData, drmInitData, @@ -1175,6 +1223,8 @@ public final class Format implements Parcelable { selectionFlags, language, accessibilityChannel, + role, + accessibility, subsampleOffsetUs, initializationData, drmInitData, @@ -1206,6 +1256,8 @@ public final class Format implements Parcelable { selectionFlags, language, accessibilityChannel, + role, + accessibility, subsampleOffsetUs, initializationData, drmInitData, @@ -1237,6 +1289,8 @@ public final class Format implements Parcelable { selectionFlags, language, accessibilityChannel, + role, + accessibility, subsampleOffsetUs, initializationData, drmInitData, @@ -1268,6 +1322,8 @@ public final class Format implements Parcelable { selectionFlags, language, accessibilityChannel, + role, + accessibility, subsampleOffsetUs, initializationData, drmInitData, @@ -1299,6 +1355,8 @@ public final class Format implements Parcelable { selectionFlags, language, accessibilityChannel, + role, + accessibility, subsampleOffsetUs, initializationData, drmInitData, @@ -1330,6 +1388,8 @@ public final class Format implements Parcelable { selectionFlags, language, accessibilityChannel, + role, + accessibility, subsampleOffsetUs, initializationData, drmInitData, @@ -1439,6 +1499,8 @@ 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) && Util.areEqual(containerMimeType, other.containerMimeType) && Util.areEqual(sampleMimeType, other.sampleMimeType) && Util.areEqual(codecs, other.codecs) @@ -1540,6 +1602,8 @@ public final class Format implements Parcelable { dest.writeInt(selectionFlags); dest.writeString(language); dest.writeInt(accessibilityChannel); + dest.writeString(role); + dest.writeString(accessibility); 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 c0aa2a7819..41a460075e 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 @@ -276,6 +276,7 @@ public class DashManifestParser extends DefaultHandler ArrayList drmSchemeDatas = new ArrayList<>(); ArrayList inbandEventStreams = new ArrayList<>(); ArrayList accessibilityDescriptors = new ArrayList<>(); + ArrayList roleDescriptors = new ArrayList<>(); ArrayList supplementalProperties = new ArrayList<>(); List representationInfos = new ArrayList<>(); @C.SelectionFlags int selectionFlags = 0; @@ -300,7 +301,10 @@ public class DashManifestParser extends DefaultHandler language = checkLanguageConsistency(language, xpp.getAttributeValue(null, "lang")); contentType = checkContentTypeConsistency(contentType, parseContentType(xpp)); } else if (XmlPullParserUtil.isStartTag(xpp, "Role")) { - selectionFlags |= parseRole(xpp); + Descriptor descriptor = parseDescriptor(xpp, "Role"); + selectionFlags |= "urn:mpeg:dash:role:2011".equals(descriptor.schemeIdUri) + && "main".equals(descriptor.value) ? C.SELECTION_FLAG_DEFAULT : 0; + roleDescriptors.add(descriptor); } else if (XmlPullParserUtil.isStartTag(xpp, "AudioChannelConfiguration")) { audioChannels = parseAudioChannelConfiguration(xpp); } else if (XmlPullParserUtil.isStartTag(xpp, "Accessibility")) { @@ -322,6 +326,7 @@ public class DashManifestParser extends DefaultHandler audioSamplingRate, language, selectionFlags, + roleDescriptors, accessibilityDescriptors, segmentBase); contentType = checkContentTypeConsistency(contentType, @@ -509,6 +514,7 @@ public class DashManifestParser extends DefaultHandler int adaptationSetAudioSamplingRate, String adaptationSetLanguage, @C.SelectionFlags int adaptationSetSelectionFlags, + List adaptationSetRoleDescriptors, List adaptationSetAccessibilityDescriptors, SegmentBase segmentBase) throws XmlPullParserException, IOException { @@ -573,6 +579,7 @@ public class DashManifestParser extends DefaultHandler bandwidth, adaptationSetLanguage, adaptationSetSelectionFlags, + adaptationSetRoleDescriptors, adaptationSetAccessibilityDescriptors, codecs, supplementalProperties); @@ -594,6 +601,7 @@ public class DashManifestParser extends DefaultHandler int bitrate, String language, @C.SelectionFlags int selectionFlags, + List roleDescriptors, List accessibilityDescriptors, String codecs, List supplementalProperties) { @@ -637,6 +645,10 @@ public class DashManifestParser extends DefaultHandler } else { accessibilityChannel = Format.NO_VALUE; } + + String role = parseRole(roleDescriptors); + String accessibility = parseAccessibility(accessibilityDescriptors); + return Format.createTextContainerFormat( id, label, @@ -646,7 +658,9 @@ public class DashManifestParser extends DefaultHandler bitrate, selectionFlags, language, - accessibilityChannel); + accessibilityChannel, + role, + accessibility); } } return Format.createContainerFormat( @@ -1266,6 +1280,32 @@ public class DashManifestParser extends DefaultHandler return MimeTypes.AUDIO_E_AC3; } + protected static String parseRole(List roleDescriptors) { + for (int i = 0; i < roleDescriptors.size(); i++) { + Descriptor descriptor = roleDescriptors.get(i); + if ("urn:mpeg:dash:role:2011".equals(descriptor.schemeIdUri) && descriptor.value != null) { + return descriptor.value; + } + } + return null; + } + + protected static String parseAccessibility(List accessibilityDescriptors) { + for (int i = 0; i < accessibilityDescriptors.size(); i++) { + Descriptor descriptor = accessibilityDescriptors.get(i); + if ("urn:mpeg:dash:role:2011".equals(descriptor.schemeIdUri) && descriptor.value != null) { + return descriptor.value; + } + + if ("urn:tva:metadata:cs:AudioPurposeCS:2007".equals(descriptor.schemeIdUri)) { + if ("1".equals(descriptor.value) || "2".equals(descriptor.value)) { + return descriptor.value; + } + } + } + return null; + } + protected static float parseFrameRate(XmlPullParser xpp, float defaultValue) { float frameRate = defaultValue; String frameRateAttribute = xpp.getAttributeValue(null, "frameRate"); 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 100323b862..e9fd1fb803 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 @@ -405,7 +405,9 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser Date: Thu, 28 Feb 2019 00:11:04 +0200 Subject: [PATCH 2/5] Remove old parseRole method that looked only for main --- .../dash/manifest/DashManifestParser.java | 18 ------------------ 1 file changed, 18 deletions(-) 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 41a460075e..d7f02926cd 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 @@ -469,24 +469,6 @@ public class DashManifestParser extends DefaultHandler return Pair.create(schemeType, schemeData); } - /** - * Parses a Role element. - * - * @param xpp The parser from which to read. - * @throws XmlPullParserException If an error occurs parsing the element. - * @throws IOException If an error occurs reading the element. - * @return {@link C.SelectionFlags} parsed from the element. - */ - protected int parseRole(XmlPullParser xpp) throws XmlPullParserException, IOException { - String schemeIdUri = parseString(xpp, "schemeIdUri", null); - String value = parseString(xpp, "value", null); - do { - xpp.next(); - } while (!XmlPullParserUtil.isEndTag(xpp, "Role")); - return "urn:mpeg:dash:role:2011".equals(schemeIdUri) && "main".equals(value) - ? C.SELECTION_FLAG_DEFAULT : 0; - } - /** * Parses children of AdaptationSet elements not specifically parsed elsewhere. * From 58d746ecaa811d29f9bb52b1e4e232b3bc92ed07 Mon Sep 17 00:00:00 2001 From: Arnold Szabo Date: Sun, 3 Mar 2019 20:26:31 +0200 Subject: [PATCH 3/5] Add IntDef for role and accessibility descriptor's value, parse these also for video / audio tracks --- .../java/com/google/android/exoplayer2/C.java | 48 ++++++++ .../com/google/android/exoplayer2/Format.java | 109 +++++++++-------- .../dash/manifest/DashManifestParser.java | 114 ++++++++++++------ .../exoplayer2/source/hls/HlsMediaPeriod.java | 8 +- .../hls/playlist/HlsPlaylistParser.java | 12 +- .../manifest/SsManifestParser.java | 8 +- 6 files changed, 206 insertions(+), 93 deletions(-) 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 2eed9f03a9..19545fe0c3 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 @@ -976,6 +976,54 @@ public final class C { */ public static final int NETWORK_TYPE_OTHER = 8; + /** + * Adaptation set's role descriptor value (ISO 23009-1) + */ + @Documented + @Retention(RetentionPolicy.SOURCE) + @IntDef({ + ROLE_UNSET, + ROLE_MAIN, + ROLE_ALTERNATE, + ROLE_SUPPLEMENTARY, + ROLE_COMMENTARY, + ROLE_DUB, + ROLE_EMERGENCY, + ROLE_CAPTION, + ROLE_SIGN + }) + public @interface Role {} + + 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; + /** * Converts a time in microseconds to the corresponding time in milliseconds, preserving * {@link #TIME_UNSET} and {@link #TIME_END_OF_SOURCE} values. 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 3ed5a99f23..43ca19e444 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 @@ -48,7 +48,18 @@ public final class Format implements Parcelable { public final @Nullable String id; /** The human readable label, or null if unknown or not applicable. */ public final @Nullable String label; - + /** 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; /** * The average bandwidth in bits per second, or {@link #NO_VALUE} if unknown or not applicable. */ @@ -153,12 +164,6 @@ public final class Format implements Parcelable { // Audio and text specific. - /** - * Track selection flags. - */ - @C.SelectionFlags - public final int selectionFlags; - /** The language as ISO 639-2/T three-letter code, or null if unknown or not applicable. */ public final @Nullable String language; @@ -167,16 +172,6 @@ public final class Format implements Parcelable { */ public final int accessibilityChannel; - /** - * The Role descriptor value. - */ - public final String role; - - /** - * The Accessibility descriptor value. - */ - public final String accessibility; - // Lazily initialized hashcode. private int hashCode; @@ -193,7 +188,9 @@ public final class Format implements Parcelable { int height, float frameRate, @Nullable List initializationData, - @C.SelectionFlags int selectionFlags) { + @C.SelectionFlags int selectionFlags, + @C.Role int role, + @C.Accessibility int accessibility) { return createVideoContainerFormat( id, /* label= */ null, @@ -205,7 +202,9 @@ public final class Format implements Parcelable { height, frameRate, initializationData, - selectionFlags); + selectionFlags, + role, + accessibility); } public static Format createVideoContainerFormat( @@ -219,7 +218,9 @@ public final class Format implements Parcelable { int height, float frameRate, @Nullable List initializationData, - @C.SelectionFlags int selectionFlags) { + @C.SelectionFlags int selectionFlags, + @C.Role int role, + @C.Accessibility int accessibility) { return new Format( id, label, @@ -244,8 +245,8 @@ public final class Format implements Parcelable { selectionFlags, /* language= */ null, /* accessibilityChannel= */ NO_VALUE, - /* role= */ null, - /* accessibility= */ null, + role, + accessibility, OFFSET_SAMPLE_RELATIVE, initializationData, /* drmInitData= */ null, @@ -349,8 +350,8 @@ public final class Format implements Parcelable { /* selectionFlags= */ 0, /* language= */ null, /* accessibilityChannel= */ NO_VALUE, - /* role= */ null, - /* accessibility= */ null, + /* role= */ C.ROLE_UNSET, + /* accessibility= */ C.ACCESSIBILITY_UNSET, OFFSET_SAMPLE_RELATIVE, initializationData, drmInitData, @@ -370,7 +371,9 @@ public final class Format implements Parcelable { int sampleRate, @Nullable List initializationData, @C.SelectionFlags int selectionFlags, - @Nullable String language) { + @Nullable String language, + @C.Role int role, + @C.Accessibility int accessibility) { return createAudioContainerFormat( id, /* label= */ null, @@ -382,7 +385,9 @@ public final class Format implements Parcelable { sampleRate, initializationData, selectionFlags, - language); + language, + role, + accessibility); } public static Format createAudioContainerFormat( @@ -396,7 +401,9 @@ public final class Format implements Parcelable { int sampleRate, @Nullable List initializationData, @C.SelectionFlags int selectionFlags, - @Nullable String language) { + @Nullable String language, + @C.Role int role, + @C.Accessibility int accessibility) { return new Format( id, label, @@ -421,8 +428,8 @@ public final class Format implements Parcelable { selectionFlags, language, /* accessibilityChannel= */ NO_VALUE, - /* role= */ null, - /* accessibility= */ null, + role, + accessibility, OFFSET_SAMPLE_RELATIVE, initializationData, /* drmInitData= */ null, @@ -527,8 +534,8 @@ public final class Format implements Parcelable { selectionFlags, language, /* accessibilityChannel= */ NO_VALUE, - /* role= */ null, - /* accessibility= */ null, + /* role= */ C.ROLE_UNSET, + /* accessibility= */ C.ACCESSIBILITY_UNSET, OFFSET_SAMPLE_RELATIVE, initializationData, drmInitData, @@ -576,8 +583,8 @@ public final class Format implements Parcelable { selectionFlags, language, /* accessibilityChannel= */ NO_VALUE, - /* role= */ null, - /* accessibility= */ null); + /* role= */ C.ROLE_UNSET, + /* accessibility= */ C.ACCESSIBILITY_UNSET); } public static Format createTextContainerFormat( @@ -590,8 +597,8 @@ public final class Format implements Parcelable { @C.SelectionFlags int selectionFlags, @Nullable String language, int accessibilityChannel, - @Nullable String role, - @Nullable String accessibility) { + @C.Role int role, + @C.Accessibility int accessibility) { return new Format( id, label, @@ -730,8 +737,8 @@ public final class Format implements Parcelable { selectionFlags, language, accessibilityChannel, - /* role= */ null, - /* accessibility= */ null, + /* role= */ C.ROLE_UNSET, + /* accessibility= */ C.ACCESSIBILITY_UNSET, subsampleOffsetUs, initializationData, drmInitData, @@ -773,8 +780,8 @@ public final class Format implements Parcelable { selectionFlags, language, /* accessibilityChannel= */ NO_VALUE, - /* role= */ null, - /* accessibility= */ null, + /* role= */ C.ROLE_UNSET, + /* accessibility= */ C.ACCESSIBILITY_UNSET, OFFSET_SAMPLE_RELATIVE, initializationData, drmInitData, @@ -836,8 +843,8 @@ public final class Format implements Parcelable { selectionFlags, language, /* accessibilityChannel= */ NO_VALUE, - /* role= */ null, - /* accessibility= */ null, + /* role= */ C.ROLE_UNSET, + /* accessibility= */ C.ACCESSIBILITY_UNSET, OFFSET_SAMPLE_RELATIVE, /* initializationData= */ null, /* drmInitData= */ null, @@ -870,8 +877,8 @@ public final class Format implements Parcelable { /* selectionFlags= */ 0, /* language= */ null, /* accessibilityChannel= */ NO_VALUE, - /* role= */ null, - /* accessibility= */ null, + /* role= */ C.ROLE_UNSET, + /* accessibility= */ C.ACCESSIBILITY_UNSET, subsampleOffsetUs, /* initializationData= */ null, /* drmInitData= */ null, @@ -908,8 +915,8 @@ public final class Format implements Parcelable { /* selectionFlags= */ 0, /* language= */ null, /* accessibilityChannel= */ NO_VALUE, - /* role= */ null, - /* accessibility= */ null, + /* role= */ C.ROLE_UNSET, + /* accessibility= */ C.ACCESSIBILITY_UNSET, OFFSET_SAMPLE_RELATIVE, /* initializationData= */ null, drmInitData, @@ -940,8 +947,8 @@ public final class Format implements Parcelable { @C.SelectionFlags int selectionFlags, @Nullable String language, int accessibilityChannel, - @Nullable String role, - @Nullable String accessibility, + @C.Role int role, + @C.Accessibility int accessibility, long subsampleOffsetUs, @Nullable List initializationData, @Nullable DrmInitData drmInitData, @@ -1005,8 +1012,8 @@ public final class Format implements Parcelable { selectionFlags = in.readInt(); language = in.readString(); accessibilityChannel = in.readInt(); - role = in.readString(); - accessibility = in.readString(); + role = in.readInt(); + accessibility = in.readInt(); subsampleOffsetUs = in.readLong(); int initializationDataSize = in.readInt(); initializationData = new ArrayList<>(initializationDataSize); @@ -1602,8 +1609,8 @@ public final class Format implements Parcelable { dest.writeInt(selectionFlags); dest.writeString(language); dest.writeInt(accessibilityChannel); - dest.writeString(role); - dest.writeString(accessibility); + dest.writeInt(role); + dest.writeInt(accessibility); 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 d7f02926cd..462ebc6300 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 @@ -302,8 +302,7 @@ public class DashManifestParser extends DefaultHandler contentType = checkContentTypeConsistency(contentType, parseContentType(xpp)); } else if (XmlPullParserUtil.isStartTag(xpp, "Role")) { Descriptor descriptor = parseDescriptor(xpp, "Role"); - selectionFlags |= "urn:mpeg:dash:role:2011".equals(descriptor.schemeIdUri) - && "main".equals(descriptor.value) ? C.SELECTION_FLAG_DEFAULT : 0; + selectionFlags |= parseSelectionFlags(descriptor); roleDescriptors.add(descriptor); } else if (XmlPullParserUtil.isStartTag(xpp, "AudioChannelConfiguration")) { audioChannels = parseAudioChannelConfiguration(xpp); @@ -589,6 +588,8 @@ public class DashManifestParser extends DefaultHandler List supplementalProperties) { String sampleMimeType = getSampleMimeType(containerMimeType, codecs); if (sampleMimeType != null) { + int role = parseRole(roleDescriptors); + int accessibility = parseAccessibility(accessibilityDescriptors); if (MimeTypes.AUDIO_E_AC3.equals(sampleMimeType)) { sampleMimeType = parseEac3SupplementalProperties(supplementalProperties); } @@ -604,7 +605,9 @@ public class DashManifestParser extends DefaultHandler height, frameRate, /* initializationData= */ null, - selectionFlags); + selectionFlags, + role, + accessibility); } else if (MimeTypes.isAudio(sampleMimeType)) { return Format.createAudioContainerFormat( id, @@ -617,7 +620,9 @@ public class DashManifestParser extends DefaultHandler audioSamplingRate, /* initializationData= */ null, selectionFlags, - language); + language, + role, + accessibility); } else if (mimeTypeIsRawText(sampleMimeType)) { int accessibilityChannel; if (MimeTypes.APPLICATION_CEA608.equals(sampleMimeType)) { @@ -627,10 +632,6 @@ public class DashManifestParser extends DefaultHandler } else { accessibilityChannel = Format.NO_VALUE; } - - String role = parseRole(roleDescriptors); - String accessibility = parseAccessibility(accessibilityDescriptors); - return Format.createTextContainerFormat( id, label, @@ -1060,6 +1061,77 @@ public class DashManifestParser extends DefaultHandler return audioChannels; } + // Selection flag parsing. + + protected int parseSelectionFlags(Descriptor roleDescriptor) { + return "urn:mpeg:dash:role:2011".equals(roleDescriptor.schemeIdUri) + && "main".equals(roleDescriptor.value) ? C.SELECTION_FLAG_DEFAULT : 0; + } + + // Role and Accessibility parsing. + + protected @C.Role int parseRole(List roleDescriptors) { + 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; + } + } + } + return C.ROLE_UNSET; + } + + protected @C.Accessibility int parseAccessibility(List accessibilityDescriptors) { + 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; + } + } + + 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; + } + } + } + return C.ACCESSIBILITY_UNSET; + } + // Utility methods. /** @@ -1262,32 +1334,6 @@ public class DashManifestParser extends DefaultHandler return MimeTypes.AUDIO_E_AC3; } - protected static String parseRole(List roleDescriptors) { - for (int i = 0; i < roleDescriptors.size(); i++) { - Descriptor descriptor = roleDescriptors.get(i); - if ("urn:mpeg:dash:role:2011".equals(descriptor.schemeIdUri) && descriptor.value != null) { - return descriptor.value; - } - } - return null; - } - - protected static String parseAccessibility(List accessibilityDescriptors) { - for (int i = 0; i < accessibilityDescriptors.size(); i++) { - Descriptor descriptor = accessibilityDescriptors.get(i); - if ("urn:mpeg:dash:role:2011".equals(descriptor.schemeIdUri) && descriptor.value != null) { - return descriptor.value; - } - - if ("urn:tva:metadata:cs:AudioPurposeCS:2007".equals(descriptor.schemeIdUri)) { - if ("1".equals(descriptor.value) || "2".equals(descriptor.value)) { - return descriptor.value; - } - } - } - return null; - } - protected static float parseFrameRate(XmlPullParser xpp, float defaultValue) { float frameRate = defaultValue; String frameRateAttribute = xpp.getAttributeValue(null, "frameRate"); 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 1c3e2f141d..61244f9a45 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 @@ -702,7 +702,9 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper variantFormat.height, variantFormat.frameRate, /* initializationData= */ null, - variantFormat.selectionFlags); + variantFormat.selectionFlags, + /* role= */ C.ROLE_UNSET, + /* accessibility= */ C.ACCESSIBILITY_UNSET); } private static Format deriveAudioFormat( @@ -740,7 +742,9 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper /* sampleRate= */ Format.NO_VALUE, /* initializationData= */ null, selectionFlags, - language); + language, + /* role= */ C.ROLE_UNSET, + /* accessibility= */ C.ACCESSIBILITY_UNSET); } } 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 e9fd1fb803..7e273fbd3f 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 @@ -329,7 +329,9 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser { height, /* frameRate= */ Format.NO_VALUE, codecSpecificData, - /* selectionFlags= */ 0); + /* selectionFlags= */ 0, + /* role= */ C.ROLE_UNSET, + /* accessibility= */ C.ACCESSIBILITY_UNSET); } else if (type == C.TRACK_TYPE_AUDIO) { sampleMimeType = sampleMimeType == null ? MimeTypes.AUDIO_AAC : sampleMimeType; int channels = parseRequiredInt(parser, KEY_CHANNELS); @@ -705,7 +707,9 @@ public class SsManifestParser implements ParsingLoadable.Parser { samplingRate, codecSpecificData, /* selectionFlags= */ 0, - language); + language, + /* role= */ C.ROLE_UNSET, + /* accessibility= */ C.ACCESSIBILITY_UNSET); } else if (type == C.TRACK_TYPE_TEXT) { String language = (String) getNormalizedAttribute(KEY_LANGUAGE); format = From 854419962ada33b34a734b3801edd9e05c083684 Mon Sep 17 00:00:00 2001 From: Arnold Szabo Date: Tue, 5 Mar 2019 23:38:49 +0200 Subject: [PATCH 4/5] Merge role and accessibility fields into RoleFlags --- .../java/com/google/android/exoplayer2/C.java | 66 ++++------ .../com/google/android/exoplayer2/Format.java | 111 ++++++----------- .../dash/manifest/DashManifestParser.java | 117 ++++++++++-------- .../exoplayer2/source/hls/HlsMediaPeriod.java | 6 +- .../hls/playlist/HlsPlaylistParser.java | 9 +- .../manifest/SsManifestParser.java | 6 +- 6 files changed, 134 insertions(+), 181 deletions(-) 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 = From d7c2519a5dbfac421ff24770785ad4097eed5033 Mon Sep 17 00:00:00 2001 From: Arnold Szabo Date: Thu, 7 Mar 2019 00:09:11 +0200 Subject: [PATCH 5/5] Fixes according to the code review --- .../java/com/google/android/exoplayer2/C.java | 5 +- .../com/google/android/exoplayer2/Format.java | 75 +++++----- .../dash/manifest/DashManifestParser.java | 132 +++++++++--------- .../source/dash/DashMediaPeriodTest.java | 3 + .../exoplayer2/source/dash/DashUtilTest.java | 3 +- .../exoplayer2/source/hls/HlsMediaPeriod.java | 4 +- .../hls/playlist/HlsMasterPlaylist.java | 1 + .../hls/playlist/HlsPlaylistParser.java | 8 +- .../manifest/SsManifestParser.java | 5 +- 9 files changed, 126 insertions(+), 110 deletions(-) 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 75f1263a31..2997c250e3 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,7 +977,10 @@ public final class C { public static final int NETWORK_TYPE_OTHER = 8; /** - * Adaptation set's role and accessibility descriptor value. + * Track role flags. Possible values are {@link #ROLE_FLAGS_MAIN}, {@link #ROLE_FLAGS_ALTERNATE}, + * {@link #ROLE_FLAGS_SUPPLEMENTARY}, {@link #ROLE_FLAGS_COMMENTARY}, {@link #ROLE_FLAGS_DUB}, + * {@link #ROLE_FLAGS_EMERGENCY}, {@link #ROLE_FLAGS_CAPTION}, {@link #ROLE_FLAGS_SIGN}, + * {@link #ROLE_FLAGS_ENHANCED_AUDIO_INTELLIGIBILITY}, {@link #ROLE_FLAGS_DESCRIPTION}. */ @Documented @Retention(RetentionPolicy.SOURCE) 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 509ef8011f..b20b3ba86c 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,7 +51,7 @@ public final class Format implements Parcelable { /** Track selection flags. **/ @C.SelectionFlags public final int selectionFlags; - /** Track role and accessibility descriptor values. **/ + /** Track role flags. **/ @C.RoleFlags public final int roleFlags; /** @@ -234,9 +234,9 @@ public final class Format implements Parcelable { /* encoderDelay= */ NO_VALUE, /* encoderPadding= */ NO_VALUE, selectionFlags, + roleFlags, /* language= */ null, /* accessibilityChannel= */ NO_VALUE, - roleFlags, OFFSET_SAMPLE_RELATIVE, initializationData, /* drmInitData= */ null, @@ -338,9 +338,9 @@ public final class Format implements Parcelable { /* encoderDelay= */ NO_VALUE, /* encoderPadding= */ NO_VALUE, /* selectionFlags= */ 0, + /* roleFlags= */ 0, /* language= */ null, /* accessibilityChannel= */ NO_VALUE, - /* roleFlags= */ 0, OFFSET_SAMPLE_RELATIVE, initializationData, drmInitData, @@ -360,8 +360,8 @@ public final class Format implements Parcelable { int sampleRate, @Nullable List initializationData, @C.SelectionFlags int selectionFlags, - @Nullable String language, - @C.RoleFlags int roleFlags) { + @C.RoleFlags int roleFlags, + @Nullable String language) { return createAudioContainerFormat( id, /* label= */ null, @@ -373,8 +373,8 @@ public final class Format implements Parcelable { sampleRate, initializationData, selectionFlags, - language, - roleFlags); + roleFlags, + language); } public static Format createAudioContainerFormat( @@ -388,8 +388,8 @@ public final class Format implements Parcelable { int sampleRate, @Nullable List initializationData, @C.SelectionFlags int selectionFlags, - @Nullable String language, - @C.RoleFlags int roleFlags) { + @C.RoleFlags int roleFlags, + @Nullable String language) { return new Format( id, label, @@ -412,9 +412,9 @@ public final class Format implements Parcelable { /* encoderDelay= */ NO_VALUE, /* encoderPadding= */ NO_VALUE, selectionFlags, + roleFlags, language, /* accessibilityChannel= */ NO_VALUE, - roleFlags, OFFSET_SAMPLE_RELATIVE, initializationData, /* drmInitData= */ null, @@ -517,9 +517,9 @@ public final class Format implements Parcelable { encoderDelay, encoderPadding, selectionFlags, + /* roleFlags= */ 0, language, /* accessibilityChannel= */ NO_VALUE, - /* roleFlags= */ 0, OFFSET_SAMPLE_RELATIVE, initializationData, drmInitData, @@ -565,9 +565,9 @@ public final class Format implements Parcelable { codecs, bitrate, selectionFlags, + /* roleFlags= */ 0, language, - /* accessibilityChannel= */ NO_VALUE, - /* roleFlags= */ 0); + /* accessibilityChannel= */ NO_VALUE); } public static Format createTextContainerFormat( @@ -578,9 +578,9 @@ public final class Format implements Parcelable { @Nullable String codecs, int bitrate, @C.SelectionFlags int selectionFlags, + @C.RoleFlags int roleFlags, @Nullable String language, - int accessibilityChannel, - @C.RoleFlags int roleFlags) { + int accessibilityChannel) { return new Format( id, label, @@ -603,9 +603,9 @@ public final class Format implements Parcelable { /* encoderDelay= */ NO_VALUE, /* encoderPadding= */ NO_VALUE, selectionFlags, + roleFlags, language, accessibilityChannel, - roleFlags, OFFSET_SAMPLE_RELATIVE, /* initializationData= */ null, /* drmInitData= */ null, @@ -716,9 +716,9 @@ public final class Format implements Parcelable { /* encoderDelay= */ NO_VALUE, /* encoderPadding= */ NO_VALUE, selectionFlags, + /* roleFlags= */ 0, language, accessibilityChannel, - /* roleFlags= */ 0, subsampleOffsetUs, initializationData, drmInitData, @@ -758,9 +758,9 @@ public final class Format implements Parcelable { /* encoderDelay= */ NO_VALUE, /* encoderPadding= */ NO_VALUE, selectionFlags, + /* roleFlags= */ 0, language, /* accessibilityChannel= */ NO_VALUE, - /* roleFlags= */ 0, OFFSET_SAMPLE_RELATIVE, initializationData, drmInitData, @@ -777,6 +777,7 @@ public final class Format implements Parcelable { @Nullable String codecs, int bitrate, @C.SelectionFlags int selectionFlags, + @C.RoleFlags int roleFlags, @Nullable String language) { return createContainerFormat( id, @@ -786,6 +787,7 @@ public final class Format implements Parcelable { codecs, bitrate, selectionFlags, + roleFlags, language); } @@ -797,6 +799,7 @@ public final class Format implements Parcelable { @Nullable String codecs, int bitrate, @C.SelectionFlags int selectionFlags, + @C.RoleFlags int roleFlags, @Nullable String language) { return new Format( id, @@ -820,9 +823,9 @@ public final class Format implements Parcelable { /* encoderDelay= */ NO_VALUE, /* encoderPadding= */ NO_VALUE, selectionFlags, + roleFlags, language, /* accessibilityChannel= */ NO_VALUE, - /* roleFlags= */ 0, OFFSET_SAMPLE_RELATIVE, /* initializationData= */ null, /* drmInitData= */ null, @@ -853,9 +856,9 @@ public final class Format implements Parcelable { /* encoderDelay= */ NO_VALUE, /* encoderPadding= */ NO_VALUE, /* selectionFlags= */ 0, + /* roleFlags= */ 0, /* language= */ null, /* accessibilityChannel= */ NO_VALUE, - /* roleFlags= */ 0, subsampleOffsetUs, /* initializationData= */ null, /* drmInitData= */ null, @@ -890,9 +893,9 @@ public final class Format implements Parcelable { /* encoderDelay= */ NO_VALUE, /* encoderPadding= */ NO_VALUE, /* selectionFlags= */ 0, + /* roleFlags= */ 0, /* language= */ null, /* accessibilityChannel= */ NO_VALUE, - /* roleFlags= */ 0, OFFSET_SAMPLE_RELATIVE, /* initializationData= */ null, drmInitData, @@ -921,9 +924,9 @@ public final class Format implements Parcelable { int encoderDelay, int encoderPadding, @C.SelectionFlags int selectionFlags, + @C.RoleFlags int roleFlags, @Nullable String language, int accessibilityChannel, - @C.RoleFlags int roleFlags, long subsampleOffsetUs, @Nullable List initializationData, @Nullable DrmInitData drmInitData, @@ -950,9 +953,9 @@ public final class Format implements Parcelable { this.encoderDelay = encoderDelay == Format.NO_VALUE ? 0 : encoderDelay; this.encoderPadding = encoderPadding == Format.NO_VALUE ? 0 : encoderPadding; this.selectionFlags = selectionFlags; + this.roleFlags = roleFlags; this.language = Util.normalizeLanguageCode(language); this.accessibilityChannel = accessibilityChannel; - this.roleFlags = roleFlags; this.subsampleOffsetUs = subsampleOffsetUs; this.initializationData = initializationData == null ? Collections.emptyList() : initializationData; @@ -984,9 +987,9 @@ public final class Format implements Parcelable { encoderDelay = in.readInt(); encoderPadding = in.readInt(); selectionFlags = in.readInt(); + roleFlags = in.readInt(); language = in.readString(); accessibilityChannel = in.readInt(); - roleFlags = in.readInt(); subsampleOffsetUs = in.readLong(); int initializationDataSize = in.readInt(); initializationData = new ArrayList<>(initializationDataSize); @@ -1020,9 +1023,9 @@ public final class Format implements Parcelable { encoderDelay, encoderPadding, selectionFlags, + roleFlags, language, accessibilityChannel, - roleFlags, subsampleOffsetUs, initializationData, drmInitData, @@ -1052,9 +1055,9 @@ public final class Format implements Parcelable { encoderDelay, encoderPadding, selectionFlags, + roleFlags, language, accessibilityChannel, - roleFlags, subsampleOffsetUs, initializationData, drmInitData, @@ -1093,9 +1096,9 @@ public final class Format implements Parcelable { encoderDelay, encoderPadding, selectionFlags, + roleFlags, language, accessibilityChannel, - roleFlags, subsampleOffsetUs, initializationData, drmInitData, @@ -1165,9 +1168,9 @@ public final class Format implements Parcelable { encoderDelay, encoderPadding, selectionFlags, + roleFlags, language, accessibilityChannel, - roleFlags, subsampleOffsetUs, initializationData, drmInitData, @@ -1197,9 +1200,9 @@ public final class Format implements Parcelable { encoderDelay, encoderPadding, selectionFlags, + roleFlags, language, accessibilityChannel, - roleFlags, subsampleOffsetUs, initializationData, drmInitData, @@ -1229,9 +1232,9 @@ public final class Format implements Parcelable { encoderDelay, encoderPadding, selectionFlags, + roleFlags, language, accessibilityChannel, - roleFlags, subsampleOffsetUs, initializationData, drmInitData, @@ -1261,9 +1264,9 @@ public final class Format implements Parcelable { encoderDelay, encoderPadding, selectionFlags, + roleFlags, language, accessibilityChannel, - roleFlags, subsampleOffsetUs, initializationData, drmInitData, @@ -1293,9 +1296,9 @@ public final class Format implements Parcelable { encoderDelay, encoderPadding, selectionFlags, + roleFlags, language, accessibilityChannel, - roleFlags, subsampleOffsetUs, initializationData, drmInitData, @@ -1325,9 +1328,9 @@ public final class Format implements Parcelable { encoderDelay, encoderPadding, selectionFlags, + roleFlags, language, accessibilityChannel, - roleFlags, subsampleOffsetUs, initializationData, drmInitData, @@ -1357,9 +1360,9 @@ public final class Format implements Parcelable { encoderDelay, encoderPadding, selectionFlags, + roleFlags, language, accessibilityChannel, - roleFlags, subsampleOffsetUs, initializationData, drmInitData, @@ -1465,11 +1468,11 @@ public final class Format implements Parcelable { && encoderPadding == other.encoderPadding && subsampleOffsetUs == other.subsampleOffsetUs && selectionFlags == other.selectionFlags + && roleFlags == other.roleFlags && Util.areEqual(id, other.id) && Util.areEqual(label, other.label) && Util.areEqual(language, other.language) && accessibilityChannel == other.accessibilityChannel - && roleFlags == other.roleFlags && Util.areEqual(containerMimeType, other.containerMimeType) && Util.areEqual(sampleMimeType, other.sampleMimeType) && Util.areEqual(codecs, other.codecs) @@ -1569,9 +1572,9 @@ public final class Format implements Parcelable { dest.writeInt(encoderDelay); dest.writeInt(encoderPadding); dest.writeInt(selectionFlags); + dest.writeInt(roleFlags); dest.writeString(language); dest.writeInt(accessibilityChannel); - 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 0a629b3d19..1b432beb2c 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 @@ -279,7 +279,6 @@ public class DashManifestParser extends DefaultHandler ArrayList roleDescriptors = new ArrayList<>(); ArrayList supplementalProperties = new ArrayList<>(); List representationInfos = new ArrayList<>(); - @C.SelectionFlags int selectionFlags = 0; boolean seenFirstBaseUrl = false; do { @@ -301,9 +300,7 @@ public class DashManifestParser extends DefaultHandler language = checkLanguageConsistency(language, xpp.getAttributeValue(null, "lang")); contentType = checkContentTypeConsistency(contentType, parseContentType(xpp)); } else if (XmlPullParserUtil.isStartTag(xpp, "Role")) { - Descriptor descriptor = parseDescriptor(xpp, "Role"); - selectionFlags |= parseSelectionFlags(descriptor); - roleDescriptors.add(descriptor); + roleDescriptors.add(parseDescriptor(xpp, "Role")); } else if (XmlPullParserUtil.isStartTag(xpp, "AudioChannelConfiguration")) { audioChannels = parseAudioChannelConfiguration(xpp); } else if (XmlPullParserUtil.isStartTag(xpp, "Accessibility")) { @@ -324,7 +321,6 @@ public class DashManifestParser extends DefaultHandler audioChannels, audioSamplingRate, language, - selectionFlags, roleDescriptors, accessibilityDescriptors, segmentBase); @@ -494,7 +490,6 @@ public class DashManifestParser extends DefaultHandler int adaptationSetAudioChannels, int adaptationSetAudioSamplingRate, String adaptationSetLanguage, - @C.SelectionFlags int adaptationSetSelectionFlags, List adaptationSetRoleDescriptors, List adaptationSetAccessibilityDescriptors, SegmentBase segmentBase) @@ -559,7 +554,6 @@ public class DashManifestParser extends DefaultHandler audioSamplingRate, bandwidth, adaptationSetLanguage, - adaptationSetSelectionFlags, adaptationSetRoleDescriptors, adaptationSetAccessibilityDescriptors, codecs, @@ -581,16 +575,16 @@ public class DashManifestParser extends DefaultHandler int audioSamplingRate, int bitrate, String language, - @C.SelectionFlags int selectionFlags, List roleDescriptors, List accessibilityDescriptors, String codecs, List supplementalProperties) { String sampleMimeType = getSampleMimeType(containerMimeType, codecs); + @C.SelectionFlags int selectionFlags = parseSelection(roleDescriptors); + @C.RoleFlags int role = parseRole(roleDescriptors); + @C.RoleFlags int accessibility = parseAccessibility(accessibilityDescriptors); + @C.RoleFlags int roleFlags = role | accessibility; if (sampleMimeType != null) { - @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); } @@ -620,8 +614,8 @@ public class DashManifestParser extends DefaultHandler audioSamplingRate, /* initializationData= */ null, selectionFlags, - language, - roleFlags); + roleFlags, + language); } else if (mimeTypeIsRawText(sampleMimeType)) { int accessibilityChannel; if (MimeTypes.APPLICATION_CEA608.equals(sampleMimeType)) { @@ -639,13 +633,21 @@ public class DashManifestParser extends DefaultHandler codecs, bitrate, selectionFlags, + roleFlags, language, - accessibilityChannel, - roleFlags); + accessibilityChannel); } } return Format.createContainerFormat( - id, label, containerMimeType, sampleMimeType, codecs, bitrate, selectionFlags, language); + id, + label, + containerMimeType, + sampleMimeType, + codecs, + bitrate, + selectionFlags, + roleFlags, + language); } protected Representation buildRepresentation( @@ -1061,9 +1063,16 @@ public class DashManifestParser extends DefaultHandler // Selection flag parsing. - protected int parseSelectionFlags(Descriptor roleDescriptor) { - return "urn:mpeg:dash:role:2011".equals(roleDescriptor.schemeIdUri) - && "main".equals(roleDescriptor.value) ? C.SELECTION_FLAG_DEFAULT : 0; + protected int parseSelection(List roleDescriptors) { + for (int i = 0; i < roleDescriptors.size(); i++) { + Descriptor descriptor = roleDescriptors.get(i); + if ("urn:mpeg:dash:role:2011".equalsIgnoreCase(descriptor.schemeIdUri) + && "main".equals(descriptor.value)) { + return C.SELECTION_FLAG_DEFAULT; + } + } + + return 0; } // Role and Accessibility parsing. @@ -1072,7 +1081,7 @@ public class DashManifestParser extends DefaultHandler @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) { + if ("urn:mpeg:dash:role:2011".equalsIgnoreCase(descriptor.schemeIdUri)) { result |= parseRoleSchemeValue(descriptor.value); } } @@ -1083,68 +1092,63 @@ public class DashManifestParser extends DefaultHandler @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) { + if ("urn:mpeg:dash:role:2011".equalsIgnoreCase(descriptor.schemeIdUri)) { result |= parseRoleSchemeValue(descriptor.value); - } - if ("urn:tva:metadata:cs:AudioPurposeCS:2007".equalsIgnoreCase(descriptor.schemeIdUri) && - descriptor.value != null) { - switch (descriptor.value){ - 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; - } + } else if ("urn:tva:metadata:cs:AudioPurposeCS:2007".equalsIgnoreCase(descriptor.schemeIdUri)) { + result |= parseAudioPurposeValue(descriptor.value); } } return result; } - protected @C.RoleFlags int parseRoleSchemeValue(String value){ - @C.RoleFlags int result = 0; + protected @C.RoleFlags int parseRoleSchemeValue(String value) { + if (value == null) { + return 0; + } switch (value) { case "main": - result |= C.ROLE_FLAGS_MAIN; - break; + return C.ROLE_FLAGS_MAIN; case "alternate": - result |= C.ROLE_FLAGS_ALTERNATE; - break; + return C.ROLE_FLAGS_ALTERNATE; case "supplementary": - result |= C.ROLE_FLAGS_SUPPLEMENTARY; - break; + return C.ROLE_FLAGS_SUPPLEMENTARY; case "commentary": - result |= C.ROLE_FLAGS_COMMENTARY; - break; + return C.ROLE_FLAGS_COMMENTARY; case "dub": - result |= C.ROLE_FLAGS_DUB; - break; + return C.ROLE_FLAGS_DUB; case "emergency": - result |= C.ROLE_FLAGS_EMERGENCY; - break; + return C.ROLE_FLAGS_EMERGENCY; case "caption": - result |= C.ROLE_FLAGS_CAPTION; - break; + return C.ROLE_FLAGS_CAPTION; case "sign": - result |= C.ROLE_FLAGS_SIGN; - break; + return C.ROLE_FLAGS_SIGN; case "description": - result |= C.ROLE_FLAGS_DESCRIPTION; - break; + return C.ROLE_FLAGS_DESCRIPTION; case "enhanced-audio-intelligibility": - result |= C.ROLE_FLAGS_ENHANCED_AUDIO_INTELLIGIBILITY; - break; + return C.ROLE_FLAGS_ENHANCED_AUDIO_INTELLIGIBILITY; + default: + return 0; + } + } + + protected @C.RoleFlags int parseAudioPurposeValue(String value) { + if (value == null) { + return 0; + } + switch (value) { + case "1": // Audio description for the visually impaired + return C.ROLE_FLAGS_DESCRIPTION; + case "2": // Audio description for the hard of hearing + return C.ROLE_FLAGS_ENHANCED_AUDIO_INTELLIGIBILITY; + case "3": // Supplemental commentary + return C.ROLE_FLAGS_SUPPLEMENTARY; + case "4": // Director's commentary + return C.ROLE_FLAGS_COMMENTARY; + case "6": // Main programme audio + return C.ROLE_FLAGS_MAIN; + default: + return 0; } - return result; } // Utility methods. diff --git a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/DashMediaPeriodTest.java b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/DashMediaPeriodTest.java index 04820fd20c..077a34a6ab 100644 --- a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/DashMediaPeriodTest.java +++ b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/DashMediaPeriodTest.java @@ -193,6 +193,7 @@ public final class DashMediaPeriodTest { /* codecs= */ null, bitrate, /* selectionFlags= */ 0, + /* roleFlags= */ 0, /* language= */ null); } @@ -207,6 +208,7 @@ public final class DashMediaPeriodTest { /* codecs= */ null, bitrate, /* selectionFlags= */ 0, + /* roleFlags= */ 0, /* language= */ null), /* baseUrl= */ "", new SingleSegmentBase()); @@ -223,6 +225,7 @@ public final class DashMediaPeriodTest { /* codecs= */ null, /* bitrate= */ Format.NO_VALUE, /* selectionFlags= */ 0, + /* roleFlags= */ 0, language), /* baseUrl= */ "", new SingleSegmentBase()); diff --git a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/DashUtilTest.java b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/DashUtilTest.java index 3f5d317519..df451bb3a8 100644 --- a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/DashUtilTest.java +++ b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/DashUtilTest.java @@ -85,7 +85,8 @@ public final class DashUtilTest { /* height= */ 768, Format.NO_VALUE, /* initializationData= */ null, - /* selectionFlags= */ 0); + /* selectionFlags= */ 0, + /* roleFlags= */ 0); if (drmInitData != null) { format = format.copyWithDrmInitData(drmInitData); } 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 3465bfe6a9..e4e0245605 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 @@ -741,8 +741,8 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper /* sampleRate= */ Format.NO_VALUE, /* initializationData= */ null, selectionFlags, - language, - /* roleFlags= */ 0); + /* roleFlags= */ 0, + language); } } diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsMasterPlaylist.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsMasterPlaylist.java index ac14ea6de5..0e7f07cd7c 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsMasterPlaylist.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsMasterPlaylist.java @@ -78,6 +78,7 @@ public final class HlsMasterPlaylist extends HlsPlaylist { /* codecs= */ null, /* bitrate= */ Format.NO_VALUE, /* selectionFlags= */ 0, + /* roleFlags= */ 0, /* language= */ null); return new HlsUrl(url, format, /* name= */ ""); } 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 31528353ee..177c9aaeff 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 @@ -362,8 +362,8 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser { samplingRate, codecSpecificData, /* selectionFlags= */ 0, - language, - /* roleFlags= */ 0); + /* roleFlags= */ 0, + language); } else if (type == C.TRACK_TYPE_TEXT) { String language = (String) getNormalizedAttribute(KEY_LANGUAGE); format = @@ -730,6 +730,7 @@ public class SsManifestParser implements ParsingLoadable.Parser { /* codecs= */ null, bitrate, /* selectionFlags= */ 0, + /* roleFlags= */ 0, /* language= */ null); } }