Interfejsy API zarządzania buforem HAL3 kamery

Zadbaj o dobrą organizację dzięki kolekcji Zapisuj i kategoryzuj treści zgodnie ze swoimi preferencjami.

W systemie Android 10 wprowadzono opcjonalne interfejsy API zarządzania buforem HAL3 aparatu , które umożliwiają zaimplementowanie logiki zarządzania buforami w celu uzyskania innej pamięci i przechwycenia kompromisów w zakresie opóźnień w implementacjach HAL aparatu.

HAL kamery wymaga N żądań (gdzie N jest równe głębokości potoku ) umieszczonych w kolejce w potoku, ale często nie wymaga jednocześnie wszystkich N zestawów buforów wyjściowych.

Na przykład warstwa HAL może mieć osiem żądań w kolejce w potoku, ale wymaga buforów wyjściowych tylko dla dwóch żądań w ostatnich etapach potoku. Na urządzeniach z systemem Android 9 i starszym platforma aparatu przydziela bufory, gdy żądanie jest umieszczane w kolejce w warstwie HAL, więc w warstwie HAL może znajdować się sześć zestawów buforów, które nie są używane. W systemie Android 10 interfejsy API zarządzania buforem HAL3 kamery umożliwiają oddzielenie buforów wyjściowych w celu zwolnienia sześciu zestawów buforów. Może to prowadzić do oszczędności setek megabajtów pamięci na urządzeniach wysokiej klasy, a także może być korzystne dla urządzeń o małej ilości pamięci.

Rysunek 1 przedstawia schemat interfejsu HAL kamery dla urządzeń z systemem Android 9 i starszym. Rysunek 2 przedstawia interfejs HAL kamery w systemie Android 10 z zaimplementowanymi interfejsami API zarządzania buforem HAL3 kamery.

Zarządzanie buforami w 9 lub niższych

Rysunek 1. Interfejs HAL kamery w systemie Android 9 i niższych

Zarządzanie buforami w Androidzie 10

Rysunek 2. Interfejs HAL kamery w systemie Android 10 przy użyciu interfejsów API zarządzania buforami

Wdrażanie interfejsów API zarządzania buforami

Aby zaimplementować interfejsy API zarządzania buforami, warstwa HAL kamery musi:

HAL kamery używa metod requestStreamBuffers i returnStreamBuffers w ICameraDeviceCallback.hal do żądania i zwracania buforów. HAL musi również implementować metodę signalStreamFlush w ICameraDeviceSession.hal , aby zasygnalizować warstwie HAL kamery, że zwraca bufory.

requestStreamBuffers

Użyj metody requestStreamBuffers , aby zażądać buforów ze struktury aparatu. W przypadku korzystania z interfejsów API zarządzania buforem kamery HAL3 żądania przechwytywania ze struktury kamery nie zawierają buforów wyjściowych, czyli pole bufferId w StreamBuffer ma wartość 0 . W związku z tym warstwa HAL kamery musi używać requestStreamBuffers do żądania buforów ze struktury kamery.

Metoda requestStreamBuffers umożliwia obiektowi wywołującemu żądanie wielu buforów z wielu strumieni wyjściowych w jednym wywołaniu, co pozwala na mniejszą liczbę wywołań IPC HIDL. Jednak wywołania zajmują więcej czasu, gdy w tym samym czasie żąda się większej liczby buforów, co może negatywnie wpłynąć na całkowite opóźnienie żądania do wyniku. Ponadto, ponieważ wywołania requestStreamBuffers są serializowane w usłudze kamery, zaleca się, aby warstwa HAL kamery używała dedykowanego wątku o wysokim priorytecie do żądania buforów.

Jeśli żądanie bufora nie powiedzie się, warstwa HAL kamery musi być w stanie prawidłowo obsłużyć błędy niekrytyczne. Na poniższej liście opisano typowe przyczyny niepowodzenia żądań bufora oraz sposób ich obsługi przez warstwę HAL kamery.

  • Aplikacja rozłącza się ze strumieniem wyjściowym: jest to błąd niekrytyczny. HAL kamery powinien wysłać ERROR_REQUEST dla każdego żądania przechwytywania kierowanego na odłączony strumień i być gotowy do normalnego przetwarzania kolejnych żądań.
  • Limit czasu: może się to zdarzyć, gdy aplikacja jest zajęta intensywnym przetwarzaniem, trzymając niektóre bufory. Kamera HAL powinna wysyłać ERROR_REQUEST w przypadku żądań przechwytywania, których nie można spełnić z powodu błędu przekroczenia limitu czasu, i powinna być gotowa do normalnego przetwarzania kolejnych żądań.
  • Struktura kamery przygotowuje nową konfigurację strumienia: warstwa HAL kamery powinna poczekać do zakończenia następnego wywołania configureStreams przed ponownym wywołaniem requestStreamBuffers .
  • HAL kamery osiągnął limit bufora (pole maxBuffers ): Przed ponownym wywołaniem requestStreamBuffers warstwa HAL kamery powinna poczekać, aż zwróci co najmniej jeden bufor strumienia.

returnStreamBuffers

Użyj metody returnStreamBuffers , aby zwrócić dodatkowe bufory do struktury aparatu. HAL kamery zwykle zwraca bufory do struktury kamery za pomocą metody processCaptureResult , ale może uwzględniać tylko żądania przechwytywania, które zostały wysłane do warstwy HAL kamery. Dzięki metodzie requestStreamBuffers możliwe jest, aby implementacja warstwy HAL kamery zachowała więcej buforów niż zażądała struktura kamery. Wtedy należy użyć metody returnStreamBuffers . Jeśli implementacja HAL nigdy nie przechowuje więcej buforów niż żądano, implementacja HAL kamery nie musi wywoływać metody returnStreamBuffers .

SignalStreamFlush

Metoda signalStreamFlush jest wywoływana przez strukturę kamery w celu powiadomienia warstwy HAL kamery o zwróceniu wszystkich dostępnych buforów. Jest to zwykle wywoływane, gdy struktura kamery ma wywołać configureStreams i musi opróżnić potok przechwytywania kamery. Podobnie jak w przypadku metody returnStreamBuffers , jeśli implementacja warstwy HAL kamery nie przechowuje więcej buforów niż żądano, możliwe jest posiadanie pustej implementacji tej metody.

Po wywołaniu przez strukturę kamery signalStreamFlush struktura przestaje wysyłać nowe żądania przechwytywania do warstwy HAL kamery, dopóki wszystkie bufory nie zostaną zwrócone do struktury kamery. Po zwróceniu wszystkich buforów wywołania metody requestStreamBuffers kończą się niepowodzeniem, a struktura kamery może kontynuować swoją pracę w stanie czystym. Następnie struktura kamery wywołuje metodę configureStreams lub processCaptureRequest . Jeśli struktura kamery wywoła metodę configureStreams , warstwa HAL kamery może ponownie rozpocząć żądanie buforów po pomyślnym zwróceniu wywołania configureStreams . Jeśli struktura kamery wywoła metodę processCaptureRequest , warstwa HAL kamery może rozpocząć żądanie buforów podczas wywołania processCaptureRequest .

Semantyka jest inna dla metody signalStreamFlush i metody flush . Gdy wywoływana jest metoda flush , warstwa HAL może przerwać oczekujące żądania przechwytywania z ERROR_REQUEST , aby jak najszybciej opróżnić potok. Po wywołaniu metody signalStreamFlush warstwa HAL musi normalnie zakończyć wszystkie oczekujące żądania przechwytywania i zwrócić wszystkie bufory do struktury kamery.

Inną różnicą między metodą signalStreamFlush a innymi metodami jest to, że signalStreamFlush jest jednokierunkową metodą HIDL, co oznacza, że ​​struktura kamery może wywołać inne blokujące interfejsy API, zanim warstwa HAL odbierze wywołanie signalStreamFlush . Oznacza to, że metoda signalStreamFlush i inne metody (w szczególności metoda configureStreams ) mogą dotrzeć do warstwy HAL kamery w innej kolejności niż kolejność ich wywoływania w strukturze kamery. Aby rozwiązać ten problem asynchroniczny, pole streamConfigCounter zostało dodane do StreamConfiguration i dodane jako argument do metody signalStreamFlush . Implementacja warstwy HAL kamery powinna używać argumentu streamConfigCounter , aby określić, czy wywołanie signalStreamFlush nadejdzie później niż odpowiadające mu wywołanie configureStreams . Zobacz rysunek 3 jako przykład.

Obsługa spóźnionych połączeń

Rysunek 3. Jak kamera HAL powinna wykrywać i obsługiwać spóźnione wywołania signalStreamFlush

Zmiany w zachowaniu podczas wdrażania interfejsów API do zarządzania buforami

Korzystając z interfejsów API zarządzania buforami do implementacji logiki zarządzania buforami, należy wziąć pod uwagę następujące możliwe zmiany w zachowaniu kamery i implementacji warstwy HAL kamery:

  • Żądania przechwytywania docierają do warstwy HAL kamery szybciej i częściej: bez interfejsów API zarządzania buforami struktura kamery żąda buforów wyjściowych dla każdego żądania przechwytywania przed wysłaniem żądania przechwytywania do warstwy HAL kamery. Podczas korzystania z interfejsów API zarządzania buforami struktura kamery nie musi już czekać na bufory, dzięki czemu może wcześniej wysyłać żądania przechwytywania do warstwy HAL kamery.

    Ponadto bez interfejsów API zarządzania buforami struktura kamery przestaje wysyłać żądania przechwytywania, jeśli jeden ze strumieni wyjściowych żądania przechwytywania osiągnie maksymalną liczbę buforów, które może jednocześnie przechowywać warstwa HAL (ta wartość jest wyznaczana przez warstwę HAL kamery w HalStream::maxBuffers w wartości zwracanej przez wywołanie configureStreams ). W przypadku interfejsów API zarządzania buforami to ograniczanie przepustowości już nie istnieje, a implementacja warstwy HAL aparatu nie może akceptować wywołań processCaptureRequest , gdy warstwa HAL ma w kolejce zbyt wiele żądań przechwytywania.

  • Opóźnienie wywołania requestStreamBuffers znacznie się różni: Istnieje wiele powodów, dla których wywołanie requestStreamBuffers może trwać dłużej niż przeciętnie. Na przykład:

    • W przypadku kilku pierwszych buforów nowo utworzonego strumienia wywołania mogą trwać dłużej, ponieważ urządzenie musi przydzielić pamięć.
    • Oczekiwane opóźnienie wzrasta proporcjonalnie do liczby buforów żądanych w każdym wywołaniu.
    • Aplikacja przechowuje bufory i jest zajęta przetwarzaniem. Może to spowodować spowolnienie żądań bufora lub przekroczenie limitu czasu z powodu braku buforów lub zajętego procesora.

Strategie zarządzania buforami

Interfejsy API zarządzania buforami umożliwiają wdrażanie różnych rodzajów strategii zarządzania buforami. Oto kilka przykładów:

  • Zgodność wsteczna: warstwa HAL żąda buforów dla żądania przechwytywania podczas wywołania processCaptureRequest . Ta strategia nie zapewnia żadnych oszczędności pamięci, ale może służyć jako pierwsza implementacja interfejsów API zarządzania buforami, wymagająca bardzo niewielu zmian w kodzie istniejącej warstwy HAL kamery.
  • Maksymalizacja oszczędności pamięci: Kamera HAL żąda buforów wyjściowych tylko bezpośrednio przed koniecznością ich zapełnienia. Ta strategia pozwala na maksymalizację oszczędności pamięci. Potencjalną wadą jest większe szarpnięcie potoku kamery, gdy realizacja żądań bufora trwa niezwykle długo.
  • Pamięć podręczna: warstwa HAL kamery buforuje kilka buforów, dzięki czemu jest mniej prawdopodobne, że sporadyczne żądanie wolnego bufora nie będzie miało na nią wpływu.

HAL kamery może przyjmować różne strategie dla poszczególnych przypadków użycia, na przykład używając strategii zmaksymalizowanego oszczędzania pamięci dla przypadków użycia, które zużywają dużo pamięci i używając strategii kompatybilności wstecznej dla innych przypadków użycia.

Przykładowa realizacja w zewnętrznej kamerze HAL

Zewnętrzna kamera HAL została wprowadzona w systemie Android 9 i można ją znaleźć w drzewie źródłowym pod adresem hardware/interfaces/camera/device/3.5/ . W systemie Android 10 został zaktualizowany, aby uwzględnić ExternalCameraDeviceSession.cpp , implementację interfejsu API zarządzania buforami. Ta zewnętrzna kamera HAL implementuje strategię maksymalizacji oszczędności pamięci wspomnianą w strategiach zarządzania buforami w kilkuset wierszach kodu C++.