Android 10, kamera donanım soyutlama katmanı uygulamalarında farklı bellek ve yakalama gecikmesi dengelemeleri elde etmek için arabellek yönetimi mantığı uygulamanıza olanak tanıyan isteğe bağlı kamera donanım soyutlama katmanı 3 arabellek yönetimi API'lerini sunar.
Kamera HAL'si, işlem hattında N istek (N, işlem hattı derinliğine eşittir) sıraya alınmasını gerektirir ancak genellikle N çıkış arabelleği grubunun tamamının aynı anda kullanılmasını gerektirmez.
Örneğin, HAL'de işlem hattında sekiz istek sıraya alınmış olabilir ancak işlem hattının son aşamalarındaki iki istek için yalnızca çıkış arabellekleri gerekir. Android 9 ve daha eski sürümlerin yüklü olduğu cihazlarda, istek HAL'de sıraya alındığında kamera çerçevesi arabellekler ayırır. Bu nedenle, HAL'de kullanılmayan altı 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 sayede üst düzey cihazlarda yüzlerce megabayt bellek tasarrufu sağlanabilir ve düşük bellekli cihazlar da bu özellikten yararlanabilir.
Şekil 1'de, Android 9 ve önceki sürümlerin yüklü olduğu cihazlardaki kamera HAL arayüzünün şeması gösterilmektedir. Şekil 2'de, Android 10'daki kamera HAL3 arabellek yönetimi API'lerinin uygulandığı kamera HAL arayüzü gösterilmektedir.
1. şekil. Android 9 ve önceki sürümlerdeki Camera 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'ı ş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, arabellekleri istemek ve döndürmek için ICameraDeviceCallback.hal
içindeki requestStreamBuffers
ve returnStreamBuffers
yöntemlerini kullanır. HAL, kamera HAL'ine arabellekleri döndürmesini bildirmek için signalStreamFlush
yöntemini ICameraDeviceSession.hal
içinde de uygulamalıdır.
requestStreamBuffers
Kamera çerçevesinden arabellek istemek 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. Diğer bir deyişle, StreamBuffer
içindeki bufferId
alanı 0
'dir. Bu nedenle, kamera HAL'ı kamera çerçevesinden arabellek istemek 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. Bu sayede 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 istekten sonuca kadar olan gecikmeyi olumsuz etkileyebilir.
Ayrıca, requestStreamBuffers
içine yapılan çağrılar kamera hizmetinde seri hale getirildiğinden, kamera HAL'ının 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'ı, ö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 bunların kamera HAL'ı tarafından nasıl işlenmesi gerektiği açıklanmaktadır.
- Uygulamanın çıkış akışıyla bağlantısı kesiliyor:
Bu, önemli olmayan bir hatadır. Kamera HAL'si, 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 yaparken ortaya çıkabilir. Kamera HAL'ı, 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'ı,
requestStreamBuffers
işlevini tekrar çağırmadan önce bir sonrakiconfigureStreams
çağrısının tamamlanmasını beklemelidir. - Kamera HAL'ı arabellek sınırına ulaştı
(
maxBuffers
alanı): Kamera HAL'ı,requestStreamBuffers
işlevini tekrar çağırmadan önce akışın en az bir arabelleğini döndürene kadar beklemelidir.
returnStreamBuffers
Fazladan arabellekleri kamera çerçevesine döndürmek için returnStreamBuffers
yöntemini kullanın. Kamera HAL'ı normalde processCaptureResult
yöntemiyle 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. returnStreamBuffers
yöntemi bu gibi durumlarda kullanılmalıdır. HAL uygulaması hiçbir zaman istenenden daha fazla arabellek tutmuyorsa kamera HAL uygulamasının returnStreamBuffers
yöntemini çağırması gerekmez.
signalStreamFlush
signalStreamFlush
yöntemi, kamera donanım soyutlama katmanına (HAL) eldeki tüm arabellekleri döndürmesini bildirmek için kamera çerçevesi tarafından çağrılır. Bu yöntem normalde kamera çerçevesi configureStreams
yöntemini çağırmak üzereyken çağrılır ve kamera yakalama işlem hattını boşaltması gerekir. 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
işlevini çağırdıktan sonra, tüm arabellekler kamera çerçevesine döndürülene kadar çerçeve, kamera donanım soyutlama katmanı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 çalışmasına temiz bir durumda devam edebilir. Kamera çerçevesi daha sonra configureStreams
veya processCaptureRequest
yöntemini çağırır. Kamera çerçevesi configureStreams
yöntemini çağırırsa kamera HAL'ı, configureStreams
çağrısı başarıyla döndükten sonra tekrar arabellek isteğinde bulunmaya başlayabilir. Kamera çerçevesi processCaptureRequest
yöntemini çağırırsa kamera HAL'ı processCaptureRequest
çağrısı sırasında arabellek isteğinde bulunmaya başlayabilir.
signalStreamFlush
yöntemi ve flush
yöntemi için semantik farklıdır. flush
yöntemi çağrıldığında HAL, boru hattını 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, signalStreamFlush
yönteminin tek yönlü bir HIDL yöntemi olmasıdır. Bu, HAL, signalStreamFlush
çağrısını almadan önce kamera çerçevesinin diğer engelleyici API'leri çağırabileceği anlamına gelir. Bu, signalStreamFlush
yöntemi ve diğer yöntemlerin (özellikle configureStreams
yöntemi) kamera HAL'ına, kamera çerçevesinde çağrıldıkları sıradan farklı bir sırada ulaşabileceği anlamına gelir. Bu eşzamansızlık sorununu gidermek için streamConfigCounter
alanı StreamConfiguration
öğesine ve signalStreamFlush
yöntemine bağımsız değişken olarak eklendi. Kamera HAL uygulaması, streamConfigCounter
argument'ı kullanarak bir signalStreamFlush
çağrısının, karşılık gelen configureStreams
çağrısından daha sonra gelip gelmediğini belirlemelidir. Örnek için Şekil 3'e bakın.
3.Şekil Kamera HAL'ı, geç gelen signalStreamFlush çağrılarını nasıl algılamalı ve işlemelidir?
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 kamerada ve kamera HAL uygulamasında aşağıdaki olası davranış değişikliklerini göz önünde bulundurun:
Yakalama istekleri, kamera donanım soyutlama katmanına daha hızlı ve daha sık ulaşır: Arabellek yönetimi API'leri olmadan kamera çerçevesi, kamera donanım soyutlama katmanına yakalama isteği göndermeden önce her yakalama isteği için çıkış arabellekleri ister. Arabellek yönetimi API'leri kullanılırken kamera çerçevesinin artık arabellekleri beklemesi gerekmez. Bu nedenle, yakalama isteklerini kamera HAL'ye daha erken gönderebilir.
Ayrıca, arabelleği yönetme API'leri olmadan, yakalama isteğinin çıkış akışlarından biri HAL'ın aynı anda tutabileceği maksimum arabellek sayısına ulaşırsa kamera çerçevesi yakalama isteği göndermeyi durdurur (bu değer,
configureStreams
çağrısının dönüş değerindekiHalStream::maxBuffers
alanında kamera HAL'ı tarafından belirlenir). Arabellek yönetimi API'leri ile bu sınırlama davranışı artık mevcut değildir ve HAL'da çok fazla yakalama isteği sıraya alınmışken kamera HAL uygulamasıprocessCaptureRequest
çağrılarını kabul etmemelidir.requestStreamBuffers
Arama gecikmesi önemli ölçüde değişiyor:requestStreamBuffers
aramaları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 arabellekleri tutuyor ve işlemeyle meşgul. Bu durum, arabellek eksikliği veya CPU'nun meşgul olması nedeniyle arabellek isteklerinin yavaşlamasına ya da zaman aşımına uğramasına neden olabilir.
Arabellek yönetimi stratejileri
Arabellek yönetimi API'leri, farklı arabellek yönetimi stratejilerinin uygulanmasına olanak tanır. Örnek olarak şunlar verilebilir:
- Geriye dönük uyumlu: HAL,
processCaptureRequest
çağrısı sırasında bir yakalama isteği için arabellekler ister. Bu strateji herhangi bir bellek tasarrufu sağlamaz ancak arabellek yönetimi API'lerinin ilk uygulaması olarak kullanılabilir ve mevcut kamera HAL'sinde çok az kod değişikliği gerektirir. - Maksimum bellek tasarrufu: Kamera HAL'ı, yalnızca doldurulması gereken bir çıkış arabelleği hemen öncesinde ister. Bu strateji, bellek tasarrufunun en üst düzeye çıkarılmasını sağlar. Tampon isteklerinin tamamlanması alışılmadık derecede uzun sürdüğünde kamera işlem hattında olası bir aksaklık yaşanabilir.
- Önbelleğe alınmış: Kamera HAL'si, aralıklı olarak yavaş arabellek isteğinden etkilenme olasılığını azaltmak için birkaç arabellek önbelleğe alır.
Kamera HAL, belirli kullanım alanları için farklı stratejiler benimseyebilir. Örneğin, çok fazla bellek kullanan kullanım alanlarında bellek tasarrufunu en üst düzeye çıkaran stratejiyi, diğer kullanım alanlarında ise geriye dönük uyumlu stratejiyi kullanabilir.
Harici kamera HAL'sindeki örnek uygulama
Harici kamera HAL'si Android 9'da kullanıma sunulmuştur ve kaynak ağacında hardware/interfaces/camera/device/3.5/
konumunda bulunabilir.
Android 10'da, arabellek yönetimi API'sinin bir uygulaması olan ExternalCameraDeviceSession.cpp
'yı içerecek şekilde güncellendi. Bu harici kamera HAL'si, Arabellek yönetimi stratejileri bölümünde belirtilen, birkaç yüz satırlık C++ koduyla maksimum bellek tasarrufu stratejisini uygular.