Kamera HAL3 Arabellek Yönetimi API'leri

Android 10, farklı bellek elde etmek ve kamera HAL uygulamalarında gecikme değişimlerini yakalamak için arabellek yönetimi mantığını uygulamanıza olanak tanıyan isteğe bağlı kamera HAL3 arabellek yönetimi API'lerini sunar.

Kamera HAL'si, ardışık düzende kuyruğa alınmış N istek (burada N, boru hattı derinliğine eşittir) gerektirir, ancak çoğu zaman aynı anda N sayıda çıktı arabelleği setine ihtiyaç duymaz.

Örneğin, HAL'de ardışık düzende sekiz istek sıralanmış olabilir, ancak yalnızca ardışık düzenin son aşamalarındaki iki istek için çıktı arabelleklerine ihtiyaç duyar. Android 9 ve daha önceki sürümleri çalıştıran cihazlarda, istek HAL'de kuyruğa alındığında kamera çerçevesi arabellekleri ayırır, böylece HAL'de kullanımda olmayan altı arabellek kümesi bulunabilir. Android 10'da, kamera HAL3 arabellek yönetimi API'leri, altı arabellek kümesini serbest bırakmak için çıkış arabelleklerinin ayrılmasına olanak tanır. Bu, ileri teknoloji cihazlarda yüzlerce megabaytlık bellek tasarrufuna yol açabilir ve aynı zamanda düşük belleğe sahip cihazlar için de faydalı olabilir.

Şekil 1, Android 9 ve daha düşük sürümleri çalıştıran cihazlar için kamera HAL arayüzünün bir diyagramını göstermektedir. Şekil 2, kamera HAL3 arabellek yönetimi API'lerinin uygulandığı Android 10'daki kamera HAL arayüzünü göstermektedir.

9 veya daha düşük sürümlerde tampon yönetimi

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

Android 10'da arabellek yönetimi

Ş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'nin şunları yapması gerekir:

Kamera HAL'si, arabellekleri istemek ve döndürmek için ICameraDeviceCallback.hal requestStreamBuffers ve returnStreamBuffers yöntemlerini kullanır. HAL'ın, arabellekleri döndürmesi için kamera HAL'sine sinyal vermek üzere ICameraDeviceSession.hal dosyasındaki signalStreamFlush yöntemini de uygulaması gerekir.

requestStreamBuffer'lar

Kamera çerçevesinden arabellek istemek için requestStreamBuffers yöntemini kullanın. Kamera HAL3 arabellek yönetimi API'lerini kullanırken, kamera çerçevesinden gelen yakalama istekleri çıktı arabellekleri içermez; yani StreamBuffer bufferId alanı 0 . Bu nedenle, kamera HAL'sinin, kamera çerçevesinden arabellek istemek için requestStreamBuffers kullanması gerekir.

requestStreamBuffers yöntemi, arayanın tek bir çağrıda birden çok çıkış akışından birden çok arabellek istemesine olanak tanıyarak daha az HIDL IPC çağrısı yapılmasına olanak tanır. Ancak, aynı anda daha fazla arabellek istendiğinde çağrılar daha fazla zaman alır ve bu, toplam istek-sonuç gecikmesini olumsuz etkileyebilir. Ayrıca requestStreamBuffers yapılan çağrılar kamera hizmetinde serileştirildiğinden, kamera HAL'sinin 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'nin ölümcül olmayan hataları düzgün şekilde işleyebilmesi gerekir. Aşağıdaki liste, arabellek isteklerinin başarısız olmasının yaygın nedenlerini ve bunların kamera HAL tarafından nasıl ele alınması gerektiğini açıklamaktadır.

  • Uygulamanın çıkış akışıyla bağlantısı kesiliyor: Bu önemli olmayan bir hatadır. Kamera HAL, bağlantısız bir akışı hedefleyen herhangi bir yakalama isteği için ERROR_REQUEST göndermeli ve sonraki istekleri normal şekilde işlemeye hazır olmalıdır.
  • Zaman Aşımı: Bu, bir uygulamanın bazı arabellekleri tutarken yoğun işlem yapmakla meşgul olması durumunda ortaya çıkabilir. Kamera HAL, zaman aşımı hatası nedeniyle yerine getirilemeyen 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'si, requestStreamBuffers tekrar çağırmadan önce bir sonraki configureStreams çağrısının tamamlanmasını beklemelidir.
  • Kamera HAL'si arabellek sınırına ulaştı ( maxBuffers alanı): Kamera HAL'i, requestStreamBuffers yeniden çağırmadan önce akışın en az bir arabelleğini döndürene kadar beklemelidir.

returnStreamBuffer'lar

Ekstra arabellekleri kamera çerçevesine döndürmek için returnStreamBuffers yöntemini kullanın. Kamera HAL'si normalde, processCaptureResult yöntemi aracılığıyla arabellekleri kamera çerçevesine döndürür, ancak yalnızca kamera HAL'sine gönderilen yakalama isteklerini hesaba katabilir. requestStreamBuffers yöntemiyle, kamera HAL uygulamasının, kamera çerçevesi tarafından talep edilenden daha fazla arabellek tutması mümkündür. Bu, returnStreamBuffers yönteminin kullanılması gereken zamandır. HAL uygulaması hiçbir zaman istenenden daha fazla arabellek tutmuyorsa, kamera HAL uygulamasının returnStreamBuffers yöntemini çağırmasına gerek yoktur.

sinyalStreamFlush

signalStreamFlush yöntemi, kamera çerçevesi tarafından kamera HAL'sine eldeki tüm arabellekleri döndürmesi konusunda bildirimde bulunmak için çağrılır. Bu normalde kamera çerçevesi, configureStreams çağırmak üzereyken ve kamera yakalama hattını 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ının olması mümkündür.

Kamera çerçevesi signalStreamFlush çağırdıktan sonra, tüm arabellekler kamera çerçevesine döndürülene kadar çerçeve, kamera HAL'sine 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 processCaptureRequest yöntemini çağırır. Kamera çerçevesi, configureStreams yöntemini çağırırsa, configureStreams çağrısı başarılı bir şekilde geri döndükten sonra kamera HAL'si yeniden arabellek istemeye başlayabilir. Kamera çerçevesi, processCaptureRequest yöntemini çağırırsa, kamera HAL'si, processCaptureRequest çağrısı sırasında arabellek istemeye başlayabilir.

signalStreamFlush yöntemi ve flush yönteminin anlambilimi farklıdır. flush yöntemi çağrıldığında HAL, boru 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 bitirmeli ve tüm arabellekleri kamera çerçevesine döndürmelidir.

signalStreamFlush yöntemi ile diğer yöntemler arasındaki diğer bir fark, signalStreamFlush tek yönlü bir HIDL yöntemi olmasıdır; bu, HAL, signalStreamFlush çağrısını almadan önce kamera çerçevesinin diğer engelleme API'lerini arayabileceği anlamına gelir. Bu, signalStreamFlush yönteminin ve diğer yöntemlerin (özellikle configureStreams yönteminin), kamera HAL'sine, kamera çerçevesinde çağrıldıkları sıradan farklı bir sırayla ulaşabileceği anlamına gelir. Bu eşzamansızlık sorununu çözmek için, streamConfigCounter alanı StreamConfiguration eklendi ve signalStreamFlush yöntemine argüman olarak eklendi. Kamera HAL uygulaması, bir signalStreamFlush çağrısının karşılık configureStreams çağrısından sonra gelip gelmediğini belirlemek için streamConfigCounter değişkenini kullanmalıdır. Örnek için Şekil 3'e bakınız.

Geç gelen çağrıları yönetme

Şekil 3. Kamera HAL'nin geç gelen signalStreamFlush çağrılarını nasıl algılaması ve işlemesi gerekir?

Arabellek yönetimi API'lerini uygularken 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'sine daha hızlı ve daha sık ulaşır: Arabellek yönetimi API'leri olmadan, kamera çerçevesi, kamera HAL'sine bir yakalama isteği göndermeden önce her yakalama isteği için çıkış arabellekleri ister. Arabellek yönetimi API'lerini kullanırken, kamera çerçevesinin artık arabellekleri beklemesine gerek yoktur ve bu nedenle yakalama isteklerini kamera HAL'sine daha erken gönderebilir.

    Ayrıca arabellek yönetimi API'leri olmadan, yakalama isteğinin çıkış akışlarından biri HAL'in aynı anda tutabileceği maksimum arabellek sayısına ulaştığında kamera çerçevesi yakalama istekleri göndermeyi durdurur (bu değer, HAL'deki kamera tarafından belirlenir). HalStream::maxBuffers alanı, configureStreams çağrısının dönüş değerindedir). Arabellek yönetimi API'leri ile bu kısıtlama davranışı artık mevcut değildir ve HAL'de sıraya alınmış çok fazla yakalama isteği olduğunda kamera HAL uygulamasının, processCaptureRequest çağrılarını kabul etmemesi gerekir.

  • requestStreamBuffers çağrı gecikmesi önemli ölçüde değişiklik gösterir: requestStreamBuffers çağrısı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 talep edilen arabellek sayısıyla orantılı olarak artar.
    • Uygulama arabellekleri tutuyor ve işlem yapmakla meşgul. Bu, arabellek eksikliği veya meşgul CPU nedeniyle arabellek isteklerinin yavaşlamasına veya zaman aşımına uğramasına neden olabilir.

Tampon 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 bir yakalama isteği için arabellek ister. Bu strateji herhangi bir bellek tasarrufu sağlamaz ancak arabellek yönetimi API'lerinin ilk uygulaması olarak hizmet verebilir ve mevcut kamera HAL'sinde çok az kod değişikliği yapılmasını gerektirir.
  • Maksimum bellek tasarrufu: Kamera HAL, çıkış arabelleklerini yalnızca doldurulması gerekmeden hemen önce talep eder. Bu strateji maksimum bellek tasarrufuna olanak tanır. Potansiyel dezavantajı, arabellek isteklerinin tamamlanması alışılmadık derecede uzun zaman aldığında daha fazla kamera ardışık düzeni patlamasıdır.
  • Önbelleğe Alınmış: Kamera HAL'si birkaç arabelleği önbelleğe alır, böylece ara sıra yapılan yavaş arabellek isteklerinden etkilenme olasılığı azalır.

Kamera HAL, belirli kullanım durumları için farklı stratejiler benimseyebilir; örneğin, çok fazla bellek kullanan kullanım durumları için maksimum bellek tasarrufu stratejisini kullanmak ve diğer kullanım durumları için geriye dönük uyumluluk stratejisini kullanmak.

Harici kamera HAL'sinde örnek uygulama

Harici kamera HAL, Android 9'da tanıtıldı ve hardware/interfaces/camera/device/3.5/ adresindeki kaynak ağacında bulunabilir. Android 10'da, arabellek yönetimi API'sinin bir uygulaması olan ExternalCameraDeviceSession.cpp içerecek şekilde güncellendi. Bu harici kamera HAL, Arabellek yönetimi stratejilerinde belirtilen maksimum bellek tasarrufu stratejisini birkaç yüz satırlık C++ kodunda uygular.