Android 10, kamera HAL uygulamalarında farklı bellek ve yakalama gecikmesi dengeleri elde etmek için arabellek yönetimi mantığını uygulamanıza olanak tanıyan isteğe bağlı kamera HAL3 arabellek yönetimi API'lerini kullanıma sunar.
Kamera HAL'i, ardışık düzeninde sıraya alınmış N istek (N, ardışık düzen derinliğine eşittir) gerektirir ancak genellikle tüm N çıkış arabelleği grubunu aynı anda kullanmaz.
Örneğin, HAL'de ardışık düzende sekiz istek olabilir ancak yalnızca ardışık düzenin son aşamalarındaki iki istek için çıkış arabellekleri gerekir. Android 9 ve daha eski sürümleri çalıştıran cihazlarda, istek HAL'de sıraya alındığında kamera çerçevesi arabellekleri ayırır. Bu nedenle, HAL'de kullanılmayan altı adet arabellek grubu olabilir. Android 10'da kamera HAL3 arabellek yönetimi API'leri, altı arabellek grubunu boşaltmak için çıkış arabelleklerinin ayrılmasına olanak tanır. Bu, yüksek kaliteli cihazlarda yüzlerce megabaytlık bellek tasarrufu sağlayabilir ve bellek miktarı düşük cihazlar için de yararlı olabilir.
Şekil 1'de, Android 9 ve önceki sürümleri çalıştıran cihazlar için kamera HAL arayüzünün şeması gösterilmektedir. Şekil 2'de, Android 10'daki kamera HAL arayüzü, kamera HAL3 arabellek yönetimi API'lerinin uygulandığı şekilde gösterilmektedir.
Şekil 1. Android 9 ve önceki sürümlerde Camera HAL arayüzü
Şekil 2. Android 10'da arabelleğe alma yönetimi API'lerini kullanan kamera HAL arayüzü
Arabellek yönetimi API'lerini uygulama
Kamera HAL'i, arabellek yönetimi API'lerini uygulamak için şunları yapmalıdır:
- HIDL'yi uygulayın
ICameraDevice@3.5
. - Kamera özellikleri anahtarını
android.info.supportedBufferManagementVersion
HIDL_DEVICE_3_5
olarak ayarlayın.
Kamera HAL'i, arabellekleri istemek ve döndürmek için ICameraDeviceCallback.hal
bölümündeki requestStreamBuffers
ve returnStreamBuffers
yöntemlerini kullanır. HAL, kamera HAL'ine arabellek döndürmesi için sinyal vermek üzere ICameraDeviceSession.hal
bölümündeki signalStreamFlush
yöntemini de uygulamalıdır.
requestStreamBuffers
Kamera çerçevesinden arabelleğe alma isteği göndermek için requestStreamBuffers
yöntemini kullanın. Kamera HAL3 arabellek yönetimi API'leri kullanılırken kamera çerçevesinden gelen yakalama istekleri çıkış arabellekleri içermez. Yani StreamBuffer
içindeki bufferId
alanı 0
olur. Bu nedenle, kamera HAL'i, kamera çerçevesinden arabelleğe alma isteği göndermek için requestStreamBuffers
kullanmalıdır.
requestStreamBuffers
yöntemi, arayanın tek bir çağrıda birden fazla çıkış akışından birden fazla arabellek istemesine olanak tanır. Böylece daha az HIDL IPC çağrısı yapılır. Ancak aynı anda daha fazla arabellek istendiğinde aramalar daha uzun sürer ve bu durum toplam istek-sonuç gecikmesini olumsuz yönde etkileyebilir.
Ayrıca, requestStreamBuffers
çağrıları kamera hizmetinde serileştirildiğinden, kamera HAL'inin arabellekleri istemek için özel bir yüksek öncelikli iş parçacığı kullanması önerilir.
Bir arabellek isteği başarısız olursa kamera HAL'i, ölümcül olmayan hataları düzgün şekilde işleyebilmelidir. Aşağıdaki listede, arabellek isteklerinin başarısız olmasının yaygın nedenleri ve kamera HAL'i tarafından nasıl ele alınması gerektiği açıklanmaktadır.
- Uygulamanın çıkış akışıyla bağlantısı kesildi:
Bu önemli olmayan bir hatadır. Kamera HAL'i, bağlantısı kesilmiş bir akışı hedefleyen tüm yakalama istekleri için
ERROR_REQUEST
göndermeli ve sonraki istekleri normal şekilde işlemeye hazır olmalıdır. - Zaman aşımı: Bu durum, bir uygulama bazı arabellekleri tutarken yoğun işlem yapıyorsa ortaya çıkabilir. Kamera HAL'i, zaman aşımı hatası nedeniyle karşılanamayan 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'i,
requestStreamBuffers
'i tekrar çağırmadan önce sonrakiconfigureStreams
çağrının tamamlanmasını beklemelidir. - Kamera HAL'i arabellek sınırına (
maxBuffers
alanı) ulaştı: Kamera HAL'i,requestStreamBuffers
işlevini tekrar çağırmadan önce yayından en az bir arabellek döndürene kadar beklemelidir.
returnStreamBuffers
Kamera çerçevesine fazladan arabellek döndürmek için returnStreamBuffers
yöntemini kullanın. Kamera HAL'i normalde processCaptureResult
yöntemi aracılığıyla kamera çerçevesine arabellekleri döndürür ancak yalnızca kamera HAL'ine 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 durumda returnStreamBuffers
yöntemi kullanılmalıdır. HAL uygulaması hiçbir zaman istenenden fazla arabellek tutmuyorsa kamera HAL uygulamasının returnStreamBuffers
yöntemini çağırması gerekmez.
signalStreamFlush
signalStreamFlush
yöntemi, kamera HAL'ini mevcut tüm arabellekleri döndürmesi için bilgilendirmek üzere kamera çerçevesi tarafından çağrılır. Bu işlev genellikle kamera çerçevesi configureStreams
işlevini çağırmaya hazırlanırken ve kamera yakalama ardışık düzenini 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ı olabilir.
Kamera çerçevesi signalStreamFlush
çağrısını yaptıktan sonra, tüm arabellekler kamera çerçevesine döndürülene kadar çerçeve, kamera HAL'ine yeni yakalama isteği 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. Ardından kamera çerçevesi, configureStreams
veya processCaptureRequest
yöntemini çağırır. Kamera çerçevesi configureStreams
yöntemini çağırırsa kamera HAL'i, configureStreams
çağrısı başarıyla döndükten sonra tekrar arabellek isteyebilir. Kamera çerçevesi processCaptureRequest
yöntemini çağırırsa kamera HAL'i processCaptureRequest
çağrısı sırasında arabellek isteğinde bulunmaya başlayabilir.
signalStreamFlush
yöntemi ile flush
yönteminin semantikleri farklıdır. flush
yöntemi çağrıldığında HAL, ardışık düzeni 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 tamamlamalı ve tüm arabellekleri kamera çerçevesine döndürmelidir.
signalStreamFlush
yöntemi ile diğer yöntemler arasındaki bir diğer fark da signalStreamFlush
'ün tek yönlü bir HIDL yöntemi olmasıdır. Bu, HAL signalStreamFlush
çağrısını almadan önce kamera çerçevesinin diğer engelleyen API'leri çağırabileceği anlamına gelir. Bu, signalStreamFlush
yönteminin ve diğer yöntemlerin (özellikle configureStreams
yönteminin) kamera HAL'ine, kamera çerçevesinde çağrıldıkları sıradan farklı bir sırada ulaşabileceği anlamına gelir. Bu senkronizasyon sorununu gidermek için streamConfigCounter
alanı StreamConfiguration
'a ve signalStreamFlush
yöntemine bağımsız değişken olarak eklendi. Kamera HAL uygulaması, bir signalStreamFlush
çağrısının ilgili configureStreams
çağrısından daha geç 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'inin geç gelen signalStreamFlush çağrılarını nasıl algılaması ve işlemesi gerekir?
Arabellek yönetimi API'leri uygulanırken 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:
Kamera HAL'ine daha hızlı ve daha sık yakalama isteği gönderilir: Arabellek yönetimi API'leri olmadan kamera çerçevesi, kamera HAL'ine yakalama isteği göndermeden önce her yakalama isteği için çıkış arabellekleri ister. Arabellek yönetimi API'leri kullanıldığında kamera çerçevesinin artık arabellekleri beklemesi gerekmez ve bu nedenle kamera HAL'ine daha erken yakalama istekleri gönderebilir.
Ayrıca, arabellek yönetimi API'leri olmadan kamera çerçevesi, yakalama isteğinin çıkış akışlarından biri HAL'ın tek seferde tutabileceği maksimum arabellek sayısına ulaşırsa yakalama isteği göndermeyi durdurur (bu değer,
configureStreams
çağrısının döndürülen değerindekiHalStream::maxBuffers
alanında kamera HAL'i tarafından belirlenir). Arabellek yönetimi API'leriyle bu akış kontrolü davranışı artık mevcut değildir ve HAL'de çok fazla yakalama isteği sıraya alındığında kamera HAL uygulamasıprocessCaptureRequest
çağrılarını kabul etmemelidir.requestStreamBuffers
arama gecikmesi önemli ölçüde değişir:requestStreamBuffers
aramasının ortalamadan daha uzun sürmesinin birçok nedeni vardır. Örnek:- Yeni oluşturulan bir yayını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ına orantılı olarak artar.
- Uygulama, arabellekleri tutuyor ve işleme almakla meşgul. Bu durum, arabelleğe alma istekleri yavaşlamasına veya arabelleğe alma alanı eksikliği ya da meşgul bir CPU nedeniyle zaman aşımına uğramasına neden olabilir.
Arabellek 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 yakalama isteği için arabellek ister. Bu strateji, 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 kullanılabilir. - Maksimum bellek tasarrufu: Kamera HAL'i, yalnızca doldurulması gerektiği andan hemen önce çıkış arabelleklerini ister. Bu strateji, maksimum bellek tasarrufu sağlar. Bunun olası bir olumsuz yönü, tampon isteklerinin tamamlanmasının alışılmadık derecede uzun sürmesi durumunda kamera ardışık düzeninde daha fazla gecikme yaşanmasıdır.
- Önbelleğe alınmış: Kamera HAL'i, ara sıra yavaş bir arabellek isteğinden etkilenme olasılığını azaltmak için birkaç arabelleği önbelleğe alır.
Kamera HAL'i, belirli kullanım alanları için farklı stratejiler benimseyebilir. Örneğin, çok fazla bellek kullanan kullanım alanları için en yüksek bellek tasarrufu stratejisini, diğer kullanım alanları için geriye dönük uyumlu stratejiyi kullanabilir.
Harici kamera HAL'inde örnek uygulama
Harici kamera HAL'i Android 9'da kullanıma sunuldu ve hardware/interfaces/camera/device/3.5/
adresindeki kaynak ağacında bulunabilir.
Android 10'da, arabelleğe alma yönetimi API'sinin bir uygulaması olan ExternalCameraDeviceSession.cpp
eklenecek şekilde güncellendi. Bu harici kamera HAL'i, Arabellek yönetimi stratejileri bölümünde belirtilen maksimum bellek tasarrufu stratejisini birkaç yüz satır C++ kodunda uygular.