Android 10, farklı bellek elde etmek ve kamera HAL uygulamalarında gecikme dengelerini yakalamak için arabellek yönetimi mantığı uygulamanıza olanak tanıyan isteğe bağlı kamera HAL3 arabellek yönetimi API'leri 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 bir ş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 arabellek yönetimi API'lerinin kullanıldığı 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'nin, kamera HAL'sine arabellek döndürmesi yönünde sinyal vermek için ICameraDeviceSession.hal
ürününde signalStreamFlush
yöntemini de uygulaması gerekir.
requestStreamBuffers
Kamera çerçevesinden arabelleğe alma isteği göndermek için requestStreamBuffers
yöntemini kullanın. Kamera HAL3 arabellek yönetimi API'lerini kullanırken kamera çerçevesinden gelen yakalama istekleri çıkış arabellekleri içermez. Yani StreamBuffer
içindeki bufferId
alanı 0
şeklindedir. 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. Bununla birlikte, aynı anda daha fazla arabellek istendiğinde çağrılar daha fazla zaman alır ve bu durum, toplam sonuç-sonuca yönelik gecikmeyi 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, arabelleğe alma 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 hata, önemli değildir. 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:
requestStreamBuffers
tekrar çağrılmadan önce kamera HAL'si bir sonrakiconfigureStreams
çağrısının tamamlanmasını beklemelidir. - Kamera HAL'si,
arabellek sınırına
(
maxBuffers
alanı) ulaştı: Kamera HAL'si,requestStreamBuffers
tekrar çağrılmadan önce, akışın en az bir arabelleğini döndürene kadar beklemelidir.
returnStreamBuffers
Kamera çerçevesine ekstra tamponlar 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. returnStreamBuffers
yönteminin kullanılması gereken durumlar budur. HAL uygulaması hiçbir zaman istenenden fazla arabellek tutmuyorsa kamera HAL uygulamasının returnStreamBuffers
yöntemini çağırması gerekmez.
sinyal Akışı Flush
signalStreamFlush
yöntemi, kamera çerçevesi tarafından kamera HAL'sine mevcut tüm arabellekleri döndürmesini bildirmek için ç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 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
veya 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 tekrar arabellek istemeye başlayabilir. 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 ve flush
yöntemi için anlamlar 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 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ında, 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şkeni kullanılmalıdır. Örnek için bkz. Şekil 3.
Şekil 3. Kamera HAL'inin geç gelen signalStreamFlush çağrılarını nasıl algılaması ve işlemesi gerekir?
Tampon 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:
Yakalama istekleri kamera HAL'ye daha hızlı ve daha sık ulaşır: Tampon yönetimi API'leri olmadığında kamera çerçevesi, kamera HAL'sine bir yakalama isteği göndermeden önce her yakalama isteği için çıkış tamponları ister. Arabellek yönetimi API'leri kullanılırken kamera çerçevesinin artık arabellek beklemesine gerek yoktur ve bu nedenle yakalama isteklerini kamera HAL'sine daha erken 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'leri sayesinde bu akış kısıtlaması 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 arabelleklerin sayısıyla 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. Bu parçalardan bazıları:
- Geriye dönük uyumlu: HAL,
processCaptureRequest
çağrısı sırasında bir 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'si, belirli kullanım alanları için farklı stratejiler uygulayabilir. Örneğin, çok fazla bellek kullanan kullanım alanları için maksimum bellek tasarrufu stratejisini ve diğer kullanım alanları için geriye dönük uyumlu stratejiyi kullanabilir.
Harici kamera HAL'inde örnek uygulama
Harici kamera HAL'si, Android 9'da kullanıma sunulmuştur ve hardware/interfaces/camera/device/3.5/
adresindeki kaynak ağaçta 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.