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ığı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.

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

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

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?

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