Kamera HAL3 Arabellek Yönetimi API'leri

Android 10, kamera HAL uygulamalarında farklı bellek elde etmek ve gecikme süresi değiş tokuşlarını 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.

HAL kamerası, boru hattında sıraya alınmış N isteği (burada N, boru hattı derinliğine eşittir) gerektirir, ancak çoğu zaman aynı anda tüm N çıktı arabelleği setini gerektirmez.

Örneğin, HAL'nin ardışık düzende sıraya alınmış sekiz isteği olabilir, ancak yalnızca boru hattının son aşamalarındaki iki istek için çıktı arabellekleri gerektirir. Android 9 ve önceki sürümleri çalıştıran cihazlarda, istek HAL'de sıraya alındığında kamera çerçevesi arabellekler ayırır, böylece HAL'de kullanılmayan altı arabellek grubu olabilir. Android 10'da, kamera HAL3 arabellek yönetimi API'leri, altı arabellek kümesini boşaltmak için çıkış arabelleklerinin ayrıştırılmasına izin verir. Bu, ileri teknoloji cihazlarda yüzlerce megabayt bellek tasarrufuna yol açabilir ve düşük bellekli cihazlar için de faydalı olabilir.

Şekil 1, Android 9 ve önceki sürümleri çalıştıran cihazlar için kamera HAL arayüzünün bir diyagramını göstermektedir. Şekil 2, uygulanan kamera HAL3 arabellek yönetimi API'leri ile Android 10'daki kamera HAL arabirimini gösterir.

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ü

Tampon yönetimi API'lerini uygulama

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

HAL kamerası, arabellekleri istemek ve döndürmek için ICameraDeviceCallback.hal içindeki requestStreamBuffers ve returnStreamBuffers yöntemlerini kullanır. HAL ayrıca, kamera ICameraDeviceSession.hal arabellekleri döndürmesi için sinyal vermek için ICameraDeviceSession.hal içindeki signalStreamFlush yöntemini uygulamalıdır.

requestStreamBuffers

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'ı, kamera çerçevesinden arabellek istemek için requestStreamBuffers kullanmalıdır.

requestStreamBuffers yöntemi, arayan kişinin tek bir aramada birden çok çıktı akışından birden çok arabellek istemesine olanak tanıyarak daha az HIDL IPC çağrısına izin verir. Ancak, aynı anda daha fazla arabellek istendiğinde çağrılar daha uzun sürer ve bu, istekten sonuca toplam gecikme süresini 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'ının önemli olmayan hataları düzgün bir ş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çıklar.

  • Uygulamanın çıkış akışıyla bağlantısı kesiliyor: Bu, önemli olmayan bir hatadır. HAL kamerası, bağlantısı kesilmiş 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 uygulama bazı arabellekleri tutarken yoğun işlem yapmakla meşgul olduğunda ortaya çıkabilir. HAL kamerası, bir 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 yeniden çağırmadan önce bir sonraki configureStreams çağrısının tamamlanmasını beklemelidir.
  • Kamera HAL'ı arabellek sınırına ulaştı ( maxBuffers alanı): HAL kamerası, requestStreamBuffers yeniden çağırmadan önce akışın en az bir arabelleğini döndürene kadar beklemelidir.

dönüşAkışTamponları

Kamera çerçevesine fazladan arabellek döndürmek için returnStreamBuffers yöntemini kullanın. Kamera HAL'ı normalde processCaptureResult yöntemi aracılığıyla 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. Bu, returnStreamBuffers yönteminin kullanılması gerektiği zamandır. HAL uygulaması hiçbir zaman istenenden daha fazla arabellek tutmazsa, kamera HAL uygulamasının returnStreamBuffers yöntemini çağırması gerekmez.

sinyalAkışFlush

signalStreamFlush yöntemi, kamera HAL'sini eldeki tüm arabellekleri döndürmesi için bilgilendirmek için kamera çerçevesi tarafından çağrılır. Bu, normalde kamera çerçevesi configureStreams çağırmak üzereyken çağrılır ve kamera yakalama ardışık düzenini boşaltması gerekir. 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 sonra, çerçeve, tüm arabellekler kamera çerçevesine döndürülene kadar kamera HAL'ı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 temiz bir durumda çalışmasına devam edebilir. Kamera çerçevesi daha sonra ya configureStreams ya da 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'ı yeniden arabellek istemeye başlayabilir. Kamera çerçevesi processCaptureRequest yöntemini çağırırsa, kamera HAL'ı processCaptureRequest çağrısı sırasında arabellek istemeye başlayabilir.

signalStreamFlush yöntemi ve flush yöntemi için anlambilim farklıdır. flush yöntemi çağrıldığında, HAL, ardışık düzeni mümkün olan en kısa sürede boşaltmak için ERROR_REQUEST ile bekleyen yakalama isteklerini 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 geri göndermelidir.

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 çağırabileceği anlamına gelir. Bu, signalStreamFlush yönteminin ve diğer yöntemlerin (özellikle configureStreams yönteminin), kamera HAL'ına kamera çerçevesinde çağrıldıklarından farklı bir sırayla ulaşabileceği anlamına gelir. Bu eşzamansızlık sorununu gidermek için, streamConfigCounter alanı StreamConfiguration'a eklendi ve StreamConfiguration yöntemine bir argüman olarak signalStreamFlush . Kamera HAL uygulaması, bir 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şkenini kullanmalıdır. Örnek için Şekil 3'e bakın.

Geç gelen aramaları yönetme

Şekil 3. Kamera HAL'sinin geç gelen sinyal StreamFlush çağrılarını nasıl algılaması ve işlemesi gerektiği

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

    Ayrıca, arabellek yönetimi API'leri olmadan, yakalama isteğinin çıkış akışlarından biri HAL'ın bir seferde tutabileceği maksimum arabellek sayısına ulaştığında kamera çerçevesi yakalama istekleri göndermeyi durdurur (bu değer, Bir configureStreams çağrısının dönüş değerindeki HalStream::maxBuffers alanı). 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ı processCaptureRequest çağrılarını kabul etmemelidir.

  • requestStreamBuffers arama gecikmesi önemli ölçüde değişir: Bir requestStreamBuffers araması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 arabellek tutuyor ve işleniyor. Bu, arabellek isteklerinin yavaşlamasına veya arabellek eksikliği veya meşgul bir CPU nedeniyle zaman aşımına uğramasına neden olabilir.

Tampon yönetimi stratejileri

Tampon yönetimi API'leri, farklı türde arabellek yönetimi stratejilerinin uygulanmasına izin verir. Bazı örnekler:

  • Geriye dönük uyumlu: HAL istekleri, processCaptureRequest çağrısı sırasında bir yakalama isteği için arabelleğe alır. Bu strateji herhangi bir 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 hizmet edebilir.
  • Maksimum bellek tasarrufu: Kamera HAL'i, yalnızca birinin doldurulması gerekmeden hemen önce çıktı arabellekleri ister. Bu strateji, maksimum bellek tasarrufu sağlar. Potansiyel dezavantajı, arabellek isteklerinin tamamlanması olağandışı uzun zaman aldığında daha fazla kamera ardışık düzenidir.
  • Önbelleğe Alındı: Kamera HAL'i birkaç arabelleği önbelleğe alır, böylece ara sıra yavaş bir arabellek isteğinden etkilenmesi daha az olasıdır.

Kamera HAL'ı, ö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 uyumlu stratejiyi kullanmak gibi belirli kullanım durumları için farklı stratejiler benimseyebilir.

Harici kamera HAL'de örnek uygulama

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