mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Use encoder input format for sample rate fallback.
This ensures that when the input sample rate handled by the encoder differs from the output of the AudioGraph, that output audio will not be broken. PiperOrigin-RevId: 725610384
This commit is contained in:
parent
1b882fec0c
commit
447d784636
@ -1370,42 +1370,6 @@ public final class AndroidTestUtil {
|
|||||||
throw new AssumptionViolatedException("Profile not supported");
|
throw new AssumptionViolatedException("Profile not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Assumes that the given sample rate is unsupported and returns the fallback sample rate the
|
|
||||||
* device will use to encode.
|
|
||||||
*
|
|
||||||
* @param mimeType The {@linkplain MimeTypes MIME type}.
|
|
||||||
* @param unsupportedSampleRate An unsupported sample rate.
|
|
||||||
* @return The fallback sample rate.
|
|
||||||
* @throws AssumptionViolatedException If the device does not have the required encoder or sample
|
|
||||||
* rate configuration.
|
|
||||||
*/
|
|
||||||
public static int getFallbackAssumingUnsupportedSampleRate(
|
|
||||||
String mimeType, int unsupportedSampleRate) {
|
|
||||||
ImmutableList<MediaCodecInfo> supportedEncoders = EncoderUtil.getSupportedEncoders(mimeType);
|
|
||||||
if (supportedEncoders.isEmpty()) {
|
|
||||||
throw new AssumptionViolatedException("No supported encoders for mime type: " + mimeType);
|
|
||||||
}
|
|
||||||
|
|
||||||
int closestSupportedSampleRate = -1;
|
|
||||||
int minSampleRateCost = Integer.MAX_VALUE;
|
|
||||||
for (int i = 0; i < supportedEncoders.size(); i++) {
|
|
||||||
int actualFallbackSampleRate =
|
|
||||||
EncoderUtil.getClosestSupportedSampleRate(
|
|
||||||
supportedEncoders.get(i), mimeType, unsupportedSampleRate);
|
|
||||||
int sampleRateCost = Math.abs(actualFallbackSampleRate - unsupportedSampleRate);
|
|
||||||
if (sampleRateCost < minSampleRateCost) {
|
|
||||||
minSampleRateCost = sampleRateCost;
|
|
||||||
closestSupportedSampleRate = actualFallbackSampleRate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (closestSupportedSampleRate == unsupportedSampleRate) {
|
|
||||||
throw new AssumptionViolatedException(
|
|
||||||
String.format("Expected sample rate %s to be unsupported", unsupportedSampleRate));
|
|
||||||
}
|
|
||||||
return closestSupportedSampleRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns a {@link Muxer.Factory} depending upon the API level. */
|
/** Returns a {@link Muxer.Factory} depending upon the API level. */
|
||||||
public static Muxer.Factory getMuxerFactoryBasedOnApi() {
|
public static Muxer.Factory getMuxerFactoryBasedOnApi() {
|
||||||
// MediaMuxer supports B-frame from API > 24.
|
// MediaMuxer supports B-frame from API > 24.
|
||||||
|
@ -45,7 +45,6 @@ import static androidx.media3.transformer.AndroidTestUtil.assumeFormatsSupported
|
|||||||
import static androidx.media3.transformer.AndroidTestUtil.createFrameCountingEffect;
|
import static androidx.media3.transformer.AndroidTestUtil.createFrameCountingEffect;
|
||||||
import static androidx.media3.transformer.AndroidTestUtil.createOpenGlObjects;
|
import static androidx.media3.transformer.AndroidTestUtil.createOpenGlObjects;
|
||||||
import static androidx.media3.transformer.AndroidTestUtil.generateTextureFromBitmap;
|
import static androidx.media3.transformer.AndroidTestUtil.generateTextureFromBitmap;
|
||||||
import static androidx.media3.transformer.AndroidTestUtil.getFallbackAssumingUnsupportedSampleRate;
|
|
||||||
import static androidx.media3.transformer.AndroidTestUtil.getMuxerFactoryBasedOnApi;
|
import static androidx.media3.transformer.AndroidTestUtil.getMuxerFactoryBasedOnApi;
|
||||||
import static androidx.media3.transformer.AndroidTestUtil.recordTestSkipped;
|
import static androidx.media3.transformer.AndroidTestUtil.recordTestSkipped;
|
||||||
import static androidx.media3.transformer.ExportResult.CONVERSION_PROCESS_NA;
|
import static androidx.media3.transformer.ExportResult.CONVERSION_PROCESS_NA;
|
||||||
@ -119,7 +118,6 @@ import java.util.List;
|
|||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.TestName;
|
import org.junit.rules.TestName;
|
||||||
@ -2430,12 +2428,8 @@ public class TransformerEndToEndTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore("TODO: b/389068218 - Fix this test and re-enable it")
|
public void export_withHighSampleRateAndFallbackEnabled_exportsWithCorrectDuration()
|
||||||
public void export_withUnsupportedSampleRateAndFallbackEnabled_exportsWithFallbackSampleRate()
|
|
||||||
throws Exception {
|
throws Exception {
|
||||||
int unsupportedSampleRate = 96_000;
|
|
||||||
int fallbackSampleRate =
|
|
||||||
getFallbackAssumingUnsupportedSampleRate(MimeTypes.AUDIO_AAC, unsupportedSampleRate);
|
|
||||||
Transformer transformer =
|
Transformer transformer =
|
||||||
new Transformer.Builder(context)
|
new Transformer.Builder(context)
|
||||||
.setEncoderFactory(
|
.setEncoderFactory(
|
||||||
@ -2451,19 +2445,14 @@ public class TransformerEndToEndTest {
|
|||||||
.build()
|
.build()
|
||||||
.run(testId, editedMediaItem);
|
.run(testId, editedMediaItem);
|
||||||
|
|
||||||
assertThat(result.exportResult.sampleRate).isEqualTo(fallbackSampleRate);
|
// The original clip is 1 second long.
|
||||||
assertThat(result.exportResult.durationMs).isWithin(50).of(1_000);
|
assertThat(result.exportResult.durationMs).isWithin(50).of(1_000);
|
||||||
assertThat(new File(result.filePath).length()).isGreaterThan(0);
|
assertThat(new File(result.filePath).length()).isGreaterThan(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore("TODO: b/389068218 - Fix this test and re-enable it")
|
public void export_withMultipleHighSampleRatesAndFallbackEnabled_exportsWithCorrectDuration()
|
||||||
public void
|
throws Exception {
|
||||||
export_withTwoUnsupportedAndOneSupportedSampleRateAndFallbackEnabled_exportsWithFallbackSampleRate()
|
|
||||||
throws Exception {
|
|
||||||
int unsupportedSampleRate = 192_000;
|
|
||||||
int fallbackSampleRate =
|
|
||||||
getFallbackAssumingUnsupportedSampleRate(MimeTypes.AUDIO_AAC, unsupportedSampleRate);
|
|
||||||
Transformer transformer =
|
Transformer transformer =
|
||||||
new Transformer.Builder(context)
|
new Transformer.Builder(context)
|
||||||
.setEncoderFactory(
|
.setEncoderFactory(
|
||||||
@ -2488,7 +2477,7 @@ public class TransformerEndToEndTest {
|
|||||||
.build()
|
.build()
|
||||||
.run(testId, composition);
|
.run(testId, composition);
|
||||||
|
|
||||||
assertThat(result.exportResult.sampleRate).isEqualTo(fallbackSampleRate);
|
// Each original clip is 1 second long.
|
||||||
assertThat(result.exportResult.durationMs).isWithin(150).of(3_000);
|
assertThat(result.exportResult.durationMs).isWithin(150).of(3_000);
|
||||||
assertThat(new File(result.filePath).length()).isGreaterThan(0);
|
assertThat(new File(result.filePath).length()).isGreaterThan(0);
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ import org.checkerframework.dataflow.qual.Pure;
|
|||||||
muxerWrapper.getSupportedSampleMimeTypes(C.TRACK_TYPE_AUDIO)))
|
muxerWrapper.getSupportedSampleMimeTypes(C.TRACK_TYPE_AUDIO)))
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
AudioFormat actualEncoderAudioFormat = new AudioFormat(encoder.getConfigurationFormat());
|
AudioFormat actualEncoderAudioFormat = new AudioFormat(encoder.getInputFormat());
|
||||||
// This occurs when the encoder does not support the requested format. In this case, the audio
|
// This occurs when the encoder does not support the requested format. In this case, the audio
|
||||||
// graph output needs to be resampled to a sample rate matching the encoder input to avoid
|
// graph output needs to be resampled to a sample rate matching the encoder input to avoid
|
||||||
// distorted audio.
|
// distorted audio.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user