Kamera HAL3 arabellek yönetimi API'leri

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.

9 veya önceki sürümlerde arabelleğe alma yönetimi

Şekil 1. Android 9 ve önceki sürümlerde Camera HAL arayüzü

Android 10'da arabellek yönetimi

Ş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:

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 sonraki configureStreams ç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.

Geç gelen aramaları işleme

Ş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ğerindeki HalStream::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.