@@ -357,13 +357,23 @@ private boolean isCodecProfileAndLevelSupported(
357357 }
358358 }
359359
360- if (!isVideo && profile != CodecProfileLevel .AACObjectXHE ) {
361- // Some devices/builds underreport audio capabilities, so assume support except for xHE-AAC
362- // which may not be widely supported. See https://github.com/google/ExoPlayer/issues/5145.
360+ if (!isVideo
361+ && !mimeType .equals (MimeTypes .AUDIO_AC4 )
362+ && profile != CodecProfileLevel .AACObjectXHE ) {
363+ // AC-4 decoders report profile levels or audio capabilities that determine whether the input
364+ // format is supported or not.
365+ // With other encodings some devices/builds underreport audio capabilities, so assume support
366+ // except for xHE-AAC which may not be widely supported. See
367+ // https://github.com/google/ExoPlayer/issues/5145.
363368 return true ;
364369 }
365370
366371 CodecProfileLevel [] profileLevels = getProfileLevels ();
372+ if (mimeType .equals (MimeTypes .AUDIO_AC4 ) && profileLevels .length == 0 ) {
373+ // Some older devices don't report profile levels for AC-4. Estimate them using other data
374+ // in the codec capabilities.
375+ profileLevels = estimateLegacyAc4ProfileLevels (capabilities );
376+ }
367377 if (SDK_INT <= 23 && MimeTypes .VIDEO_VP9 .equals (mimeType ) && profileLevels .length == 0 ) {
368378 // Some older devices don't report profile levels for VP9. Estimate them using other data in
369379 // the codec capabilities.
@@ -819,6 +829,39 @@ private static int getMaxSupportedInstancesV23(CodecCapabilities capabilities) {
819829 return capabilities .getMaxSupportedInstances ();
820830 }
821831
832+ /**
833+ * Called on devices with AC-4 decoders whose {@link CodecCapabilities} do not report profile
834+ * levels. The returned {@link CodecProfileLevel CodecProfileLevels} are estimated based on other
835+ * data in the {@link CodecCapabilities}.
836+ *
837+ * @param capabilities The {@link CodecCapabilities} for an AC-4 decoder, or {@code null} if not
838+ * known.
839+ * @return The estimated {@link CodecProfileLevel CodecProfileLevels} for the decoder.
840+ */
841+ private static CodecProfileLevel [] estimateLegacyAc4ProfileLevels (
842+ @ Nullable CodecCapabilities capabilities ) {
843+ int maxInChannelCount = 2 ;
844+ if (capabilities != null ) {
845+ @ Nullable AudioCapabilities audioCapabilities = capabilities .getAudioCapabilities ();
846+ if (audioCapabilities != null ) {
847+ maxInChannelCount = audioCapabilities .getMaxInputChannelCount ();
848+ }
849+ }
850+
851+ int level = CodecProfileLevel .AC4Level3 ;
852+ if (maxInChannelCount > 18 ) { // AC-4 Level 3 stream is up to 17.1 channel
853+ level = CodecProfileLevel .AC4Level4 ;
854+ }
855+
856+ return new CodecProfileLevel [] {
857+ createCodecProfileLevel (CodecProfileLevel .AC4Profile00 , level ),
858+ createCodecProfileLevel (CodecProfileLevel .AC4Profile10 , level ),
859+ createCodecProfileLevel (CodecProfileLevel .AC4Profile11 , level ),
860+ createCodecProfileLevel (CodecProfileLevel .AC4Profile21 , level ),
861+ createCodecProfileLevel (CodecProfileLevel .AC4Profile22 , level )
862+ };
863+ }
864+
822865 /**
823866 * Called on devices with {@link Build.VERSION#SDK_INT} 23 and below, for VP9 decoders whose
824867 * {@link CodecCapabilities} do not correctly report profile levels. The returned {@link
0 commit comments