Pular para o conteúdo principal

Capítulo 12: Mergulho Profundo no CameraCharacteristics

12.1 A Folha de Especificações no Seu Bolso

Antes de poder chamar o openCamera(), antes de poder construir uma CaptureRequest, antes de poder configurar uma sessão — existe o CameraCharacteristics. Ele é a janela imutável, que não exige o acionamento da energia, para tudo o que uma câmera pode fazer. Pense nele como a folha de especificações da câmera, exposta como um objeto estruturado e consultável.

O CameraCharacteristics é a sua ferramenta mais importante para escrever aplicativos que funcionem nos mais de 10.000 modelos de dispositivos Android. Você não pode assumir que o ISO manual funciona. Não pode assumir que o RAW está disponível. Não pode nem assumir que a câmera suporta a pré-visualização em 1080p — a menos que você pergunte ao CameraCharacteristics.

No Capítulo 6, abordamos o básico: direção da lente, tamanho do sensor, distância focal. Neste mergulho profundo, vamos muito mais longe:

  • Os cinco níveis de hardware (LEGACY → LIMITED → FULL → LEVEL_3 → EXTERNAL) e o que cada um garante.
  • As mais de dez flags de capacidade (MANUAL_SENSOR, RAW, DEPTH_OUTPUT, etc.) e quais níveis de hardware as fornecem.
  • Como as chaves de metadados são organizadas hierarquicamente por subsistema (android.sensor.*, android.lens.*, android.control.*, ...).
  • Como escrever uma consulta de capacidade completa em tempo de execução com fallbacks graciosos.

O aplicativo Android Camera Parameters (GitHub, Play Store) é essencialmente um navegador de CameraCharacteristics turbinado. Abra-o em qualquer câmera e você verá exatamente as chaves que discutimos neste capítulo, organizadas por categoria, com rótulos legíveis por humanos e renderização de valores ao vivo.

12.2 O Que o CameraCharacteristics Realmente É

Formalmente, o CameraCharacteristics é:

  • Imutável — Uma vez obtido via CameraManager.getCameraCharacteristics(id), o objeto nunca muda (com uma exceção documentada: SENSOR_ORIENTATION em dobráveis na API 32+).
  • Sem consumo de energia — Consultá-lo não liga o sensor ou o ISP. Você pode chamá-lo no onCreate() de sua primeira Activity sem impacto na bateria.
  • Por câmera — Cada ID de câmera lógica possui seu próprio objeto CameraCharacteristics.
  • Tipado e baseado em chaves — Os dados são acessados via <Key<T>> get(Key<T> key), onde cada chave possui um tipo documentado (Int, Long, Float, Rect, Array, etc.).

Você obtém um com uma única chamada:

val cameraManager = getSystemService(CAMERA_SERVICE) as CameraManager
val cameraIdList = cameraManager.cameraIdList // ex: ["0", "1", "2", "3"]

for (id in cameraIdList) {
val characteristics: CameraCharacteristics = cameraManager.getCameraCharacteristics(id)
// Pode consultar à vontade — sem consumo de energia do sensor!
}

No Android 15 (API 35), você pode usar o CameraManager.getCameraDeviceSetup(id) para consultas leves de configuração de sessão sem abrir a câmera (consulte o Capítulo 28 para detalhes do CameraDeviceSetup).

12.3 Nível de Hardware: INFO_SUPPORTED_HARDWARE_LEVEL

A chave individual mais importante do CameraCharacteristics é a INFO_SUPPORTED_HARDWARE_LEVEL. Ela define todo o nível do HAL da câmera e informa (genericamente) quais recursos têm funcionamento garantido. Existem cinco níveis de hardware:

Os Cinco Níveis de Hardware

NívelConstanteDispositivos TípicosO Que Significa na Prática
LEGACYINFO_SUPPORTED_HARDWARE_LEVEL_LEGACYDispositivos econômicos pré-2015, chipsets muito antigosA API Camera2 é um wrapper em torno da antiga API android.hardware.Camera. Sem controles por quadro, sem configurações manuais, RAW impossível, burst não confiável. Trate esses dispositivos como "era Camera1 com sintaxe Camera2".
LIMITEDINFO_SUPPORTED_HARDWARE_LEVEL_LIMITEDCelulares econômicos (Android Go, SoCs de entrada como MediaTek Helio, Snapdragon 4xx)HAL Camera2 nativo, mas apenas um subconjunto de recursos. 3A (AF/AE/AWB) funcionam. Pré-visualização + JPEG funcionam. Mas nenhum controle manual do sensor, sem RAW, sem burst garantido, sem reprocessamento YUV. Este é o nível de câmera "funcional de base" do Android.
FULLINFO_SUPPORTED_HARDWARE_LEVEL_FULLCelulares intermediários e flagship (Snapdragon 6xx/7xx/8xx, Exynos mid+, Dimensity 7xxx+)O nível de "câmera pro". Garante MANUAL_SENSOR, MANUAL_POST_PROCESSING, BURST_CAPTURE, configurações por quadro, 30fps em resolução total, RAW, todos os formatos de saída, profundidade de pipeline previsível. O que você deseja para qualquer app de câmera sério.
LEVEL_3INFO_SUPPORTED_HARDWARE_LEVEL_3Flagships de ponta com ISP avançado (Snapdragon 8 Gen 1+, Pixel 6+, Exynos 2xxx+)FULL + extras: reprocessamento YUV (suporte a fluxo de entrada, reprocessamento offline), reprocessamento privado, estatísticas avançadas, JPEG de hardware + RAW em resolução máxima simultaneamente. Necessário para ZSL com saída RAW.
EXTERNALINFO_SUPPORTED_HARDWARE_LEVEL_EXTERNALCâmeras USB, webcams conectadas via OTGHAL de câmera externa. Comporta-se como LIMITED ou FULL dependendo do dispositivo USB. Ressalva importante: a câmera pode ser conectada/desconectada a qualquer momento, então escute pelo ACTION_CAMERA_DEVICE_STATE_CHANGED.
important

O nível de hardware é uma garantia, não uma flag de "melhor esforço". Se um dispositivo relata FULL, o CTS (Compatibility Test Suite) do Google verificou que cada recurso de nível FULL funciona. Se um dispositivo relata LIMITED, você não pode confiar em nenhum recurso de nível FULL — mesmo que ele funcione em um dispositivo LIMITED específico, ele falhará em outro.

Verificando o Nível de Hardware em Tempo de Execução

val hardwareLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL)

when (hardwareLevel) {
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY -> {
Log.w("CamCaps", "Hardware LEGACY — manual/RAW desativados. Revertendo para JPEG básico.")
disableManualControls()
disableRawCapture()
}
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED -> {
Log.i("CamCaps", "Hardware LIMITED — apenas foto básica + pré-visualização.")
disableManualControls()
disableRawCapture()
disableBurstCapture()
}
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL -> {
Log.i("CamCaps", "Hardware FULL — ativando controles manuais, RAW e burst.")
enableManualControls()
enableRawCapture()
enableBurstCapture()
}
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3 -> {
Log.i("CamCaps", "Hardware LEVEL_3 — FULL + reprocessamento + ZSL + estatísticas avançadas.")
enableManualControls()
enableRawCapture()
enableBurstCapture()
enableReprocessing()
enableZeroShutterLag()
}
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL -> {
Log.i("CamCaps", "Câmera EXTERNAL — pode ser LIMITED ou FULL; registrando listener de desconexão.")
registerHotplugListener()
// Sonda dinamicamente as capacidades em vez de assumir
}
else -> {
Log.w("CamCaps", "Nível de hardware desconhecido $hardwareLevel — assumindo LIMITED por segurança.")
safeDefaultFeatures()
}
}

12.4 Capacidades: REQUEST_AVAILABLE_CAPABILITIES

O nível de hardware é um nível genérico. Para detecção de recursos refinados, o Camera2 expõe o REQUEST_AVAILABLE_CAPABILITIES — um IntArray de flags de capacidade. Cada flag descreve uma coisa específica que a câmera pode fazer.

A relação formal entre o nível de hardware e as capacidades:

As Flags de Capacidade, Explicadas

Constante da FlagSignificadoGarantia por Nível de HardwareImplicação Prática
BACKWARD_COMPATIBLEA câmera implementa a API Camera2 básicaTodos os 5 níveis (LEGACY–EXTERNAL)Se esta flag faltar, o dispositivo de câmera é efetivamente não funcional para o seu app.
MANUAL_SENSORO app pode controlar manualmente SENSOR_EXPOSURE_TIME, SENSOR_SENSITIVITY, SENSOR_FRAME_DURATION, LENS_FOCUS_DISTANCE, LENS_APERTUREGarantido em FULL e LEVEL_3Interfaces de modo Pro e câmera manual exigem isso. Sem ela, todos os seletores manuais de ISO/exposição devem ser ocultados.
MANUAL_POST_PROCESSINGO app pode controlar manualmente os estágios do ISP: redução de ruído, aprimoramento de bordas, curva de tons, ganhos de correção de cor, matriz de correção de corGarantido em FULL e LEVEL_3Necessário para visuais de "estilo de filme" personalizados, balanço de branco manual via ganhos, controle de nitidez/desfoque.
RAWO sensor emite dados RAW Bayer via formatos ImageFormat.RAW_SENSOR, RAW10 ou RAW12Garantido em FULL e LEVEL_3Captura de DNG, pipeline de edição RAW-para-JPEG e fotografia computacional começam aqui.
PRIVATE_REPROCESSINGA câmera suporta InputSurface + reprocessamento offline de imagens no formato privado do HAL para JPEG/YUVGarantido em LEVEL_3. Raro em FULL.Habilita o Zero-Shutter-Lag (ZSL): armazena quadros passados em buffer circular, reprocessa um recente em uma foto estática de alta qualidade.
YUV_REPROCESSINGA câmera suporta InputSurface + reprocessamento de imagens YUV_420_888 fornecidas pelo app de volta através do ISPGarantido em LEVEL_3Habilita pipelines como "aplicar LUT cinematográfico ao vídeo gravado" ou "refocar profundidade de retrato na pós-produção".
DEPTH_OUTPUTA câmera pode emitir mapas de profundidade (formatos DEPTH16 / DEPTH_POINT_CLOUD)Opcional em QUALQUER nível. Verifique o array explicitamente.Bokeh de modo retrato, medição em AR, escaneamento 3D. Frequentemente pareado com LOGICAL_MULTI_CAMERA (câmeras físicas duplas para profundidade estéreo).
LOGICAL_MULTI_CAMERAEsta câmera lógica é apoiada por 2+ sensores físicos (ex: ultra-wide + wide + telefoto)Opcional em QUALQUER nível. Geralmente apenas flagships.Habilita o zoom óptico contínuo (consulte o Capítulo 20). Você pode consultar LOGICAL_MULTI_CAMERA_PHYSICAL_IDS para obter os IDs das câmeras físicas.
BURST_CAPTUREcaptureBurst() com > 1 quadro funciona em resolução total sem queda de quadrosGarantido em FULL e LEVEL_3Sem isso, a captura em burst pode travar, descartar quadros ou falhar silenciosamente. O bracketing de exposição / foco exige isso.
CONSTRAINED_HIGH_SPEED_VIDEOSuporta createHighSpeedRequestList() + vídeo de alta velocidade (120fps, 240fps)Opcional em FULL/LEVEL_3. Raro em LIMITED.Gravação em câmera lenta (consulte o Capítulo 19).
MOTION_TRACKINGA câmera pode rastrear objetos / rostos em alta taxa de quadros com baixa latênciaOpcional (raro). Encontrado em Pixels e alguns flagships.Rastreamento de movimento em AR, autofoco esportivo.
LOGICAL_MULTI_CAMERA_SYNCMúltiplas câmeras físicas em um dispositivo lógico podem capturar quadros sincronizadosOpcional. Necessário para captura multi-sensor simultânea real.Fotografia computacional que usa múltiplas lentes ao mesmo tempo (ex: zoom de fusão).

Consultando Todas as Capacidades em Tempo de Execução

val capabilities = characteristics.get(
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES
) ?: intArrayOf()

fun hasCapability(cap: Int): Boolean = capabilities.contains(cap)

val supportsManualSensor = hasCapability(
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR
)
val supportsRaw = hasCapability(
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW
)
val supportsBurst = hasCapability(
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE
)
val supportsDepth = hasCapability(
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT
)
val supportsLogicalMultiCam = hasCapability(
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA
)
val supportsHighSpeed = hasCapability(
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO
)
val supportsYuvReprocessing = hasCapability(
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING
)
val supportsPrivateReprocessing = hasCapability(
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING
)

// Construir relatório legível
val capabilityReport = buildString {
appendLine("=== Relatório de Capacidades da Câmera ===")
appendLine("BACKWARD_COMPATIBLE: ${hasCapability(
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
)}")
appendLine("MANUAL_SENSOR: $supportsManualSensor")
appendLine("MANUAL_POST_PROCESSING: ${hasCapability(
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING
)}")
appendLine("RAW: $supportsRaw")
appendLine("BURST_CAPTURE: $supportsBurst")
appendLine("YUV_REPROCESSING: $supportsYuvReprocessing")
appendLine("PRIVATE_REPROCESSING: $supportsPrivateReprocessing")
appendLine("DEPTH_OUTPUT: $supportsDepth")
appendLine("LOGICAL_MULTI_CAMERA: $supportsLogicalMultiCam")
appendLine("CONSTRAINED_HIGH_SPEED: $supportsHighSpeed")
}

Log.i("CamCaps", capabilityReport)

// Agora condicione seus recursos de UI
manualIsoSlider.isEnabled = supportsManualSensor
manualExposureSlider.isEnabled = supportsManualSensor
rawCaptureToggle.isEnabled = supportsRaw
burstCaptureButton.isEnabled = supportsBurst
depthPortraitMode.isEnabled = supportsDepth
zoomSwitcher.isEnabled = supportsLogicalMultiCam
slowMoButton.isEnabled = supportsHighSpeed
zslMode.isEnabled = supportsPrivateReprocessing // LEVEL_3
dica

O aplicativo Android Camera Parameters renderiza exatamente esta consulta como caixas de seleção coloridas no cartão Capabilities da visualização de resumo da câmera. Verde = suportado, cinza = não suportado. Você pode comparar várias câmeras lado a lado para ver como as capacidades da ultra-wide diferem das da câmera principal.

12.5 Organização dos Metadados: O Namespace android.*

Cada chave em CameraCharacteristics, CaptureRequest e CaptureResult segue uma convenção de nomenclatura hierárquica: android.<subsistema>.<parâmetro>. Os componentes separados por pontos agrupam as configurações relacionadas pelo subsistema de hardware/software que elas controlam.

As Classes de Subsistemas

Prefixo do SubsistemaClasse de Metadados KotlinO Que Cobre
android.sensor.*CameraCharacteristics.SensorInfo*, CaptureRequest.SENSOR_*, CaptureResult.SENSOR_*Leitura do sensor: tempo de exposição, sensibilidade ISO, duração do quadro, timestamp, matriz de pixels, matriz ativa, direção do obturador eletrônico, modos de padrão de teste
android.lens.*LensInfo*, Lens.*Óptica: distância de foco, abertura, distância focal, estabilização óptica (OIS), densidade do filtro (ND), faixa de foco, aberturas disponíveis
android.control.*Control*Algoritmos 3A: modos / estado / alvo / regiões de exposição automática (AE), modos / estado / gatilho / regiões de foco automático (AF), modos / estado / regiões de balanço de branco automático (AWB), anti-banding, modos de cena, modos de efeito, estabilização de vídeo (EIS)
android.scaler.*Scaler.*Configuração do pipeline de saída: região de corte (zoom digital), rotação, mapa de configuração de fluxo (formatos de saída, tamanhos, durações), durações mínimas de quadro disponíveis
android.jpeg.*Jpeg*Codificação JPEG: qualidade, orientação, coordenadas GPS, tamanho da miniatura, qualidade da miniatura
android.request.*Request*Capacidades de todo o pipeline: array de capacidades disponíveis, profundidade máxima do pipeline, número máximo de saídas raw/proc, chaves de objetos de metadados, lista de modelos disponíveis
android.flash.*FlashInfo*, Flash*Unidade de flash: disponibilidade, estado de carga, temperatura de cor, brilho máximo, modo (desligado / único / lanterna)
android.statistics.*Statistics*Saída de estatísticas do ISP: detecção facial, IDs faciais, marcos faciais, pontuações faciais, histograma, mapa de nitidez, mapa de sombreamento da lente, mapa de pixels quentes
android.info.*Info*Informações estáticas da câmera: nível de hardware suportado, versão do dispositivo, nível de hardware suportado, modos de detecção facial disponíveis, modos de redução de ruído disponíveis
android.black.*BlackLevel*Trava de nível de preto, padrão de nível de preto (correção de ruído de padrão fixo)
android.colorCorrection.*ColorCorrection*Pipeline de cores: matriz de transformação, ganhos de correção de cor (canais R, G, B), modo de correção de aberração
android.tonemap.*Tonemap*Mapeamento de tons: curva de mapeamento de tons (gama personalizada), modo de mapeamento de tons, contraste, saturação
android.edge.*Edge*Aprimoramento de bordas / nitidez: modo, intensidade
android.noiseReduction.*NoiseReduction*Redução de ruído: modo, intensidade, intensidade de NR temporal
android.shading.*Shading*Sombreamento da lente / correção de vinheta: modo, intensidade
android.hotPixel.*HotPixel*Correção de pixel quente: modo, mapa de pixels quentes
android.distortionCorrection.*DistortionCorrection*Correção de distorção geométrica da lente: modo
android.depth.*Depth*Saída de profundidade: profundidade é exclusiva, amostras máximas de profundidade, formato de profundidade
android.logicalMultiCamera.*LogicalMultiCamera*Multicâmera lógica: IDs das câmeras físicas, sincronização física do sensor

Uma Nota sobre a Disponibilidade das Chaves

Nem toda chave existe em todos os dispositivos. Se você chamar get(CHAVE) para uma chave que o dispositivo não suporta, você receberá null — daí os padrões ?: 0 ou ?.let que você vê ao longo deste livro.

O padrão seguro é: verifique se a chave existe antes de lê-la, ou use a segurança contra nulos do Kotlin para fornecer um padrão.

// Acesso seguro com padrões de fallback
val exposureTimeNs: Long = characteristics.get(
CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE
)?.upper ?: 1_000_000L // padrão de 1ms máx se a chave faltar

// Processamento opcional se a chave existir
characteristics.get(CameraCharacteristics.LENS_INFO_AVAILABLE_APERTURES)?.let { apertures ->
Log.d("CamCaps", "Dispositivo suporta ${apertures.size} aberturas: ${apertures.contentToString()}")
buildApertureSelector(apertures)
} ?: run {
Log.d("CamCaps", "Nenhuma abertura variável neste dispositivo")
hideApertureControl()
}

12.6 Uma Consulta de Capacidade em Tempo de Execução Completa (Nível de Produção)

Juntando tudo, aqui está uma consulta de capacidade pronta para produção que você pode inserir em qualquer app Camera2. Ela combina o nível de hardware, flags de capacidade e verificações de chaves individuais:

data class CameraCapabilityProfile(
val cameraId: String,
val lensFacing: Int,
val hardwareLevel: Int,
val hardwareLevelName: String,
val supportsManualSensor: Boolean,
val supportsManualPostProcessing: Boolean,
val supportsRaw: Boolean,
val supportsBurst: Boolean,
val supportsDepth: Boolean,
val supportsLogicalMultiCam: Boolean,
val supportsHighSpeedVideo: Boolean,
val supportsYuvReprocessing: Boolean,
val supportsPrivateReprocessing: Boolean,
val maxBurstRaw: Int,
val maxBurstProcessed: Int,
val pipelineMaxDepth: Int,
val availableFocalLengths: FloatArray?,
val availableApertures: FloatArray?,
val minFocusDistanceDiopters: Float?,
val maxDigitalZoom: Float?
)

fun buildCapabilityProfile(
cameraManager: CameraManager,
cameraId: String
): CameraCapabilityProfile {
val c = cameraManager.getCameraCharacteristics(cameraId)

val hwLevel = c.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL)
?: CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY

val hwLevelName = when (hwLevel) {
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY -> "LEGACY"
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED -> "LIMITED"
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL -> "FULL"
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3 -> "LEVEL_3"
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL -> "EXTERNAL"
else -> "UNKNOWN($hwLevel)"
}

val caps = c.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES) ?: intArrayOf()
fun has(cap: Int) = caps.contains(cap)

// O nível de hardware fornece garantias de capacidade, mas verifique as flags por segurança
val atLeastFull = hwLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL ||
hwLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3

return CameraCapabilityProfile(
cameraId = cameraId,
lensFacing = c.get(CameraCharacteristics.LENS_FACING)
?: CameraCharacteristics.LENS_FACING_BACK,
hardwareLevel = hwLevel,
hardwareLevelName = hwLevelName,

// Usar verificação de flag + fallback de garantia de nível de hardware por segurança
supportsManualSensor = has(
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR
) || atLeastFull,
supportsManualPostProcessing = has(
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING
) || atLeastFull,
supportsRaw = has(
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW
) || atLeastFull,
supportsBurst = has(
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE
) || atLeastFull,
supportsDepth = has(
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT
),
supportsLogicalMultiCam = has(
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA
),
supportsHighSpeedVideo = has(
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO
),
supportsYuvReprocessing = has(
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING
),
supportsPrivateReprocessing = has(
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING
),

maxBurstRaw = c.get(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_RAW) ?: 1,
maxBurstProcessed = c.get(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC) ?: 1,
pipelineMaxDepth = c.get(CameraCharacteristics.REQUEST_PIPELINE_MAX_DEPTH) ?: 1,

availableFocalLengths = c.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS),
availableApertures = c.get(CameraCharacteristics.LENS_INFO_AVAILABLE_APERTURES),
minFocusDistanceDiopters = c.get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE),
maxDigitalZoom = c.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM)
)
}

// Uso:
val profile = buildCapabilityProfile(cameraManager, "0")
Log.d("CamCaps", "Perfil da Câmera 0: ${profile.hardwareLevelName}, " +
"Manual=${profile.supportsManualSensor}, RAW=${profile.supportsRaw}, " +
"Burst=${profile.supportsBurst}, Profundidade=${profile.supportsDepth}, " +
"Zoom=${profile.maxDigitalZoom}x")

12.7 Visualizando no Aplicativo Android Camera Parameters

O aplicativo Android Camera Parameters (GitHub, Play Store) é o companheiro ideal para este capítulo. Ele transforma os pares chave/valor brutos do CameraCharacteristics em uma interface navegável:

  • Cartão de resumo — Nível de hardware (com emblema colorido: vermelho=LEGACY, laranja=LIMITED, verde=FULL, azul esverdeado=LEVEL_3, azul=EXTERNAL), direção da lente, resolução do sensor, distâncias focais.
  • Cartão de capacidades — Lista de verificação de cada flag REQUEST_AVAILABLE_CAPABILITIES, verde se presente.
  • Abas de categoria — Organizadas exatamente pelos subsistemas android.*: Sensor, Lens, Control, Scaler, Jpeg, Flash, Statistics, Info, Request.
  • Aba JSON Bruto — O objeto CameraCharacteristics serializado completo para copiar/colar em relatórios de bugs.
  • Modo Comparar — Deslize entre as câmeras (0, 1, 2, 3) para ver como os níveis de hardware e as capacidades diferem entre as lentes.

12.8 Resumo

ConceitoConclusão Principal
Nível de Hardware5 níveis: LEGACY (wrapper) → LIMITED (base) → FULL (pro + manual/RAW) → LEVEL_3 (FULL + reprocessamento) → EXTERNAL (USB). FULL é o mínimo para qualquer trabalho de câmera sério. Garantias verificadas pelo CTS.
Flags de CapacidadeDetecção de recursos refinados via REQUEST_AVAILABLE_CAPABILITIES. Flags principais: MANUAL_SENSOR, MANUAL_POST_PROCESSING, RAW, BURST_CAPTURE, DEPTH_OUTPUT, LOGICAL_MULTI_CAMERA, PRIVATE_REPROCESSING, YUV_REPROCESSING, CONSTRAINED_HIGH_SPEED_VIDEO.
Mapeamento Nível → CapacidadeFULL garante MANUAL_SENSOR, MANUAL_POST_PROCESSING, RAW, BURST. LEVEL_3 adiciona REPROCESSAMENTO YUV/PRIVADO. DEPTH e LOGICAL_MULTI_CAMERA são opcionais em todos os níveis.
Namespace de MetadadosChaves organizadas como android.<subsistema>.<parâmetro>. Principais subsistemas: sensor, lens, control, scaler, jpeg, request, flash, statistics, info. Cada subsistema tem informações estáticas (CameraCharacteristics), entradas de solicitação (CaptureRequest) e saídas de resultado (CaptureResult).
Consultas SegurasForneça sempre padrões de segurança contra nulos para o get() — muitas chaves são opcionais. Use o nível de hardware como filtro genérico, as flags de capacidade como filtro fino e a presença da chave individual para ajuste por dispositivo.

O Que Vem a Seguir

Agora que você entende o que uma câmera pode fazer (características) e como controlá-la (o pipeline + tipos de captura), você tem a base completa para a Parte IV.

No Capítulo 13: ISO e Exposição de Câmera Manual, você aprenderá a usar a capacidade MANUAL_SENSOR para controlar manualmente o SENSOR_EXPOSURE_TIME e a SENSOR_SENSITIVITY — implementando um seletor de exposição em modo pro com pré-visualização ao vivo, compensação de exposição e as trocas do triângulo de exposição.