Android 10, kamera HAL uygulamalarında farklı bellek elde etmek ve gecikme süresi değiş tokuşlarını yakalamak için arabellek yönetimi mantığını uygulamanıza olanak tanıyan isteğe bağlı kamera HAL3 arabellek yönetimi API'lerini sunar.
HAL kamerası, boru hattında sıraya alınmış N isteği (burada N, boru hattı derinliğine eşittir) gerektirir, ancak çoğu zaman aynı anda tüm N çıktı arabelleği setini gerektirmez.
Örneğin, HAL'nin ardışık düzende sıraya alınmış sekiz isteği olabilir, ancak yalnızca boru hattının son aşamalarındaki iki istek için çıktı arabellekleri gerektirir. Android 9 ve önceki sürümleri çalıştıran cihazlarda, istek HAL'de sıraya alındığında kamera çerçevesi arabellekler ayırır, böylece HAL'de kullanılmayan altı arabellek grubu olabilir. Android 10'da, kamera HAL3 arabellek yönetimi API'leri, altı arabellek kümesini boşaltmak için çıkış arabelleklerinin ayrıştırılmasına izin verir. Bu, ileri teknoloji cihazlarda yüzlerce megabayt bellek tasarrufuna yol açabilir ve düşük bellekli cihazlar için de faydalı olabilir.
Şekil 1, Android 9 ve önceki sürümleri çalıştıran cihazlar için kamera HAL arayüzünün bir diyagramını göstermektedir. Şekil 2, uygulanan kamera HAL3 arabellek yönetimi API'leri ile Android 10'daki kamera HAL arabirimini gösterir.
Şekil 1. Android 9 ve önceki sürümlerde kamera HAL arayüzü
Şekil 2. Android 10'da arabellek yönetimi API'lerini kullanan kamera HAL arayüzü
Tampon yönetimi API'lerini uygulama
Arabellek yönetimi API'lerini uygulamak için kamera HAL'ı şunları yapmalıdır:
- HIDL
ICameraDevice@3.5
. -
HIDL_DEVICE_3_5
android.info.supportedBufferManagementVersion
ayarlayın.
HAL kamerası, arabellekleri istemek ve döndürmek için ICameraDeviceCallback.hal
içindeki requestStreamBuffers
ve returnStreamBuffers
yöntemlerini kullanır. HAL ayrıca, kamera ICameraDeviceSession.hal
arabellekleri döndürmesi için sinyal vermek için ICameraDeviceSession.hal içindeki signalStreamFlush
yöntemini uygulamalıdır.
requestStreamBuffers
Kamera çerçevesinden arabellek istemek için requestStreamBuffers
yöntemini kullanın. Kamera HAL3 arabellek yönetimi API'lerini kullanırken, kamera çerçevesinden gelen yakalama istekleri çıktı arabellekleri içermez, yani StreamBuffer
bufferId
alanı 0
. Bu nedenle, kamera HAL'ı, kamera çerçevesinden arabellek istemek için requestStreamBuffers
kullanmalıdır.
requestStreamBuffers
yöntemi, arayan kişinin tek bir aramada birden çok çıktı akışından birden çok arabellek istemesine olanak tanıyarak daha az HIDL IPC çağrısına izin verir. Ancak, aynı anda daha fazla arabellek istendiğinde çağrılar daha uzun sürer ve bu, istekten sonuca toplam gecikme süresini olumsuz etkileyebilir. Ayrıca requestStreamBuffers
yapılan çağrılar kamera hizmetinde serileştirildiğinden, kamera HAL'inin arabellek istemek için özel bir yüksek öncelikli iş parçacığı kullanması önerilir.
Bir arabellek isteği başarısız olursa, kamera HAL'ının önemli olmayan hataları düzgün bir şekilde işleyebilmesi gerekir. Aşağıdaki liste, arabellek isteklerinin başarısız olmasının yaygın nedenlerini ve bunların kamera HAL tarafından nasıl ele alınması gerektiğini açıklar.
- Uygulamanın çıkış akışıyla bağlantısı kesiliyor: Bu, önemli olmayan bir hatadır. HAL kamerası, bağlantısı kesilmiş bir akışı hedefleyen herhangi bir yakalama isteği için
ERROR_REQUEST
göndermeli ve sonraki istekleri normal şekilde işlemeye hazır olmalıdır. - Zaman aşımı: Bu, bir uygulama bazı arabellekleri tutarken yoğun işlem yapmakla meşgul olduğunda ortaya çıkabilir. HAL kamerası, bir zaman aşımı hatası nedeniyle yerine getirilemeyen yakalama istekleri için
ERROR_REQUEST
göndermeli ve sonraki istekleri normal şekilde işlemeye hazır olmalıdır. - Kamera çerçevesi yeni bir akış yapılandırması hazırlıyor: Kamera HAL'si,
requestStreamBuffers
yeniden çağırmadan önce bir sonrakiconfigureStreams
çağrısının tamamlanmasını beklemelidir. - Kamera HAL'ı arabellek sınırına ulaştı (
maxBuffers
alanı): HAL kamerası,requestStreamBuffers
yeniden çağırmadan önce akışın en az bir arabelleğini döndürene kadar beklemelidir.
dönüşAkışTamponları
Kamera çerçevesine fazladan arabellek döndürmek için returnStreamBuffers
yöntemini kullanın. Kamera HAL'ı normalde processCaptureResult
yöntemi aracılığıyla arabellekleri kamera çerçevesine döndürür, ancak yalnızca kamera HAL'ına gönderilen yakalama isteklerini hesaba katabilir. requestStreamBuffers
yöntemiyle, kamera HAL uygulamasının, kamera çerçevesi tarafından istenenden daha fazla arabellek tutması mümkündür. Bu, returnStreamBuffers
yönteminin kullanılması gerektiği zamandır. HAL uygulaması hiçbir zaman istenenden daha fazla arabellek tutmazsa, kamera HAL uygulamasının returnStreamBuffers
yöntemini çağırması gerekmez.
sinyalAkışFlush
signalStreamFlush
yöntemi, kamera HAL'sini eldeki tüm arabellekleri döndürmesi için bilgilendirmek için kamera çerçevesi tarafından çağrılır. Bu, normalde kamera çerçevesi configureStreams
çağırmak üzereyken çağrılır ve kamera yakalama ardışık düzenini boşaltması gerekir. returnStreamBuffers
yöntemine benzer şekilde, bir kamera HAL uygulaması istenenden daha fazla arabellek tutmuyorsa, bu yöntemin boş bir uygulamasının olması mümkündür.
Kamera çerçevesi signalStreamFlush
sonra, çerçeve, tüm arabellekler kamera çerçevesine döndürülene kadar kamera HAL'ına yeni yakalama istekleri göndermeyi durdurur. Tüm arabellekler döndürüldüğünde requestStreamBuffers
yöntemi çağrıları başarısız olur ve kamera çerçevesi temiz bir durumda çalışmasına devam edebilir. Kamera çerçevesi daha sonra ya configureStreams
ya da processCaptureRequest
yöntemini çağırır. Kamera çerçevesi configureStreams
yöntemini çağırırsa, configureStreams
çağrısı başarıyla geri döndükten sonra kamera HAL'ı yeniden arabellek istemeye başlayabilir. Kamera çerçevesi processCaptureRequest
yöntemini çağırırsa, kamera HAL'ı processCaptureRequest
çağrısı sırasında arabellek istemeye başlayabilir.
signalStreamFlush
yöntemi ve flush
yöntemi için anlambilim farklıdır. flush
yöntemi çağrıldığında, HAL, ardışık düzeni mümkün olan en kısa sürede boşaltmak için ERROR_REQUEST
ile bekleyen yakalama isteklerini iptal edebilir. signalStreamFlush
yöntemi çağrıldığında, HAL bekleyen tüm yakalama isteklerini normal şekilde tamamlamalı ve tüm arabellekleri kamera çerçevesine geri göndermelidir.
signalStreamFlush
yöntemi ile diğer yöntemler arasındaki diğer bir fark, signalStreamFlush
tek yönlü bir HIDL yöntemi olmasıdır; bu, HAL, signalStreamFlush
çağrısını almadan önce kamera çerçevesinin diğer engelleme API'lerini çağırabileceği anlamına gelir. Bu, signalStreamFlush
yönteminin ve diğer yöntemlerin (özellikle configureStreams
yöntemi), kamera HAL'ına kamera çerçevesinde çağrıldıklarından farklı bir sırayla ulaşabileceği anlamına gelir. Bu eşzamansızlık sorununu gidermek için, streamConfigCounter
alanı StreamConfiguration'a eklendi ve StreamConfiguration
yöntemine bir argüman olarak signalStreamFlush
. Kamera HAL uygulaması, bir signalStreamFlush
çağrısının karşılık gelen configureStreams
çağrısından sonra gelip gelmediğini belirlemek için streamConfigCounter
bağımsız değişkenini kullanmalıdır. Örnek için Şekil 3'e bakın.
Şekil 3. Kamera HAL'ının geç gelen signalStreamFlush çağrılarını nasıl algılaması ve işlemesi gerektiği
Arabellek yönetimi API'lerini uygularken davranış değişiklikleri
Arabellek yönetimi mantığını uygulamak için arabellek yönetimi API'lerini kullanırken, kamera ve kamera HAL uygulamasında aşağıdaki olası davranış değişikliklerini göz önünde bulundurun:
Yakalama istekleri, kamera HAL'ına daha hızlı ve daha sık ulaşır: Arabellek yönetimi API'leri olmadan, kamera çerçevesi, kamera HAL'ına bir yakalama isteği göndermeden önce her yakalama isteği için çıktı arabellekleri ister. Arabellek yönetimi API'lerini kullanırken, kamera çerçevesinin artık arabellekleri beklemesi gerekmez ve bu nedenle kamera HAL'ına daha önce yakalama istekleri gönderebilir.
Ayrıca, arabellek yönetimi API'leri olmadan, yakalama isteğinin çıkış akışlarından biri HAL'ın bir seferde tutabileceği maksimum arabellek sayısına ulaştığında kamera çerçevesi yakalama istekleri göndermeyi durdurur (bu değer, Bir
configureStreams
çağrısının dönüş değerindekiHalStream::maxBuffers
alanı). Arabellek yönetimi API'leri ile bu kısıtlama davranışı artık mevcut değildir ve HAL'de sıraya alınmış çok fazla yakalama isteği olduğunda kamera HAL uygulamasıprocessCaptureRequest
çağrılarını kabul etmemelidir.requestStreamBuffers
arama gecikmesi önemli ölçüde değişir: BirrequestStreamBuffers
aramasının ortalamadan daha uzun sürmesinin birçok nedeni vardır. Örneğin:- Yeni oluşturulan bir akışın ilk birkaç arabelleği için, cihazın bellek ayırması gerektiğinden aramalar daha uzun sürebilir.
- Beklenen gecikme, her çağrıda istenen arabellek sayısıyla orantılı olarak artar.
- Uygulama arabellek tutuyor ve işleniyor. Bu, arabellek isteklerinin yavaşlamasına veya arabellek eksikliği veya yoğun bir CPU nedeniyle zaman aşımına uğramasına neden olabilir.
Tampon yönetimi stratejileri
Tampon yönetimi API'leri, farklı türde arabellek yönetimi stratejilerinin uygulanmasına izin verir. Bazı örnekler:
- Geriye dönük uyumlu: HAL istekleri,
processCaptureRequest
çağrısı sırasında bir yakalama isteği için arabelleğe alır. Bu strateji herhangi bir bellek tasarrufu sağlamaz, ancak mevcut kamera HAL'inde çok az kod değişikliği gerektiren arabellek yönetimi API'lerinin ilk uygulaması olarak hizmet edebilir. - Maksimum bellek tasarrufu: Kamera HAL'i, yalnızca birinin doldurulması gerekmeden hemen önce çıktı arabellekleri ister. Bu strateji, maksimum bellek tasarrufu sağlar. Potansiyel dezavantajı, arabellek isteklerinin tamamlanması olağandışı uzun zaman aldığında daha fazla kamera ardışık düzeni sarsıntısıdır.
- Önbelleğe Alındı: Kamera HAL'si, ara sıra gerçekleşen yavaş bir arabellek isteğinden etkilenme olasılığını azaltmak için birkaç arabelleği önbelleğe alır.
Kamera HAL'ı, örneğin çok fazla bellek kullanan kullanım durumları için maksimum bellek tasarrufu stratejisini kullanmak ve diğer kullanım durumları için geriye dönük uyumlu stratejiyi kullanmak gibi belirli kullanım durumları için farklı stratejiler benimseyebilir.
Harici kamera HAL'de örnek uygulama
Harici kamera HAL, Android 9'da tanıtıldı ve kaynak ağacında hardware/interfaces/camera/device/3.5/
adresinde bulunabilir. Android 10'da, arabellek yönetimi API'sinin bir uygulaması olan ExternalCameraDeviceSession.cpp
içerecek şekilde güncellendi. Bu harici kamera HAL, birkaç yüz satırlık C++ kodunda Arabellek yönetimi stratejilerinde belirtilen maksimum bellek tasarrufu stratejisini uygular.