Commit 33938c05 by Oliver Woodman Committed by GitHub

Merge pull request #6664 from google/dev-v2-r2.10.8

r2.10.8
parents d73d64bc 30f79a4c
Showing with 156 additions and 65 deletions
# Release notes # # Release notes #
### 2.10.7 (2019-11-12) ### ### 2.10.8 (2019-11-19) ###
* E-AC3 JOC
* Handle new signaling in DASH manifests
([#6636](https://github.com/google/ExoPlayer/issues/6636)).
* Fix E-AC3 JOC passthrough playback failing to initialize due to incorrect
channel count check.
* FLAC
* Fix sniffing for some FLAC streams.
* Fix FLAC `Format.bitrate` values.
* Parse ALAC channel count and sample rate information from a more robust source
when contained in MP4
([#6648](https://github.com/google/ExoPlayer/issues/6648)).
* Fix seeking into multi-period content in the edge case that the period
containing the seek position has just been removed
([#6641](https://github.com/google/ExoPlayer/issues/6641)).
### 2.10.7 (2019-11-06) ###
* HLS: Fix detection of Dolby Atmos to match the HLS authoring specification. * HLS: Fix detection of Dolby Atmos to match the HLS authoring specification.
* MediaSession extension: Update shuffle and repeat modes when playback state * MediaSession extension: Update shuffle and repeat modes when playback state
......
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
// limitations under the License. // limitations under the License.
project.ext { project.ext {
// ExoPlayer version and version code. // ExoPlayer version and version code.
releaseVersion = '2.10.7' releaseVersion = '2.10.8'
releaseVersionCode = 2010007 releaseVersionCode = 2010008
minSdkVersion = 16 minSdkVersion = 16
targetSdkVersion = 28 targetSdkVersion = 28
compileSdkVersion = 28 compileSdkVersion = 28
......
...@@ -5,7 +5,7 @@ seekMap: ...@@ -5,7 +5,7 @@ seekMap:
numberOfTracks = 1 numberOfTracks = 1
track 0: track 0:
format: format:
bitrate = 768000 bitrate = 1536000
id = null id = null
containerMimeType = null containerMimeType = null
sampleMimeType = audio/raw sampleMimeType = audio/raw
......
...@@ -5,7 +5,7 @@ seekMap: ...@@ -5,7 +5,7 @@ seekMap:
numberOfTracks = 1 numberOfTracks = 1
track 0: track 0:
format: format:
bitrate = 768000 bitrate = 1536000
id = null id = null
containerMimeType = null containerMimeType = null
sampleMimeType = audio/raw sampleMimeType = audio/raw
......
...@@ -5,7 +5,7 @@ seekMap: ...@@ -5,7 +5,7 @@ seekMap:
numberOfTracks = 1 numberOfTracks = 1
track 0: track 0:
format: format:
bitrate = 768000 bitrate = 1536000
id = null id = null
containerMimeType = null containerMimeType = null
sampleMimeType = audio/raw sampleMimeType = audio/raw
......
...@@ -5,7 +5,7 @@ seekMap: ...@@ -5,7 +5,7 @@ seekMap:
numberOfTracks = 1 numberOfTracks = 1
track 0: track 0:
format: format:
bitrate = 768000 bitrate = 1536000
id = null id = null
containerMimeType = null containerMimeType = null
sampleMimeType = audio/raw sampleMimeType = audio/raw
......
...@@ -5,7 +5,7 @@ seekMap: ...@@ -5,7 +5,7 @@ seekMap:
numberOfTracks = 1 numberOfTracks = 1
track 0: track 0:
format: format:
bitrate = 768000 bitrate = 1536000
id = null id = null
containerMimeType = null containerMimeType = null
sampleMimeType = audio/raw sampleMimeType = audio/raw
......
...@@ -5,7 +5,7 @@ seekMap: ...@@ -5,7 +5,7 @@ seekMap:
numberOfTracks = 1 numberOfTracks = 1
track 0: track 0:
format: format:
bitrate = 768000 bitrate = 1536000
id = null id = null
containerMimeType = null containerMimeType = null
sampleMimeType = audio/raw sampleMimeType = audio/raw
......
...@@ -5,7 +5,7 @@ seekMap: ...@@ -5,7 +5,7 @@ seekMap:
numberOfTracks = 1 numberOfTracks = 1
track 0: track 0:
format: format:
bitrate = 768000 bitrate = 1536000
id = null id = null
containerMimeType = null containerMimeType = null
sampleMimeType = audio/raw sampleMimeType = audio/raw
......
...@@ -5,7 +5,7 @@ seekMap: ...@@ -5,7 +5,7 @@ seekMap:
numberOfTracks = 1 numberOfTracks = 1
track 0: track 0:
format: format:
bitrate = 768000 bitrate = 1536000
id = null id = null
containerMimeType = null containerMimeType = null
sampleMimeType = audio/raw sampleMimeType = audio/raw
......
...@@ -72,11 +72,8 @@ public final class FlacExtractor implements Extractor { ...@@ -72,11 +72,8 @@ public final class FlacExtractor implements Extractor {
*/ */
public static final int FLAG_DISABLE_ID3_METADATA = 1; public static final int FLAG_DISABLE_ID3_METADATA = 1;
/** /** FLAC stream marker */
* FLAC signature: first 4 is the signature word, second 4 is the sizeof STREAMINFO. 0x22 is the private static final byte[] FLAC_STREAM_MARKER = {'f', 'L', 'a', 'C'};
* mandatory STREAMINFO.
*/
private static final byte[] FLAC_SIGNATURE = {'f', 'L', 'a', 'C', 0, 0, 0, 0x22};
private final ParsableByteArray outputBuffer; private final ParsableByteArray outputBuffer;
private final Id3Peeker id3Peeker; private final Id3Peeker id3Peeker;
...@@ -126,7 +123,7 @@ public final class FlacExtractor implements Extractor { ...@@ -126,7 +123,7 @@ public final class FlacExtractor implements Extractor {
if (input.getPosition() == 0) { if (input.getPosition() == 0) {
id3Metadata = peekId3Data(input); id3Metadata = peekId3Data(input);
} }
return peekFlacSignature(input); return peekFlacStreamMarker(input);
} }
@Override @Override
...@@ -255,15 +252,15 @@ public final class FlacExtractor implements Extractor { ...@@ -255,15 +252,15 @@ public final class FlacExtractor implements Extractor {
} }
/** /**
* Peeks from the beginning of the input to see if {@link #FLAC_SIGNATURE} is present. * Peeks from the beginning of the input to see if {@link #FLAC_STREAM_MARKER} is present.
* *
* @return Whether the input begins with {@link #FLAC_SIGNATURE}. * @return Whether the input begins with {@link #FLAC_STREAM_MARKER}.
*/ */
private static boolean peekFlacSignature(ExtractorInput input) private static boolean peekFlacStreamMarker(ExtractorInput input)
throws IOException, InterruptedException { throws IOException, InterruptedException {
byte[] header = new byte[FLAC_SIGNATURE.length]; byte[] header = new byte[FLAC_STREAM_MARKER.length];
input.peekFully(header, /* offset= */ 0, FLAC_SIGNATURE.length); input.peekFully(header, /* offset= */ 0, FLAC_STREAM_MARKER.length);
return Arrays.equals(header, FLAC_SIGNATURE); return Arrays.equals(header, FLAC_STREAM_MARKER);
} }
/** /**
......
...@@ -1433,6 +1433,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1433,6 +1433,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
* @throws IllegalSeekPositionException If the window index of the seek position is outside the * @throws IllegalSeekPositionException If the window index of the seek position is outside the
* bounds of the timeline. * bounds of the timeline.
*/ */
@Nullable
private Pair<Object, Long> resolveSeekPosition( private Pair<Object, Long> resolveSeekPosition(
SeekPosition seekPosition, boolean trySubsequentPeriods) { SeekPosition seekPosition, boolean trySubsequentPeriods) {
Timeline timeline = playbackInfo.timeline; Timeline timeline = playbackInfo.timeline;
...@@ -1467,11 +1468,12 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1467,11 +1468,12 @@ import java.util.concurrent.atomic.AtomicBoolean;
} }
if (trySubsequentPeriods) { if (trySubsequentPeriods) {
// Try and find a subsequent period from the seek timeline in the internal timeline. // Try and find a subsequent period from the seek timeline in the internal timeline.
@Nullable
Object periodUid = resolveSubsequentPeriod(periodPosition.first, seekTimeline, timeline); Object periodUid = resolveSubsequentPeriod(periodPosition.first, seekTimeline, timeline);
if (periodUid != null) { if (periodUid != null) {
// We found one. Map the SeekPosition onto the corresponding default position. // We found one. Use the default position of the corresponding window.
return getPeriodPosition( return getPeriodPosition(
timeline, timeline.getPeriod(periodIndex, period).windowIndex, C.TIME_UNSET); timeline, timeline.getPeriodByUid(periodUid, period).windowIndex, C.TIME_UNSET);
} }
} }
// We didn't find one. Give up. // We didn't find one. Give up.
......
...@@ -29,11 +29,11 @@ public final class ExoPlayerLibraryInfo { ...@@ -29,11 +29,11 @@ public final class ExoPlayerLibraryInfo {
/** The version of the library expressed as a string, for example "1.2.3". */ /** The version of the library expressed as a string, for example "1.2.3". */
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION_INT) or vice versa. // Intentionally hardcoded. Do not derive from other constants (e.g. VERSION_INT) or vice versa.
public static final String VERSION = "2.10.7"; public static final String VERSION = "2.10.8";
/** The version of the library expressed as {@code "ExoPlayerLib/" + VERSION}. */ /** The version of the library expressed as {@code "ExoPlayerLib/" + VERSION}. */
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa. // Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
public static final String VERSION_SLASHY = "ExoPlayerLib/2.10.7"; public static final String VERSION_SLASHY = "ExoPlayerLib/2.10.8";
/** /**
* The version of the library expressed as an integer, for example 1002003. * The version of the library expressed as an integer, for example 1002003.
...@@ -43,7 +43,7 @@ public final class ExoPlayerLibraryInfo { ...@@ -43,7 +43,7 @@ public final class ExoPlayerLibraryInfo {
* integer version 123045006 (123-045-006). * integer version 123045006 (123-045-006).
*/ */
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa. // Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
public static final int VERSION_INT = 2010007; public static final int VERSION_INT = 2010008;
/** /**
* Whether the library was compiled with {@link com.google.android.exoplayer2.util.Assertions} * Whether the library was compiled with {@link com.google.android.exoplayer2.util.Assertions}
......
...@@ -543,7 +543,8 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media ...@@ -543,7 +543,8 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
@C.Encoding @C.Encoding
protected int getPassthroughEncoding(int channelCount, String mimeType) { protected int getPassthroughEncoding(int channelCount, String mimeType) {
if (MimeTypes.AUDIO_E_AC3_JOC.equals(mimeType)) { if (MimeTypes.AUDIO_E_AC3_JOC.equals(mimeType)) {
if (audioSink.supportsOutput(channelCount, C.ENCODING_E_AC3_JOC)) { // E-AC3 JOC is object-based so the output channel count is arbitrary.
if (audioSink.supportsOutput(/* channelCount= */ Format.NO_VALUE, C.ENCODING_E_AC3_JOC)) {
return MimeTypes.getEncoding(MimeTypes.AUDIO_E_AC3_JOC); return MimeTypes.getEncoding(MimeTypes.AUDIO_E_AC3_JOC);
} }
// E-AC3 receivers can decode JOC streams, but in 2-D rather than 3-D, so try to fall back. // E-AC3 receivers can decode JOC streams, but in 2-D rather than 3-D, so try to fall back.
......
...@@ -1114,8 +1114,8 @@ import java.util.List; ...@@ -1114,8 +1114,8 @@ import java.util.List;
mimeType = mimeTypeAndInitializationData.first; mimeType = mimeTypeAndInitializationData.first;
initializationData = mimeTypeAndInitializationData.second; initializationData = mimeTypeAndInitializationData.second;
if (MimeTypes.AUDIO_AAC.equals(mimeType)) { if (MimeTypes.AUDIO_AAC.equals(mimeType)) {
// TODO: Do we really need to do this? See [Internal: b/10903778] // Update sampleRate and channelCount from the AudioSpecificConfig initialization data,
// Update sampleRate and channelCount from the AudioSpecificConfig initialization data. // which is more reliable. See [Internal: b/10903778].
Pair<Integer, Integer> audioSpecificConfig = Pair<Integer, Integer> audioSpecificConfig =
CodecSpecificDataUtil.parseAacAudioSpecificConfig(initializationData); CodecSpecificDataUtil.parseAacAudioSpecificConfig(initializationData);
sampleRate = audioSpecificConfig.first; sampleRate = audioSpecificConfig.first;
...@@ -1160,6 +1160,12 @@ import java.util.List; ...@@ -1160,6 +1160,12 @@ import java.util.List;
initializationData = new byte[childAtomBodySize]; initializationData = new byte[childAtomBodySize];
parent.setPosition(childPosition + Atom.FULL_HEADER_SIZE); parent.setPosition(childPosition + Atom.FULL_HEADER_SIZE);
parent.readBytes(initializationData, /* offset= */ 0, childAtomBodySize); parent.readBytes(initializationData, /* offset= */ 0, childAtomBodySize);
// Update sampleRate and channelCount from the AudioSpecificConfig initialization data,
// which is more reliable. See https://github.com/google/ExoPlayer/pull/6629.
Pair<Integer, Integer> audioSpecificConfig =
CodecSpecificDataUtil.parseAlacAudioSpecificConfig(initializationData);
sampleRate = audioSpecificConfig.first;
channelCount = audioSpecificConfig.second;
} }
childPosition += childAtomSize; childPosition += childAtomSize;
} }
......
...@@ -73,6 +73,8 @@ import java.util.List; ...@@ -73,6 +73,8 @@ import java.util.List;
byte[] data = packet.data; byte[] data = packet.data;
if (streamMetadata == null) { if (streamMetadata == null) {
streamMetadata = new FlacStreamMetadata(data, 17); streamMetadata = new FlacStreamMetadata(data, 17);
int maxInputSize =
streamMetadata.maxFrameSize == 0 ? Format.NO_VALUE : streamMetadata.maxFrameSize;
byte[] metadata = Arrays.copyOfRange(data, 9, packet.limit()); byte[] metadata = Arrays.copyOfRange(data, 9, packet.limit());
metadata[4] = (byte) 0x80; // Set the last metadata block flag, ignore the other blocks metadata[4] = (byte) 0x80; // Set the last metadata block flag, ignore the other blocks
List<byte[]> initializationData = Collections.singletonList(metadata); List<byte[]> initializationData = Collections.singletonList(metadata);
...@@ -82,7 +84,7 @@ import java.util.List; ...@@ -82,7 +84,7 @@ import java.util.List;
MimeTypes.AUDIO_FLAC, MimeTypes.AUDIO_FLAC,
/* codecs= */ null, /* codecs= */ null,
streamMetadata.bitRate(), streamMetadata.bitRate(),
/* maxInputSize= */ Format.NO_VALUE, maxInputSize,
streamMetadata.channels, streamMetadata.channels,
streamMetadata.sampleRate, streamMetadata.sampleRate,
initializationData, initializationData,
......
...@@ -83,7 +83,7 @@ public final class CodecSpecificDataUtil { ...@@ -83,7 +83,7 @@ public final class CodecSpecificDataUtil {
private CodecSpecificDataUtil() {} private CodecSpecificDataUtil() {}
/** /**
* Parses an AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1 * Parses an AAC AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1
* *
* @param audioSpecificConfig A byte array containing the AudioSpecificConfig to parse. * @param audioSpecificConfig A byte array containing the AudioSpecificConfig to parse.
* @return A pair consisting of the sample rate in Hz and the channel count. * @return A pair consisting of the sample rate in Hz and the channel count.
...@@ -95,7 +95,7 @@ public final class CodecSpecificDataUtil { ...@@ -95,7 +95,7 @@ public final class CodecSpecificDataUtil {
} }
/** /**
* Parses an AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1 * Parses an AAC AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1
* *
* @param bitArray A {@link ParsableBitArray} containing the AudioSpecificConfig to parse. The * @param bitArray A {@link ParsableBitArray} containing the AudioSpecificConfig to parse. The
* position is advanced to the end of the AudioSpecificConfig. * position is advanced to the end of the AudioSpecificConfig.
...@@ -104,8 +104,8 @@ public final class CodecSpecificDataUtil { ...@@ -104,8 +104,8 @@ public final class CodecSpecificDataUtil {
* @return A pair consisting of the sample rate in Hz and the channel count. * @return A pair consisting of the sample rate in Hz and the channel count.
* @throws ParserException If the AudioSpecificConfig cannot be parsed as it's not supported. * @throws ParserException If the AudioSpecificConfig cannot be parsed as it's not supported.
*/ */
public static Pair<Integer, Integer> parseAacAudioSpecificConfig(ParsableBitArray bitArray, public static Pair<Integer, Integer> parseAacAudioSpecificConfig(
boolean forceReadToEnd) throws ParserException { ParsableBitArray bitArray, boolean forceReadToEnd) throws ParserException {
int audioObjectType = getAacAudioObjectType(bitArray); int audioObjectType = getAacAudioObjectType(bitArray);
int sampleRate = getAacSamplingFrequency(bitArray); int sampleRate = getAacSamplingFrequency(bitArray);
int channelConfiguration = bitArray.readBits(4); int channelConfiguration = bitArray.readBits(4);
...@@ -166,10 +166,10 @@ public final class CodecSpecificDataUtil { ...@@ -166,10 +166,10 @@ public final class CodecSpecificDataUtil {
* Builds a simple HE-AAC LC AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1 * 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 sampleRate The sample rate in Hz.
* @param numChannels The number of channels. * @param channelCount The channel count.
* @return The AudioSpecificConfig. * @return The AudioSpecificConfig.
*/ */
public static byte[] buildAacLcAudioSpecificConfig(int sampleRate, int numChannels) { public static byte[] buildAacLcAudioSpecificConfig(int sampleRate, int channelCount) {
int sampleRateIndex = C.INDEX_UNSET; int sampleRateIndex = C.INDEX_UNSET;
for (int i = 0; i < AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE.length; ++i) { for (int i = 0; i < AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE.length; ++i) {
if (sampleRate == AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE[i]) { if (sampleRate == AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE[i]) {
...@@ -178,13 +178,13 @@ public final class CodecSpecificDataUtil { ...@@ -178,13 +178,13 @@ public final class CodecSpecificDataUtil {
} }
int channelConfig = C.INDEX_UNSET; int channelConfig = C.INDEX_UNSET;
for (int i = 0; i < AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE.length; ++i) { for (int i = 0; i < AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE.length; ++i) {
if (numChannels == AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE[i]) { if (channelCount == AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE[i]) {
channelConfig = i; channelConfig = i;
} }
} }
if (sampleRate == C.INDEX_UNSET || channelConfig == C.INDEX_UNSET) { if (sampleRate == C.INDEX_UNSET || channelConfig == C.INDEX_UNSET) {
throw new IllegalArgumentException("Invalid sample rate or number of channels: " throw new IllegalArgumentException(
+ sampleRate + ", " + numChannels); "Invalid sample rate or number of channels: " + sampleRate + ", " + channelCount);
} }
return buildAacAudioSpecificConfig(AUDIO_OBJECT_TYPE_AAC_LC, sampleRateIndex, channelConfig); return buildAacAudioSpecificConfig(AUDIO_OBJECT_TYPE_AAC_LC, sampleRateIndex, channelConfig);
} }
...@@ -206,6 +206,22 @@ public final class CodecSpecificDataUtil { ...@@ -206,6 +206,22 @@ public final class CodecSpecificDataUtil {
} }
/** /**
* Parses an ALAC AudioSpecificConfig (i.e. an <a
* href="https://github.com/macosforge/alac/blob/master/ALACMagicCookieDescription.txt">ALACSpecificConfig</a>).
*
* @param audioSpecificConfig A byte array containing the AudioSpecificConfig to parse.
* @return A pair consisting of the sample rate in Hz and the channel count.
*/
public static Pair<Integer, Integer> parseAlacAudioSpecificConfig(byte[] audioSpecificConfig) {
ParsableByteArray byteArray = new ParsableByteArray(audioSpecificConfig);
byteArray.setPosition(9);
int channelCount = byteArray.readUnsignedByte();
byteArray.setPosition(20);
int sampleRate = byteArray.readUnsignedIntToInt();
return Pair.create(sampleRate, channelCount);
}
/**
* Builds an RFC 6381 AVC codec string using the provided parameters. * Builds an RFC 6381 AVC codec string using the provided parameters.
* *
* @param profileIdc The encoding profile. * @param profileIdc The encoding profile.
......
...@@ -109,7 +109,7 @@ public final class FlacStreamMetadata { ...@@ -109,7 +109,7 @@ public final class FlacStreamMetadata {
/** Returns the bit-rate of the FLAC stream. */ /** Returns the bit-rate of the FLAC stream. */
public int bitRate() { public int bitRate() {
return bitsPerSample * sampleRate; return bitsPerSample * sampleRate * channels;
} }
/** Returns the duration of the FLAC stream in microseconds. */ /** Returns the duration of the FLAC stream in microseconds. */
......
...@@ -36,7 +36,7 @@ public final class DolbyVisionConfig { ...@@ -36,7 +36,7 @@ public final class DolbyVisionConfig {
int dvProfile = (profileData >> 1); int dvProfile = (profileData >> 1);
int dvLevel = ((profileData & 0x1) << 5) | ((data.readUnsignedByte() >> 3) & 0x1F); int dvLevel = ((profileData & 0x1) << 5) | ((data.readUnsignedByte() >> 3) & 0x1F);
String codecsPrefix; String codecsPrefix;
if (dvProfile == 4 || dvProfile == 5) { if (dvProfile == 4 || dvProfile == 5 || dvProfile == 7) {
codecsPrefix = "dvhe"; codecsPrefix = "dvhe";
} else if (dvProfile == 8) { } else if (dvProfile == 8) {
codecsPrefix = "hev1"; codecsPrefix = "hev1";
......
...@@ -5,11 +5,11 @@ seekMap: ...@@ -5,11 +5,11 @@ seekMap:
numberOfTracks = 1 numberOfTracks = 1
track 0: track 0:
format: format:
bitrate = 768000 bitrate = 1536000
id = null id = null
containerMimeType = null containerMimeType = null
sampleMimeType = audio/flac sampleMimeType = audio/flac
maxInputSize = -1 maxInputSize = 5776
width = -1 width = -1
height = -1 height = -1
frameRate = -1.0 frameRate = -1.0
......
...@@ -5,11 +5,11 @@ seekMap: ...@@ -5,11 +5,11 @@ seekMap:
numberOfTracks = 1 numberOfTracks = 1
track 0: track 0:
format: format:
bitrate = 768000 bitrate = 1536000
id = null id = null
containerMimeType = null containerMimeType = null
sampleMimeType = audio/flac sampleMimeType = audio/flac
maxInputSize = -1 maxInputSize = 5776
width = -1 width = -1
height = -1 height = -1
frameRate = -1.0 frameRate = -1.0
......
...@@ -5,11 +5,11 @@ seekMap: ...@@ -5,11 +5,11 @@ seekMap:
numberOfTracks = 1 numberOfTracks = 1
track 0: track 0:
format: format:
bitrate = 768000 bitrate = 1536000
id = null id = null
containerMimeType = null containerMimeType = null
sampleMimeType = audio/flac sampleMimeType = audio/flac
maxInputSize = -1 maxInputSize = 5776
width = -1 width = -1
height = -1 height = -1
frameRate = -1.0 frameRate = -1.0
......
...@@ -5,11 +5,11 @@ seekMap: ...@@ -5,11 +5,11 @@ seekMap:
numberOfTracks = 1 numberOfTracks = 1
track 0: track 0:
format: format:
bitrate = 768000 bitrate = 1536000
id = null id = null
containerMimeType = null containerMimeType = null
sampleMimeType = audio/flac sampleMimeType = audio/flac
maxInputSize = -1 maxInputSize = 5776
width = -1 width = -1
height = -1 height = -1
frameRate = -1.0 frameRate = -1.0
......
...@@ -5,11 +5,11 @@ seekMap: ...@@ -5,11 +5,11 @@ seekMap:
numberOfTracks = 1 numberOfTracks = 1
track 0: track 0:
format: format:
bitrate = 768000 bitrate = 1536000
id = null id = null
containerMimeType = null containerMimeType = null
sampleMimeType = audio/flac sampleMimeType = audio/flac
maxInputSize = -1 maxInputSize = 5776
width = -1 width = -1
height = -1 height = -1
frameRate = -1.0 frameRate = -1.0
......
...@@ -5,11 +5,11 @@ seekMap: ...@@ -5,11 +5,11 @@ seekMap:
numberOfTracks = 1 numberOfTracks = 1
track 0: track 0:
format: format:
bitrate = 768000 bitrate = 1536000
id = null id = null
containerMimeType = null containerMimeType = null
sampleMimeType = audio/flac sampleMimeType = audio/flac
maxInputSize = -1 maxInputSize = 5776
width = -1 width = -1
height = -1 height = -1
frameRate = -1.0 frameRate = -1.0
......
...@@ -5,11 +5,11 @@ seekMap: ...@@ -5,11 +5,11 @@ seekMap:
numberOfTracks = 1 numberOfTracks = 1
track 0: track 0:
format: format:
bitrate = 768000 bitrate = 1536000
id = null id = null
containerMimeType = null containerMimeType = null
sampleMimeType = audio/flac sampleMimeType = audio/flac
maxInputSize = -1 maxInputSize = 5776
width = -1 width = -1
height = -1 height = -1
frameRate = -1.0 frameRate = -1.0
......
...@@ -5,11 +5,11 @@ seekMap: ...@@ -5,11 +5,11 @@ seekMap:
numberOfTracks = 1 numberOfTracks = 1
track 0: track 0:
format: format:
bitrate = 768000 bitrate = 1536000
id = null id = null
containerMimeType = null containerMimeType = null
sampleMimeType = audio/flac sampleMimeType = audio/flac
maxInputSize = -1 maxInputSize = 5776
width = -1 width = -1
height = -1 height = -1
frameRate = -1.0 frameRate = -1.0
......
...@@ -5,11 +5,11 @@ seekMap: ...@@ -5,11 +5,11 @@ seekMap:
numberOfTracks = 1 numberOfTracks = 1
track 0: track 0:
format: format:
bitrate = 768000 bitrate = 1536000
id = null id = null
containerMimeType = null containerMimeType = null
sampleMimeType = audio/flac sampleMimeType = audio/flac
maxInputSize = -1 maxInputSize = 5776
width = -1 width = -1
height = -1 height = -1
frameRate = -1.0 frameRate = -1.0
......
...@@ -5,11 +5,11 @@ seekMap: ...@@ -5,11 +5,11 @@ seekMap:
numberOfTracks = 1 numberOfTracks = 1
track 0: track 0:
format: format:
bitrate = 768000 bitrate = 1536000
id = null id = null
containerMimeType = null containerMimeType = null
sampleMimeType = audio/flac sampleMimeType = audio/flac
maxInputSize = -1 maxInputSize = 5776
width = -1 width = -1
height = -1 height = -1
frameRate = -1.0 frameRate = -1.0
......
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.util;
import static com.google.common.truth.Truth.assertThat;
import android.util.Pair;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Unit test for {@link CodecSpecificDataUtil}. */
@RunWith(AndroidJUnit4.class)
public class CodecSpecificDataUtilTest {
@Test
public void parseAlacAudioSpecificConfig() {
byte[] alacSpecificConfig =
new byte[] {
0, 0, 16, 0, // frameLength
0, // compatibleVersion
16, // bitDepth
40, 10, 14, // tuning parameters
2, // numChannels = 2
0, 0, // maxRun
0, 0, 64, 4, // maxFrameBytes
0, 46, -32, 0, // avgBitRate
0, 1, 119, 0, // sampleRate = 96000
};
Pair<Integer, Integer> sampleRateAndChannelCount =
CodecSpecificDataUtil.parseAlacAudioSpecificConfig(alacSpecificConfig);
assertThat(sampleRateAndChannelCount.first).isEqualTo(96000);
assertThat(sampleRateAndChannelCount.second).isEqualTo(2);
}
}
...@@ -1417,8 +1417,10 @@ public class DashManifestParser extends DefaultHandler ...@@ -1417,8 +1417,10 @@ public class DashManifestParser extends DefaultHandler
for (int i = 0; i < supplementalProperties.size(); i++) { for (int i = 0; i < supplementalProperties.size(); i++) {
Descriptor descriptor = supplementalProperties.get(i); Descriptor descriptor = supplementalProperties.get(i);
String schemeIdUri = descriptor.schemeIdUri; String schemeIdUri = descriptor.schemeIdUri;
if ("tag:dolby.com,2014:dash:DolbyDigitalPlusExtensionType:2014".equals(schemeIdUri) if (("tag:dolby.com,2018:dash:EC3_ExtensionComplexityIndex:2018".equals(schemeIdUri)
&& "ec+3".equals(descriptor.value)) { && "JOC".equals(descriptor.value))
|| ("tag:dolby.com,2014:dash:DolbyDigitalPlusExtensionType:2014".equals(schemeIdUri)
&& "ec+3".equals(descriptor.value))) {
return MimeTypes.AUDIO_E_AC3_JOC; return MimeTypes.AUDIO_E_AC3_JOC;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment