diff --git a/library/common/src/main/java/com/google/android/exoplayer2/util/CodecSpecificDataUtil.java b/library/common/src/main/java/com/google/android/exoplayer2/util/CodecSpecificDataUtil.java index 4a2959a5c8..55907e4137 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/util/CodecSpecificDataUtil.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/util/CodecSpecificDataUtil.java @@ -288,7 +288,8 @@ public final class CodecSpecificDataUtil { * @return The individual NAL units, or null if the input did not consist of NAL start code * delimited units. */ - public static @Nullable byte[][] splitNalUnits(byte[] data) { + @Nullable + public static byte[][] splitNalUnits(byte[] data) { if (!isNalStartCode(data, 0)) { // data does not consist of NAL start code delimited units. return null; diff --git a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/manifest/SsManifestParser.java b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/manifest/SsManifestParser.java index d395e95fd9..a95cb7bcba 100644 --- a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/manifest/SsManifestParser.java +++ b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/manifest/SsManifestParser.java @@ -663,96 +663,65 @@ public class SsManifestParser implements ParsingLoadable.Parser { @Override public void parseStartTag(XmlPullParser parser) throws ParserException { - int type = (Integer) getNormalizedAttribute(KEY_TYPE); - String id = parser.getAttributeValue(null, KEY_INDEX); - String name = (String) getNormalizedAttribute(KEY_NAME); - int bitrate = parseRequiredInt(parser, KEY_BITRATE); - String sampleMimeType = fourCCToMimeType(parseRequiredString(parser, KEY_FOUR_CC)); + Format.Builder formatBuilder = new Format.Builder(); + @Nullable String sampleMimeType = fourCCToMimeType(parseRequiredString(parser, KEY_FOUR_CC)); + int type = (Integer) getNormalizedAttribute(KEY_TYPE); if (type == C.TRACK_TYPE_VIDEO) { - int width = parseRequiredInt(parser, KEY_MAX_WIDTH); - int height = parseRequiredInt(parser, KEY_MAX_HEIGHT); List codecSpecificData = buildCodecSpecificData( parser.getAttributeValue(null, KEY_CODEC_PRIVATE_DATA)); - format = - Format.createVideoContainerFormat( - id, - name, - MimeTypes.VIDEO_MP4, - sampleMimeType, - /* codecs= */ null, - /* metadata= */ null, - bitrate, - width, - height, - /* frameRate= */ Format.NO_VALUE, - codecSpecificData, - /* selectionFlags= */ 0, - /* roleFlags= */ 0); + formatBuilder + .setContainerMimeType(MimeTypes.VIDEO_MP4) + .setWidth(parseRequiredInt(parser, KEY_MAX_WIDTH)) + .setHeight(parseRequiredInt(parser, KEY_MAX_HEIGHT)) + .setInitializationData(codecSpecificData); } else if (type == C.TRACK_TYPE_AUDIO) { - sampleMimeType = sampleMimeType == null ? MimeTypes.AUDIO_AAC : sampleMimeType; - int channels = parseRequiredInt(parser, KEY_CHANNELS); - int samplingRate = parseRequiredInt(parser, KEY_SAMPLING_RATE); + if (sampleMimeType == null) { + // If we don't know the MIME type, assume AAC. + sampleMimeType = MimeTypes.AUDIO_AAC; + } + int channelCount = parseRequiredInt(parser, KEY_CHANNELS); + int sampleRate = parseRequiredInt(parser, KEY_SAMPLING_RATE); List codecSpecificData = buildCodecSpecificData( parser.getAttributeValue(null, KEY_CODEC_PRIVATE_DATA)); if (codecSpecificData.isEmpty() && MimeTypes.AUDIO_AAC.equals(sampleMimeType)) { - codecSpecificData = Collections.singletonList( - CodecSpecificDataUtil.buildAacLcAudioSpecificConfig(samplingRate, channels)); + codecSpecificData = + Collections.singletonList( + CodecSpecificDataUtil.buildAacLcAudioSpecificConfig(sampleRate, channelCount)); } - String language = (String) getNormalizedAttribute(KEY_LANGUAGE); - format = - Format.createAudioContainerFormat( - id, - name, - MimeTypes.AUDIO_MP4, - sampleMimeType, - /* codecs= */ null, - /* metadata= */ null, - bitrate, - channels, - samplingRate, - codecSpecificData, - /* selectionFlags= */ 0, - /* roleFlags= */ 0, - language); + formatBuilder + .setContainerMimeType(MimeTypes.AUDIO_MP4) + .setChannelCount(channelCount) + .setSampleRate(sampleRate) + .setInitializationData(codecSpecificData); } else if (type == C.TRACK_TYPE_TEXT) { - String subType = (String) getNormalizedAttribute(KEY_SUB_TYPE); @C.RoleFlags int roleFlags = 0; - switch (subType) { - case "CAPT": - roleFlags = C.ROLE_FLAG_CAPTION; - break; - case "DESC": - roleFlags = C.ROLE_FLAG_DESCRIBES_MUSIC_AND_SOUND; - break; - default: - break; + @Nullable String subType = (String) getNormalizedAttribute(KEY_SUB_TYPE); + if (subType != null) { + switch (subType) { + case "CAPT": + roleFlags = C.ROLE_FLAG_CAPTION; + break; + case "DESC": + roleFlags = C.ROLE_FLAG_DESCRIBES_MUSIC_AND_SOUND; + break; + default: + break; + } } - String language = (String) getNormalizedAttribute(KEY_LANGUAGE); - format = - Format.createTextContainerFormat( - id, - name, - MimeTypes.APPLICATION_MP4, - sampleMimeType, - /* codecs= */ null, - bitrate, - /* selectionFlags= */ 0, - roleFlags, - language); + formatBuilder.setContainerMimeType(MimeTypes.APPLICATION_MP4).setRoleFlags(roleFlags); } else { - format = - Format.createContainerFormat( - id, - name, - MimeTypes.APPLICATION_MP4, - sampleMimeType, - /* codecs= */ null, - bitrate, - /* selectionFlags= */ 0, - /* roleFlags= */ 0, - /* language= */ null); + formatBuilder.setContainerMimeType(MimeTypes.APPLICATION_MP4); } + + format = + formatBuilder + .setId(parser.getAttributeValue(null, KEY_INDEX)) + .setLabel((String) getNormalizedAttribute(KEY_NAME)) + .setSampleMimeType(sampleMimeType) + .setAverageBitrate(parseRequiredInt(parser, KEY_BITRATE)) + .setLanguage((String) getNormalizedAttribute(KEY_LANGUAGE)) + .build(); } @Override @@ -764,7 +733,7 @@ public class SsManifestParser implements ParsingLoadable.Parser { ArrayList csd = new ArrayList<>(); if (!TextUtils.isEmpty(codecSpecificDataString)) { byte[] codecPrivateData = Util.getBytesFromHexString(codecSpecificDataString); - byte[][] split = CodecSpecificDataUtil.splitNalUnits(codecPrivateData); + @Nullable byte[][] split = CodecSpecificDataUtil.splitNalUnits(codecPrivateData); if (split == null) { csd.add(codecPrivateData); } else { @@ -774,6 +743,7 @@ public class SsManifestParser implements ParsingLoadable.Parser { return csd; } + @Nullable private static String fourCCToMimeType(String fourCC) { if (fourCC.equalsIgnoreCase("H264") || fourCC.equalsIgnoreCase("X264") || fourCC.equalsIgnoreCase("AVC1") || fourCC.equalsIgnoreCase("DAVC")) {