Android 10, farklı bellek elde etmek ve kamera HAL uygulamalarında gecikme değişimlerini 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.
Kamera HAL'si, ardışık düzende kuyruğa alınmış N istek (burada N, boru hattı derinliğine eşittir) gerektirir, ancak çoğu zaman aynı anda N sayıda çıktı arabelleği setine ihtiyaç duymaz.
Örneğin, HAL'de ardışık düzende sekiz istek sıralanmış olabilir, ancak yalnızca ardışık düzenin son aşamalarındaki iki istek için çıktı arabelleklerine ihtiyaç duyar. Android 9 ve daha önceki sürümleri çalıştıran cihazlarda, istek HAL'de kuyruğa alındığında kamera çerçevesi arabellekleri ayırır, böylece HAL'de kullanımda olmayan altı arabellek kümesi bulunabilir. Android 10'da, kamera HAL3 arabellek yönetimi API'leri, altı arabellek kümesini serbest bırakmak için çıkış arabelleklerinin ayrılmasına olanak tanır. Bu, ileri teknoloji cihazlarda yüzlerce megabaytlık bellek tasarrufuna yol açabilir ve aynı zamanda düşük belleğe sahip cihazlar için de faydalı olabilir.
Şekil 1, Android 9 ve daha düşük sürümleri çalıştıran cihazlar için kamera HAL arayüzünün bir diyagramını göstermektedir. Şekil 2, kamera HAL3 arabellek yönetimi API'lerinin uygulandığı Android 10'daki kamera HAL arayüzünü göstermektedir.
Ş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ü
Arabellek yönetimi API'lerini uygulama
Arabellek yönetimi API'lerini uygulamak için kamera HAL'nin şunları yapması gerekir:
- HIDL
ICameraDevice@3.5
uygulayın. -
android.info.supportedBufferManagementVersion
kamera özellikleri anahtarınıHIDL_DEVICE_3_5
olarak ayarlayın.
Kamera HAL'si, arabellekleri istemek ve döndürmek için ICameraDeviceCallback.hal
requestStreamBuffers
ve returnStreamBuffers
yöntemlerini kullanır. HAL'ın, arabellekleri döndürmesi için kamera HAL'sine sinyal vermek üzere ICameraDeviceSession.hal
dosyasındaki signalStreamFlush
yöntemini de uygulaması gerekir.
requestStreamBuffer'lar
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'sinin, kamera çerçevesinden arabellek istemek için requestStreamBuffers
kullanması gerekir.
requestStreamBuffers
yöntemi, arayanın tek bir çağrıda birden çok çıkış akışından birden çok arabellek istemesine olanak tanıyarak daha az HIDL IPC çağrısı yapılmasına olanak tanır. Ancak, aynı anda daha fazla arabellek istendiğinde çağrılar daha fazla zaman alır ve bu, toplam istek-sonuç gecikmesini olumsuz etkileyebilir. Ayrıca requestStreamBuffers
yapılan çağrılar kamera hizmetinde serileştirildiğinden, kamera HAL'sinin 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'nin ölümcül olmayan hataları düzgün ş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çıklamaktadır.
- Uygulamanın çıkış akışıyla bağlantısı kesiliyor: Bu önemli olmayan bir hatadır. Kamera HAL, bağlantısız 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 uygulamanın bazı arabellekleri tutarken yoğun işlem yapmakla meşgul olması durumunda ortaya çıkabilir. Kamera HAL, 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
tekrar çağırmadan önce bir sonrakiconfigureStreams
çağrısının tamamlanmasını beklemelidir. - Kamera HAL'si arabellek sınırına ulaştı (
maxBuffers
alanı): Kamera HAL'i,requestStreamBuffers
yeniden çağırmadan önce akışın en az bir arabelleğini döndürene kadar beklemelidir.
returnStreamBuffer'lar
Ekstra arabellekleri kamera çerçevesine döndürmek için returnStreamBuffers
yöntemini kullanın. Kamera HAL'si normalde, processCaptureResult
yöntemi aracılığıyla arabellekleri kamera çerçevesine döndürür, ancak yalnızca kamera HAL'sine gönderilen yakalama isteklerini hesaba katabilir. requestStreamBuffers
yöntemiyle, kamera HAL uygulamasının, kamera çerçevesi tarafından talep edilenden daha fazla arabellek tutması mümkündür. Bu, returnStreamBuffers
yönteminin kullanılması gereken zamandır. HAL uygulaması hiçbir zaman istenenden daha fazla arabellek tutmuyorsa, kamera HAL uygulamasının returnStreamBuffers
yöntemini çağırmasına gerek yoktur.
sinyalStreamFlush
signalStreamFlush
yöntemi, kamera çerçevesi tarafından kamera HAL'sine eldeki tüm arabellekleri döndürmesi konusunda bildirimde bulunmak için çağrılır. Bu normalde kamera çerçevesi, configureStreams
çağırmak üzereyken ve kamera yakalama hattını boşaltması gerektiğinde çağrılır. 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
çağırdıktan sonra, tüm arabellekler kamera çerçevesine döndürülene kadar çerçeve, kamera HAL'sine yeni yakalama istekleri göndermeyi durdurur. Tüm arabellekler döndürüldüğünde requestStreamBuffers
yöntem çağrıları başarısız olur ve kamera çerçevesi temiz bir durumda çalışmaya devam edebilir. Daha sonra kamera çerçevesi, configureStreams
processCaptureRequest
yöntemini çağırır. Kamera çerçevesi, configureStreams
yöntemini çağırırsa, configureStreams
çağrısı başarılı bir şekilde geri döndükten sonra kamera HAL'si yeniden arabellek istemeye başlayabilir. Kamera çerçevesi, processCaptureRequest
yöntemini çağırırsa, kamera HAL'si, processCaptureRequest
çağrısı sırasında arabellek istemeye başlayabilir.
signalStreamFlush
yöntemi ve flush
yönteminin anlambilimi farklıdır. flush
yöntemi çağrıldığında HAL, boru hattını mümkün olan en kısa sürede boşaltmak için bekleyen yakalama isteklerini ERROR_REQUEST
ile iptal edebilir. signalStreamFlush
yöntemi çağrıldığında HAL, bekleyen tüm yakalama isteklerini normal şekilde bitirmeli ve tüm arabellekleri kamera çerçevesine döndürmelidir.
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 arayabileceği anlamına gelir. Bu, signalStreamFlush
yönteminin ve diğer yöntemlerin (özellikle configureStreams
yönteminin), kamera HAL'sine, kamera çerçevesinde çağrıldıkları sıradan farklı bir sırayla ulaşabileceği anlamına gelir. Bu eşzamansızlık sorununu çözmek için, streamConfigCounter
alanı StreamConfiguration
eklendi ve signalStreamFlush
yöntemine argüman olarak eklendi. Kamera HAL uygulaması, bir signalStreamFlush
çağrısının karşılık configureStreams
çağrısından sonra gelip gelmediğini belirlemek için streamConfigCounter
değişkenini kullanmalıdır. Örnek için Şekil 3'e bakınız.
Şekil 3. Kamera HAL'nin geç gelen signalStreamFlush çağrılarını nasıl algılaması ve işlemesi gerekir?
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'sine daha hızlı ve daha sık ulaşır: Arabellek yönetimi API'leri olmadan, kamera çerçevesi, kamera HAL'sine bir yakalama isteği göndermeden önce her yakalama isteği için çıkış arabellekleri ister. Arabellek yönetimi API'lerini kullanırken, kamera çerçevesinin artık arabellekleri beklemesine gerek yoktur ve bu nedenle yakalama isteklerini kamera HAL'sine daha erken gönderebilir.
Ayrıca arabellek yönetimi API'leri olmadan, yakalama isteğinin çıkış akışlarından biri HAL'in aynı anda tutabileceği maksimum arabellek sayısına ulaştığında kamera çerçevesi yakalama istekleri göndermeyi durdurur (bu değer, HAL'deki kamera tarafından belirlenir).
HalStream::maxBuffers
alanı,configureStreams
çağrısının dönüş değerindedir). 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ının,processCaptureRequest
çağrılarını kabul etmemesi gerekir.requestStreamBuffers
çağrı gecikmesi önemli ölçüde değişiklik gösterir:requestStreamBuffers
çağrısı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 talep edilen arabellek sayısıyla orantılı olarak artar.
- Uygulama arabellekleri tutuyor ve işlem yapmakla meşgul. Bu, arabellek eksikliği veya meşgul CPU nedeniyle arabellek isteklerinin yavaşlamasına veya zaman aşımına uğramasına neden olabilir.
Tampon yönetimi stratejileri
Arabellek yönetimi API'leri, farklı türde arabellek yönetimi stratejilerinin uygulanmasına olanak tanır. Bazı örnekler:
- Geriye dönük uyumlu: HAL,
processCaptureRequest
çağrısı sırasında bir yakalama isteği için arabellek ister. Bu strateji herhangi bir bellek tasarrufu sağlamaz ancak arabellek yönetimi API'lerinin ilk uygulaması olarak hizmet verebilir ve mevcut kamera HAL'sinde çok az kod değişikliği yapılmasını gerektirir. - Maksimum bellek tasarrufu: Kamera HAL, çıkış arabelleklerini yalnızca doldurulması gerekmeden hemen önce talep eder. Bu strateji maksimum bellek tasarrufuna olanak tanır. Potansiyel dezavantajı, arabellek isteklerinin tamamlanması alışılmadık derecede uzun zaman aldığında daha fazla kamera ardışık düzeni patlamasıdır.
- Önbelleğe Alınmış: Kamera HAL'si birkaç arabelleği önbelleğe alır, böylece ara sıra yapılan yavaş arabellek isteklerinden etkilenme olasılığı azalır.
Kamera HAL, belirli kullanım durumları için farklı stratejiler benimseyebilir; ö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 uyumluluk stratejisini kullanmak.
Harici kamera HAL'sinde örnek uygulama
Harici kamera HAL, Android 9'da tanıtıldı ve hardware/interfaces/camera/device/3.5/
adresindeki kaynak ağacında bulunabilir. Android 10'da, arabellek yönetimi API'sinin bir uygulaması olan ExternalCameraDeviceSession.cpp
içerecek şekilde güncellendi. Bu harici kamera HAL, Arabellek yönetimi stratejilerinde belirtilen maksimum bellek tasarrufu stratejisini birkaç yüz satırlık C++ kodunda uygular.