Kamera HAL3 arabellek yönetimi API'leri

Android 10, kamera HAL uygulamalarında farklı bellek ve yakalama gecikmesi dengeleri elde etmek için arabellek yönetimi mantığı uygulamanıza olanak tanıyan isteğe bağlı camera HAL3 arabellek yönetimi API'lerini kullanıma sunar.

Kamera HAL'ı, ardışık düzende N istek (N, ardışık düzen derinliğine eşittir) olmasını gerektirir ancak genellikle N çıkış arabelleği grubunun tamamını aynı anda gerektirmez.

Örneğin, HAL'ın ardışık düzende sekiz istek sıraya alınmış 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ü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 diyagramı gösterilmektedir. Şekil 2'de, Android 10'daki kamera HAL3 arabellek yönetimi API'lerinin uygulandığı kamera HAL arayüzü gösterilmektedir.

9 veya daha eski sürümlerde arabellek yönetimi

Şekil 1. Android 9 ve önceki sürümlerdeki Kamera HAL arayüzü

Android 10'da arabellek yönetimi

Şekil 2. Android 10'da arabellek yönetimi API'lerini kullanan Camera HAL arayüzü

Arabellek yönetimi API'lerini uygulama

Arabellek yönetimi API'lerini uygulamak için kamera HAL'ı şunları yapmalıdır:

Kamera HAL, arabellekleri istemek ve döndürmek için ICameraDeviceCallback.hal içindeki requestStreamBuffers ve returnStreamBuffers yöntemlerini kullanır. HAL, arabellekleri döndürmesi için kamera HAL'ına sinyal göndermek üzere signalStreamFlush yöntemini de ICameraDeviceSession.hal içinde 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 olur. 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 isteğinde bulunmasına 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 gecikme süresini 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'i tarafından nasıl işlenmesi gerektiği açıklanmaktadır.

  • Uygulama, çıkış akışıyla bağlantısını kesiyor: Bu, önemli olmayan bir hatadır. Kamera HAL'ı, 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 sonraki configureStreams çağrısının tamamlanmasını beklemelidir.
  • Kamera donanım soyutlama katmanı, arabellek sınırına ulaştı (maxBuffers alanı): Kamera donanım soyutlama katmanı, akışın en az bir arabelleğini döndürene kadar requestStreamBuffers işlevini tekrar çağırmadan önce 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ı, kamera çerçevesi tarafından istenenden daha fazla arabellek tutabilir. 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 HAL'ini eldeki tüm arabellekleri döndürmesi için bilgilendirmek üzere 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 anlamsal yapı farklıdır. flush yöntemi çağrıldığında HAL, işlem 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 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.

Geç gelen aramaları işleme

Şekil 3. 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'ına daha erken gönderebilir.

    Ayrıca, arabellek yönetimi 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ğerindeki HalStream::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. Arabellek isteklerinin tamamlanması alışılmadık derecede uzun sürdüğünde kamera işlem hattında daha fazla duraklama 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, bellek tasarrufunu en üst düzeye çıkarma stratejisini birkaç yüz satırlık C++ koduyla uygular.