|
24 | 24 | import android.annotation.SuppressLint;
|
25 | 25 | import android.content.Context;
|
26 | 26 | import android.media.AudioDeviceInfo;
|
27 |
| -import android.media.AudioFormat; |
28 | 27 | import android.media.MediaCodec;
|
29 | 28 | import android.media.MediaCrypto;
|
30 | 29 | import android.media.MediaFormat;
|
@@ -334,14 +333,37 @@ public String getName() {
|
334 | 333 | }
|
335 | 334 | // If the input is PCM then it will be passed directly to the sink. Hence the sink must support
|
336 | 335 | // the input format directly.
|
337 |
| - if (MimeTypes.AUDIO_RAW.equals(format.sampleMimeType) && !audioSink.supportsFormat(format)) { |
338 |
| - return RendererCapabilities.create(C.FORMAT_UNSUPPORTED_SUBTYPE); |
339 |
| - } |
340 |
| - // For all other input formats, we expect the decoder to output 16-bit PCM. |
341 |
| - if (!audioSink.supportsFormat( |
342 |
| - Util.getPcmFormat(C.ENCODING_PCM_16BIT, format.channelCount, format.sampleRate))) { |
343 |
| - return RendererCapabilities.create(C.FORMAT_UNSUPPORTED_SUBTYPE); |
| 336 | + if (MimeTypes.AUDIO_RAW.equals(format.sampleMimeType)) { |
| 337 | + if (!audioSink.supportsFormat(format)) { |
| 338 | + return RendererCapabilities.create(C.FORMAT_UNSUPPORTED_SUBTYPE); |
| 339 | + } |
| 340 | + } else { |
| 341 | + // For all other input formats, MediaCodec can do some conversions for us. Check if the sink |
| 342 | + // supports any of the formats we can get out of MediaCodec. |
| 343 | + boolean pcmEncodingSupported = false; |
| 344 | + // On API levels before 24, any non-PCM input format is decoded to 16-bit PCM. |
| 345 | + if (Util.SDK_INT >= 24) { |
| 346 | + int[] platformEncodings = Util.getClosestPlatformPcmEncodings(format.pcmEncoding); |
| 347 | + for (int platformEncoding : platformEncodings) { |
| 348 | + if (audioSink.supportsFormat( |
| 349 | + Util.getPcmFormat(platformEncoding, format.channelCount, format.sampleRate))) { |
| 350 | + pcmEncodingSupported = true; |
| 351 | + break; |
| 352 | + } |
| 353 | + } |
| 354 | + } |
| 355 | + // If none of the suggested encodings are supported, fall back to MediaCodec's default value |
| 356 | + // of 16-bit PCM. |
| 357 | + if (!pcmEncodingSupported |
| 358 | + && audioSink.supportsFormat( |
| 359 | + Util.getPcmFormat(C.ENCODING_PCM_16BIT, format.channelCount, format.sampleRate))) { |
| 360 | + pcmEncodingSupported = true; |
| 361 | + } |
| 362 | + if (!pcmEncodingSupported) { |
| 363 | + return RendererCapabilities.create(C.FORMAT_UNSUPPORTED_SUBTYPE); |
| 364 | + } |
344 | 365 | }
|
| 366 | + |
345 | 367 | List<MediaCodecInfo> decoderInfos =
|
346 | 368 | getDecoderInfos(mediaCodecSelector, format, /* requiresSecureDecoder= */ false, audioSink);
|
347 | 369 | if (decoderInfos.isEmpty()) {
|
@@ -1005,11 +1027,18 @@ protected MediaFormat getMediaFormat(
|
1005 | 1027 | // not sync frames. Set a format key to override this.
|
1006 | 1028 | mediaFormat.setInteger("ac4-is-sync", 1);
|
1007 | 1029 | }
|
1008 |
| - if (Util.SDK_INT >= 24 |
1009 |
| - && audioSink.getFormatSupport( |
1010 |
| - Util.getPcmFormat(C.ENCODING_PCM_FLOAT, format.channelCount, format.sampleRate)) |
| 1030 | + if (Util.SDK_INT >= 24) { |
| 1031 | + int[] platformEncodings = Util.getClosestPlatformPcmEncodings(format.pcmEncoding); |
| 1032 | + for (int platformEncoding : platformEncodings) { |
| 1033 | + if (audioSink.getFormatSupport( |
| 1034 | + Util.getPcmFormat(platformEncoding, format.channelCount, format.sampleRate)) |
1011 | 1035 | == AudioSink.SINK_FORMAT_SUPPORTED_DIRECTLY) {
|
1012 |
| - mediaFormat.setInteger(MediaFormat.KEY_PCM_ENCODING, AudioFormat.ENCODING_PCM_FLOAT); |
| 1036 | + mediaFormat.setInteger(MediaFormat.KEY_PCM_ENCODING, platformEncoding); |
| 1037 | + break; |
| 1038 | + } |
| 1039 | + } |
| 1040 | + // If none of the suggested encodings are supported, fall back to MediaCodec's default value |
| 1041 | + // of 16-bit PCM. |
1013 | 1042 | }
|
1014 | 1043 | if (Util.SDK_INT >= 32) {
|
1015 | 1044 | mediaFormat.setInteger(MediaFormat.KEY_MAX_OUTPUT_CHANNEL_COUNT, 99);
|
|
0 commit comments