Kamera HAL3 arabellek yönetimi API'leri

Android 10, kamera donanım soyutlama katmanı uygulamalarında farklı bellek ve yakalama gecikmesi dengelemeleri elde etmek için arabellek yönetimi mantığı uygulamanıza olanak tanıyan isteğe bağlı kamera donanım soyutlama katmanı 3 arabellek yönetimi API'lerini sunar.

Kamera HAL'si, işlem hattında N istek (N, işlem hattı derinliğine eşittir) sıraya alınmasını gerektirir ancak genellikle N çıkış arabelleği grubunun tamamının aynı anda kullanılmasını gerektirmez.

Örneğin, HAL'de işlem hattında sekiz istek sıraya alınmış olabilir ancak işlem hattının son aşamalarındaki iki istek için yalnızca çı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 şeması gösterilmektedir. Şekil 2'de, Android 10'daki kamera HAL3 arabellek yönetimi API'lerinin uygulandığı kamera HAL arayüzü gösterilmektedir.

9 veya önceki sürümlerde arabellek yönetimi

1. şekil. Android 9 ve önceki sürümlerdeki Camera 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'ı ş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, kamera HAL'ine arabellekleri döndürmesini bildirmek için signalStreamFlush yöntemini ICameraDeviceSession.hal içinde de 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'dir. 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 istemesine 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 kadar olan gecikmeyi 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'ı tarafından nasıl işlenmesi gerektiği açıklanmaktadır.

  • Uygulamanın çıkış akışıyla bağlantısı kesiliyor: Bu, önemli olmayan bir hatadır. Kamera HAL'si, 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 HAL'ı arabellek sınırına ulaştı (maxBuffers alanı): Kamera HAL'ı, requestStreamBuffers işlevini tekrar çağırmadan önce akışın en az bir arabelleğini döndürene kadar 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ının, kamera çerçevesi tarafından istenenden daha fazla arabellek tutması mümkündür. 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 donanım soyutlama katmanına (HAL) eldeki tüm arabellekleri döndürmesini bildirmek için 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 semantik farklıdır. flush yöntemi çağrıldığında HAL, boru hattını 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

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

    Ayrıca, arabelleği yönetme 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. Tampon isteklerinin tamamlanması alışılmadık derecede uzun sürdüğünde kamera işlem hattında olası bir aksaklık 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, birkaç yüz satırlık C++ koduyla maksimum bellek tasarrufu stratejisini uygular.