From 42efb5413a095080f69a8b82e307f0d931a92f40 Mon Sep 17 00:00:00 2001 From: olly Date: Wed, 24 Aug 2016 10:50:18 -0700 Subject: [PATCH] SmoothStreaming fixes - The -1 needs to be a 0. My bad. - Create AAC CSD if not defined in manifest, like in V1. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=131190995 --- .../smoothstreaming/DefaultSsChunkSource.java | 2 +- .../manifest/SsManifestParser.java | 4 +++ .../util/CodecSpecificDataUtil.java | 29 +++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/library/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/DefaultSsChunkSource.java b/library/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/DefaultSsChunkSource.java index bb6e044c55..c4118d1de4 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/DefaultSsChunkSource.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/DefaultSsChunkSource.java @@ -95,7 +95,7 @@ public class DefaultSsChunkSource implements SsChunkSource { for (int i = 0; i < extractorWrappers.length; i++) { int manifestTrackIndex = trackSelection.getIndexInTrackGroup(i); Format format = streamElement.formats[manifestTrackIndex]; - int nalUnitLengthFieldLength = streamElement.type == C.TRACK_TYPE_VIDEO ? 4 : -1; + int nalUnitLengthFieldLength = streamElement.type == C.TRACK_TYPE_VIDEO ? 4 : 0; Track track = new Track(manifestTrackIndex, streamElement.type, streamElement.timescale, C.TIME_UNSET, manifest.durationUs, format, Track.TRANSFORMATION_NONE, trackEncryptionBoxes, nalUnitLengthFieldLength, null, null); diff --git a/library/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/manifest/SsManifestParser.java b/library/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/manifest/SsManifestParser.java index 9a7fa97b58..dc171f3f38 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/manifest/SsManifestParser.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/manifest/SsManifestParser.java @@ -633,6 +633,10 @@ public class SsManifestParser implements ParsingLoadable.Parser { int samplingRate = 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)); + } String language = (String) getNormalizedAttribute(KEY_LANGUAGE); format = Format.createAudioContainerFormat(id, MimeTypes.AUDIO_MP4, sampleMimeType, null, bitrate, channels, samplingRate, codecSpecificData, 0, language); diff --git a/library/src/main/java/com/google/android/exoplayer2/util/CodecSpecificDataUtil.java b/library/src/main/java/com/google/android/exoplayer2/util/CodecSpecificDataUtil.java index 91d90aabdf..f6f3e2a400 100644 --- a/library/src/main/java/com/google/android/exoplayer2/util/CodecSpecificDataUtil.java +++ b/library/src/main/java/com/google/android/exoplayer2/util/CodecSpecificDataUtil.java @@ -67,6 +67,8 @@ public final class CodecSpecificDataUtil { AUDIO_SPECIFIC_CONFIG_CHANNEL_CONFIGURATION_INVALID }; + // Advanced Audio Coding Low-Complexity profile. + private static final int AUDIO_OBJECT_TYPE_AAC_LC = 2; // Spectral Band Replication. private static final int AUDIO_OBJECT_TYPE_SBR = 5; // Error Resilient Bit-Sliced Arithmetic Coding. @@ -118,6 +120,33 @@ public final class CodecSpecificDataUtil { return Pair.create(sampleRate, channelCount); } + /** + * Builds a simple HE-AAC LC AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1 + * + * @param sampleRate The sample rate in Hz. + * @param numChannels The number of channels. + * @return The AudioSpecificConfig. + */ + public static byte[] buildAacLcAudioSpecificConfig(int sampleRate, int numChannels) { + int sampleRateIndex = C.INDEX_UNSET; + for (int i = 0; i < AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE.length; ++i) { + if (sampleRate == AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE[i]) { + sampleRateIndex = i; + } + } + int channelConfig = C.INDEX_UNSET; + for (int i = 0; i < AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE.length; ++i) { + if (numChannels == AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE[i]) { + channelConfig = i; + } + } + if (sampleRate == C.INDEX_UNSET || channelConfig == C.INDEX_UNSET) { + throw new IllegalArgumentException("Invalid sample rate or number of channels: " + + sampleRate + ", " + numChannels); + } + return buildAacAudioSpecificConfig(AUDIO_OBJECT_TYPE_AAC_LC, sampleRateIndex, channelConfig); + } + /** * Builds a simple AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1 *