|
26 | 26 | import android.annotation.SuppressLint;
|
27 | 27 | import android.content.Context;
|
28 | 28 | import android.media.AudioDeviceInfo;
|
29 |
| -import android.media.AudioFormat; |
30 | 29 | import android.media.MediaCodec;
|
31 | 30 | import android.media.MediaCrypto;
|
32 | 31 | import android.media.MediaFormat;
|
@@ -338,14 +337,38 @@ public String getName() {
|
338 | 337 | }
|
339 | 338 | // If the input is PCM then it will be passed directly to the sink. Hence the sink must support
|
340 | 339 | // the input format directly.
|
341 |
| - if (MimeTypes.AUDIO_RAW.equals(format.sampleMimeType) && !audioSink.supportsFormat(format)) { |
342 |
| - return RendererCapabilities.create(C.FORMAT_UNSUPPORTED_SUBTYPE); |
343 |
| - } |
344 |
| - // For all other input formats, we expect the decoder to output 16-bit PCM. |
345 |
| - if (!audioSink.supportsFormat( |
346 |
| - Util.getPcmFormat(C.ENCODING_PCM_16BIT, format.channelCount, format.sampleRate))) { |
347 |
| - return RendererCapabilities.create(C.FORMAT_UNSUPPORTED_SUBTYPE); |
| 340 | + if (MimeTypes.AUDIO_RAW.equals(format.sampleMimeType)) { |
| 341 | + if (!audioSink.supportsFormat(format)) { |
| 342 | + return RendererCapabilities.create(C.FORMAT_UNSUPPORTED_SUBTYPE); |
| 343 | + } |
| 344 | + } else { |
| 345 | + // For all other input formats, MediaCodec can do some conversions for us. Check if the sink |
| 346 | + // supports any of the formats we can get out of MediaCodec. |
| 347 | + boolean pcmEncodingSupported = false; |
| 348 | + // On API levels before 24, any non-PCM input format is decoded to 16-bit PCM. |
| 349 | + if (Util.SDK_INT >= 24) { |
| 350 | + int[] platformEncodings = Util.getClosestPlatformPcmEncodings(format.pcmEncoding); |
| 351 | + for (int platformEncoding : platformEncodings) { |
| 352 | + if (audioSink.getFormatSupport( |
| 353 | + Util.getPcmFormat(platformEncoding, format.channelCount, format.sampleRate)) |
| 354 | + == AudioSink.SINK_FORMAT_SUPPORTED_DIRECTLY) { |
| 355 | + pcmEncodingSupported = true; |
| 356 | + break; |
| 357 | + } |
| 358 | + } |
| 359 | + } |
| 360 | + // If none of the suggested encodings are supported, fall back to MediaCodec's default value |
| 361 | + // of 16-bit PCM. |
| 362 | + if (!pcmEncodingSupported |
| 363 | + && audioSink.supportsFormat( |
| 364 | + Util.getPcmFormat(C.ENCODING_PCM_16BIT, format.channelCount, format.sampleRate))) { |
| 365 | + pcmEncodingSupported = true; |
| 366 | + } |
| 367 | + if (!pcmEncodingSupported) { |
| 368 | + return RendererCapabilities.create(C.FORMAT_UNSUPPORTED_SUBTYPE); |
| 369 | + } |
348 | 370 | }
|
| 371 | + |
349 | 372 | List<MediaCodecInfo> decoderInfos =
|
350 | 373 | getDecoderInfos(mediaCodecSelector, format, /* requiresSecureDecoder= */ false, audioSink);
|
351 | 374 | if (decoderInfos.isEmpty()) {
|
@@ -1025,11 +1048,18 @@ protected MediaFormat getMediaFormat(
|
1025 | 1048 | mediaFormat.setInteger("ac4-is-sync", 1);
|
1026 | 1049 | }
|
1027 | 1050 | }
|
1028 |
| - if (SDK_INT >= 24 |
1029 |
| - && audioSink.getFormatSupport( |
1030 |
| - Util.getPcmFormat(C.ENCODING_PCM_FLOAT, format.channelCount, format.sampleRate)) |
| 1051 | + if (SDK_INT >= 24) { |
| 1052 | + int[] platformEncodings = Util.getClosestPlatformPcmEncodings(format.pcmEncoding); |
| 1053 | + for (int platformEncoding : platformEncodings) { |
| 1054 | + if (audioSink.getFormatSupport( |
| 1055 | + Util.getPcmFormat(platformEncoding, format.channelCount, format.sampleRate)) |
1031 | 1056 | == AudioSink.SINK_FORMAT_SUPPORTED_DIRECTLY) {
|
1032 |
| - mediaFormat.setInteger(MediaFormat.KEY_PCM_ENCODING, AudioFormat.ENCODING_PCM_FLOAT); |
| 1057 | + mediaFormat.setInteger(MediaFormat.KEY_PCM_ENCODING, platformEncoding); |
| 1058 | + break; |
| 1059 | + } |
| 1060 | + } |
| 1061 | + // If none of the suggested encodings are supported, fall back to MediaCodec's default value |
| 1062 | + // of 16-bit PCM. |
1033 | 1063 | }
|
1034 | 1064 | if (SDK_INT >= 32) {
|
1035 | 1065 | mediaFormat.setInteger(MediaFormat.KEY_MAX_OUTPUT_CHANNEL_COUNT, 99);
|
|
0 commit comments