Android, otomotiv HIDL Donanım Soyutlama Katmanı (HAL) içerir. Android önyükleme işleminin çok başında görüntü yakalama ve görüntüleme sağlar sistem ömrü boyunca çalışmaya devam eder. HAL şunları içerir: dıştan görünüm sistemi (EVS) yığını ve genellikle arkadan görünümü desteklemek için kullanılır Android tabanlı Araç İçi bulunan araçlarda kamera ve surround görünüm ekranları Bilgi-eğlence sistemi (IVI) sistemleri. EVS, gelişmiş özelliklerin uygulanmasına da olanak tanır. en iyi uygulamaları paylaşacağız.
Android ayrıca EVS'ye özel bir yakalama ve görüntüleme sürücüsü içerir
arayüzü (/hardware/interfaces/automotive/evs/1.0
dilinde). Ancak
mevcut Android cihaz üzerinde bir arka görüş kamerası uygulaması geliştirmek
kullanıyorsanız, bu tür bir uygulama büyük olasılıkla çok geç çalışır.
Android'in başlatma işlemine hazırlanır. Özel bir HAL kullanılması, arayüzlerin sadeleşmesini sağlar.
ve bir OEM'in EVS yığınını desteklemek için uygulaması gerekenleri net bir şekilde açıklıyor.
Sistem bileşenleri
EVS aşağıdaki sistem bileşenlerini içerir:
.EVS uygulaması
Örnek C++ EVS uygulaması
(/packages/services/Car/evs/app
) referans olarak kullanılıyor
bazı ipuçları vereceğim. Bu uygulama,
ve tamamlanmış kareleri görüntülenmek üzere EVS Yöneticisine geri gönderme.
EVS ve Araba Hizmeti kullanılabilir olur olmaz başlatılmaya başlanması bekleniyor.
açıldıktan sonraki iki (2) saniye içinde hedeflenir. OEM'ler EVS'yi değiştirebilir veya değiştirebilir
uygulamayı seçebilirsiniz.
EVS Yöneticisi
EVS Yöneticisi (/packages/services/Car/evs/manager
)
bir EVS uygulamasının her şeyi uygulamak için ihtiyaç duyduğu yapı taşlarını
basit dikiz kamerası ekranını 6DOF çoklu kameraya dönüştürün. Arayüzü
HIDL ile sunulur ve birden fazla eşzamanlı istemciyi kabul edecek şekilde tasarlanmıştır.
Diğer uygulama ve hizmetler (özellikle Araba Hizmeti) EVS'yi sorgulayabilir
EVS sisteminin ne zaman aktif olduğunu öğrenmek için yönetici durumu.
EVS HIDL arayüzü
EVS sistemi (hem kamera hem de görüntü öğeleri)
android.hardware.automotive.evs
paketi. Örnek uygulama
(sentetik test resimleri oluşturur ve test sırasında
yer aldığı örneğin, gidiş dönüşü sağlayan)
/hardware/interfaces/automotive/evs/1.0/default
.hal dosyalarında ifade edilen API'nin uygulanmasından OEM sorumludur
/hardware/interfaces/automotive/evs
içinde. Bu tür uygulamalar,
fiziki kameralara ve kameralara ait verileri yapılandırıp
Gralloc'un tanıyabildiği paylaşılan bellek arabellekleri aracılığıyla iletim. Ekran
uygulamanın tarafı, paylaşılan bellek arabelleği sağlamaktan
Uygulama tarafından doldurulabilen (genellikle EGL oluşturma ile) ve sunum yapan
görüntülenmesi istenebilecek başka her şeye tercih ederek, bitmiş karelere
gösteren bir ekran görüntüsüdür. EVS arayüzünün tedarikçi firma uygulamaları depolanabilir
/vendor/… /device/…
veya hardware/…
altında (ör.
/hardware/[vendor]/[platform]/evs
) bilgileri gösterilir.
Çekirdek sürücüleri
EVS yığınını destekleyen bir cihaz için çekirdek sürücüleri gerekir. Şunun yerine:
OEM'ler, yeni sürücüler oluşturarak EVS gerektiren özellikleri
mevcut kamera veya ekran donanımı sürücülerini kontrol edin. Sürücüleri yeniden kullanmak
özellikle de mobil cihazlarda görsel sunumun gerçekleşebileceği
diğer etkin iş parçacıklarıyla koordinasyon gerektirir. Android 8.0, v4l2 tabanlı bir sürüm
örnek sürücü (packages/services/Car/evs/sampleDriver
içinde)
v4l2 desteği için çekirdeğe ve
çıkış resmi.
EVS donanım arayüzü açıklaması
Bu bölümde HAL ile ilgili açıklamalar yer almaktadır. Tedarikçi firmaların bu API'nin uygulamalarını kendi donanımlarına göre uyarlar.
IEvsNumaralandırıcı
Bu nesne, mevcut EVS donanımını sistem (bir veya daha fazla kamera ve tek ekranlı cihaz).
getCameraList() generates (vec<CameraDesc> cameras);
Sistemdeki tüm kameraların açıklamalarını içeren bir vektörü döndürür. Evet
kamera grubunun sabit ve başlatma sırasında bilindiği varsayılmıştır. Ayrıntılı bilgi için
kamera açıklamaları için bkz. CameraDesc
.
openCamera(string camera_id) generates (IEvsCamera camera);
Belirli bir kamerayla etkileşim kurmak için kullanılan bir arayüz nesnesi alır
benzersiz camera_id dizesiyle tanımlanır. Hata durumunda NULL değeri döndürür.
Açık olan bir kamerayı yeniden açma denemeleri başarısız olamaz. Yarıştan kaçınmak için
uygulamanın başlatılması ve kapatılması, bir kameranın yeniden açılmasıyla ilgili koşullar
yeni isteğin yerine getirilebilmesi için önceki örneği kapatmalısınız. CEVAP
bu şekilde geçici olarak kesilen kamera örneği, etkin olmayan bir
devletin imha edilmesini bekleyen ve söz konusu talebe yanıt vererek
kamera durumu: OWNERSHIP_LOST
dönüş kodu.
closeCamera(IEvsCamera camera);
IEvsKamera arayüzünü açar (ve
openCamera()
arama). Kamera video akışı:
closeCamera
aranmadan önce stopVideoStream()
aranarak durduruldu.
openDisplay() generates (IEvsDisplay display);
Sistemin özel olarak ayarlamak için kullandığı bir arayüz nesnesini
EVS ekranı. Yalnızca bir müşteri aşağıdaki noktalarda çalışır durumdaki bir IEvsDisplay örneğini bulundurabilir:
gerekir. openCamera
bölümünde açıklanan agresif açık davranışa benzer şekilde,
herhangi bir zamanda yeni bir IEvsDisplay nesnesi oluşturulabilir ve önceki tüm IEvsDisplay nesnesi
sağlar. Geçersiz kılınan örnekler var olmaya devam eder ve işlev çağrılarına yanıt verir
ancak öldüğünde değişen işlemler gerçekleştirmemesi gerekir. En sonunda,
istemci uygulamasının OWNERSHIP_LOST
hatasını fark etmesi beklenir
ve etkin olmayan arayüzü kapatıp serbest bırakın.
closeDisplay(IEvsDisplay display);
IEvsDisplay arayüzünü serbest bırakır (ve
openDisplay()
arama). Beklemedeki tamponlar
getTargetBuffer()
çağrılarının önce ekrana döndürülmesi gerekir
ekranı kapatabilirsiniz.
getDisplayState() generates (DisplayState state);
Geçerli görüntüleme durumunu alır. HAL uygulaması,
gerçek mevcut duruma (en son istenen durumdan farklı olabilir).
Ekran durumlarının değiştirilmesinden sorumlu mantık cihazın üzerinde bulunmalıdır
istenmeyen bir şekilde uygulanır. Bu da, HAL uygulamasının kendiliğinden
görüntüleme durumları. Ekran o anda herhangi bir istemci tarafından tutulmuyorsa (
openDisplay) içeriyorsa bu işlev NOT_OPEN
değerini döndürür. Aksi halde
EVS Ekranının mevcut durumunu bildirir (bkz.
IEvsDisplay API).
struct CameraDesc { string camera_id; int32 vendor_flags; // Opaque value }
camera_id
Belirli bir kamerayı benzersiz şekilde tanımlayan bir dize. Cihazın çekirdek cihaz adı veya cihaz için bir ad olabilir. Örneğin: rearview olarak ayarlayın. Bu dizenin değeri HAL uygulaması tarafından seçilir ve yukarıdaki yığın tarafından opak bir şekilde kullanılır.vendor_flags
Özel kamerayı geçirme yöntemi bilgileri şeffaf bir şekilde sürücüden özel bir EVS uygulamasına aktarıyor. Geçti sürücüden EVS uygulamasına kadar yorumsuz bir deneyim yaşarsınız. somut olarak ortaya koyar.
IEvsKamera
Bu nesne tek bir kamerayı temsil eder ve şunun birincil arayüzüdür: olanak tanır.
getCameraInfo() generates (CameraDesc info);
Bu kameradan CameraDesc
tanesini döndürür.
setMaxFramesInFlight(int32 bufferCount) generates (EvsResult result);
Kameranın desteklemesi gereken arabellek zincirinin derinliğini belirtir. En fazla
bu sayıda kare, IEvsKamera istemcisi tarafından eşzamanlı olarak tutulabilir. Bu
birçok karenin geri dönmeden alıcıya iletildiğinden
doneWithFrame
, akış bir arabellek döndürülene kadar kareleri atlar
yeniden kullanılabilir. Bu görüşme, akışlar devam ederken bile herhangi bir zamanda yapılabilir.
zaten çalışıyor. Bu durumda tamponların eklenmesi veya zincirden kaldırılması gerekir.
gerektiği şekilde ele alın. Bu giriş noktasına çağrı yapılmazsa IEvsKamera,
varsayılan olarak en az bir kare
oluşturmanız gerekir. sağlayabilir.
İstenen bufferCount kullanılamazsa işlev,
BUFFER_NOT_AVAILABLE
veya ilgili başka bir hata kodu. Böyle durumlarda
sistem önceden ayarlanan değerle çalışmaya devam eder.
startVideoStream(IEvsCameraStream receiver) generates (EvsResult result);
EVS kamera çerçevelerinin bu kameradan teslim edilmesini istiyor. IEvsKameraStream
tarihine kadar yeni resim çerçeveleri içeren düzenli aramalar almaya başlar.
stopVideoStream()
çağrıldı. Çerçeveler yayınlanmaya başlamalıdır
startVideoStream
çağrısından sonra 500 ms. içinde ve başladıktan sonra,
en az 10 FPS'de üretilmiştir. Video akışını başlatmak için gereken süre
tüm arka görüş kamerasının başlatma süresi gereksinimleri için etkili bir şekilde hesaba katılır. Öğe
akış başlatılmadı, bir hata kodu döndürülmelidir; Aksi takdirde Tamam döndürülür.
oneway doneWithFrame(BufferDesc buffer);
IEvsKameraStream tarafından iletilen bir kareyi döndürür. Tamamlandığında
IEvsKameraStream arayüzüne gönderilen bir kareyi tüketiyorsa, çerçeve
tekrar kullanılmak üzere IEvsKamera'ya geri gönderildi. Az sayıda, sonlu bir tampon
küçük bir e-posta adresi kullanmaya devam edebilirsiniz. Tedarik tükenirse başka bir
kareler bir tampon döndürülene kadar yayınlanır. Bu da
atlanan kareler (boş tutma yerine sahip bir arabellek, akışın sonunu belirtir ve
bu işlev aracılığıyla döndürülmesi gerekmez). Başarı yanıtı olarak "Tamam" veya
uygun hata kodu: INVALID_ARG
veya
BUFFER_NOT_AVAILABLE
.
stopVideoStream();
EVS kamera çerçevelerinin teslimini durdurur. Yayınlama eşzamansız olduğundan
kareler, bu çağrı geri geldikten sonra bir süre daha gelmeye devam edebilir. Her bir kare
akışın kapatıldığına dair bir sinyal gönderene kadar geri döndürülmelidir.
IEvsKameraStream. Akışta stopVideoStream
adlı kişiyi aramak yasaldır
daha önce durdurulmuş olan veya hiç başlatılmamış olan feed'ler kullanılır. Bu durumlarda yoksayılır.
getExtendedInfo(int32 opaqueIdentifier) generates (int32 value);
HAL uygulamasından sürücüye özel bilgileri ister. Değerler
opaqueIdentifier
için izin verilen siteler sürücüye özeldir ancak değer yoktur
sürücünün kilitlenmesine neden olabilir. Sürücü, tanınmayan öğeler için 0 değerini döndürmelidir
opaqueIdentifier
setExtendedInfo(int32 opaqueIdentifier, int32 opaqueValue) generates (EvsResult result);
HAL uygulamasına sürücüye özel bir değer gönderir. Bu uzantı
yalnızca araca özel uzantıları kolaylaştırmak için sağlanır ve HAL olmadan
uygulaması için bu çağrının varsayılan durumda çalışması gerekir. Öğe
değerleri tanır ve kabul eder. Tamam döndürülmelidir; aksi takdirde
INVALID_ARG
veya başka bir temsilcinin hata kodu döndürülür.
struct BufferDesc { uint32 width; // Units of pixels uint32 height; // Units of pixels uint32 stride; // Units of pixels uint32 pixelSize; // Size of single pixel in bytes uint32 format; // May contain values from android_pixel_format_t uint32 usage; // May contain values from Gralloc.h uint32 bufferId; // Opaque value handle memHandle; // gralloc memory buffer handle }
API üzerinden geçirilen bir görüntüyü açıklar. HAL sürücüsü,
görüntü arabelleğini ve HAL istemcisini tanımlamak için
bu yapıyı salt okunur olarak işlemelidir. Alanlar yeterli bilgi içeriyor
istemcinin bir ANativeWindowBuffer
nesnesini yeniden oluşturmasına izin vermek için
resmin EGL ile kullanılması için gerekebilir,
eglCreateImageKHR()
uzantısı.
width
Sunulan resmin piksel cinsinden genişliği.height
Sunulan resmin piksel cinsinden yüksekliği.stride
Her satırın bellekte gerçekte kapladığı piksel sayısı, satırların hizalaması için dolgu hesaba katılır. Eşleştirmek için piksel cinsinden ifade edilir gralloc'un tampon açıklamaları için benimsediği kural.pixelSize
Her bir pikselin kapladığı bayt sayısı, içindeki satırlar arasında geçiş yapmak için gereken bayt cinsinden boyutun resim (bayt cinsindenstride
= piksel cinsindenstride
*pixelSize
) bilgileri gösterilir.format
Resim tarafından kullanılan piksel biçimi. Sağlanan biçim platformun OpenGL uygulamasıyla uyumlu olmalıdır. Geçmek için uyumluluk testi,HAL_PIXEL_FORMAT_YCRCB_420_SP
kamera kullanımı için tercih edilir veRGBA
veyaBGRA
tercih edilir.usage
HAL uygulaması tarafından ayarlanan kullanım işaretleri. HAL müşterileri bunların değiştirilmemiş olması gerekir (ayrıntılar içinGralloc.h
ilgili işaret).bufferId
HAL uygulaması tarafından bir arabelleğin, HAL API'leri üzerinden bir dönüşten sonra tanınmasını sağlar. İlgili içeriği oluşturmak için kullanılan bu alanda depolanan değer, HAL uygulaması tarafından rastgele seçilebilir.memHandle
Ayarlanan temel bellek arabelleğinin tutma yeri resim verilerini içerir. HAL uygulaması, Gralloc'u arabellek tutma yeri ekleyin.
IEvsKameraAkışı
İstemci bu arayüzü, eşzamansız video çerçevesini almak için uygular teslimatlar.
deliverFrame(BufferDesc buffer);
Bir video karesi incelenmeye her hazır olduğunda HAL'den çağrı alır.
Bu yöntemle alınan arabellek herkese açık kullanıcı adları,
IEvsCamera::doneWithFrame()
Video akışı
IEvsCamera::stopVideoStream()
çağrısı, bu geri arama devam edebilir
bir süreçtir. Her kare yine de döndürülmelidir; son kare
akışla iletildiğinde, bir NULL bufferHandle
ile
anlamına gelir. NULL
bufferHandle
adlı uygulamanın,
doneWithFrame()
ancak diğer tüm herkese açık kullanıcı adları döndürülmelidir
Özel arabellek biçimleri teknik olarak mümkün olsa da, test, tamponun desteklenen dört biçimden birinde olmasını gerektirir: NV21 (YCrCb 4:2:0 Yarı Düzlemsel), YV12 (YCrCb 4:2:0 Düzlem), YUYV (YCrCb 4:2:2 Boşluklu), RGBA (32 bit R:G:B:x), BGRA (32 bit B:G:R:x). Seçilen biçim geçerli bir biçim olmalıdır Platformun GLES uygulamasındaki GL doku kaynağı.
Uygulama hiçbir yazışmaya dayanmamalıdır
bufferId
alanı ile memHandle
arasında
BufferDesc
yapısı. bufferId
değerleri:
HAL sürücüsü uygulamasına özeldir ve HAL
onları uygun gördüğünüz şekilde düzenleyebilirsiniz.
IEvsEkranı
Bu nesne Evs ekranını temsil eder, ekranın durumunu kontrol eder ve resimlerin gerçek sunumunu üstlenir.
getDisplayInfo() generates (DisplayDesc info);
Sistem tarafından sağlanan EVS ekranı hakkında temel bilgileri döndürür (bkz. DisplayDesc) tıklayın.
setDisplayState(DisplayState state) generates (EvsResult result);
Görüntülenme durumunu ayarlar. Müşteriler, görüntüleme durumunu ve HAL uygulamasının, yürütülmesi için bir isteği incelikle kabul etmesi başka herhangi bir durumdayken de herhangi bir eyaletten isteği gönderin.
Başlatıldıktan sonra, ekran
NOT_VISIBLE
durumu (bundan sonra istemcinin istekte bulunması beklenir)
VISIBLE_ON_NEXT_FRAME
durumunu bildirip video sağlamaya
başlayın.
artık gerekli değilse müşterinin
Son video karesi geçildikten sonra NOT_VISIBLE
durumu.
Bu, herhangi bir eyalette herhangi bir zamanda istenebilecekler için geçerlidir. Ekran
görünür durumdaysa,
VISIBLE_ON_NEXT_FRAME
İstenen durum sağlanmadığı sürece her zaman Tamam değerini döndürür
tanınmayan bir enum değeridir. Bu durumda INVALID_ARG
geri döndü.
getDisplayState() generates (DisplayState state);
Görüntülenme durumunu alır. HAL uygulaması, (bu, en son istenen durumdan farklı olabilir). İlgili içeriği oluşturmak için kullanılan ekran durumlarını değiştirmekten sorumlu mantık cihazın üzerinde bulunmalıdır istenmeyen bir şekilde uygulanır. Bu da, HAL uygulamasının kendiliğinden görüntüleme durumları.
getTargetBuffer() generates (handle bufferHandle);
Ekranla ilişkili bir çerçeve arabelleğine herkese açık kullanıcı adı döndürür. Bu tampon
tarafından kilitlenebilir ve/veya yazılım ve/veya GL tarafından yazılabilir. Bu tampon döndürülmelidir
Ekran şu anda açık olsa bile returnTargetBufferForDisplay()
için çağrı yapılarak
artık görünür değil.
Özel arabellek biçimleri teknik olarak mümkün olsa da uyumluluk testi arabelleğin desteklenen dört biçimden birinde olmasını gerektirir: NV21 (YCrCb 4:2:0 Yarı Düzlemli), YV12 (YCrCb 4:2:0 Düzlem), YUYV (YCrCb 4:2:2 Boşluklu), RGBA (32 bit R:G:B:x), BGRA (32 bit B:G:R:x). Seçilen biçim geçerli bir GL olmalıdır Platformun GLES uygulamasında oluşturma hedefi oluşturma.
Hata durumunda boş tutma yerine sahip bir arabellek döndürülür, ancak böyle bir arabellek
returnTargetBufferForDisplay
alanına geri verilmesi gerekiyor.
returnTargetBufferForDisplay(handle bufferHandle) generates (EvsResult result);
Arabelleğin görüntülenmeye hazır olduğunu ekrana bildirir. Yalnızca tamponlar alındı
getTargetBuffer()
numaralı telefona yapılan çağrı ile şunlar geçerli olur:
çağrısı ile BufferDesc
çağrısının içeriği,
istemci uygulaması. Bu çağrıdan sonra arabellek,
teslim edilir. Başarı durumunda Tamam veya uygun hata kodu döndürür
INVALID_ARG
veya BUFFER_NOT_AVAILABLE
dahil.
struct DisplayDesc { string display_id; int32 vendor_flags; // Opaque value }
EVS ekranının temel özelliklerini açıklar ve bir EVS'nin gerektirdiği özellikleri açıklar bazı ipuçları vereceğim. Bu yapının doldurulmasından HAL sorumludur. EVS ekranını açıklayacağım. Fiziksel bir ekran veya üzerinde çalıştığınız sanal bir ekran olabilir. başka bir sunu cihazının üzerine yerleştirilmiş veya karışık olarak gösteriliyor.
display_id
Ekranı benzersiz şekilde tanımlayan bir dize. Bu, cihazın çekirdek cihaz adı veya cihazın adı olabilir. Örneğin, dikiz. Bu dizenin değeri HAL tarafından seçilir uygulanır ve yukarıdaki yığın tarafından opak bir şekilde kullanılır.vendor_flags
Özel kamerayı geçirme yöntemi bilgi, sürücüden özel bir EVS uygulamasına aktarılabilecek şekilde değişir. Geçti sürücüden EVS uygulamasına kadar yorumsuz bir deneyim yaşarsınız. somut olarak ortaya koyar.
enum DisplayState : uint32 { NOT_OPEN, // Display has not been “opened” yet NOT_VISIBLE, // Display is inhibited VISIBLE_ON_NEXT_FRAME, // Will become visible with next frame VISIBLE, // Display is currently active DEAD, // Display is not available. Interface should be closed }
EVS ekranının durumunu tanımlar. EVS ekranının devre dışı bırakılabileceği (
veya etkinleştirilir (sürücüye resim gösterilir).
Ekranın henüz görünmediği ancak hazır olduğu geçici bir durum içerir
sonraki görüntü karesinin iletilmesiyle birlikte görünür hale gelmesini
returnTargetBufferForDisplay()
arama.
EVS Yöneticisi
EVS Yöneticisi, cihazlar için EVS sistemine herkese açık arayüz sağlar. harici kamera görüntülerini toplayıp sunmak. Donanım sürücülerinin izin verdiği yerler kaynak (kamera veya ekran) başına yalnızca bir etkin arayüz), EVS Yöneticisi kameralara paylaşılan erişimi kolaylaştırır. Tek bir birincil EVS uygulaması: ve EVS Yöneticisi'nin ilk müşterisidir ve kendisi için araç teslimi görüntüleme verileri (ek istemcilere kameraya salt okuma erişimi verilebilir resim) ekleyebilirsiniz.
EVS Yöneticisi, altta yatan HAL sürücüleriyle aynı API'yi uygular ve birden fazla eşzamanlı istemciyi (en fazla Müşterilerden biri EVS Yöneticisi aracılığıyla kamerayı açıp akış).
Uygulamalar, EVS Donanım HAL'si ile çalışırken hiçbir fark görmüyor. EVS Manager API'nin izin verdiği durumlar haricinde, EVS Manager API'nin kullanılması eş zamanlı kamera akışı erişimi. EVS Yöneticisi de aslında kendisinde ve EVS Donanım HAL katmanının temsilcisi olarak çalışır ve EVS Donanımı için bir temsilci görevini görür. HAL.
Aşağıdaki bölümlerde yalnızca farklı EVS Yöneticisi uygulamasındaki (genişletilmiş) davranış; kalan çağrı sayısı açıklamalarıyla aynıdır.
IEvsNumaralandırıcı
openCamera(string camera_id) generates (IEvsCamera camera);
Belirli bir kamerayla etkileşim kurmak için kullanılan bir arayüz nesnesi alır
benzersiz camera_id dizesiyle tanımlanır. Hata durumunda NULL değeri döndürür.
EVS Yönetici katmanında, yeterli sistem kaynağı mevcut olduğu sürece,
Açık olan bir kamera başka bir işlem tarafından tekrar açılabilir. Bu işlem
Video akışının birden fazla tüketici uygulamasında gösterilmesi. İlgili içeriği oluşturmak için kullanılan
EVS Yönetici katmanındaki camera_id
dizeleri bu dizelerle aynı
EVS Donanım katmanına rapor edildi.
IEvsKamera
EVS Yöneticisi, IEvsKamera uygulamasının dahili olarak sanallaştırılmasını sağladığı için Bu nedenle, bir istemcinin kamera üzerinde yaptığı işlemler diğer istemcileri etkilemez. kameralarına bağımsız olarak erişemez.
startVideoStream(IEvsCameraStream receiver) generates (EvsResult result);
Video akışları başlatır. Müşteriler video akışlarını bağımsız olarak başlatabilir ve durdurabilir kameranın diğer ucunda. Temel kamera, ilk kameranın büyük önem taşır.
doneWithFrame(uint32 frameId, handle bufferHandle) generates (EvsResult result);
Bir kare döndürür. Her müşteri, işlem tamamlandığında karelerini döndürmelidir. çerçevelerini istedikleri kadar tutmalarına izin verilir. kare sayısı yapılandırılan sınıra ulaştığından, istemci boyutu otomatik olarak bir kare döndürene kadar başka kare daha eklemez. Bu kare atlama, diğer çerçeveleri beklendiği gibi almaya devam eder.
stopVideoStream();
Video akışını durdurur. Her müşteri video akışını herhangi bir zamanda durdurabilir. diğer müşterileri etkilemeye devam ediyor. Donanım katmanındaki alttaki kamera akışı kameranın son istemcisi akışı durdurduğunda da durdurulur.
setExtendedInfo(int32 opaqueIdentifier, int32 opaqueValue) generates (EvsResult result);
Sürücüye özel bir değer göndererek bir istemcinin etkilenmesini sağlayabilir. devre dışı bırakabilirsiniz. Çünkü EVS yöneticisi bu durumun etkilerini tarafından tanımlanan kontrol sözcükleridir, sanallaştırılmazlar. belirli bir kameranın tüm istemcileri için geçerlidir. Örneğin, bir tedarikçi firma bu aramayı kullandıysa değiştirmek için kare hızlarını değiştirmek üzere, etkilenen donanım katmanı kamerasının tüm istemcileri yeni hızda kare alır.
IEvsEkranı
Ekranın, EVS Yöneticisi düzeyinde bile olsa yalnızca bir sahibine izin verilir. İlgili içeriği oluşturmak için kullanılan Yönetici hiçbir işlev katmaz ve yalnızca IEvsDisplay arayüzünü iletir doğrudan temeldeki HAL uygulamasına yönlendirmelidir.
EVS uygulaması
Android, EVS'nin yerel C++ referans uygulamasını içerir için EVS Yöneticisi ve Araç HAL'si ile iletişim kuran bir uygulamadır. Temel dikiz kamerası işlevlerini sağlayabilirsiniz. Uygulamanın başlatılması bekleniyor çok erken bir aşamada yapılır; modele bağlı olarak mevcut kameralar ve aracın durumu (dişli ve dönüş sinyali durumu) OEM'ler, EVS uygulamasını kendi aracına özel olarak değiştirebilir veya değiştirebilir mantık ve sunum.
..
.
Resim verileri, uygulamaya standart bir grafik üzerinde sunulduğundan arabelleğe alındığında uygulama, resmi kaynaktan tamponu kullanabilirsiniz. Bu durumda veri metninin maliyeti ortaya çıkarsa da Ayrıca, uygulamaya, resmi Google Etiket Yöneticisi'nden tamponu istediği biçimde gösterebilir.
Örneğin, uygulama piksel verilerini taşımayı seçebilir. satır içi ölçeklendirme veya rotasyon işlemiyle ilgili olabilir. Uygulama ayrıca, kaynak resmi bir OpenGL dokusu olarak kullanmayı ve karmaşık sahneyi çıktı arabelleğine ekler. Bu öğeler arasında simgeler, kurallar ve animasyonlar. Daha gelişmiş bir uygulama da birden fazla eş zamanlı giriş kamerası ekleyebilir ve bunları tek bir çıkış çerçevesine ekleyebilirsiniz (ör. araç çevresinin yukarıdan aşağıya, sanal görünümünde kullanım için)
EVS Ekran HAL'sinde EGL/SurfaceFlinger'ı kullanma
Bu bölümde, EVS Ekran HAL uygulaması oluşturmak için EGL'nin nasıl kullanılacağı açıklanmaktadır. en iyi uygulamaları paylaşacağız.
EVS
HAL referansı uygulaması, kamera önizlemesini şurada oluşturmak için EGL kullanır:
ekranı ve libgui
oluşturun. Android 8 (ve sonraki sürümlerde) libgui
VNDK-private olarak sınıflandırılır.
Tedarikçi firma işlemlerinin kullanamadığı, VNDK kitaplıklarında kullanılabilen kitaplık grubunu ifade eder.
HAL uygulamalarının tedarikçi bölümünde bulunması gerektiğinden, tedarikçi firmaların
HAL uygulamalarında yüzey.
Tedarikçi süreçleri için libgui oluşturma
EGL/SurfaceFlinger'ı kullanmak için tek seçenek libgui
kullanımıdır.
inceleyebilirsiniz. libgui
özelliğini uygulamanın en basit yolu
-
frameworks/native/libs/gui
doğrudan derleme komut dosyasında ek bir derleme hedefi kullanarak. Bu hedef,
iki alanın eklenmesi hariç libgui
hedefi:
name
vendor_available
cc_library_shared { name: "libgui_vendor", vendor_available: true, vndk: { enabled: false, }, double_loadable: true,
defaults: ["libgui_bufferqueue-defaults"],
srcs: [ … // bufferhub is not used when building libgui for vendors target: { vendor: { cflags: [ "-DNO_BUFFERHUB", "-DNO_INPUT", ], …
Not: Tedarikçi firma hedefleri, paket verilerinden 32 bit'lik bir kelimeyi kaldıran NO_INPUT
makrosuyla oluşturulur. SurfaceFlinger bu alanın kaldırıldığını beklediğinden, SurfaceFlinger paketi ayrıştıramadı. Bu durum bir fcntl
hatası olarak gözlemlenir:
W Parcel : Attempt to read object from Parcel 0x78d9cffad8 at offset 428 that is not in the object list E Parcel : fcntl(F_DUPFD_CLOEXEC) failed in Parcel::read, i is 0, fds[i] is 0, fd_count is 20, error: Unknown error 2147483647 W Parcel : Attempt to read object from Parcel 0x78d9cffad8 at offset 544 that is not in the object list
Bu durumu çözmek için:
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 6066421fa..25cf5f0ce 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -54,6 +54,9 @@ status_t layer_state_t::write(Parcel& output) const output.writeFloat(color.b); #ifndef NO_INPUT inputInfo.write(output); +#else + // Write a dummy 32-bit word. + output.writeInt32(0); #endif output.write(transparentRegion); output.writeUint32(transform);
Örnek derleme
talimatları aşağıda bulabilirsiniz. Bu e-postada
$(ANDROID_PRODUCT_OUT)/system/lib64/libgui_vendor.so
$ cd <your_android_source_tree_top> $ . ./build/envsetup. $ lunch <product_name>-<build_variant> ============================================ PLATFORM_VERSION_CODENAME=REL PLATFORM_VERSION=10 TARGET_PRODUCT=<product_name> TARGET_BUILD_VARIANT=<build_variant> TARGET_BUILD_TYPE=release TARGET_ARCH=arm64 TARGET_ARCH_VARIANT=armv8-a TARGET_CPU_VARIANT=generic TARGET_2ND_ARCH=arm TARGET_2ND_ARCH_VARIANT=armv7-a-neon TARGET_2ND_CPU_VARIANT=cortex-a9 HOST_ARCH=x86_64 HOST_2ND_ARCH=x86 HOST_OS=linux HOST_OS_EXTRA=<host_linux_version> HOST_CROSS_OS=windows HOST_CROSS_ARCH=x86 HOST_CROSS_2ND_ARCH=x86_64 HOST_BUILD_TYPE=release BUILD_ID=QT OUT_DIR=out ============================================
$ m -j libgui_vendor … $ find $ANDROID_PRODUCT_OUT/system -name "libgui_vendor*" .../out/target/product/hawk/system/lib64/libgui_vendor.so .../out/target/product/hawk/system/lib/libgui_vendor.so
EVS HAL uygulamasında bağlayıcı kullanma
Android 8 (ve sonraki sürümler) cihazlarda /dev/binder
cihaz düğümü şuna özel hale geldi:
ve bu nedenle tedarikçinin süreçlerine
erişememesi anlamına gelir. Bunun yerine
tedarikçi firma süreçleri, /dev/hwbinder
öğesini kullanmalı ve tüm AIDL arayüzlerini dönüştürmelidir
HIDL'ye. Tedarikçi firma süreçleri arasında AIDL arayüzlerini kullanmaya devam etmek isteyenler,
/dev/vndbinder
bağlayıcı alanını kullanın.
IPC Alanı | Açıklama |
---|---|
/dev/binder |
AIDL arayüzleriyle çerçeve/uygulama işlemleri arasında IPC |
/dev/hwbinder |
HIDL arayüzleriyle çerçeve/tedarikçi firma işlemleri arasında IPC HIDL arayüzleriyle satıcı işlemleri arasında IPC |
/dev/vndbinder |
AIDL arayüzleriyle tedarikçi/tedarikçi firma işlemleri arasında IPC |
SurfaceFlinger AIDL arayüzlerini tanımlarken, tedarikçi süreçleri yalnızca HIDL arayüzlerini kullanarak
nasıl iletişim kurabileceğinizi
öğreneceksiniz. Mevcut müşteri memnuniyetini
AIDL, HIDL ile arayüz oluşturur. Neyse ki Android, bağlayıcıyı seçmek için bir yöntem sağlıyor.
libbinder
için sürücüyü temsil eder.
diff --git a/evs/sampleDriver/service.cpp b/evs/sampleDriver/service.cpp index d8fb3166..5fd02935 100644 --- a/evs/sampleDriver/service.cpp +++ b/evs/sampleDriver/service.cpp @@ -21,6 +21,7 @@ #include <utils/Errors.h> #include <utils/StrongPointer.h> #include <utils/Log.h> +#include <binder/ProcessState.h> #include "ServiceNames.h" #include "EvsEnumerator.h" @@ -43,6 +44,9 @@ using namespace android; int main() { ALOGI("EVS Hardware Enumerator service is starting"); + // Use /dev/binder for SurfaceFlinger + ProcessState::initWithDriver("/dev/binder"); + // Start a thread to listen to video device addition events. std::atomic<bool> running { true }; std::thread ueventHandler(EvsEnumerator::EvsUeventThread, std::ref(running));
Not: Tedarikçi firma süreçleri, istekte bulunmadan önce bunu çağırmalıdır.
Process
veya IPCThreadState
ya da bağlayıcı çağrı yapmadan önce.
SELinux politikaları
Cihaz uygulaması tam tiz yapılırsa SELinux,
işlem /dev/binder
üzerinde gerçekleştirilemez. Örneğin, bir EVS HAL örneği
uygulama hal_evs_driver
alan adına atandı ve
binder_device
alanı için r/w izinleri.
W ProcessState: Opening '/dev/binder' failed: Permission denied F ProcessState: Binder driver could not be opened. Terminating. F libc : Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 9145 (android.hardwar), pid 9145 (android.hardwar) W android.hardwar: type=1400 audit(0.0:974): avc: denied { read write } for name="binder" dev="tmpfs" ino=2208 scontext=u:r:hal_evs_driver:s0 tcontext=u:object_r:binder_device:s0 tclass=chr_file permissive=0
Ancak bu izinleri eklemek, aşağıdaki kuralları ihlal ettiğinden derleme hatasına neden olur
tam tiz cihaz için system/sepolicy/domain.te
içinde tanımlanan hiçbir zaman kurallarına izin verme
libsepol.report_failure: neverallow on line 631 of system/sepolicy/public/domain.te (or line 12436 of policy.conf) violated by allow hal_evs_driver binder_device:chr_file { read write }; libsepol.check_assertions: 1 neverallow failures occurred
full_treble_only(` neverallow { domain -coredomain -appdomain -binder_in_vendor_violators } binder_device:chr_file rw_file_perms; ')
binder_in_vendor_violators
.
bir hatayı yakalamak ve geliştirme sürecini yönlendirmek için sağlanan bir özelliktir. Ayrıca bir dizi
yukarıda açıklanan Android 10 ihlalini çözüme ulaştırmak istiyorum.
diff --git a/evs/sepolicy/evs_driver.te b/evs/sepolicy/evs_driver.te index f1f31e9fc..6ee67d88e 100644 --- a/evs/sepolicy/evs_driver.te +++ b/evs/sepolicy/evs_driver.te @@ -3,6 +3,9 @@ type hal_evs_driver, domain, coredomain; hal_server_domain(hal_evs_driver, hal_evs) hal_client_domain(hal_evs_driver, hal_evs) +# Allow to use /dev/binder +typeattribute hal_evs_driver binder_in_vendor_violators; + # allow init to launch processes in this context type hal_evs_driver_exec, exec_type, file_type, system_file_type; init_daemon_domain(hal_evs_driver)
Tedarikçi süreci olarak EVS HAL referans uygulaması derleme
Referans olması açısından, aşağıdaki değişiklikleri
packages/services/Car/evs/Android.mk
Projenin başarılı bir şekilde
açıklanan tüm değişikliklerin uygulamanız için nasıl çalıştığını öğrenin.
diff --git a/evs/sampleDriver/Android.mk b/evs/sampleDriver/Android.mk index 734feea7d..0d257214d 100644 --- a/evs/sampleDriver/Android.mk +++ b/evs/sampleDriver/Android.mk @@ -16,7 +16,7 @@ LOCAL_SRC_FILES := \ LOCAL_SHARED_LIBRARIES := \ android.hardware.automotive.evs@1.0 \ libui \ - libgui \ + libgui_vendor \ libEGL \ libGLESv2 \ libbase \ @@ -33,6 +33,7 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_INIT_RC := android.hardware.automotive.evs@1.0-sample.rc LOCAL_MODULE := android.hardware.automotive.evs@1.0-sample +LOCAL_PROPRIETARY_MODULE := true LOCAL_MODULE_TAGS := optional LOCAL_STRIP_MODULE := keep_symbols @@ -40,6 +41,7 @@ LOCAL_STRIP_MODULE := keep_symbols LOCAL_CFLAGS += -DLOG_TAG=\"EvsSampleDriver\" LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code +LOCAL_CFLAGS += -Iframeworks/native/include #NOTE: It can be helpful, while debugging, to disable optimizations #LOCAL_CFLAGS += -O0 -g diff --git a/evs/sampleDriver/service.cpp b/evs/sampleDriver/service.cpp index d8fb31669..5fd029358 100644 --- a/evs/sampleDriver/service.cpp +++ b/evs/sampleDriver/service.cpp @@ -21,6 +21,7 @@ #include <utils/Errors.h> #include <utils/StrongPointer.h> #include <utils/Log.h> +#include <binder/ProcessState.h> #include "ServiceNames.h" #include "EvsEnumerator.h" @@ -43,6 +44,9 @@ using namespace android; int main() { ALOGI("EVS Hardware Enumerator service is starting"); + // Use /dev/binder for SurfaceFlinger + ProcessState::initWithDriver("/dev/binder"); + // Start a thread to listen video device addition events. std::atomic<bool> running { true }; std::thread ueventHandler(EvsEnumerator::EvsUeventThread, std::ref(running)); diff --git a/evs/sepolicy/evs_driver.te b/evs/sepolicy/evs_driver.te index f1f31e9fc..632fc7337 100644 --- a/evs/sepolicy/evs_driver.te +++ b/evs/sepolicy/evs_driver.te @@ -3,6 +3,9 @@ type hal_evs_driver, domain, coredomain; hal_server_domain(hal_evs_driver, hal_evs) hal_client_domain(hal_evs_driver, hal_evs) +# allow to use /dev/binder +typeattribute hal_evs_driver binder_in_vendor_violators; + # allow init to launch processes in this context type hal_evs_driver_exec, exec_type, file_type, system_file_type; init_daemon_domain(hal_evs_driver) @@ -22,3 +25,7 @@ allow hal_evs_driver ion_device:chr_file r_file_perms; # Allow the driver to access kobject uevents allow hal_evs_driver self:netlink_kobject_uevent_socket create_socket_perms_no_ioctl; + +# Allow the driver to use the binder device +allow hal_evs_driver binder_device:chr_file rw_file_perms;