Araç Kamerası HAL'si

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 Sistemi
bileşenler diyagramı.
Şekil 1. EVS sistem bileşenlerine genel bakış.

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 cinsinden stride = piksel cinsinden stride * 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 ve RGBA veya BGRA 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çin Gralloc.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ış).

EVS Yöneticisi ve
EVS Donanım API&#39;si diyagramı.
Şekil 2. EVS Yöneticisi, EVS'nin temelini yansıtıyor Donanım API'sı.

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.

.
Şekil 3. EVS uygulaması örnek mantığı, kamerayı al liste'ye dokunun.

.
.
Şekil 4. EVS uygulaması örnek mantığı, alma kare geri çağırmasına olanak tanır.

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;