Android 10 memperkenalkan API pengelolaan buffer HAL3 opsional kamera yang memungkinkan Anda menerapkan logika pengelolaan buffer untuk mencapai berbagai pertukaran latensi memori dan pengambilan dalam implementasi HAL kamera.
HAL kamera memerlukan N permintaan (dengan N sama dengan kedalaman pipeline) yang diantrekan dalam pipeline-nya, tetapi sering kali tidak memerlukan semua N kumpulan buffer output pada saat yang sama.
Misalnya, HAL mungkin memiliki delapan permintaan yang diantrekan dalam pipeline, tetapi hanya memerlukan buffer output untuk dua permintaan di 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 buffer HAL3 kamera memungkinkan pemisahan buffer output untuk mengosongkan enam kumpulan buffer. Hal ini dapat menghemat memori hingga ratusan megabyte pada perangkat kelas atas dan juga dapat 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 buffer HAL3 kamera yang diterapkan.
Gambar 1. Antarmuka HAL kamera di Android 9 dan yang lebih lama
Gambar 2. Antarmuka HAL kamera di Android 10 menggunakan API pengelolaan buffer
Mengimplementasikan API pengelolaan buffer
Untuk mengimplementasikan API pengelolaan buffer, HAL kamera harus:
- Mengimplementasikan HIDL
ICameraDevice@3.5. - Menetapkan kunci karakteristik kamera
android.info.supportedBufferManagementVersionkeHIDL_DEVICE_3_5.
HAL kamera menggunakan metode
requestStreamBuffers
dan
returnStreamBuffers
di
ICameraDeviceCallback.hal
untuk meminta dan menampilkan buffer. HAL juga harus mengimplementasikan
signalStreamFlush
metode di
ICameraDeviceSession.hal
untuk memberi sinyal kepada HAL kamera agar menampilkan buffer.
requestStreamBuffers
Gunakan metode
requestStreamBuffers
untuk meminta buffer dari framework kamera. Saat menggunakan API pengelolaan buffer HAL3
kamera, permintaan pengambilan dari framework kamera tidak
berisi buffer 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 aliran output dalam satu panggilan, sehingga memungkinkan lebih sedikit panggilan HIDL IPC. Namun, panggilan memerlukan lebih banyak waktu saat lebih banyak buffer diminta pada saat yang sama dan hal ini dapat memengaruhi latensi total permintaan-ke-hasil secara negatif.
Selain itu, karena panggilan ke requestStreamBuffers diserialkan dalam layanan kamera, sebaiknya HAL kamera menggunakan thread prioritas tinggi khusus untuk meminta buffer.
Jika permintaan buffer gagal, HAL kamera harus dapat menangani error non-fatal dengan benar. Daftar berikut menjelaskan alasan umum kegagalan permintaan buffer dan cara HAL kamera menanganinya.
- Aplikasi terputus dari aliran output: Ini adalah error non-fatal. HAL kamera harus mengirim
ERROR_REQUESTuntuk setiap permintaan pengambilan yang menargetkan aliran 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 buffer. HAL kamera harus
mengirim
ERROR_REQUESTuntuk permintaan pengambilan yang tidak dapat dipenuhi karena error waktu tunggu habis dan siap memproses permintaan berikutnya secara normal. - Framework kamera sedang menyiapkan konfigurasi aliran baru:
HAL kamera harus menunggu hingga panggilan
configureStreamsberikutnya selesai sebelum memanggilrequestStreamBufferslagi. - HAL kamera telah mencapai
batas buffer
(kolom
maxBuffers): HAL kamera harus menunggu hingga menampilkan setidaknya satu buffer aliran sebelum memanggilrequestStreamBufferslagi.
returnStreamBuffers
Gunakan metode
returnStreamBuffers
untuk menampilkan buffer tambahan ke framework kamera. HAL kamera biasanya
menampilkan buffer ke framework kamera melalui metode
processCaptureResult, tetapi hanya dapat memperhitungkan permintaan pengambilan yang telah dikirim ke
HAL kamera. Dengan metode requestStreamBuffers, implementasi HAL kamera dapat mempertahankan lebih banyak buffer daripada yang diminta oleh framework kamera. Saat itulah metode returnStreamBuffers harus digunakan. Jika implementasi HAL tidak pernah menyimpan lebih banyak buffer daripada yang diminta, implementasi HAL kamera tidak perlu memanggil metode returnStreamBuffers.
signalStreamFlush
Metode
signalStreamFlush
dipanggil oleh framework kamera untuk memberi tahu HAL kamera agar menampilkan semua
buffer yang ada. Metode ini biasanya dipanggil saat framework kamera akan
memanggil
configureStreams
dan harus menguras pipeline pengambilan kamera. Mirip dengan metode returnStreamBuffers, jika implementasi HAL kamera tidak menyimpan lebih banyak buffer daripada yang diminta, implementasi metode ini dapat kosong.
Setelah framework kamera memanggil
signalStreamFlush,
framework akan berhenti mengirim permintaan pengambilan baru ke HAL kamera hingga semua
buffer ditampilkan 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 buffer lagi setelah panggilan configureStreams berhasil ditampilkan. Jika framework kamera memanggil metode processCaptureRequest, HAL kamera dapat mulai meminta buffer 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 menguras pipeline sesegera mungkin. Saat metode signalStreamFlush dipanggil, HAL harus menyelesaikan semua permintaan pengambilan yang tertunda secara normal dan menampilkan semua buffer ke framework kamera.
Perbedaan lain antara metode signalStreamFlush dan metode lainnya adalah signalStreamFlush adalah metode HIDL satu arah, yang berarti framework kamera dapat memanggil API pemblokiran lainnya sebelum HAL menerima panggilan signalStreamFlush. Artinya, metode signalStreamFlush dan metode lainnya (khususnya metode configureStreams) mungkin tiba di HAL kamera dalam urutan yang berbeda dari urutan panggilan di 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 dari panggilan configureStreams yang sesuai. Lihat Gambar 3 untuk mengetahui contohnya.
Gambar 3. Cara HAL kamera mendeteksi dan menangani panggilan signalStreamFlush yang terlambat
Perubahan perilaku saat mengimplementasikan API pengelolaan buffer
Saat menggunakan API pengelolaan buffer untuk mengimplementasikan logika pengelolaan buffer, pertimbangkan kemungkinan perubahan perilaku berikut pada implementasi kamera dan HAL kamera:
Permintaan pengambilan tiba di HAL kamera lebih cepat dan lebih sering: Tanpa API pengelolaan buffer, framework kamera meminta buffer output untuk setiap permintaan pengambilan sebelum mengirim permintaan pengambilan ke HAL kamera. Saat menggunakan API pengelolaan buffer, framework kamera tidak perlu lagi menunggu buffer dan oleh karena itu dapat mengirim permintaan pengambilan ke HAL kamera lebih awal.
Selain itu, tanpa API pengelolaan buffer, framework kamera berhenti mengirim permintaan pengambilan jika salah satu aliran output permintaan pengambilan telah mencapai jumlah maksimum buffer yang dapat disimpan HAL dalam satu waktu (nilai ini ditetapkan oleh HAL kamera di kolom
HalStream::maxBuffersdalam nilai yang ditampilkan dari panggilanconfigureStreams). Dengan API pengelolaan buffer, perilaku pembatasan ini tidak lagi ada dan implementasi HAL kamera tidak boleh menerima panggilanprocessCaptureRequestjika HAL memiliki terlalu banyak permintaan pengambilan yang diantrekan.Latensi panggilan
requestStreamBufferssangat bervariasi: Ada banyak alasan mengapa panggilanrequestStreamBuffersmungkin memerlukan waktu lebih lama dari rata-rata. Contohnya:- Untuk beberapa buffer pertama dari aliran 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 buffer dan sibuk memproses. Hal ini dapat menyebabkan permintaan buffer melambat atau mencapai waktu tunggu habis karena kekurangan buffer atau CPU yang sibuk.
Strategi pengelolaan buffer
API pengelolaan buffer memungkinkan berbagai jenis strategi pengelolaan buffer diimplementasikan. Contohnya antara lain:
- Kompatibel dengan versi sebelumnya: HAL meminta buffer untuk permintaan pengambilan selama panggilan
processCaptureRequest. Strategi ini tidak memberikan penghematan memori, tetapi dapat berfungsi sebagai implementasi pertama API pengelolaan buffer, yang hanya memerlukan sedikit perubahan kode pada HAL kamera yang ada. - Penghematan memori maksimal: HAL kamera hanya meminta buffer output segera sebelum satu buffer diperlukan untuk diisi. Strategi ini memungkinkan penghematan memori maksimal. Potensi kerugiannya adalah lebih banyak jank pipeline kamera saat permintaan buffer memerlukan waktu yang sangat lama untuk diselesaikan.
- Di-cache: HAL kamera meng-cache beberapa buffer sehingga kemungkinan kecil akan terpengaruh oleh permintaan buffer yang lambat sesekali.
HAL kamera dapat mengadopsi strategi yang berbeda untuk kasus penggunaan tertentu, misalnya, menggunakan strategi penghematan memori maksimal untuk kasus penggunaan yang menggunakan banyak memori dan menggunakan strategi yang kompatibel dengan versi sebelumnya untuk kasus penggunaan lainnya.
Contoh implementasi di HAL kamera eksternal
HAL kamera eksternal diperkenalkan di Android 9 dan dapat ditemukan di
pohon sumber di
hardware/interfaces/camera/device/3.5/.
Di Android 10, HAL ini telah diupdate untuk menyertakan
ExternalCameraDeviceSession.cpp,
implementasi API pengelolaan buffer. HAL kamera eksternal ini
mengimplementasikan strategi penghematan memori maksimal yang disebutkan dalam Strategi pengelolaan buffer
dalam beberapa ratus baris kode
C++.