Return offload unsupported for formats not supported by the sdk level

PiperOrigin-RevId: 539079342
This commit is contained in:
michaelkatz 2023-06-09 14:46:54 +00:00 committed by Tofunmi Adigun-Hameed
parent 71153a43a8
commit fafeafa72d
4 changed files with 124 additions and 9 deletions

View File

@ -1954,6 +1954,48 @@ public final class Util {
.build();
}
/**
* Retrieves the API Level that {@link AudioFormat} introduced an encoding.
*
* <p>Method returns {@link Integer#MAX_VALUE} if the encoding is unknown.
*
* @param encoding for which to get the API level.
*/
@UnstableApi
public static int getApiLevelThatAudioFormatIntroducedAudioEncoding(int encoding) {
switch (encoding) {
case C.ENCODING_PCM_16BIT:
case C.ENCODING_PCM_8BIT:
return 3;
case C.ENCODING_PCM_FLOAT:
case C.ENCODING_AC3:
case C.ENCODING_E_AC3:
return 21;
case C.ENCODING_DTS:
case C.ENCODING_DTS_HD:
return 23;
case C.ENCODING_DOLBY_TRUEHD:
return 25;
case C.ENCODING_MP3:
case C.ENCODING_AAC_LC:
case C.ENCODING_AAC_HE_V1:
case C.ENCODING_AAC_HE_V2:
case C.ENCODING_AAC_ELD:
case C.ENCODING_AAC_XHE:
case C.ENCODING_AC4:
case C.ENCODING_E_AC3_JOC:
return 28;
case C.ENCODING_OPUS:
return 30;
case C.ENCODING_PCM_32BIT:
return 31;
case C.ENCODING_DTS_UHD_P2:
return 34;
default:
return Integer.MAX_VALUE;
}
}
/**
* Returns the frame size for audio with {@code channelCount} channels in the specified encoding.
*

View File

@ -378,8 +378,8 @@ public final class AudioCapabilities {
public static ImmutableList<Integer> getDirectPlaybackSupportedEncodings() {
ImmutableList.Builder<Integer> supportedEncodingsListBuilder = ImmutableList.builder();
for (int encoding : ALL_SURROUND_ENCODINGS_AND_MAX_CHANNELS.keySet()) {
// AudioFormat.ENCODING_DTS_UHD_P2 is supported from API 34.
if (Util.SDK_INT < 34 && encoding == C.ENCODING_DTS_UHD_P2) {
if (Util.SDK_INT < Util.getApiLevelThatAudioFormatIntroducedAudioEncoding(encoding)) {
// Example: AudioFormat.ENCODING_DTS_UHD_P2 is supported only from API 34.
continue;
}
if (AudioTrack.isDirectPlaybackSupported(

View File

@ -81,15 +81,12 @@ public final class DefaultAudioOffloadSupportProvider
@C.Encoding
int encoding = MimeTypes.getEncoding(checkNotNull(format.sampleMimeType), format.codecs);
if (encoding == C.ENCODING_INVALID) {
return AudioOffloadSupport.DEFAULT_UNSUPPORTED;
}
// AudioFormat.ENCODING_DTS_UHD_P2 is defined from API 34 onwards. We return offload
// unsupported to prevent crash in Util.getAudioFormat() below when it tries to create
// an AudioFormat with ENCODING_DTS_UHD_P2.
if ((Util.SDK_INT < 34) && (encoding == C.ENCODING_DTS_UHD_P2)) {
if (encoding == C.ENCODING_INVALID
|| Util.SDK_INT < Util.getApiLevelThatAudioFormatIntroducedAudioEncoding(encoding)) {
// Example: AudioFormat.ENCODING_OPUS is supported only from API 30.
return AudioOffloadSupport.DEFAULT_UNSUPPORTED;
}
int channelConfig = Util.getAudioTrackChannelConfig(format.channelCount);
if (channelConfig == AudioFormat.CHANNEL_INVALID) {
return AudioOffloadSupport.DEFAULT_UNSUPPORTED;

View File

@ -0,0 +1,76 @@
/*
* Copyright 2023 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 androidx.media3.exoplayer.audio;
import static com.google.common.truth.Truth.assertThat;
import androidx.media3.common.AudioAttributes;
import androidx.media3.common.Format;
import androidx.media3.common.MimeTypes;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;
/** Unit tests for {@link DefaultAudioOffloadSupportProvider}. */
@RunWith(AndroidJUnit4.class)
public final class DefaultAudioOffloadSupportProviderTest {
@Test
public void
getAudioOffloadSupport_withoutSampleRate_returnsAudioOffloadSupportDefaultUnsupported() {
Format formatWithoutSampleRate =
new Format.Builder().setSampleMimeType(MimeTypes.AUDIO_MPEG).build();
DefaultAudioOffloadSupportProvider audioOffloadSupportProvider =
new DefaultAudioOffloadSupportProvider();
AudioOffloadSupport audioOffloadSupport =
audioOffloadSupportProvider.getAudioOffloadSupport(
formatWithoutSampleRate, AudioAttributes.DEFAULT);
assertThat(audioOffloadSupport.isFormatSupported).isFalse();
}
@Test
@Config(maxSdk = 29)
public void
getAudioOffloadSupport_withOpusAndSdkUnder30_returnsAudioOffloadSupportDefaultUnsupported() {
Format formatOpus =
new Format.Builder().setSampleMimeType(MimeTypes.AUDIO_OPUS).setSampleRate(48_000).build();
DefaultAudioOffloadSupportProvider audioOffloadSupportProvider =
new DefaultAudioOffloadSupportProvider();
AudioOffloadSupport audioOffloadSupport =
audioOffloadSupportProvider.getAudioOffloadSupport(formatOpus, AudioAttributes.DEFAULT);
assertThat(audioOffloadSupport.isFormatSupported).isFalse();
}
@Test
@Config(maxSdk = 33)
public void
getAudioOffloadSupport_withDtsXAndSdkUnder34_returnsAudioOffloadSupportDefaultUnsupported() {
Format formatDtsX =
new Format.Builder().setSampleMimeType(MimeTypes.AUDIO_DTS_X).setSampleRate(48_000).build();
DefaultAudioOffloadSupportProvider audioOffloadSupportProvider =
new DefaultAudioOffloadSupportProvider();
AudioOffloadSupport audioOffloadSupport =
audioOffloadSupportProvider.getAudioOffloadSupport(formatDtsX, AudioAttributes.DEFAULT);
assertThat(audioOffloadSupport.isFormatSupported).isFalse();
}
}