API pengelolaan buffer HAL3 kamera

Android 10 memperkenalkan API pengelolaan buffer camera HAL3 opsional yang memungkinkan Anda menerapkan logika pengelolaan buffer untuk mencapai berbagai kompromi memori dan latensi pengambilan gambar 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 set buffer output secara bersamaan.

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 rendah, framework kamera mengalokasikan buffer saat permintaan diantrekan di HAL sehingga ada enam set buffer di HAL yang tidak digunakan. Di Android 10, API pengelolaan buffer HAL3 kamera memungkinkan pemisahan buffer output untuk mengosongkan enam set buffer. Hal ini dapat menghemat memori hingga ratusan megabyte di perangkat kelas atas dan juga dapat bermanfaat bagi 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 penerapan API pengelolaan buffer HAL3 kamera.

Pengelolaan buffer di Android 9 atau yang lebih rendah

Gambar 1. Antarmuka HAL Kamera di Android 9 dan yang lebih lama

Pengelolaan buffer di Android 10

Gambar 2. Antarmuka HAL Kamera di Android 10 menggunakan API pengelolaan buffer

Mengimplementasikan API pengelolaan buffer

Untuk mengimplementasikan API pengelolaan buffer, HAL kamera harus:

HAL kamera menggunakan metode requestStreamBuffers dan returnStreamBuffers di ICameraDeviceCallback.hal untuk meminta dan menampilkan buffer. HAL juga harus menerapkan metode signalStreamFlush di ICameraDeviceSession.hal untuk memberi sinyal ke 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 mengurangi panggilan HIDL IPC. Namun, panggilan memerlukan lebih banyak waktu jika lebih banyak buffer diminta pada waktu yang sama dan hal ini dapat berdampak negatif pada total latensi permintaan-ke-hasil. Selain itu, karena panggilan ke requestStreamBuffers diserialkan di layanan kamera, sebaiknya HAL kamera menggunakan thread berprioritas tinggi khusus untuk meminta buffer.

Jika permintaan buffer gagal, HAL kamera harus dapat menangani error tidak fatal dengan benar. Daftar berikut menjelaskan alasan umum permintaan buffer gagal dan cara penanganannya oleh HAL kamera.

  • Aplikasi terputus dari aliran output: Ini adalah error non-fatal. HAL kamera harus mengirim ERROR_REQUEST untuk setiap permintaan pengambilan gambar 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 buffer. HAL kamera harus mengirim ERROR_REQUEST untuk permintaan pengambilan yang tidak dapat dipenuhi karena error waktu tunggu dan siap memproses permintaan berikutnya secara normal.
  • Framework kamera sedang menyiapkan konfigurasi streaming baru: HAL kamera harus menunggu hingga panggilan configureStreams berikutnya selesai sebelum memanggil requestStreamBuffers lagi.
  • HAL kamera telah mencapai batas buffer (kolom maxBuffers): HAL kamera harus menunggu hingga menampilkan setidaknya satu buffer streaming sebelum memanggil requestStreamBuffers lagi.

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 telah diminta oleh framework kamera. Saat itulah metode returnStreamBuffers harus digunakan. Jika implementasi HAL tidak pernah menampung 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 tersedia. Fungsi ini biasanya dipanggil saat framework kamera akan memanggil configureStreams dan harus menguras pipeline pengambilan gambar kamera. Mirip dengan metode returnStreamBuffers, jika implementasi HAL kamera tidak menyimpan lebih banyak buffer daripada yang diminta, implementasi metode ini mungkin kosong.

Setelah framework kamera memanggil signalStreamFlush, framework berhenti mengirim permintaan pengambilan baru ke HAL kamera hingga semua buffer dikembalikan ke framework kamera. Setelah semua buffer dikembalikan, 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.

Semantik berbeda untuk metode signalStreamFlush dan flush metode. Saat metode flush dipanggil, HAL dapat membatalkan permintaan pengambilan gambar yang tertunda dengan ERROR_REQUEST untuk menguras pipeline secepat mungkin. Saat metode signalStreamFlush dipanggil, HAL harus menyelesaikan semua permintaan pengambilan gambar yang tertunda secara normal dan menampilkan semua buffer ke framework kamera.

Perbedaan lain antara metode signalStreamFlush dan metode lainnya adalah bahwa signalStreamFlush adalah metode HIDL satu arah, yang berarti bahwa 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 dengan urutan saat dipanggil 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 daripada panggilan configureStreams yang sesuai. Lihat Contoh 3.

Menangani panggilan yang terlambat tiba

Gambar 3. Cara HAL kamera mendeteksi dan menangani panggilan signalStreamFlush yang terlambat

Perubahan perilaku saat menerapkan API pengelolaan buffer

Saat menggunakan API pengelolaan buffer untuk menerapkan logika pengelolaan 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 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 ditampung HAL dalam satu waktu (nilai ini ditetapkan oleh HAL kamera di kolom HalStream::maxBuffers dalam nilai yang ditampilkan dari panggilan configureStreams). Dengan API pengelolaan buffer, perilaku pembatasan ini tidak lagi ada dan implementasi HAL kamera tidak boleh menerima panggilan processCaptureRequest saat HAL memiliki terlalu banyak permintaan pengambilan gambar yang diantrekan.

  • Latensi panggilan requestStreamBuffers sangat bervariasi: Ada banyak alasan mengapa panggilan requestStreamBuffers 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 sedang menahan buffer dan sibuk memproses. Hal ini dapat menyebabkan permintaan buffer melambat atau mencapai waktu tunggu habis karena kurangnya buffer atau CPU yang sibuk.

Strategi pengelolaan buffer

API pengelolaan buffer memungkinkan penerapan berbagai jenis strategi pengelolaan buffer. Contohnya antara lain:

  • Kompatibel dengan versi lama: HAL meminta buffer untuk permintaan pengambilan selama panggilan processCaptureRequest. Strategi ini tidak memberikan penghematan memori, tetapi dapat berfungsi sebagai penerapan pertama API pengelolaan buffer, yang hanya memerlukan sedikit perubahan kode pada HAL kamera yang ada.
  • Penghematan memori yang dimaksimalkan: HAL kamera hanya meminta buffer output tepat sebelum buffer tersebut perlu diisi. Strategi ini memungkinkan penghematan memori yang maksimal. Potensi kerugiannya adalah lebih banyak jank pada pipeline kamera saat permintaan buffer memerlukan waktu yang sangat lama untuk diselesaikan.
  • Di-cache: HAL kamera meng-cache beberapa buffer sehingga kemungkinan kecil terpengaruh oleh permintaan buffer lambat sesekali.

HAL kamera dapat menerapkan 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 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, API ini telah diupdate untuk menyertakan ExternalCameraDeviceSession.cpp, implementasi buffer management API. HAL kamera eksternal ini menerapkan strategi penghematan memori maksimal yang disebutkan dalam Strategi pengelolaan buffer dalam beberapa ratus baris kode C++.