A partir do Android 17 QPR1 (nível 37.1 da API ou
Build.VERSION_CODES_FULL.CINNAMON_BUN_1), o Android introduz suporte da plataforma
para a codificação Extended High Efficiency Advanced Audio Coding (xHE-AAC).
Definido em ISO/IEC 23003-3 (MPEG-D USAC) e ISO/IEC 23003-4 (MPEG-D DRC), o xHE-AAC combina codificação unificada de fala e áudio com normalização obrigatória de intensidade e controle dinâmico de faixa integrado. Embora a decodificação xHE-AAC seja compatível e obrigatória pelo
Documento de definição de compatibilidade (CDD) do Android em várias
versões da plataforma, a adição de um codificador xHE-AAC
(implementações de hardware c2.android.xheaac.encoder e OEM) permite gravar
mensagens de voz e áudio de baixa taxa de bits, transmissões de áudio ao vivo e payloads
de comunicação com clareza de fala superior e volume consistente em todos os dispositivos.
Benefícios do xHE-AAC
A gravação de voz tradicional em apps de mensagens Android geralmente usa o AAC-LC (AAC de baixa complexidade) mais antigo a 28 kbps. Em taxas de bits baixas (<32 kbps), o AAC-LC apresenta artefatos perceptíveis de limitação de banda, qualidade de fala ruim e eficiência de compactação abaixo do ideal. Para os usuários finais, isso resulta em áudio abafado e metálico, em que as consoantes são difíceis de distinguir, exigindo que os ouvintes reproduzam as mensagens ou se esforcem para entender a fala em ambientes ruidosos. Além disso, níveis de volume inconsistentes entre os clipes de voz obrigam os usuários a ajustar o volume do dispositivo com frequência.
O xHE-AAC supera essas limitações aplicando algoritmos de codificação de áudio mais avançados, por exemplo, alternando dinamicamente entre ferramentas dedicadas de codificação de fala e de áudio geral, além de estender o intervalo de frequência com replicação de banda espectral (SBR, na sigla em inglês) aprimorada (eSBR) e oferecer capacidade de codificação estéreo paramétrica com muito pouco overhead de codificação adicional.
O DRC MPEG-D integrado oferece controle obrigatório de intensidade para o xHE-AAC reproduzir conteúdo em um volume consistente e oferece processamento de controle de faixa dinâmica para proporcionar a melhor experiência possível ao usuário em qualquer plataforma e ambiente.
Casos de uso de segmentação
- Serviços de Comunicação Avançada (RCS) e mensagens de voz:em conformidade com o perfil universal RCC.71 da GSMA versão 3.1 e mais recente, que exige xHE-AAC para mensagens de áudio de baixa taxa de bits.
- Streaming de áudio ao vivo e podcasts:oferece qualidade do áudio resiliente em conexões de rede móvel ou via satélite degradadas.
Disponibilidade da plataforma (nível da API 37.1 ou mais recente)
O suporte à codificação xHE-AAC da plataforma exige o nível 37.1 da API
(Build.VERSION.SDK_INT_FULL >= Build.VERSION_CODES_FULL.CINNAMON_BUN_1 /
SDK 3700001 ou mais recente).
Consultar suporte ao codificador xHE-AAC
Não suponha que a codificação xHE-AAC esteja disponível em todos os dispositivos
chamando MediaCodec.createByCodecName(...)
com "c2.android.xheaac.encoder".
- Alguns dispositivos podem fornecer um codificador xHE-AAC acelerado por hardware do fornecedor do chipset em vez do codificador de software da plataforma.
- Versões mais antigas do SO ou ROMs personalizadas não têm suporte para codificação xHE-AAC.
- Antes de codificar um anexo para mensagens ponto a ponto (como RCS ou
chat), os apps também precisam verificar se o cliente de recebimento anuncia
suporte à decodificação USAC/xHE-AAC (por exemplo, usando a descoberta de recursos SDP
profile-level-id=55/object=42) para evitar falhas de interoperabilidade em receptores legados.
Inspecionar recursos do MediaCodecList
Para verificar se o dispositivo atual é compatível com a codificação xHE-AAC, inspecione o profileLevels dos codificadores compatíveis com MediaFormat.MIMETYPE_AUDIO_AAC:
Kotlin
import android.media.MediaCodecInfo.CodecProfileLevel import android.media.MediaCodecList import android.media.MediaFormat import android.os.Build /** * Checks if the current device supports xHE-AAC audio encoding. */ fun isXheAacEncodingSupported(): Boolean { // Verify API Level >= 37.1 (CINNAMON_BUN_1 / SDK 3700001) if (Build.VERSION.SDK_INT_FULL < Build.VERSION_CODES_FULL.CINNAMON_BUN_1) { return false } val codecList = MediaCodecList(MediaCodecList.REGULAR_CODECS) for (codecInfo in codecList.codecInfos) { if (!codecInfo.isEncoder) continue if (MediaFormat.MIMETYPE_AUDIO_AAC in codecInfo.supportedTypes) { val capabilities = codecInfo.getCapabilitiesForType(MediaFormat.MIMETYPE_AUDIO_AAC) // Check if AACObjectXHE (42) is present in profileLevels val supportsXhe = capabilities.profileLevels.any { profileLevel -> profileLevel.profile == CodecProfileLevel.AACObjectXHE } if (supportsXhe) { return true } } } return false }
Java
import android.media.MediaCodecInfo; import android.media.MediaCodecInfo.CodecProfileLevel; import android.media.MediaCodecList; import android.media.MediaFormat; import android.os.Build; /** * Checks if the current device supports xHE-AAC audio encoding. */ public boolean isXheAacEncodingSupported() { // Verify API Level >= 37.1 (CINNAMON_BUN_1 / SDK 3700001) if (Build.VERSION.SDK_INT_FULL < Build.VERSION_CODES_FULL.CINNAMON_BUN_1) { return false; } MediaCodecList codecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS); for (MediaCodecInfo codecInfo : codecList.getCodecInfos()) { if (!codecInfo.isEncoder()) continue; for (String type : codecInfo.getSupportedTypes()) { if (MediaFormat.MIMETYPE_AUDIO_AAC.equals(type)) { MediaCodecInfo.CodecCapabilities capabilities = codecInfo.getCapabilitiesForType(MediaFormat.MIMETYPE_AUDIO_AAC); for (CodecProfileLevel profileLevel : capabilities.profileLevels) { if (profileLevel.profile == CodecProfileLevel.AACObjectXHE) { return true; } } } } } return false; }
Configurar e instanciar o codificador xHE-AAC
Depois de verificar o suporte a xHE-AAC, configure seu MediaFormat com
KEY_AAC_PROFILE definido como
MediaCodecInfo.CodecProfileLevel.AACObjectXHE
(valor 42).
Kotlin
fun setupXheAacEncoder(): MediaCodec? { if (!isXheAacEncodingSupported()) { return null } val mimeType = MediaFormat.MIMETYPE_AUDIO_AAC val sampleRate = 48000 val channelCount = 1 // Mono voice recording val bitRate = 20000 // 20 kbps delivers superior speech clarity val format = MediaFormat.createAudioFormat(mimeType, sampleRate, channelCount).apply { setInteger(MediaFormat.KEY_BIT_RATE, bitRate) setInteger(MediaFormat.KEY_AAC_PROFILE, CodecProfileLevel.AACObjectXHE) } // Find the hardware or software encoder supporting this format and profile val codecList = MediaCodecList(MediaCodecList.REGULAR_CODECS) val encoderName = codecList.findEncoderForFormat(format) ?: return null val encoder = MediaCodec.createByCodecName(encoderName) encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE) return encoder }
Java
public MediaCodec setupXheAacEncoder() throws IOException { if (!isXheAacEncodingSupported()) { return null; } String mimeType = MediaFormat.MIMETYPE_AUDIO_AAC; int sampleRate = 48000; int channelCount = 1; // Mono voice recording int bitRate = 20000; // 20 kbps delivers superior speech clarity MediaFormat format = MediaFormat.createAudioFormat(mimeType, sampleRate, channelCount); format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate); format.setInteger(MediaFormat.KEY_AAC_PROFILE, CodecProfileLevel.AACObjectXHE); // Find the hardware or software encoder supporting this format and profile MediaCodecList codecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS); String encoderName = codecList.findEncoderForFormat(format); if (encoderName == null) { return null; } MediaCodec encoder = MediaCodec.createByCodecName(encoderName); encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); return encoder; }
Limites de codificadores de software compatíveis (c2.android.xheaac.encoder)
Ao usar o codificador de software xHE-AAC fornecido pelo sistema
(c2.android.xheaac.encoder), o componente anuncia os seguintes
limites de capacidade:
- Contagem de canais:até
2canais (mono / estéreo). - Taxas de amostragem:
44100 Hz,48000 Hz. - Intervalo da taxa de bits:de
12,000 bpsa400,000 bps(12 kbps a 400 kbps). - Multiplexação de contêiner:compatível com fluxos elementares MP4A brutos e multiplexação de contêiner MP4/M4A da plataforma (
MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4).