Skip to content

Commit 33938c0

Browse files
authored
Merge pull request google#6664 from google/dev-v2-r2.10.8
r2.10.8
2 parents d73d64b + 30f79a4 commit 33938c0

31 files changed

+156
-65
lines changed

RELEASENOTES.md

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,23 @@
11
# Release notes #
22

3-
### 2.10.7 (2019-11-12) ###
3+
### 2.10.8 (2019-11-19) ###
4+
5+
* E-AC3 JOC
6+
* Handle new signaling in DASH manifests
7+
([#6636](https://github.com/google/ExoPlayer/issues/6636)).
8+
* Fix E-AC3 JOC passthrough playback failing to initialize due to incorrect
9+
channel count check.
10+
* FLAC
11+
* Fix sniffing for some FLAC streams.
12+
* Fix FLAC `Format.bitrate` values.
13+
* Parse ALAC channel count and sample rate information from a more robust source
14+
when contained in MP4
15+
([#6648](https://github.com/google/ExoPlayer/issues/6648)).
16+
* Fix seeking into multi-period content in the edge case that the period
17+
containing the seek position has just been removed
18+
([#6641](https://github.com/google/ExoPlayer/issues/6641)).
19+
20+
### 2.10.7 (2019-11-06) ###
421

522
* HLS: Fix detection of Dolby Atmos to match the HLS authoring specification.
623
* MediaSession extension: Update shuffle and repeat modes when playback state

constants.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
// limitations under the License.
1414
project.ext {
1515
// ExoPlayer version and version code.
16-
releaseVersion = '2.10.7'
17-
releaseVersionCode = 2010007
16+
releaseVersion = '2.10.8'
17+
releaseVersionCode = 2010008
1818
minSdkVersion = 16
1919
targetSdkVersion = 28
2020
compileSdkVersion = 28

extensions/flac/src/androidTest/assets/bear.flac.0.dump

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ seekMap:
55
numberOfTracks = 1
66
track 0:
77
format:
8-
bitrate = 768000
8+
bitrate = 1536000
99
id = null
1010
containerMimeType = null
1111
sampleMimeType = audio/raw

extensions/flac/src/androidTest/assets/bear.flac.1.dump

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ seekMap:
55
numberOfTracks = 1
66
track 0:
77
format:
8-
bitrate = 768000
8+
bitrate = 1536000
99
id = null
1010
containerMimeType = null
1111
sampleMimeType = audio/raw

extensions/flac/src/androidTest/assets/bear.flac.2.dump

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ seekMap:
55
numberOfTracks = 1
66
track 0:
77
format:
8-
bitrate = 768000
8+
bitrate = 1536000
99
id = null
1010
containerMimeType = null
1111
sampleMimeType = audio/raw

extensions/flac/src/androidTest/assets/bear.flac.3.dump

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ seekMap:
55
numberOfTracks = 1
66
track 0:
77
format:
8-
bitrate = 768000
8+
bitrate = 1536000
99
id = null
1010
containerMimeType = null
1111
sampleMimeType = audio/raw

extensions/flac/src/androidTest/assets/bear_with_id3.flac.0.dump

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ seekMap:
55
numberOfTracks = 1
66
track 0:
77
format:
8-
bitrate = 768000
8+
bitrate = 1536000
99
id = null
1010
containerMimeType = null
1111
sampleMimeType = audio/raw

extensions/flac/src/androidTest/assets/bear_with_id3.flac.1.dump

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ seekMap:
55
numberOfTracks = 1
66
track 0:
77
format:
8-
bitrate = 768000
8+
bitrate = 1536000
99
id = null
1010
containerMimeType = null
1111
sampleMimeType = audio/raw

extensions/flac/src/androidTest/assets/bear_with_id3.flac.2.dump

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ seekMap:
55
numberOfTracks = 1
66
track 0:
77
format:
8-
bitrate = 768000
8+
bitrate = 1536000
99
id = null
1010
containerMimeType = null
1111
sampleMimeType = audio/raw

extensions/flac/src/androidTest/assets/bear_with_id3.flac.3.dump

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ seekMap:
55
numberOfTracks = 1
66
track 0:
77
format:
8-
bitrate = 768000
8+
bitrate = 1536000
99
id = null
1010
containerMimeType = null
1111
sampleMimeType = audio/raw

extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacExtractor.java

+9-12
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,8 @@ public final class FlacExtractor implements Extractor {
7272
*/
7373
public static final int FLAG_DISABLE_ID3_METADATA = 1;
7474

75-
/**
76-
* FLAC signature: first 4 is the signature word, second 4 is the sizeof STREAMINFO. 0x22 is the
77-
* mandatory STREAMINFO.
78-
*/
79-
private static final byte[] FLAC_SIGNATURE = {'f', 'L', 'a', 'C', 0, 0, 0, 0x22};
75+
/** FLAC stream marker */
76+
private static final byte[] FLAC_STREAM_MARKER = {'f', 'L', 'a', 'C'};
8077

8178
private final ParsableByteArray outputBuffer;
8279
private final Id3Peeker id3Peeker;
@@ -126,7 +123,7 @@ public boolean sniff(ExtractorInput input) throws IOException, InterruptedExcept
126123
if (input.getPosition() == 0) {
127124
id3Metadata = peekId3Data(input);
128125
}
129-
return peekFlacSignature(input);
126+
return peekFlacStreamMarker(input);
130127
}
131128

132129
@Override
@@ -255,15 +252,15 @@ private int handlePendingSeek(
255252
}
256253

257254
/**
258-
* Peeks from the beginning of the input to see if {@link #FLAC_SIGNATURE} is present.
255+
* Peeks from the beginning of the input to see if {@link #FLAC_STREAM_MARKER} is present.
259256
*
260-
* @return Whether the input begins with {@link #FLAC_SIGNATURE}.
257+
* @return Whether the input begins with {@link #FLAC_STREAM_MARKER}.
261258
*/
262-
private static boolean peekFlacSignature(ExtractorInput input)
259+
private static boolean peekFlacStreamMarker(ExtractorInput input)
263260
throws IOException, InterruptedException {
264-
byte[] header = new byte[FLAC_SIGNATURE.length];
265-
input.peekFully(header, /* offset= */ 0, FLAC_SIGNATURE.length);
266-
return Arrays.equals(header, FLAC_SIGNATURE);
261+
byte[] header = new byte[FLAC_STREAM_MARKER.length];
262+
input.peekFully(header, /* offset= */ 0, FLAC_STREAM_MARKER.length);
263+
return Arrays.equals(header, FLAC_STREAM_MARKER);
267264
}
268265

269266
/**

library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -1433,6 +1433,7 @@ private void handleSourceInfoRefreshEndedPlayback() {
14331433
* @throws IllegalSeekPositionException If the window index of the seek position is outside the
14341434
* bounds of the timeline.
14351435
*/
1436+
@Nullable
14361437
private Pair<Object, Long> resolveSeekPosition(
14371438
SeekPosition seekPosition, boolean trySubsequentPeriods) {
14381439
Timeline timeline = playbackInfo.timeline;
@@ -1467,11 +1468,12 @@ private Pair<Object, Long> resolveSeekPosition(
14671468
}
14681469
if (trySubsequentPeriods) {
14691470
// Try and find a subsequent period from the seek timeline in the internal timeline.
1471+
@Nullable
14701472
Object periodUid = resolveSubsequentPeriod(periodPosition.first, seekTimeline, timeline);
14711473
if (periodUid != null) {
1472-
// We found one. Map the SeekPosition onto the corresponding default position.
1474+
// We found one. Use the default position of the corresponding window.
14731475
return getPeriodPosition(
1474-
timeline, timeline.getPeriod(periodIndex, period).windowIndex, C.TIME_UNSET);
1476+
timeline, timeline.getPeriodByUid(periodUid, period).windowIndex, C.TIME_UNSET);
14751477
}
14761478
}
14771479
// We didn't find one. Give up.

library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerLibraryInfo.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ public final class ExoPlayerLibraryInfo {
2929

3030
/** The version of the library expressed as a string, for example "1.2.3". */
3131
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION_INT) or vice versa.
32-
public static final String VERSION = "2.10.7";
32+
public static final String VERSION = "2.10.8";
3333

3434
/** The version of the library expressed as {@code "ExoPlayerLib/" + VERSION}. */
3535
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
36-
public static final String VERSION_SLASHY = "ExoPlayerLib/2.10.7";
36+
public static final String VERSION_SLASHY = "ExoPlayerLib/2.10.8";
3737

3838
/**
3939
* The version of the library expressed as an integer, for example 1002003.
@@ -43,7 +43,7 @@ public final class ExoPlayerLibraryInfo {
4343
* integer version 123045006 (123-045-006).
4444
*/
4545
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
46-
public static final int VERSION_INT = 2010007;
46+
public static final int VERSION_INT = 2010008;
4747

4848
/**
4949
* Whether the library was compiled with {@link com.google.android.exoplayer2.util.Assertions}

library/core/src/main/java/com/google/android/exoplayer2/audio/MediaCodecAudioRenderer.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,8 @@ protected void onOutputFormatChanged(MediaCodec codec, MediaFormat outputFormat)
543543
@C.Encoding
544544
protected int getPassthroughEncoding(int channelCount, String mimeType) {
545545
if (MimeTypes.AUDIO_E_AC3_JOC.equals(mimeType)) {
546-
if (audioSink.supportsOutput(channelCount, C.ENCODING_E_AC3_JOC)) {
546+
// E-AC3 JOC is object-based so the output channel count is arbitrary.
547+
if (audioSink.supportsOutput(/* channelCount= */ Format.NO_VALUE, C.ENCODING_E_AC3_JOC)) {
547548
return MimeTypes.getEncoding(MimeTypes.AUDIO_E_AC3_JOC);
548549
}
549550
// E-AC3 receivers can decode JOC streams, but in 2-D rather than 3-D, so try to fall back.

library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/AtomParsers.java

+8-2
Original file line numberDiff line numberDiff line change
@@ -1114,8 +1114,8 @@ private static void parseAudioSampleEntry(ParsableByteArray parent, int atomType
11141114
mimeType = mimeTypeAndInitializationData.first;
11151115
initializationData = mimeTypeAndInitializationData.second;
11161116
if (MimeTypes.AUDIO_AAC.equals(mimeType)) {
1117-
// TODO: Do we really need to do this? See [Internal: b/10903778]
1118-
// Update sampleRate and channelCount from the AudioSpecificConfig initialization data.
1117+
// Update sampleRate and channelCount from the AudioSpecificConfig initialization data,
1118+
// which is more reliable. See [Internal: b/10903778].
11191119
Pair<Integer, Integer> audioSpecificConfig =
11201120
CodecSpecificDataUtil.parseAacAudioSpecificConfig(initializationData);
11211121
sampleRate = audioSpecificConfig.first;
@@ -1160,6 +1160,12 @@ private static void parseAudioSampleEntry(ParsableByteArray parent, int atomType
11601160
initializationData = new byte[childAtomBodySize];
11611161
parent.setPosition(childPosition + Atom.FULL_HEADER_SIZE);
11621162
parent.readBytes(initializationData, /* offset= */ 0, childAtomBodySize);
1163+
// Update sampleRate and channelCount from the AudioSpecificConfig initialization data,
1164+
// which is more reliable. See https://github.com/google/ExoPlayer/pull/6629.
1165+
Pair<Integer, Integer> audioSpecificConfig =
1166+
CodecSpecificDataUtil.parseAlacAudioSpecificConfig(initializationData);
1167+
sampleRate = audioSpecificConfig.first;
1168+
channelCount = audioSpecificConfig.second;
11631169
}
11641170
childPosition += childAtomSize;
11651171
}

library/core/src/main/java/com/google/android/exoplayer2/extractor/ogg/FlacReader.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ protected boolean readHeaders(ParsableByteArray packet, long position, SetupData
7373
byte[] data = packet.data;
7474
if (streamMetadata == null) {
7575
streamMetadata = new FlacStreamMetadata(data, 17);
76+
int maxInputSize =
77+
streamMetadata.maxFrameSize == 0 ? Format.NO_VALUE : streamMetadata.maxFrameSize;
7678
byte[] metadata = Arrays.copyOfRange(data, 9, packet.limit());
7779
metadata[4] = (byte) 0x80; // Set the last metadata block flag, ignore the other blocks
7880
List<byte[]> initializationData = Collections.singletonList(metadata);
@@ -82,7 +84,7 @@ protected boolean readHeaders(ParsableByteArray packet, long position, SetupData
8284
MimeTypes.AUDIO_FLAC,
8385
/* codecs= */ null,
8486
streamMetadata.bitRate(),
85-
/* maxInputSize= */ Format.NO_VALUE,
87+
maxInputSize,
8688
streamMetadata.channels,
8789
streamMetadata.sampleRate,
8890
initializationData,

library/core/src/main/java/com/google/android/exoplayer2/util/CodecSpecificDataUtil.java

+25-9
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public final class CodecSpecificDataUtil {
8383
private CodecSpecificDataUtil() {}
8484

8585
/**
86-
* Parses an AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1
86+
* Parses an AAC AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1
8787
*
8888
* @param audioSpecificConfig A byte array containing the AudioSpecificConfig to parse.
8989
* @return A pair consisting of the sample rate in Hz and the channel count.
@@ -95,7 +95,7 @@ public static Pair<Integer, Integer> parseAacAudioSpecificConfig(byte[] audioSpe
9595
}
9696

9797
/**
98-
* Parses an AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1
98+
* Parses an AAC AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1
9999
*
100100
* @param bitArray A {@link ParsableBitArray} containing the AudioSpecificConfig to parse. The
101101
* position is advanced to the end of the AudioSpecificConfig.
@@ -104,8 +104,8 @@ public static Pair<Integer, Integer> parseAacAudioSpecificConfig(byte[] audioSpe
104104
* @return A pair consisting of the sample rate in Hz and the channel count.
105105
* @throws ParserException If the AudioSpecificConfig cannot be parsed as it's not supported.
106106
*/
107-
public static Pair<Integer, Integer> parseAacAudioSpecificConfig(ParsableBitArray bitArray,
108-
boolean forceReadToEnd) throws ParserException {
107+
public static Pair<Integer, Integer> parseAacAudioSpecificConfig(
108+
ParsableBitArray bitArray, boolean forceReadToEnd) throws ParserException {
109109
int audioObjectType = getAacAudioObjectType(bitArray);
110110
int sampleRate = getAacSamplingFrequency(bitArray);
111111
int channelConfiguration = bitArray.readBits(4);
@@ -166,10 +166,10 @@ public static Pair<Integer, Integer> parseAacAudioSpecificConfig(ParsableBitArra
166166
* Builds a simple HE-AAC LC AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1
167167
*
168168
* @param sampleRate The sample rate in Hz.
169-
* @param numChannels The number of channels.
169+
* @param channelCount The channel count.
170170
* @return The AudioSpecificConfig.
171171
*/
172-
public static byte[] buildAacLcAudioSpecificConfig(int sampleRate, int numChannels) {
172+
public static byte[] buildAacLcAudioSpecificConfig(int sampleRate, int channelCount) {
173173
int sampleRateIndex = C.INDEX_UNSET;
174174
for (int i = 0; i < AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE.length; ++i) {
175175
if (sampleRate == AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE[i]) {
@@ -178,13 +178,13 @@ public static byte[] buildAacLcAudioSpecificConfig(int sampleRate, int numChanne
178178
}
179179
int channelConfig = C.INDEX_UNSET;
180180
for (int i = 0; i < AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE.length; ++i) {
181-
if (numChannels == AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE[i]) {
181+
if (channelCount == AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE[i]) {
182182
channelConfig = i;
183183
}
184184
}
185185
if (sampleRate == C.INDEX_UNSET || channelConfig == C.INDEX_UNSET) {
186-
throw new IllegalArgumentException("Invalid sample rate or number of channels: "
187-
+ sampleRate + ", " + numChannels);
186+
throw new IllegalArgumentException(
187+
"Invalid sample rate or number of channels: " + sampleRate + ", " + channelCount);
188188
}
189189
return buildAacAudioSpecificConfig(AUDIO_OBJECT_TYPE_AAC_LC, sampleRateIndex, channelConfig);
190190
}
@@ -205,6 +205,22 @@ public static byte[] buildAacAudioSpecificConfig(int audioObjectType, int sample
205205
return specificConfig;
206206
}
207207

208+
/**
209+
* Parses an ALAC AudioSpecificConfig (i.e. an <a
210+
* href="https://github.com/macosforge/alac/blob/master/ALACMagicCookieDescription.txt">ALACSpecificConfig</a>).
211+
*
212+
* @param audioSpecificConfig A byte array containing the AudioSpecificConfig to parse.
213+
* @return A pair consisting of the sample rate in Hz and the channel count.
214+
*/
215+
public static Pair<Integer, Integer> parseAlacAudioSpecificConfig(byte[] audioSpecificConfig) {
216+
ParsableByteArray byteArray = new ParsableByteArray(audioSpecificConfig);
217+
byteArray.setPosition(9);
218+
int channelCount = byteArray.readUnsignedByte();
219+
byteArray.setPosition(20);
220+
int sampleRate = byteArray.readUnsignedIntToInt();
221+
return Pair.create(sampleRate, channelCount);
222+
}
223+
208224
/**
209225
* Builds an RFC 6381 AVC codec string using the provided parameters.
210226
*

library/core/src/main/java/com/google/android/exoplayer2/util/FlacStreamMetadata.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public int maxDecodedFrameSize() {
109109

110110
/** Returns the bit-rate of the FLAC stream. */
111111
public int bitRate() {
112-
return bitsPerSample * sampleRate;
112+
return bitsPerSample * sampleRate * channels;
113113
}
114114

115115
/** Returns the duration of the FLAC stream in microseconds. */

library/core/src/main/java/com/google/android/exoplayer2/video/DolbyVisionConfig.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public static DolbyVisionConfig parse(ParsableByteArray data) {
3636
int dvProfile = (profileData >> 1);
3737
int dvLevel = ((profileData & 0x1) << 5) | ((data.readUnsignedByte() >> 3) & 0x1F);
3838
String codecsPrefix;
39-
if (dvProfile == 4 || dvProfile == 5) {
39+
if (dvProfile == 4 || dvProfile == 5 || dvProfile == 7) {
4040
codecsPrefix = "dvhe";
4141
} else if (dvProfile == 8) {
4242
codecsPrefix = "hev1";

library/core/src/test/assets/ogg/bear_flac.ogg.0.dump

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ seekMap:
55
numberOfTracks = 1
66
track 0:
77
format:
8-
bitrate = 768000
8+
bitrate = 1536000
99
id = null
1010
containerMimeType = null
1111
sampleMimeType = audio/flac
12-
maxInputSize = -1
12+
maxInputSize = 5776
1313
width = -1
1414
height = -1
1515
frameRate = -1.0

library/core/src/test/assets/ogg/bear_flac.ogg.1.dump

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ seekMap:
55
numberOfTracks = 1
66
track 0:
77
format:
8-
bitrate = 768000
8+
bitrate = 1536000
99
id = null
1010
containerMimeType = null
1111
sampleMimeType = audio/flac
12-
maxInputSize = -1
12+
maxInputSize = 5776
1313
width = -1
1414
height = -1
1515
frameRate = -1.0

library/core/src/test/assets/ogg/bear_flac.ogg.2.dump

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ seekMap:
55
numberOfTracks = 1
66
track 0:
77
format:
8-
bitrate = 768000
8+
bitrate = 1536000
99
id = null
1010
containerMimeType = null
1111
sampleMimeType = audio/flac
12-
maxInputSize = -1
12+
maxInputSize = 5776
1313
width = -1
1414
height = -1
1515
frameRate = -1.0

0 commit comments

Comments
 (0)