Android 10 memperkenalkan API pengelolaan buffer camera HAL3 opsional yang memungkinkan Anda menerapkan logika pengelolaan buffer untuk mencapai berbagai kompromi latensi memori dan pengambilan dalam implementasi HAL kamera.
HAL kamera memerlukan permintaan N (dengan N sama dengan kedalaman pipeline) yang diantrekan dalam pipeline-nya, tetapi sering kali tidak memerlukan semua kumpulan buffer output N secara bersamaan.
Misalnya, HAL mungkin memiliki delapan permintaan yang diantrekan di pipeline, tetapi hanya memerlukan buffer output untuk dua permintaan pada tahap terakhir pipeline. Pada perangkat yang menjalankan Android 9 dan yang lebih lama, framework kamera mengalokasikan buffer saat permintaan diantrekan di HAL sehingga mungkin ada enam kumpulan buffer di HAL yang tidak digunakan. Di Android 10, API pengelolaan buffering HAL3 kamera memungkinkan pemisahan buffering output untuk mengosongkan enam set buffering. Hal ini dapat menghemat memori hingga ratusan megabyte pada perangkat kelas atas dan juga bermanfaat untuk perangkat dengan memori rendah.
Gambar 1 menunjukkan diagram antarmuka HAL kamera untuk perangkat yang menjalankan Android 9 dan yang lebih lama. Gambar 2 menunjukkan antarmuka HAL kamera di Android 10 dengan API pengelolaan buffering HAL3 kamera yang diterapkan.
Gambar 1. Antarmuka HAL kamera di Android 9 dan yang lebih lama
Gambar 2. Antarmuka Camera HAL di Android 10 menggunakan API pengelolaan buffer
Mengimplementasikan API pengelolaan buffering
Untuk mengimplementasikan API pengelolaan buffer, HAL kamera harus:
- Implementasikan HIDL
ICameraDevice@3.5
. - Tetapkan kunci karakteristik kamera
android.info.supportedBufferManagementVersion
keHIDL_DEVICE_3_5
.
HAL kamera menggunakan
metode
requestStreamBuffers
dan
returnStreamBuffers
di
ICameraDeviceCallback.hal
untuk meminta dan menampilkan buffering. HAL juga harus menerapkan metode
signalStreamFlush
di
ICameraDeviceSession.hal
untuk memberi sinyal ke HAL kamera agar menampilkan buffering.
requestStreamBuffers
Gunakan
metode requestStreamBuffers
untuk meminta buffering dari framework kamera. Saat menggunakan API pengelolaan buffering HAL3
kamera, permintaan pengambilan dari framework kamera tidak
berisi buffering output, yaitu kolom bufferId
di
StreamBuffer
adalah 0
. Oleh karena itu, HAL kamera harus menggunakan requestStreamBuffers
untuk meminta
buffer dari framework kamera.
Metode requestStreamBuffers
memungkinkan pemanggil meminta beberapa buffer
dari beberapa stream output dalam satu panggilan, sehingga panggilan IPC HIDL
dapat lebih sedikit. Namun, panggilan memerlukan waktu lebih lama jika lebih banyak buffer diminta secara bersamaan dan hal ini dapat berdampak negatif terhadap total latensi permintaan ke hasil.
Selain itu, karena panggilan ke requestStreamBuffers
diserialisasi dalam layanan
kamera, sebaiknya HAL kamera menggunakan thread
prioritas tinggi khusus untuk meminta buffering.
Jika permintaan buffering gagal, HAL kamera harus dapat menangani error non-fatal dengan benar. Daftar berikut ini menjelaskan alasan umum kegagalan permintaan buffer dan cara menanganinya oleh HAL kamera.
- Aplikasi terputus dari aliran data output:
Ini adalah error nonfatal. HAL kamera harus mengirim
ERROR_REQUEST
untuk setiap permintaan pengambilan yang menargetkan streaming yang terputus dan siap memproses permintaan berikutnya secara normal. - Waktu tunggu habis: Hal ini dapat terjadi saat aplikasi sibuk melakukan
pemrosesan intensif sambil menyimpan beberapa buffering. HAL kamera harus
mengirim
ERROR_REQUEST
untuk permintaan pengambilan yang tidak dapat dipenuhi karena error waktu tunggu habis dan siap memproses permintaan berikutnya secara normal. - Framework kamera sedang menyiapkan konfigurasi streaming baru:
Kamera HAL harus menunggu hingga panggilan
configureStreams
berikutnya selesai sebelum memanggilrequestStreamBuffers
lagi. - Kamera HAL telah mencapai
batas buffer
(kolom
maxBuffers
): HAL kamera harus menunggu hingga menampilkan setidaknya satu buffer streaming sebelum memanggilrequestStreamBuffers
lagi.
returnStreamBuffers
Gunakan metode
returnStreamBuffers
untuk menampilkan buffering tambahan ke framework kamera. HAL kamera biasanya menampilkan buffer ke framework kamera melalui metode processCaptureResult
, tetapi hanya dapat memperhitungkan permintaan pengambilan gambar yang telah dikirim ke HAL kamera. Dengan metode requestStreamBuffers
, penerapan HAL kamera dapat mempertahankan lebih banyak buffering daripada yang telah diminta oleh framework kamera. Inilah saatnya metode returnStreamBuffers
harus
digunakan. Jika implementasi HAL tidak pernah menyimpan lebih banyak buffering daripada yang diminta, implementasi HAL kamera tidak perlu memanggil metode
returnStreamBuffers
.
sinyalStreamFlush
Metode
signalStreamFlush
dipanggil oleh framework kamera untuk memberi tahu HAL kamera agar menampilkan semua
buffer yang ada. Ini biasanya dipanggil saat framework kamera akan
memanggil
configureStreams
dan harus menghabiskan pipeline pengambilan kamera. Serupa dengan metode
returnStreamBuffers
, jika implementasi HAL kamera tidak menyimpan lebih banyak buffering daripada
yang diminta, Anda dapat memiliki implementasi metode ini yang kosong.
Setelah framework kamera memanggil
signalStreamFlush
,
framework berhenti mengirim permintaan pengambilan baru ke HAL kamera hingga semua
buffer telah dikembalikan ke framework kamera. Saat semua buffer ditampilkan, panggilan metode requestStreamBuffers
akan gagal, dan framework kamera dapat melanjutkan pekerjaannya dalam status bersih. Framework kamera kemudian
memanggil metode
configureStreams
atau
processCaptureRequest
. Jika framework kamera memanggil metode configureStreams
, HAL
kamera dapat mulai meminta buffering lagi setelah panggilan configureStreams
berhasil
ditampilkan. Jika framework kamera memanggil metode processCaptureRequest
,
HAL kamera dapat mulai meminta buffering selama panggilan
processCaptureRequest
.
Semantiknya berbeda untuk metode signalStreamFlush
dan
metode
flush
. Saat metode flush
dipanggil, HAL dapat membatalkan permintaan pengambilan
yang tertunda dengan
ERROR_REQUEST
untuk menghabiskan pipeline sesegera mungkin. Saat
metode signalStreamFlush
dipanggil, HAL harus menyelesaikan semua permintaan
perekaman yang tertunda secara normal dan menampilkan semua buffering ke framework kamera.
Perbedaan lain antara metode signalStreamFlush
dan metode lainnya adalah
signalStreamFlush
adalah metode HIDL satu arah, yang berarti bahwa framework
kamera dapat memanggil API pemblokiran lainnya sebelum HAL menerima
panggilan signalStreamFlush
. Ini berarti bahwa
metode signalStreamFlush
dan metode lainnya (khususnya
metode configureStreams
) mungkin sampai di HAL kamera dalam urutan yang berbeda
dari urutan pemanggilan dalam framework kamera. Untuk mengatasi masalah
asinkron ini, kolom streamConfigCounter
ditambahkan ke
StreamConfiguration
dan ditambahkan sebagai argumen ke metode
signalStreamFlush
. Implementasi HAL kamera harus menggunakan argumen streamConfigCounter
untuk menentukan apakah panggilan signalStreamFlush
tiba lebih lambat daripada
panggilan configureStreams
yang sesuai. Lihat Gambar 3 untuk mengetahui contohnya.
Gambar 3. Cara HAL kamera mendeteksi dan menangani panggilan signalStreamFlush yang terlambat tiba
Perubahan perilaku saat menerapkan API pengelolaan buffering
Saat menggunakan API pengelolaan buffering untuk menerapkan logika pengelolaan buffering, pertimbangkan kemungkinan perubahan perilaku berikut pada kamera dan penerapan HAL kamera:
Permintaan pengambilan tiba di HAL kamera lebih cepat dan lebih sering: Tanpa API pengelolaan buffering, framework kamera meminta buffer output untuk setiap permintaan pengambilan sebelum mengirim permintaan pengambilan ke HAL kamera. Saat menggunakan API pengelolaan buffering, framework kamera tidak perlu lagi menunggu buffering sehingga dapat mengirim permintaan pengambilan ke HAL kamera lebih awal.
Selain itu, tanpa API pengelolaan buffering, framework kamera berhenti mengirim permintaan pengambilan jika salah satu aliran output permintaan pengambilan telah mencapai jumlah maksimum buffering yang dapat disimpan HAL sekaligus (nilai ini ditetapkan oleh HAL kamera di kolom
HalStream::maxBuffers
dalam nilai yang ditampilkan dari panggilanconfigureStreams
). Dengan API pengelolaan buffering, perilaku throttling ini tidak lagi ada dan implementasi HAL kamera tidak boleh menerima panggilanprocessCaptureRequest
saat HAL memiliki terlalu banyak permintaan pengambilan yang diantrekan.Latensi panggilan
requestStreamBuffers
bervariasi secara signifikan: Ada banyak alasan panggilanrequestStreamBuffers
mungkin memerlukan waktu lebih lama daripada rata-rata. Contoh:- Untuk beberapa buffer pertama dari streaming yang baru dibuat, panggilan dapat memerlukan waktu lebih lama karena perangkat perlu mengalokasikan memori.
- Latensi yang diharapkan meningkat sebanding dengan jumlah buffer yang diminta dalam setiap panggilan.
- Aplikasi menyimpan buffering dan sedang sibuk memproses. Hal ini dapat menyebabkan permintaan buffer melambat atau mencapai waktu tunggu karena kurangnya buffer atau CPU yang sibuk.
Strategi pengelolaan buffering
API pengelolaan buffering memungkinkan berbagai jenis strategi pengelolaan buffering diimplementasikan. Contohnya antara lain:
- Kompatibel dengan versi lama: HAL meminta buffering untuk permintaan pengambilan
selama panggilan
processCaptureRequest
. Strategi ini tidak memberikan penghematan memori, tetapi dapat berfungsi sebagai implementasi pertama API manajemen buffer, yang memerlukan sangat sedikit perubahan kode pada HAL kamera yang ada. - Penghematan memori yang dimaksimalkan: HAL kamera hanya meminta buffering output segera sebelum buffer diperlukan untuk diisi. Strategi ini memungkinkan penghematan memori yang dimaksimalkan. Kemungkinan kelemahannya adalah lebih banyak jank pipeline kamera saat permintaan buffering memerlukan waktu yang sangat lama untuk diselesaikan.
- Di-cache: HAL kamera meng-cache beberapa buffering sehingga kemungkinan tidak akan dipengaruhi oleh permintaan buffering yang lambat sesekali.
HAL kamera dapat menggunakan strategi yang berbeda untuk kasus penggunaan tertentu, misalnya, menggunakan strategi penghematan memori yang dimaksimalkan untuk kasus penggunaan yang menggunakan banyak memori dan menggunakan strategi yang kompatibel dengan versi lama untuk kasus penggunaan lainnya.
Contoh implementasi di HAL kamera eksternal
HAL kamera eksternal diperkenalkan di Android 9 dan dapat ditemukan dalam
hierarki sumber di
hardware/interfaces/camera/device/3.5/
.
Di Android 10, API ini telah diperbarui untuk menyertakan
ExternalCameraDeviceSession.cpp
,
implementasi API pengelolaan buffering. HAL kamera eksternal ini
menerapkan strategi penghematan memori yang dimaksimalkan yang disebutkan dalam Strategi manajemen
buffer dalam beberapa ratus baris
kode C++.