Commit e163fe69 by olly Committed by Oliver Woodman

Optimize AAC seeking except for xHE-AAC

In 2.11.2 to 2.11.5, we considered all AAC streams as consisting
only of sync samples. In 2.11.6+, we considered no AAC streams as
consisting of sync samples, because the property is not guaranteed
specifically for xHE-AAC. This will have caused a small regression
is seek speed for some types of media.

This change brings back the optimization for AAC, specifically
excluding only xHE-AAC (and cases where we don't know what type of
AAC we're dealing with).

PiperOrigin-RevId: 328950697
parent 3dbb4c4d
...@@ -170,15 +170,16 @@ public final class MimeTypes { ...@@ -170,15 +170,16 @@ public final class MimeTypes {
} }
/** /**
* Returns true if it is known that all samples in a stream of the given MIME type are guaranteed * Returns true if it is known that all samples in a stream of the given MIME type and codec are
* to be sync samples (i.e., {@link C#BUFFER_FLAG_KEY_FRAME} is guaranteed to be set on every * guaranteed to be sync samples (i.e., {@link C#BUFFER_FLAG_KEY_FRAME} is guaranteed to be set on
* sample). * every sample).
* *
* @param mimeType A MIME type. * @param mimeType The MIME type of the stream.
* @return True if it is known that all samples in a stream of the given MIME type are guaranteed * @param codec The RFC 6381 codec string of the stream, or {@code null} if unknown.
* to be sync samples. False otherwise, including if {@code null} is passed. * @return Whether it is known that all samples in the stream are guaranteed to be sync samples.
*/ */
public static boolean allSamplesAreSyncSamples(@Nullable String mimeType) { public static boolean allSamplesAreSyncSamples(
@Nullable String mimeType, @Nullable String codec) {
if (mimeType == null) { if (mimeType == null) {
return false; return false;
} }
...@@ -198,6 +199,20 @@ public final class MimeTypes { ...@@ -198,6 +199,20 @@ public final class MimeTypes {
case AUDIO_E_AC3: case AUDIO_E_AC3:
case AUDIO_E_AC3_JOC: case AUDIO_E_AC3_JOC:
return true; return true;
case AUDIO_AAC:
if (codec == null) {
return false;
}
@Nullable Mp4aObjectType objectType = getObjectTypeFromMp4aRFC6381CodecString(codec);
if (objectType == null) {
return false;
}
@C.Encoding
int encoding = AacUtil.getEncodingForAudioObjectType(objectType.audioObjectTypeIndication);
// xHE-AAC is an exception in which it's not true that all samples will be sync samples.
// Also return false for ENCODING_INVALID, which indicates we weren't able to parse the
// encoding from the codec string.
return encoding != C.ENCODING_INVALID && encoding != C.ENCODING_AAC_XHE;
default: default:
return false; return false;
} }
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
*/ */
package com.google.android.exoplayer2.util; package com.google.android.exoplayer2.util;
import static android.media.MediaCodecInfo.CodecProfileLevel.AACObjectHE;
import static android.media.MediaCodecInfo.CodecProfileLevel.AACObjectXHE;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
...@@ -171,4 +173,17 @@ public final class MimeTypesTest { ...@@ -171,4 +173,17 @@ public final class MimeTypesTest {
assertThat(objectType.objectTypeIndication).isEqualTo(expectedObjectTypeIndicator); assertThat(objectType.objectTypeIndication).isEqualTo(expectedObjectTypeIndicator);
assertThat(objectType.audioObjectTypeIndication).isEqualTo(expectedAudioObjectTypeIndicator); assertThat(objectType.audioObjectTypeIndication).isEqualTo(expectedAudioObjectTypeIndicator);
} }
@Test
public void allSamplesAreSyncSamples_forAac_usesCodec() {
assertThat(MimeTypes.allSamplesAreSyncSamples(MimeTypes.AUDIO_AAC, "mp4a.40." + AACObjectHE))
.isTrue();
assertThat(MimeTypes.allSamplesAreSyncSamples(MimeTypes.AUDIO_AAC, "mp4a.40." + AACObjectXHE))
.isFalse();
assertThat(MimeTypes.allSamplesAreSyncSamples(MimeTypes.AUDIO_AAC, "mp4a.40")).isFalse();
assertThat(MimeTypes.allSamplesAreSyncSamples(MimeTypes.AUDIO_AAC, "mp4a.40.")).isFalse();
assertThat(MimeTypes.allSamplesAreSyncSamples(MimeTypes.AUDIO_AAC, "invalid")).isFalse();
assertThat(MimeTypes.allSamplesAreSyncSamples(MimeTypes.AUDIO_AAC, /* codec= */ null))
.isFalse();
}
} }
...@@ -264,7 +264,8 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb ...@@ -264,7 +264,8 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb
for (TrackSelection trackSelection : selections) { for (TrackSelection trackSelection : selections) {
if (trackSelection != null) { if (trackSelection != null) {
Format selectedFormat = trackSelection.getSelectedFormat(); Format selectedFormat = trackSelection.getSelectedFormat();
if (!MimeTypes.allSamplesAreSyncSamples(selectedFormat.sampleMimeType)) { if (!MimeTypes.allSamplesAreSyncSamples(
selectedFormat.sampleMimeType, selectedFormat.codecs)) {
return true; return true;
} }
} }
......
...@@ -659,7 +659,7 @@ public class SampleQueue implements TrackOutput { ...@@ -659,7 +659,7 @@ public class SampleQueue implements TrackOutput {
upstreamFormat = format; upstreamFormat = format;
} }
upstreamAllSamplesAreSyncSamples = upstreamAllSamplesAreSyncSamples =
MimeTypes.allSamplesAreSyncSamples(upstreamFormat.sampleMimeType); MimeTypes.allSamplesAreSyncSamples(upstreamFormat.sampleMimeType, upstreamFormat.codecs);
loggedUnexpectedNonSyncSample = false; loggedUnexpectedNonSyncSample = false;
return true; return true;
} }
......
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