API di gestione del buffer HAL3 della videocamera

Android 10 introduce un modello opzionale buffer HAL3 della videocamera API di gestione che ti consentono implementare una logica di gestione del buffer per ottenere memoria e acquisizioni diverse di latenza nelle implementazioni HAL per le videocamere.

La videocamera HAL richiede N richieste (dove N è uguale a profondità della pipeline) in coda nella sua pipeline, ma spesso non richiede tutti gli N set di buffer di output contemporaneamente.

Ad esempio, l'HAL potrebbe avere otto richieste in coda nella pipeline, richiede solo buffer di output per le due richieste nelle ultime fasi del una pipeline o un blocco note personalizzato. Sui dispositivi con Android 9 e versioni precedenti, il framework della fotocamera assegna buffer quando la richiesta viene accodata nell'HAL, quindi potrebbero esserci sei set di buffer non in uso nell'HAL. In Android 10, le API di gestione del buffer HAL3 della fotocamera consentono il disaccoppiamento buffer per liberare i sei gruppi di buffer. Ciò può portare a centinaia di di risparmi di memoria di MB sui dispositivi di fascia alta. Inoltre, può essere utile per dispositivi con poca memoria.

La figura 1 mostra uno schema dell'interfaccia HAL della videocamera per i dispositivi Android 9 e versioni precedenti. La figura 2 mostra l'interfaccia della fotocamera HAL in Android 10 con implementate le API di gestione del buffer HAL3 della videocamera.

Gestione del buffer con versione 9 o inferiore

Figura 1. Interfaccia della fotocamera HAL in Android 9 e versioni precedenti

Gestione del buffer in Android 10

Figura 2. Interfaccia della fotocamera HAL in Android 10 che utilizza le API di gestione del buffer

Implementazione delle API di gestione del buffer

Per implementare le API di gestione del buffer, l'HAL della fotocamera deve:

La videocamera HAL utilizza requestStreamBuffers e returnStreamBuffers in ICameraDeviceCallback.hal per richiedere e restituire i buffer. L'HAL deve inoltre implementare signalStreamFlush in ICameraDeviceSession.hal per segnalare all'HAL della fotocamera di restituire i buffer.

requestStreamBuffers

Utilizza la requestStreamBuffers per richiedere buffer dal framework della fotocamera. Quando si utilizza la fotocamera HAL3 le API di gestione del buffer, le richieste dal framework della fotocamera non contenere buffer di output, ovvero il campo bufferId StreamBuffer è 0. Di conseguenza, l'HAL della videocamera deve usare requestStreamBuffers per richiedere buffer dal framework della fotocamera.

Il metodo requestStreamBuffers consente al chiamante di richiedere più buffer da più flussi di output in una singola chiamata, consentendo un minor numero di IPC HIDL chiamate. Tuttavia, le chiamate richiedono più tempo quando vengono richiesti più buffer nello stesso momento, il che potrebbe influire negativamente sulla latenza totale tra richiesta e risultato. Inoltre, le chiamate in requestStreamBuffers sono serializzate nella videocamera è consigliabile che l'HAL della videocamera utilizzi un servizio dedicato il thread per richiedere i buffer.

Se una richiesta di buffer non va a buon fine, l'HAL della videocamera deve essere in grado di gestire correttamente e non irreversibili. Nell'elenco che segue vengono descritti i motivi più comuni per cui il buffering non vanno a buon fine e come devono essere gestite dall'HAL della videocamera.

  • L'app si disconnette dallo stream di output: Si tratta di un errore non irreversibile. La videocamera HAL dovrebbe inviare ERROR_REQUEST per qualsiasi richiesta di acquisizione scegliere come target uno stream disconnesso ed essere pronto a elaborare le richieste successive normalmente.
  • Timeout:questo può verificarsi quando un'app è impegnata a svolgere ma anche ad alta intensità, mantenendo alcuni buffer. La videocamera HAL deve invia ERROR_REQUEST per le richieste di acquisizione che non possono essere soddisfatte a causa di un di timeout ed essere in grado di elaborare le richieste successive normalmente.
  • Il framework della videocamera sta preparando una nuova configurazione dello streaming: L'HAL della videocamera dovrebbe attendere fino al successivo configureStreams: la chiamata è stata completata prima di chiamare di nuovo requestStreamBuffers.
  • La videocamera HAL ha raggiunto la limite di buffer (il campo maxBuffers): La videocamera HAL dovrebbe attendere finché non restituisce almeno un buffer dello stream prima di chiamare requestStreamBuffers di nuovo.

ReturnStreamBuffers

Utilizza la returnStreamBuffers per restituire buffer aggiuntivi al framework della fotocamera. La videocamera HAL normalmente restituisce i buffer al framework della fotocamera tramite processCaptureResult ma può tenere conto solo delle richieste di acquisizione inviate per la videocamera HAL. Con il metodo requestStreamBuffers, è possibile che il tag dell'HAL per la videocamera per conservare più buffer di quanto richiesto il framework della fotocamera. Questo è quando il metodo returnStreamBuffers deve essere in uso. Se l'implementazione HAL non contiene mai un numero di buffer maggiore di quello richiesto, l'implementazione dell'HAL per la videocamera non deve chiamare returnStreamBuffers .

FlussoSegnaleFlush

La signalStreamFlush viene chiamato dal framework della fotocamera per comunicare all'HAL della videocamera di restituire tutti buffer a portata di mano. Normalmente viene chiamato quando il framework della fotocamera sta per essere chiamata configureStreams e deve svuotare la pipeline di acquisizione della videocamera. Simile a returnStreamBuffers , se un'implementazione HAL della videocamera non contiene più buffer di richiesta, è possibile avere un'implementazione vuota di questo metodo.

Dopo le chiamate del framework della fotocamera signalStreamFlush, il framework interrompe l'invio di nuove richieste di acquisizione all'HAL della fotocamera finché sono stati restituiti buffer al framework della fotocamera. Quando tutti i buffer vengono restituiti, le chiamate al metodo requestStreamBuffers non vanno a buon fine e la fotocamera può continuare a lavorare in modo pulito. Il framework della fotocamera chiama configureStreams o processCaptureRequest . Se il framework della fotocamera chiama il metodo configureStreams, la fotocamera L'HAL può iniziare a richiedere nuovamente buffer dopo il ritorno della chiamata configureStreams correttamente. Se il framework della fotocamera chiama il metodo processCaptureRequest, l'HAL della videocamera può iniziare a richiedere buffer durante processCaptureRequest chiamata.

La semantica è diversa per il metodo signalStreamFlush e flush . Quando viene chiamato il metodo flush, l'HAL può interrompere l'acquisizione in attesa con richieste ERROR_REQUEST per svuotare la pipeline il prima possibile. Quando viene chiamato il metodo signalStreamFlush, l'HAL deve terminare tutte le istanze acquisiscono normalmente le richieste e restituiscono tutti i buffer al framework della fotocamera.

Un'altra differenza tra il metodo signalStreamFlush e altri metodi è che signalStreamFlush è un metodo HIDL unidirezionale, il che significa che la videocamera potrebbe chiamare altre API di blocco prima che l'HAL riceva Chiamata signalStreamFlush. Ciò significa che il metodo signalStreamFlush e altri metodi (nello specifico configureStreams) potrebbe arrivare all'HAL della fotocamera in un ordine diverso rispetto all'ordine in cui sono state chiamate nel framework della fotocamera. Per risolvere questo problema di asincroni, il campo streamConfigCounter è stato aggiunto a StreamConfiguration e aggiunto come argomento a signalStreamFlush . L'implementazione dell'HAL della fotocamera deve utilizzare streamConfigCounter per determinare se una chiamata signalStreamFlush arriva dopo la sua chiamata configureStreams corrispondente. Vedi la Figura 3 per un esempio.

Gestione delle chiamate che arrivano in ritardo

Figura 3. In che modo la videocamera HAL deve rilevare e gestire le chiamate StreamFlush di segnale che arrivano in ritardo

Il comportamento cambia durante l'implementazione delle API di gestione del buffer

Quando utilizzi le API di gestione del buffer per implementare la logica di gestione del buffer, prendi in considerazione le seguenti possibili modifiche del comportamento della videocamera e della videocamera HAL:

  • Le richieste di acquisizione arrivano alla fotocamera HAL più velocemente e più frequentemente: senza le API di gestione del buffer, il framework della videocamera richiede buffer di output per ogni richiesta di acquisizione prima di inviare una richiesta di acquisizione a la videocamera HAL. Quando si utilizzano le API di gestione del buffer, il framework della fotocamera non deve più attendere i buffer e può quindi inviare richieste di acquisizione alla fotocamera HAL.

    Inoltre, senza le API di gestione del buffer, il framework della videocamera si arresta che invia richieste di acquisizione se uno dei flussi di output dell'acquisizione ha raggiunto il numero massimo di buffer che l'HAL può mantenere una volta (questo valore è indicato dall'HAL della videocamera nella Campo HalStream::maxBuffers nel valore restituito di un configureStreams chiamata). Con le API di gestione del buffer, questo comportamento di limitazione non è più esiste e l'implementazione HAL della videocamera non deve accettare processCaptureRequest chiamate quando l'HAL ha troppe richieste di acquisizione in coda.

  • La latenza di chiamata di requestStreamBuffers varia notevolmente: sono presenti molti motivi per cui una chiamata al requestStreamBuffers può richiedere più tempo rispetto a media. Ad esempio:

    • Per i primi buffer di uno stream appena creato, richiama può richiedere più tempo perché il dispositivo deve allocare memoria.
    • La latenza prevista aumenta in proporzione al numero di buffer richiesti in ogni chiamata.
    • L'app contiene i buffer ed è impegnata nell'elaborazione. Questo può causare un rallentamento delle richieste di buffer o un timeout a causa di un di buffer o di CPU occupata.

Strategie di gestione del buffer

Le API di gestione del buffer consentono diversi tipi di gestione del buffer strategie da implementare. Ecco alcuni esempi:

  • Compatibile con le versioni precedenti: l'HAL richiede il buffer per una richiesta di acquisizione. durante la chiamata processCaptureRequest. Questa strategia non fornisce risparmio di memoria, ma può servire come prima implementazione del buffer che richiedono pochissime modifiche al codice dell'HAL per la videocamera esistente.
  • Risparmio di memoria massimizzato:l'HAL della fotocamera richiede solo buffer di output immediatamente prima della necessità di compilarne una. Questa strategia consente il massimo risparmio di memoria. Il potenziale svantaggio è che la pipeline per le videocamere un blocco quando il completamento delle richieste di buffer richiede un tempo insolitamente lungo.
  • Memorizzata nella cache: l'HAL della videocamera memorizza nella cache alcuni buffer in modo che sia meno probabile essere influenzata da una richiesta occasionale di buffer lento.

La videocamera HAL può adottare diverse strategie per casi d'uso particolari, ad Ad esempio, la strategia di risparmio di memoria massimizzato per i casi d'uso che usano di memoria e di usare la strategia compatibile con le versioni precedenti per altri casi d'uso.

Esempio di implementazione nella videocamera HAL esterna

La fotocamera esterna HAL è stata introdotta in Android 9 e si trova nella struttura di origine in hardware/interfaces/camera/device/3.5/ In Android 10, è stato aggiornato per includere ExternalCameraDeviceSession.cpp, un'implementazione dell'API di gestione del buffer. Questa videocamera esterna HAL implementa la strategia di risparmio di memoria massimizzata menzionata in Gestione del buffer strategie in poche centinaia di righe di C++.