Android 10 memperkenalkan API manajemen buffer HAL3 kamera opsional yang memungkinkan Anda mengimplementasikan logika manajemen buffer untuk mencapai memori yang berbeda dan menangkap trade-off latensi dalam implementasi HAL kamera.
Kamera HAL memerlukan N permintaan (di mana N sama dengan kedalaman pipa ) yang diantri dalam pipanya, namun sering kali tidak memerlukan semua N set buffer keluaran pada saat yang bersamaan.
Misalnya, HAL mungkin memiliki delapan permintaan yang diantri dalam alur, namun hanya memerlukan buffer keluaran untuk dua permintaan di tahap terakhir alur. Pada perangkat yang menjalankan Android 9 dan lebih rendah, framework kamera mengalokasikan buffer saat permintaan dimasukkan ke dalam antrean di HAL sehingga mungkin ada enam set buffer di HAL yang tidak digunakan. Di Android 10, API manajemen buffer HAL3 kamera memungkinkan pemisahan buffer output untuk mengosongkan enam set buffer. Hal ini dapat menghemat ratusan megabyte memori 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 lebih rendah. Gambar 2 menunjukkan antarmuka HAL kamera di Android 10 dengan implementasi API manajemen buffer HAL3 kamera.
Gambar 1. Antarmuka kamera HAL di Android 9 dan lebih rendah
Gambar 2. Antarmuka Kamera HAL di Android 10 menggunakan API manajemen buffer
Menerapkan API manajemen buffer
Untuk mengimplementasikan API manajemen buffer, kamera HAL harus:
- Terapkan HIDL
ICameraDevice@3.5
. - Setel kunci karakteristik kamera
android.info.supportedBufferManagementVersion
keHIDL_DEVICE_3_5
.
Kamera HAL menggunakan metode requestStreamBuffers
dan returnStreamBuffers
di ICameraDeviceCallback.hal
untuk meminta dan mengembalikan buffer. HAL juga harus mengimplementasikan metode signalStreamFlush
di ICameraDeviceSession.hal
untuk memberi sinyal pada kamera HAL agar mengembalikan buffer.
permintaanStreamBuffers
Gunakan metode requestStreamBuffers
untuk meminta buffer dari kerangka kamera. Saat menggunakan API manajemen buffer HAL3 kamera, permintaan pengambilan dari kerangka kamera tidak berisi buffer output, yaitu bidang bufferId
di StreamBuffer
adalah 0
. Oleh karena itu, kamera HAL harus menggunakan requestStreamBuffers
untuk meminta buffer dari kerangka kamera.
Metode requestStreamBuffers
memungkinkan pemanggil untuk meminta beberapa buffer dari beberapa aliran output dalam satu panggilan, sehingga memungkinkan lebih sedikit panggilan HIDL IPC. Namun, panggilan membutuhkan waktu lebih lama ketika lebih banyak buffer diminta pada saat yang sama dan hal ini mungkin berdampak negatif terhadap total latensi permintaan hingga hasil. Selain itu, karena panggilan ke requestStreamBuffers
diserialkan dalam layanan kamera, disarankan agar kamera HAL menggunakan thread khusus berprioritas tinggi untuk meminta buffer.
Jika permintaan buffer gagal, kamera HAL harus mampu menangani kesalahan nonfatal dengan baik. Daftar berikut menjelaskan alasan umum kegagalan permintaan buffer dan cara menanganinya oleh kamera HAL.
- Aplikasi terputus dari aliran keluaran: Ini adalah kesalahan nonfatal. Kamera HAL harus mengirimkan
ERROR_REQUEST
untuk setiap permintaan pengambilan yang menargetkan aliran terputus dan siap memproses permintaan berikutnya secara normal. - Batas Waktu: Ini dapat terjadi ketika aplikasi sedang sibuk melakukan pemrosesan intensif sambil menahan beberapa buffer. Kamera HAL harus mengirimkan
ERROR_REQUEST
untuk permintaan pengambilan yang tidak dapat dipenuhi karena kesalahan batas waktu dan siap untuk memproses permintaan berikutnya secara normal. - Kerangka kamera sedang mempersiapkan konfigurasi streaming baru: Kamera HAL harus menunggu hingga panggilan
configureStreams
berikutnya selesai sebelum memanggilrequestStreamBuffers
lagi. - Kamera HAL telah mencapai batas buffernya (bidang
maxBuffers
): Kamera HAL harus menunggu hingga mengembalikan setidaknya satu buffer aliran sebelum memanggilrequestStreamBuffers
lagi.
returnStreamBuffers
Gunakan metode returnStreamBuffers
untuk mengembalikan buffer tambahan ke kerangka kamera. Kamera HAL biasanya mengembalikan buffer ke kerangka kamera melalui metode processCaptureResult
, namun hanya dapat memperhitungkan permintaan pengambilan yang telah dikirim ke kamera HAL. Dengan metode requestStreamBuffers
, implementasi HAL kamera dapat mempertahankan lebih banyak buffer daripada yang diminta oleh kerangka kamera. Inilah saatnya metode returnStreamBuffers
harus digunakan. Jika implementasi HAL tidak pernah menampung buffer lebih dari yang diminta, implementasi HAL kamera tidak perlu memanggil metode returnStreamBuffers
.
signalStreamFlush
Metode signalStreamFlush
dipanggil oleh kerangka kamera untuk memberi tahu kamera HAL agar mengembalikan semua buffer yang ada. Ini biasanya dipanggil ketika kerangka kamera akan memanggil configureStreams
dan harus menguras alur pengambilan kamera. Mirip dengan metode returnStreamBuffers
, jika implementasi HAL kamera tidak menampung lebih banyak buffer daripada yang diminta, implementasi metode ini mungkin kosong.
Setelah kerangka kamera memanggil signalStreamFlush
, kerangka kerja berhenti mengirimkan permintaan pengambilan baru ke HAL kamera hingga semua buffer dikembalikan ke kerangka kamera. Ketika semua buffer dikembalikan, pemanggilan metode requestStreamBuffers
gagal, dan kerangka kamera dapat melanjutkan pekerjaannya dalam keadaan bersih. Kerangka kerja kamera kemudian memanggil metode configureStreams
atau processCaptureRequest
. Jika kerangka kamera memanggil metode configureStreams
, kamera HAL dapat mulai meminta buffer lagi setelah panggilan configureStreams
berhasil kembali. Jika kerangka kamera memanggil metode processCaptureRequest
, kamera HAL dapat mulai meminta buffer selama panggilan processCaptureRequest
.
Semantiknya berbeda untuk metode signalStreamFlush
dan metode flush
. Ketika metode flush
dipanggil, HAL dapat membatalkan permintaan penangkapan yang tertunda dengan ERROR_REQUEST
untuk menguras pipeline sesegera mungkin. Ketika metode signalStreamFlush
dipanggil, HAL harus menyelesaikan semua permintaan pengambilan yang tertunda secara normal dan mengembalikan semua buffer ke kerangka kamera.
Perbedaan lain antara metode signalStreamFlush
dan metode lainnya adalah signalStreamFlush
adalah metode HIDL satu arah , yang berarti kerangka kamera mungkin memanggil API pemblokiran lain sebelum HAL menerima panggilan signalStreamFlush
. Ini berarti bahwa metode signalStreamFlush
dan metode lainnya (khususnya metode configureStreams
) mungkin tiba di HAL kamera dalam urutan yang berbeda dari urutan pemanggilannya dalam kerangka kamera. Untuk mengatasi masalah asinkron ini, bidang 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 dari panggilan configureStreams
yang sesuai. Lihat Gambar 3 sebagai contoh.
Gambar 3. Bagaimana kamera HAL harus mendeteksi dan menangani panggilan signalStreamFlush yang datang terlambat
Perubahan perilaku saat mengimplementasikan API manajemen buffer
Saat menggunakan API manajemen buffer untuk mengimplementasikan logika manajemen buffer, pertimbangkan kemungkinan perubahan perilaku berikut pada kamera dan implementasi HAL kamera:
Permintaan pengambilan tiba di HAL kamera lebih cepat dan lebih sering: Tanpa API manajemen buffer, framework kamera meminta buffer output untuk setiap permintaan pengambilan sebelum mengirimkan permintaan pengambilan ke HAL kamera. Saat menggunakan API manajemen buffer, kerangka kamera tidak perlu lagi menunggu buffer dan oleh karena itu dapat mengirimkan permintaan pengambilan ke HAL kamera lebih awal.
Selain itu, tanpa API manajemen buffer, kerangka kamera akan berhenti mengirimkan permintaan pengambilan jika salah satu aliran keluaran permintaan pengambilan telah mencapai jumlah buffer maksimum yang dapat ditampung HAL pada satu waktu (nilai ini ditentukan oleh HAL kamera di Bidang
HalStream::maxBuffers
dalam nilai kembalian panggilanconfigureStreams
). Dengan API manajemen buffer, perilaku pembatasan ini tidak ada lagi dan implementasi HAL kamera tidak boleh menerima panggilanprocessCaptureRequest
ketika HAL memiliki terlalu banyak antrean permintaan pengambilan.latensi panggilan
requestStreamBuffers
sangat bervariasi: Ada banyak alasan mengapa panggilanrequestStreamBuffers
mungkin memerlukan waktu lebih lama daripada rata-rata. Misalnya:- Untuk beberapa buffer pertama dari aliran yang baru dibuat, panggilan bisa memakan waktu lebih lama karena perangkat perlu mengalokasikan memori.
- Latensi yang diharapkan meningkat sebanding dengan jumlah buffer yang diminta dalam setiap panggilan.
- Aplikasi menahan buffer dan sedang sibuk memproses. Hal ini dapat menyebabkan permintaan buffer melambat atau mencapai batas waktu karena kurangnya buffer atau CPU sibuk.
Strategi manajemen penyangga
API manajemen buffer memungkinkan penerapan berbagai jenis strategi manajemen buffer. Beberapa contohnya adalah:
- Kompatibel ke belakang: HAL meminta buffer untuk permintaan penangkapan selama panggilan
processCaptureRequest
. Strategi ini tidak memberikan penghematan memori apa pun, namun dapat berfungsi sebagai implementasi pertama API manajemen buffer, yang hanya memerlukan sedikit perubahan kode pada HAL kamera yang ada. - Penghematan memori yang maksimal: Kamera HAL hanya meminta buffer keluaran segera sebelum buffer perlu diisi. Strategi ini memungkinkan penghematan memori yang maksimal. Potensi kerugiannya adalah lebih banyak saluran kamera yang tersendat ketika permintaan buffer membutuhkan waktu yang sangat lama untuk diselesaikan.
- Cache: Kamera HAL menyimpan beberapa buffer dalam cache sehingga kecil kemungkinannya terpengaruh oleh permintaan buffer lambat yang sesekali terjadi.
Kamera HAL dapat mengadopsi strategi berbeda untuk kasus penggunaan tertentu, misalnya, menggunakan strategi penghematan memori maksimal untuk kasus penggunaan yang menggunakan banyak memori dan menggunakan strategi kompatibel ke belakang untuk kasus penggunaan lainnya.
Contoh implementasi pada kamera eksternal HAL
Kamera eksternal HAL diperkenalkan di Android 9 dan dapat ditemukan di pohon sumber di hardware/interfaces/camera/device/3.5/
. Di Android 10, telah diperbarui untuk menyertakan ExternalCameraDeviceSession.cpp
, sebuah implementasi API manajemen buffer. Kamera eksternal HAL ini menerapkan strategi penghematan memori maksimal yang disebutkan dalam strategi manajemen Buffer dalam beberapa ratus baris kode C++.