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.
Figura 1. Interfaccia della fotocamera HAL in Android 9 e versioni precedenti
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:
- Implementare l'HIDL
ICameraDevice@3.5
- Imposta la chiave relativa alle caratteristiche della fotocamera
android.info.supportedBufferManagementVersion
aHIDL_DEVICE_3_5
.
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 nuovorequestStreamBuffers
. - 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 chiamarerequestStreamBuffers
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.
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 unconfigureStreams
chiamata). Con le API di gestione del buffer, questo comportamento di limitazione non è più esiste e l'implementazione HAL della videocamera non deve accettareprocessCaptureRequest
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 alrequestStreamBuffers
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++.