diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/Ac3Util.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/Ac3Util.java index bc46a4f10a..e1a70e2579 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/audio/Ac3Util.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/Ac3Util.java @@ -33,13 +33,31 @@ public final class Ac3Util { */ public static final class Ac3SyncFrameInfo { + /** + * Undefined AC3 stream type. + */ + public static final int STREAM_TYPE_UNDEFINED = -1; + /** + * Type 0 AC3 stream type. See ETSI TS 102 366 E.1.3.1.1. + */ + public static final int STREAM_TYPE_TYPE0 = 0; + /** + * Type 1 AC3 stream type. See ETSI TS 102 366 E.1.3.1.1. + */ + public static final int STREAM_TYPE_TYPE1 = 1; + /** + * Type 2 AC3 stream type. See ETSI TS 102 366 E.1.3.1.1. + */ + public static final int STREAM_TYPE_TYPE2 = 2; + /** * The sample mime type of the bitstream. One of {@link MimeTypes#AUDIO_AC3} and * {@link MimeTypes#AUDIO_E_AC3}. */ public final String mimeType; /** - * The type of the bitstream, only for AUDIO_E_AC3 + * The type of the stream if {@link #mimeType} is {@link MimeTypes#AUDIO_E_AC3}, or + * {@link #STREAM_TYPE_UNDEFINED} otherwise. */ public final int streamType; /** @@ -106,13 +124,6 @@ public final class Ac3Util { private static final int[] SYNCFRAME_SIZE_WORDS_BY_HALF_FRMSIZECOD_44_1 = new int[] {69, 87, 104, 121, 139, 174, 208, 243, 278, 348, 417, 487, 557, 696, 835, 975, 1114, 1253, 1393}; - /** - * Stream type. See ETSI TS 102 366 E.1.3.1.1. - */ - public static final int STREAM_TYPE_UNDEFINED = -1; - public static final int STREAM_TYPE_TYPE0 = 0; - public static final int STREAM_TYPE_TYPE1 = 1; - /** * Returns the AC-3 format given {@code data} containing the AC3SpecificBox according to * ETSI TS 102 366 Annex F. The reading position of {@code data} will be modified. @@ -150,8 +161,7 @@ public final class Ac3Util { String language, DrmInitData drmInitData) { data.skipBytes(2); // data_rate, num_ind_sub - // Read only the first independent substream. - // TODO: Read later independent substreams? + // Read the first independent substream. int fscod = (data.readUnsignedByte() & 0xC0) >> 6; int sampleRate = SAMPLE_RATE_BY_FSCOD[fscod]; int nextByte = data.readUnsignedByte(); @@ -160,8 +170,7 @@ public final class Ac3Util { channelCount++; } - // Read only the first dependent substream. - // TODO: Read later dependent substreams? + // Read the first dependent substream. nextByte = data.readUnsignedByte(); int numDepSub = ((nextByte & 0x1E) >> 1); if (numDepSub > 0) { @@ -189,7 +198,7 @@ public final class Ac3Util { boolean isEac3 = data.readBits(5) == 16; data.setPosition(initialPosition); String mimeType; - int streamType; + int streamType = Ac3SyncFrameInfo.STREAM_TYPE_UNDEFINED; int sampleRate; int acmod; int frameSize; @@ -215,7 +224,6 @@ public final class Ac3Util { } else /* is AC-3 */ { mimeType = MimeTypes.AUDIO_AC3; data.skipBits(16 + 16); // syncword, crc1 - streamType = STREAM_TYPE_UNDEFINED; // AC-3 stream hasn't streamType int fscod = data.readBits(2); int frmsizecod = data.readBits(6); frameSize = getAc3SyncframeSize(fscod, frmsizecod); @@ -235,8 +243,8 @@ public final class Ac3Util { } boolean lfeon = data.readBit(); int channelCount = CHANNEL_COUNT_BY_ACMOD[acmod] + (lfeon ? 1 : 0); - return new Ac3SyncFrameInfo(mimeType, streamType, channelCount, sampleRate, - frameSize, sampleCount); + return new Ac3SyncFrameInfo(mimeType, streamType, channelCount, sampleRate, frameSize, + sampleCount); } /** 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 a34d248006..2e85f3a1ad 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 @@ -690,9 +690,9 @@ public class DashManifestParser extends DefaultHandler throws XmlPullParserException, IOException { String schemeIdUri = parseString(xpp, "schemeIdUri", null); int audioChannels = "urn:mpeg:dash:23003:3:audio_channel_configuration:2011".equals(schemeIdUri) - ? parseInt(xpp, "value", Format.NO_VALUE) : - ("tag:dolby.com,2014:dash:audio_channel_configuration:2011".equals(schemeIdUri) - ? parseDolbyChannelConfiguration(xpp, "value", Format.NO_VALUE) : Format.NO_VALUE); + ? parseInt(xpp, "value", Format.NO_VALUE) + : ("tag:dolby.com,2014:dash:audio_channel_configuration:2011".equals(schemeIdUri) + ? parseDolbyChannelConfiguration(xpp) : Format.NO_VALUE); do { xpp.next(); } while (!XmlPullParserUtil.isEndTag(xpp, "AudioChannelConfiguration")); @@ -903,31 +903,32 @@ public class DashManifestParser extends DefaultHandler return value == null ? defaultValue : value; } - protected static int parseDolbyChannelConfiguration(XmlPullParser xpp, String name, - int defaultValue) { - String value = Util.toLowerInvariant(xpp.getAttributeValue(null, name)); + /** + * Parses the number of channels from the value attribute of an AudioElementConfiguration with + * schemeIdUri "tag:dolby.com,2014:dash:audio_channel_configuration:2011", as defined by table E.5 + * in ETSI TS 102 366. + * + * @param xpp The parser from which to read. + * @return The parsed number of channels, or {@link Format#NO_VALUE} if the channel count could + * not be parsed. + */ + protected static int parseDolbyChannelConfiguration(XmlPullParser xpp) { + String value = Util.toLowerInvariant(xpp.getAttributeValue(null, "value")); if (value == null) { - return defaultValue; + return Format.NO_VALUE; } - int channels; - // TODO: Parse other channel configurations switch (value) { case "4000": - channels = 1; - break; + return 1; case "a000": - channels = 2; - break; + return 2; case "f801": - channels = 6; - break; + return 6; case "fa01": - channels = 8; - break; + return 8; default: - channels = defaultValue; + return Format.NO_VALUE; } - return channels; } private static final class RepresentationInfo {