Rozszerzenia aparatu

Producenci urządzeń mogą udostępniać rozszerzenia takie jak bokeh, tryb nocny i HDR programistom zewnętrznym za pośrednictwem interfejsu rozszerzeń aparatu udostępnianego przez bibliotekę dostawcy OEM. Programiści mogą korzystać z interfejsów API rozszerzeń Camera2 i API rozszerzeń CameraX, aby uzyskać dostęp do rozszerzeń zaimplementowanych w bibliotece dostawcy OEM.

Aby zapoznać się z listą obsługiwanych rozszerzeń, która jest taka sama w Camera2 i CameraX, zobacz API rozszerzeń CameraX . Jeśli chcesz dodać rozszerzenie, zgłoś błąd za pomocą narzędzia do śledzenia problemów .

Na tej stronie opisano, jak wdrożyć i włączyć bibliotekę dostawców OEM na urządzeniach.

Architektura

Poniższy diagram opisuje architekturę interfejsu rozszerzeń kamery lub extensions-interface : Architektura

Rysunek 1. Schemat architektury rozszerzeń kamery

Jak pokazano na diagramie, aby obsługiwać rozszerzenia kamery, należy zaimplementować extensions-interface dostarczony przez bibliotekę dostawcy OEM. Twoja biblioteka dostawców OEM udostępnia dwa interfejsy API: API rozszerzeń CameraX i API rozszerzeń Camera2 , które są używane odpowiednio przez aplikacje CameraX i Camera2 w celu uzyskania dostępu do rozszerzeń dostawców.

Zaimplementuj bibliotekę dostawców OEM

Aby zaimplementować bibliotekę dostawcy OEM, skopiuj pliki camera-extensions-stub do projektu biblioteki systemowej. Pliki te definiują interfejs rozszerzeń aparatu.

Pliki camera-extensions-stub są podzielone na następujące kategorie:

Niezbędne pliki interfejsu (nie modyfikuj)

  • PreviewExtenderImpl.java
  • ImageCaptureExtenderImpl.java
  • ExtenderStateListener.java
  • ProcessorImpl.java
  • PreviewImageProcessorImpl.java
  • CaptureProcessorImpl.java
  • CaptureStageImpl.java
  • RequestUpdateProcessorImpl.java
  • ProcessResultImpl.java
  • advanced/AdvancedExtenderImpl.java
  • advanced/Camera2OutputConfigImpl.java
  • advanced/Camera2SessionConfigImpl.java
  • advanced/ImageProcessorImpl.java
  • advanced/ImageReaderOutputConfigImpl.java
  • advanced/ImageReferenceImpl.java
  • advanced/MultiResolutionImageReaderOutputConfigImpl.java
  • advanced/OutputSurfaceImpl.java
  • advanced/RequestProcessorImpl.java
  • advanced/SessionProcessorImpl.java
  • advanced/SurfaceOutputConfigImpl.java

Obowiązkowe wdrożenia (dodaj swoją implementację)

  • ExtensionVersionImpl.java
  • InitializerImpl.java

Klasy przedłużacza Bokeh (zaimplementuj je, jeśli obsługiwane jest rozszerzenie Bokeh)

  • BokehImageCaptureExtenderImpl.java
  • BokehPreviewExtenderImpl.java
  • advanced/BokehAdvancedExtenderImpl.java

Klasy wydłużające noc (zaimplementuj je, jeśli obsługiwane jest rozszerzenie nocne)

  • NightImageCaptureExtenderImpl.java
  • NightPreviewExtenderImpl.java
  • advanced/NightAdvancedExtenderImpl.java

Klasy automatycznego przedłużacza (zaimplementuj je, jeśli obsługiwane jest automatyczne rozszerzanie)

  • AutoImageCaptureExtenderImpl.java
  • AutoPreviewExtenderImpl.java
  • advanced/AutoAdvancedExtenderImpl.java

Klasy przedłużaczy HDR (zaimplementuj je, jeśli obsługiwane jest rozszerzenie HDR)

  • HdrImageCaptureExtenderImpl.java
  • HdrPreviewExtenderImpl.java
  • advanced/HdrAdvancedExtenderImpl.java

Klasy rozszerzenia Retusz twarzy (zaimplementuj je, jeśli obsługiwane jest rozszerzenie Retusz twarzy)

  • BeautyImageCaptureExtenderImpl.java
  • BeautyPreviewExtenderImpl.java
  • advanced/BeautyAdvancedExtenderImpl.java

Narzędzia (opcjonalne, można usunąć)

  • advanced/Camera2OutputConfigImplBuilder.java
  • advanced/Camera2SessionConfigImplBuilder.java

Nie musisz dostarczać implementacji dla każdego rozszerzenia. Jeśli nie zaimplementujesz rozszerzenia, ustaw isExtensionAvailable() tak, aby zwracała false lub usuń odpowiednie klasy Extendera. Interfejsy API rozszerzeń Camera2 i CameraX zgłaszają aplikacji informację, że rozszerzenie jest niedostępne.

Przyjrzyjmy się, jak interfejsy API rozszerzeń Camera2 i CameraX współdziałają z biblioteką dostawcy, aby włączyć rozszerzenie. Poniższy diagram ilustruje całościowy przepływ na przykładzie rozszerzenia Night:

Główny przepływ

Rysunek 2. Implementacja przedłużenia nocnego

  1. Weryfikacja wersji:

    Camera2/X wywołuje ExtensionVersionImpl.checkApiVersion() , aby upewnić się, że wersja extensions-interface zaimplementowanego przez OEM jest zgodna z wersjami obsługiwanymi przez Camera2/X.

  2. Inicjalizacja biblioteki dostawcy:

    InitializerImpl ma metodę init() , która inicjuje bibliotekę dostawcy. Camera2/X kończy inicjalizację przed uzyskaniem dostępu do klas Extendera.

  3. Klasy instancji instancji Extender:

    Tworzy instancję klas Extender dla rozszerzenia. Istnieją dwa typy Extenderów: Basic Extender i Advanced Extender. Musisz zaimplementować jeden typ Extendera dla wszystkich rozszerzeń. Aby uzyskać więcej informacji, zobacz temat Podstawowy i zaawansowany przedłużacz .

    Camera2/X tworzy instancje klas Extender i współdziała z nimi w celu pobrania informacji i włączenia rozszerzenia. Dla danego rozszerzenia Camera2/X może wielokrotnie tworzyć instancje klas Extender. W rezultacie nie wykonuj intensywnej inicjalizacji w konstruktorze ani wywołaniu init() . Ciężkie prace wykonuj tylko wtedy, gdy sesja kamery ma się wkrótce rozpocząć, na przykład gdy wywoływana jest metoda onInit() w programie Basic Extender lub initSession() w programie Advanced Extender.

    W przypadku rozszerzenia Night tworzone są następujące klasy Extendera dla typu Basic Extender:

    • NightImageCaptureExtenderImpl.java
    • NightPreviewExtenderImpl.java

    A dla typu Advanced Extender:

    • NightAdvancedExtenderImpl.java
  4. Sprawdź dostępność rozszerzenia:

    Przed włączeniem rozszerzenia isExtensionAvailable() sprawdza, czy rozszerzenie jest dostępne dla określonego identyfikatora kamery za pośrednictwem instancji Extendera.

  5. Zainicjuj urządzenie Extender za pomocą informacji o kamerze:

    Camera2/X wywołuje init() w instancji Extender i przekazuje jej identyfikator kamery i CameraCharacteristics .

  6. Informacje o zapytaniu:

    Wywołuje klasę Extender, aby pobrać informacje, takie jak obsługiwane rozdzielczości, nadal przechwytywać szacowane opóźnienia i przechwytywać klucze żądań z urządzenia Extender w ramach przygotowań do włączenia rozszerzenia.

  7. Włącz rozszerzenie na urządzeniu Extender:

    Klasa Extender zapewnia wszystkie interfejsy potrzebne do włączenia tej klasy. Oferuje mechanizm umożliwiający podłączenie implementacji OEM do potoku Camera2, taki jak wstrzykiwanie parametrów żądania przechwytywania lub włączanie postprocesora.

    W przypadku typu Advanced Extender Camera2/X współdziała z SessionProcessorImpl , aby włączyć rozszerzenie. Camera2/X pobiera instancję SessionProcessorImpl , wywołując metodę createSessionProcessor() na urządzeniu Extender.

W poniższych sekcjach opisano bardziej szczegółowo przebieg rozszerzenia.

Weryfikacja wersji

Podczas ładowania biblioteki dostawcy OEM z urządzenia w czasie wykonywania Camera2/X sprawdza, czy biblioteka jest kompatybilna z wersją extensions-interface . extensions-interface wykorzystuje wersjonowanie semantyczne lub MAJOR.MINOR.PATCH, na przykład 1.1.0 lub 1.2.0. Jednak podczas weryfikacji wersji używane są tylko wersje główne i poboczne.

Aby zweryfikować wersję, Camera2/X wywołuje funkcję ExtensionVersionImpl.checkApiVersion() z obsługiwaną wersją extensions-interface . Camera2/X następnie wykorzystuje wersję zgłoszoną przez bibliotekę OEM, aby określić, czy rozszerzenie można włączyć i jakie możliwości powinno wywoływać.

Zgodność wersji głównej

Jeśli główne wersje interfejsu rozszerzeń różnią się w przypadku Camera2/X i biblioteki dostawcy, wówczas jest to uważane za niekompatybilne i rozszerzenie jest wyłączone.

Kompatybilność wsteczna

Tak długo, jak wersja główna jest identyczna, Camera2/X zapewnia kompatybilność wsteczną z bibliotekami dostawców OEM zbudowanymi przy użyciu wcześniejszych wersji extensions-interface . Na przykład, jeśli Camera2/X obsługuje extensions-interface 1.3.0, biblioteki dostawców OEM, które zaimplementowały 1.0.0, 1.1.0 i 1.2.0, są nadal kompatybilne. Oznacza to również, że po zaimplementowaniu określonej wersji biblioteki dostawcy Camera2/X upewnia się, że biblioteka jest wstecznie kompatybilna z nadchodzącymi wersjami extension-interface .

Kompatybilność w przód

Kompatybilność z bibliotekami dostawców nowszych extensions-interface zależy od Ciebie, producenta OEM. Jeśli potrzebujesz pewnych funkcji do wdrożenia rozszerzeń, możesz włączyć rozszerzenia, zaczynając od określonej wersji. W takim przypadku możesz zwrócić obsługiwaną wersję extensions-interface , gdy wersja biblioteki Camera2/X spełnia wymagania. Jeśli wersje Camera2/X nie są obsługiwane, możesz zwrócić niekompatybilną wersję, np. 99.0.0, aby wyłączyć rozszerzenia.

Inicjalizacja biblioteki dostawcy

Po sprawdzeniu wersji extensions-interface zaimplementowanej przez bibliotekę OEM, Camera2/X rozpoczyna proces inicjalizacji. Metoda InitializerImpl.init() sygnalizuje bibliotece OEM, że aplikacja próbuje użyć rozszerzeń.

Camera2/X nie wykonuje żadnych innych wywołań biblioteki OEM (poza sprawdzaniem wersji), dopóki biblioteka dostawcy OEM nie wywoła OnExtensionsInitializedCallback.onSuccess() w celu powiadomienia o zakończeniu inicjalizacji.

Musisz zaimplementować InitializerImpl od extensions-interface 1.1.0. Camera2/X pomija etap inicjalizacji biblioteki, jeśli biblioteka dostawcy OEM implementuje extensions-interface 1.0.0.

Podstawowy Extender kontra zaawansowany Extender

Istnieją dwa typy implementacji extensions-interface : Basic Extender i Advanced Extender. Advanced Extender jest obsługiwany od extensions-interface 1.2.0.

Zaimplementuj Basic Extender dla rozszerzeń przetwarzających obrazy w kamerze HAL lub użyj postprocesora zdolnego do przetwarzania strumieni YUV.

Zaimplementuj Advanced Extender dla rozszerzeń, które muszą dostosować konfigurację strumienia Camera2 i wysyłać żądania przechwytywania w razie potrzeby.

Dla porównania zobacz poniższą tabelę:

Podstawowy przedłużacz Zaawansowany przedłużacz
Konfiguracje strumieniowe Naprawił
Podgląd: PRIVATE lub YUV_420_888 (jeśli istnieje procesor)
Przechwytywanie zdjęć: JPEG lub YUV_420_888 (jeśli istnieje procesor)
Możliwość dostosowania przez OEM.
Wysyłam żądanie przechwytywania Tylko Camera2/X może wysyłać żądania przechwytywania. Można ustawić parametry tych żądań. Gdy procesor jest przeznaczony do przechwytywania obrazu, Camera2/X może wysyłać wiele żądań przechwytywania i wysyłać wszystkie obrazy i wyniki przechwytywania do procesora. Dostępna jest instancja RequestProcessorImpl umożliwiająca wykonanie żądania przechwycenia przez kamerę2 oraz uzyskanie wyników i obrazu.

Camera2/X wywołuje startRepeating i startCapture na SessionProcessorImpl , aby zasygnalizować producentowi OEM, aby odpowiednio uruchomił powtarzające się żądanie podglądu i rozpoczął sekwencję przechwytywania nieruchomego obrazu.

Haki w rurociągu kamery
  • onPresetSession udostępnia parametry sesji.
  • onEnableSession wysyła pojedyncze żądanie zaraz po skonfigurowaniu CameraCaptureSession .
  • onDisableSession wysyła pojedyncze żądanie przed zamknięciem CameraCaptureSession .
  • initSession inicjuje i zwraca dostosowaną konfigurację sesji kamery2 w celu utworzenia sesji przechwytywania.
  • onCaptureSessionStart jest wywoływany zaraz po skonfigurowaniu CameraCaptureSession .
  • onCaptureSessionEnd jest wywoływany przed zamknięciem CameraCaptureSession .
Nadaje się do Rozszerzenia zaimplementowane w kamerze HAL lub w procesorze przetwarzającym obrazy YUV.
  • Zawiera implementacje rozszerzeń oparte na Camera2.
  • Wymaga dostosowanej konfiguracji strumienia, np. strumienia RAW.
  • Wymaga interaktywnej sekwencji przechwytywania.
Obsługiwana wersja API Rozszerzenia Camera2: Android 13 lub nowszy
Rozszerzenia CameraX: camera-extensions 1.1.0 lub nowsze
Rozszerzenia Camera2: Android 12L lub nowszy
Rozszerzenia CameraX: camera-extensions 1.2.0-alpha03 lub nowsze

Aplikacja przepływa

W poniższej tabeli przedstawiono trzy typy przepływów aplikacji i odpowiadające im wywołania interfejsu API rozszerzeń aparatu. Chociaż Camera2/X udostępnia te interfejsy API, należy odpowiednio zaimplementować bibliotekę dostawcy, aby obsługiwać te przepływy, co opiszemy bardziej szczegółowo w dalszej części.

Rozszerzenia Camera2 Rozszerzenia CameraX
Zapytanie o dostępność rozszerzenia CameraExtensionCharacteristics . getSupportedExtensions ExtensionsManager. isExtensionAvailable
Zapytanie o informacje CameraExtensionCharacteristics. getExtensionSupportedSizes CameraExtensionCharacteristics. getEstimatedCaptureLatencyRangeMillis CameraExtensionCharacteristics. getAvailableCaptureRequestKeys CameraExtensionCharacteristics. getAvailableCaptureResultKeys ExtensionsManager. getEstimatedCaptureLatencyRange

CameraX obsługuje resztę informacji w bibliotece.

Podgląd i przechwytywanie z włączonym rozszerzeniem CameraDevice. createExtensionSession

cameraExtensionsSession. setRepeatingRequest

cameraExtensionsSession. capture

val cameraSelector = ExtensionsManager. getExtensionEnabledCameraSelector bindToLifecycle(lifecycleOwner, CameraSelector, podgląd, ...)

Podstawowy przedłużacz

Interfejs Basic Extender zapewnia zaczepy w kilku miejscach w potoku kamery. Każdy typ rozszerzenia ma odpowiednie klasy Extendera, które producenci OEM muszą zaimplementować.

W poniższej tabeli wymieniono klasy Extenderów, które producenci OEM muszą zaimplementować dla każdego rozszerzenia:

Klasy rozszerzające do zaimplementowania
Noc NightPreviewExtenderImpl.java

NightImageCaptureExtenderImpl.java

HDR HdrPreviewExtenderImpl.java HdrImageCaptureExtenderImpl.java
Automatyczny AutoPreviewExtenderImpl.java AutoImageCaptureExtenderImpl.java
Bokeh BokehPreviewExtenderImpl.java BokehImageCaptureExtenderImpl.java
Retusz twarzy BeautyPreviewExtenderImpl.java BeautyImageCaptureExtenderImpl.java

W poniższym przykładzie używamy PreviewExtenderImpl i ImageCaptureExtenderImpl jako symboli zastępczych. Zastąp je nazwami rzeczywistych plików, które wdrażasz.

Podstawowy Extender ma następujące możliwości:

  • Wstrzyknij parametry sesji podczas konfigurowania CameraCaptureSession ( onPresetSession ).
  • Powiadamia Cię o zdarzeniach rozpoczęcia i zamknięcia sesji przechwytywania oraz wyśle ​​pojedyncze żądanie powiadomienia warstwy HAL o zwróconych parametrach ( onEnableSession , onDisableSession ).
  • Wstrzyknij parametry przechwytywania dla żądania ( PreviewExtenderImpl.getCaptureStage , ImageCaptureExtenderImpl.getCaptureStages ).
  • Dodaj procesory do podglądu i nadal przechwytywania, które są w stanie przetwarzać strumień YUV_420_888 .

Zobaczmy, jak Camera2/X wywołuje extensions-interface , aby osiągnąć trzy wymienione powyżej przepływy aplikacji.

Przebieg aplikacji 1: Sprawdź dostępność rozszerzenia

PodstawowyExtenderAppFlow1

Rysunek 3. Przepływ aplikacji 1 na urządzeniu Basic Extender

W tym przebiegu Camera2/X bezpośrednio wywołuje metodę isExtensionAvailable() zarówno PreviewExtenderImpl , jak i ImageCaptureExtenderImpl bez wywoływania init() . Obie klasy Extender muszą zwrócić true , aby włączyć rozszerzenia.

Często jest to pierwszy krok aplikacji, aby przed włączeniem rozszerzenia sprawdzić, czy dany typ rozszerzenia jest obsługiwany dla danego identyfikatora kamery. Dzieje się tak dlatego, że niektóre rozszerzenia są obsługiwane tylko w przypadku niektórych identyfikatorów kamer.

Przebieg aplikacji 2: Zapytanie o informacje

PodstawowyExtenderAppFlow2

Rysunek 4. Przepływ aplikacji 2 na urządzeniu Basic Extender

Po ustaleniu, czy rozszerzenie jest dostępne, aplikacje powinny sprawdzić następujące informacje przed włączeniem rozszerzenia.

  • Nadal zakres opóźnienia przechwytywania: ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange zwraca zakres opóźnienia przechwytywania, aby aplikacja mogła ocenić, czy należy włączyć rozszerzenie dla bieżącego scenariusza.

  • Obsługiwane rozmiary powierzchni podglądu i przechwytywania: ImageCaptureExtenderImpl.getSupportedResolutions i PreviewExtenderImpl.getSupportedResolutions zwracają listę formatów obrazu i rozmiarów obsługiwanych dla formatu i rozmiaru powierzchni.

  • Obsługiwane klucze żądań i wyników: Camera2/X wywołuje następujące metody w celu pobrania obsługiwanych kluczy żądań przechwytywania i kluczy wyników z implementacji:

    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys
    • ImageCaptureExtenderImpl.getAvailableCapturetResultKeys

Camera2/X zawsze najpierw wywołuje init() w tych klasach Extendera, zanim zapyta o więcej informacji.

Przebieg aplikacji 3: Podgląd/przechwytywanie zdjęć z włączonym rozszerzeniem (implementacja HAL)

PodstawowyExtenderAppFlow3

Rysunek 5. Przepływ aplikacji 3 na urządzeniu Basic Extender

Powyższy diagram ilustruje główny przebieg włączania podglądu i ciągłego przechwytywania za pomocą rozszerzenia bez żadnego procesora. Oznacza to, że kamera HAL przetwarza rozszerzenie.

W tym procesie Camera2/X najpierw wywołuje init() a następnie onInit , która powiadamia użytkownika o rozpoczęciu sesji kamery z określonymi rozszerzeniami. Możesz wykonać inicjalizację ciężkiego podnoszenia w onInit() .

Podczas konfigurowania CameraCaptureSession Camera2/X wywołuje onPresetSession , aby uzyskać parametry sesji. Po pomyślnym skonfigurowaniu sesji przechwytywania Camera2/X wywołuje onEnableSession , zwracając instancję CaptureStageImpl zawierającą parametry przechwytywania. Camera2/X natychmiast wysyła pojedyncze żądanie z tymi parametrami przechwytywania, aby powiadomić HAL. Podobnie, przed zamknięciem sesji przechwytywania, Camera2/X wywołuje onDisableSession , a następnie wysyła pojedyncze żądanie ze zwróconymi parametrami przechwytywania.

Powtarzające się żądanie wyzwalane przez Camera2/X zawiera parametry żądania zwrócone przez PreviewExtenderImpl.getCaptureStage() . Ponadto żądanie przechwytywania nadal zawiera parametry zwrócone przez ImageCaptureExtenderImpl.getCaptureStages() .

Na koniec Camera2/X wywołuje onDeInit() po zakończeniu sesji kamery. Możesz zwolnić zasoby w onDeinit() .

Podgląd procesora

Oprócz kamery HAL można także zaimplementować rozszerzenia w procesorze.

Zaimplementuj PreviewExtenderImpl.getProcessorType , aby określić typ procesora, jak wyjaśniono poniżej:

  • PROCESSOR_TYPE_NONE : Brak procesora. Obrazy przetwarzane są w aparacie HAL.

  • PROCESSOR_TYPE_REQUEST_UPDATE_ONLY : Typ procesora umożliwia aktualizację powtarzającego się żądania o nowe parametry żądania przechwytywania w oparciu o najnowszy TotalCaptureResult .

    PreviewExtenderImpl.getProcessor musi zwrócić instancję RequestUpdateProcessorImpl , która przetwarza instancję TotalCaptureResult i zwraca instancję CaptureStageImpl , aby zaktualizować powtarzające się żądanie. PreviewExtenderImpl.getCaptureStage() powinna również odzwierciedlać wynik przetwarzania i zwracać najnowszą wersję CaptureStageImpl .

  • PROCESSOR_TYPE_IMAGE_PROCESSOR : Ten typ umożliwia zaimplementowanie procesora do przetwarzania obrazów YUV_420_888 i zapisywania wyników na PRIVATE powierzchni.

    Musisz zaimplementować i zwrócić instancję PreviewImageProcessorImpl w PreviewExtenderImpl.getProcessor . Procesor odpowiada za przetwarzanie obrazów wejściowych YUV_420_888 . Powinien zapisać dane wyjściowe w formacie PRIVATE podglądu. Camera2/X używa powierzchni YUV_420_888 zamiast PRIVATE do skonfigurowania CameraCaptureSession do podglądu.

    Zobacz poniższą ilustrację przedstawiającą przepływ:

Procesor podglądu

Rysunek 6. Podgląd przepływu za pomocą PreviewImageProcessorImpl

Interfejs PreviewImageProcessorImpl rozszerza ProcessImpl i ma trzy ważne metody:

  • onOutputSurface(Surface surface, int imageFormat) ustawia powierzchnię wyjściową procesora. W przypadku PreviewImageProcessorImpl imageFormat jest formatem pikselowym, takim jak PixelFormat.RGBA_8888 .

  • onResolutionUpdate(Size size) ustawia rozmiar obrazu wejściowego.

  • onImageFormatUpdate(int imageFormat) ustawia format obrazu wejściowego. Obecnie może to być tylko YUV_420_888 .

Procesor przechwytywania obrazu

W przypadku przechwytywania zdjęć można zaimplementować procesor, zwracając instancję CaptureProcessorImpl za pomocą ImageCaptureExtenderImpl.getCaptureProcessor . Procesor jest odpowiedzialny za przetworzenie listy przechwyconych obrazów YUV_420_888 i instancji TotalCaptureResult oraz zapisanie wyników na powierzchni YUV_420_888 .

Możesz bezpiecznie założyć, że podgląd jest włączony i działa przed wysłaniem żądania przechwytywania obrazu.

Zobacz przepływ na schemacie poniżej:

Procesor przechwytywania

Rysunek 7. Nadal przechwytuj przepływ za pomocą CaptureProcessorImpl

  1. Camera2/X używa powierzchni w formacie YUV_420_888 do przechwytywania zdjęć w celu skonfigurowania sesji przechwytywania. Camera2/X przygotowuje CaptureProcessorImpl wywołując:

    • CaptureProcessorImpl.onImageFormatUpdate() z YUV_420_888 .
    • CaptureProcessorImpl.onResolutionUpdate() z rozmiarem obrazu wejściowego.
    • CaptureProcessorImpl.onOutputSurface() z powierzchnią wyjściową YUV_420_888 .
  2. ImageCaptureExtenderImpl.getCaptureStages zwraca listę CaptureStageImpl , gdzie każdy element jest mapowany na instancję CaptureRequest z parametrami przechwytywania wysyłanymi przez Camera2/X. Na przykład, jeśli zwróci listę trzech instancji CaptureStageImpl , Camera2/X wysyła trzy żądania przechwytywania z odpowiednimi parametrami przechwytywania za pomocą interfejsu API captureBurst .

  3. Otrzymane obrazy i instancje TotalCaptureResult są łączone w pakiety i wysyłane do CaptureProcessorImpl w celu przetworzenia.

  4. CaptureProcessorImpl zapisuje wynikowy obraz (w formacie YUV_420_888 ) na powierzchni wyjściowej określonej przez wywołanie onOutputSurface() . W razie potrzeby Camera2/X konwertuje je na obrazy JPEG.

Obsługa kluczy i wyników żądań przechwytywania

Oprócz podglądu i robienia zdjęć z kamery aplikacje mogą ustawiać zoom, parametry lampy błyskowej lub uruchamiać funkcję ustawiania ostrości poprzez dotknięcie. Te parametry mogą nie być zgodne z implementacją rozszerzenia.

Do extensions-interface 1.3.0 dodano następujące metody, aby umożliwić wyświetlenie parametrów obsługiwanych przez Twoją implementację:

  • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys() zwraca klucze żądania przechwytywania obsługiwane przez Twoją implementację.
  • ImageCaptureExtenderImpl.getAvailableCaptureResultKeys() zwraca klucze wyników przechwytywania zawarte w wyniku przechwytywania.

Jeśli warstwa HAL kamery przetwarza rozszerzenie, Camera2/X pobiera wyniki przechwytywania w CameraCaptureSession.CaptureCallback . Jeśli jednak procesor jest zaimplementowany, Camera2/X pobiera wyniki przechwytywania w ProcessResultImpl , które są przekazywane do metody process() w PreviewImageProcessorImpl i CaptureProcessorImpl . Jesteś odpowiedzialny za raportowanie wyników przechwytywania poprzez ProcessResultImpl do Camera2/X.

Jako przykład zobacz definicję interfejsu CaptureProcessorImpl poniżej. W extensions-interface w wersji 1.3.0 lub nowszej wywoływane jest drugie wywołanie process() :

Interface CaptureProcessorImpl extends ProcessorImpl {
    // invoked when extensions-interface version < 1.3.0
    void process(Map<Integer, Pair<Image, TotalCaptureResult>> results);
    // invoked when extensions-interface version >= 1.3.0
    void process(Map<Integer, Pair<Image, TotalCaptureResult>> results,
            ProcessResultImpl resultCallback, Executor executor);
}

W przypadku typowych operacji aparatu, takich jak powiększanie, ustawianie ostrości przez dotknięcie, lampa błyskowa i kompensacja ekspozycji, zalecamy obsługę następujących klawiszy zarówno dla żądania przechwytywania, jak i wyniku przechwytywania:

  • Powiększenie:
    • CaptureRequest#CONTROL_ZOOM_RATIO
    • CaptureRequest#SCALER_CROP_REGION
  • Dotknij, aby ustawić ostrość:
    • CaptureRequest#CONTROL_AF_MODE
    • CaptureRequest#CONTROL_AF_TRIGGER
    • CaptureRequest#CONTROL_AF_REGIONS
    • CaptureRequest#CONTROL_AE_REGIONS
    • CaptureRequest#CONTROL_AWB_REGIONS
  • Błysk:
    • CaptureRequest#CONTROL_AE_MODE
    • CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
    • CaptureRequest#FLASH_MODE
  • Kompensacja ekspozycji:
    • CaptureRequest#CONTROL_AE_EXPOSURE_COMPENSATION

W przypadku podstawowych przedłużaczy, które implementują wersję 1.2.0 lub wcześniejsze, interfejs API rozszerzeń CameraX jawnie obsługuje wszystkie powyższe klucze. W przypadku extensions-interface 1.3.0 zarówno CameraX, jak i Camera2 honorują zwróconą listę i obsługują tylko zawarte w niej klucze. Na przykład, jeśli zdecydujesz się zwrócić tylko CaptureRequest#CONTROL_ZOOM_RATIO i CaptureRequest#SCALER_CROP_REGION w implementacji 1.3.0, oznacza to, że w aplikacji obsługiwane jest tylko powiększanie, natomiast nie jest dozwolone ustawianie ostrości przez dotknięcie, lampa błyskowa i kompensacja ekspozycji.

Zaawansowany przedłużacz

Advanced Extender to rodzaj implementacji dostawcy oparty na API Camera2. Ten typ Extendera został dodany w extensions-interface 1.2.0. W zależności od producenta urządzenia rozszerzenia mogą zostać zaimplementowane w warstwie aplikacji, co zależy od następujących czynników:

  • Niestandardowa konfiguracja strumienia: skonfiguruj niestandardowe strumienie, takie jak strumień RAW, lub utwórz wiele strumieni dla różnych identyfikatorów kamer fizycznych.

  • Możliwość wysyłania żądań Camera2: Obsługa skomplikowanej logiki interakcji, która może wysyłać żądania przechwytywania z parametrami opartymi na wynikach poprzednich żądań.

Advanced Extender zapewnia opakowanie lub warstwę pośrednią, dzięki czemu można dostosować konfigurację strumienia i wysyłać żądania przechwytywania na żądanie.

Pliki do wdrożenia

Aby przełączyć się na implementację Advanced Extender, metoda isAdvancedExtenderImplemented() w ExtensionVersionImpl musi zwracać true . Dla każdego typu rozszerzenia producenci OEM muszą zaimplementować odpowiednie klasy Extendera. Pliki implementacyjne Advanced Extender znajdują się w pakiecie Advanced .

Klasy rozszerzające do zaimplementowania
Noc advanced/NightAdvancedExtenderImpl.java
HDR advanced/HdrAdvancedExtenderImpl.java
Automatyczny advanced/AutoAdvancedExtenderImpl.java
Bokeh advanced/BokehAdvancedExtenderImpl.java
Retusz twarzy advanced/BeautyAdvancedExtenderImpl.java

W poniższym przykładzie używamy AdvancedExtenderImpl jako symbolu zastępczego. Zastąp ją nazwą pliku Extender dla implementowanego rozszerzenia.

Zobaczmy, jak Camera2/X wywołuje extensions-interface , aby uzyskać trzy przepływy aplikacji.

Przebieg aplikacji 1: Sprawdź dostępność rozszerzeń

Zaawansowany przepływ aplikacji 1

Rysunek 8. Przepływ aplikacji 1 na urządzeniu Advanced Extender

W pierwszej kolejności aplikacja sprawdza, czy dane rozszerzenie jest obsługiwane.

Przebieg aplikacji 2: Zapytanie o informacje

AdvancedAppFlow2

Rysunek 9. Przepływ aplikacji 2 na urządzeniu Advanced Extender

Po wywołaniu AdvancedExtenderImpl.init() aplikacja może zapytać o następujące informacje na temat AdvancedExtenderImpl :

  • Szacowane opóźnienie przechwytywania: AdvancedExtenderImpl.getEstimatedCaptureLatencyRange() zwraca zakres opóźnienia przechwytywania, aby aplikacja mogła ocenić, czy włączenie rozszerzenia w bieżącym scenariuszu jest właściwe.

  • Obsługiwane rozdzielczości podglądu i przechwytywania:

    • AdvancedExtenderImpl.getSupportedPreviewOutputResolutions() zwraca mapę formatu obrazu do listy rozmiarów obsługiwanych dla formatu i rozmiaru powierzchni podglądu. Producenci OEM muszą obsługiwać co najmniej format PRIVATE .

    • AdvancedExtenderImpl.getSupportedCaptureOutputResolutions() zwraca obsługiwany format i rozmiary powierzchni przechwytywania nieruchomych obiektów. Producenci OEM muszą obsługiwać dane wyjściowe w formacie JPEG i YUV_420_888 .

    • AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions() zwraca obsługiwane rozmiary dla dodatkowego strumienia YUV_420_888 na potrzeby analizy obrazu. Jeśli powierzchnia YUV do analizy obrazu nie jest obsługiwana, getSupportedYuvAnalysisResolutions() powinna zwrócić null lub pustą listę.

  • Dostępne klucze/wyniki żądań przechwytywania (dodane w extensions-interface 1.3.0): Camera2/X wywołuje następujące metody w celu pobrania obsługiwanych kluczy żądań przechwytywania i kluczy wyników z twojej implementacji:

    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys
    • AdvancedExtenderImpl.getAvailableCaptureResultKeys

Aby uzyskać więcej informacji, zobacz klucze i wyniki żądań przechwytywania pomocy technicznej .

Przebieg aplikacji 3: Podgląd/przechwytywanie zdjęć z włączonym rozszerzeniem

Zaawansowany przepływ aplikacji3

Rysunek 10. Przepływ aplikacji 3 na urządzeniu Advanced Extender

Powyższy diagram przedstawia główny przebieg uruchamiania podglądu i ciągłego przechwytywania dla typu Advanced Extender. Przejdźmy przez każdy krok.

  1. Instancja SessionProcessorImpl

    Podstawowa implementacja Advanced Extender znajduje się w SessionProcessorImpl , który jest odpowiedzialny za zapewnienie dostosowanej konfiguracji sesji i wysyłanie żądań przechwytywania w celu zainicjowania żądania podglądu i dalszego przechwytywania. Wywoływana jest AdvancedExtenderImpl.createSessionProcessor() w celu zwrócenia instancji SessionProcessorImpl .

  2. initSession

    SessionProcessorImpl.initSession() inicjuje sesję dla rozszerzenia. W tym miejscu przydzielasz zasoby i zwracasz konfigurację sesji w celu przygotowania CameraCaptureSession .

    W przypadku parametrów wejściowych Camera2/X określa konfiguracje powierzchni wyjściowej dla podglądu, przechwytywania zdjęć i opcjonalnej analizy obrazu YUV. Ta konfiguracja powierzchni wyjściowej ( OutputSurfaceImpl ) zawiera powierzchnię, rozmiar i format obrazu, które są pobierane następującymi metodami w AdvancedExtenderImpl :

    • getSupportedPreviewOutputResolutions()
    • getSupportedCaptureOutputResolutions()
    • getSupportedYuvAnalysisResolutions()

    Należy zwrócić instancję Camera2SessionConfigImpl , która składa się z listy instancji Camera2OutputConfigImpl i parametrów sesji używanych do konfigurowania CameraCaptureSession . Jesteś odpowiedzialny za wysyłanie prawidłowych obrazów z kamery na powierzchnie wyjściowe przekazywane przez Camera2/X. Oto kilka opcji umożliwiających włączenie wyjścia:

    • Przetwarzanie w kamerze HAL: Możesz bezpośrednio dodać powierzchnie wyjściowe do CameraCaptureSession za pomocą implementacji SurfaceOutputConfigImpl . Konfiguruje to powierzchnię wyjściową dostarczoną do rurociągu kamery i umożliwia kamerze HAL przetwarzanie obrazu.
    • Przetwarzanie pośredniej powierzchni ImageReader (RAW, YUV itp.): Dodaj pośrednie powierzchnie ImageReader do CameraCaptureSession z instancją ImageReaderOutputConfigImpl .

      Musisz przetworzyć obrazy pośrednie i zapisać obraz wynikowy na powierzchni wyjściowej.

    • Użyj udostępniania powierzchni Camera2: Użyj udostępniania powierzchni innej powierzchni, dodając dowolną instancję Camera2OutputConfigImpl do metody getSurfaceSharingOutputConfigs() innej instancji Camera2OutputConfigImpl . Format i rozmiar powierzchni muszą być identyczne.

    Wszystkie Camera2OutputConfigImpl , w tym SurfaceOutputConfigImpl i ImageReaderOutputConfigImpl , muszą mieć unikalny identyfikator ( getId() ), który służy do określenia powierzchni docelowej i pobrania obrazu z ImageReaderOutputConfigImpl .

  3. onCaptureSessionStart i RequestProcessorImpl

    Po uruchomieniu CameraCaptureSession i wywołaniu struktury Camera onConfigured() , Camera2/X wywołuje SessionProcessorImpl.onCaptureSessionStart() z opakowaniem żądań Camera2 RequestProcessImpl . Camera2/X implementuje RequestProcessImpl , który umożliwia wykonywanie żądań przechwytywania i pobieranie obrazów , jeśli używany jest ImageReaderOutputConfigImpl .

    Interfejsy API RequestProcessImpl są podobne do interfejsów API Camera2 CameraCaptureSession pod względem wykonywania żądań. Różnice są następujące:

    • Powierzchnia docelowa jest określona przez identyfikator instancji Camera2OutputConfigImpl .
    • Możliwość pobrania obrazu z ImageReader .

    Można wywołać funkcję RequestProcessorImpl.setImageProcessor() z określonym identyfikatorem Camera2OutputConfigImpl , aby zarejestrować instancję ImageProcessorImpl w celu odbierania obrazów.

    Instancja RequestProcessImpl staje się nieprawidłowa po wywołaniu przez Camera2/X SessionProcessorImpl.onCaptureSessionEnd() .

  4. Uruchom podgląd i zrób zdjęcie

    W implementacji Advanced Extender możesz wysyłać żądania przechwytywania poprzez interfejs RequestProcessorImpl . Camera2/X powiadamia Cię o rozpoczęciu powtarzającego się żądania podglądu lub sekwencji przechwytywania zdjęć, wywołując odpowiednio SessionProcessorImpl#startRepeating i SessionProcessorImpl#startCapture . Powinieneś wysyłać żądania przechwytywania, aby spełnić te żądania podglądu i nieruchomego przechwytywania.

    Camera2/X ustawia również parametry żądania przechwytywania za pomocą SessionProcessorImpl#setParameters . Należy ustawić te parametry żądania (jeśli parametry są obsługiwane) zarówno w przypadku żądań powtarzanych, jak i pojedynczych.

    Musisz obsługiwać co najmniej CaptureRequest.JPEG_ORIENTATION i CaptureRequest.JPEG_QUALITY . extensions-interface 1.3.0 obsługuje klucze żądań i wyników, które są ujawniane następującymi metodami:

    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys()
    • AdvancedExtenderImpl.getAvailableCaptureResultKeys()

    Gdy programiści ustawiają klucze na liście getAvailableCaptureRequestKeys , należy włączyć parametry i upewnić się, że wynik przechwytywania zawiera klucze z listy getAvailableCaptureResultKeys .

  5. startTrigger

    SessionProcessorImpl.startTrigger() jest wywoływana w celu uruchomienia wyzwalacza, takiego jak CaptureRequest.CONTROL_AF_TRIGGER i CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER . Możesz zignorować wszelkie klucze żądania przechwytywania, które nie zostały ogłoszone w AdvancedExtenderImpl.getAvailableCaptureRequestKeys() .

    startTrigger() jest obsługiwana od extensions-interface 1.3.0. Umożliwia aplikacjom wdrażanie funkcji „dotknij, aby ustawić ostrość” i flashowanie z rozszerzeniami.

  6. Posprzątać

    Po zakończeniu sesji przechwytywania wywoływana jest metoda SessionProcessorImpl.onCaptureSessionEnd() przed zamknięciem CameraCaptureSession . Po zamknięciu sesji przechwytywania deInitSession() przeprowadza czyszczenie.

Obsługa podglądu, przechwytywania zdjęć i analizy obrazu

Powinieneś zastosować rozszerzenie zarówno do zastosowań podglądu, jak i do przechwytywania. Jeśli jednak opóźnienie jest zbyt duże, aby płynnie wyświetlić podgląd, można zastosować rozszerzenie tylko do przechwytywania zdjęć.

Dla typu Basic Extender, niezależnie od włączenia rozszerzenia do podglądu, należy zaimplementować zarówno ImageCaptureExtenderImpl , jak i PreviewExtenderImpl dla danego rozszerzenia. Często aplikacja używa również strumienia YUV do analizy zawartości obrazu, takiej jak znalezienie kodów QR lub tekst. Aby lepiej obsługiwać ten przypadek użycia, należy obsługiwać kombinację strumieniową podglądu, nadal przechwytywać, oraz strumień YUV_420_888 do konfigurowania CameraCaptureSession . Oznacza to, że jeśli zaimplementujesz procesor, musisz obsługiwać kombinację strumienia trzech strumieni YUV_420_888 .

W przypadku zaawansowanego przedłużacza Camera2/x przechodzi trzy powierzchnie wyjściowe do wywołania SessionProcessorImpl.initSession() . Te powierzchnie wyjściowe służą odpowiednio podglądowi, wciąż przechwytywaniu i analizie obrazu. Musisz upewnić się, że podgląd i nadal przechwytywanie powierzchni wyjściowych pokazują ważne wyjście. Jednak dla powierzchni wyjściowej analizy obrazu upewnij się, że działa ona tylko wtedy, gdy nie jest zerowy. Jeśli Twoja implementacja nie może obsługiwać strumienia analizy obrazu, możesz zwrócić pustą listę w AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions() . Zapewnia to, że powierzchnia wyjściowa analizy obrazu jest zawsze zerowa w SessionProcessorImpl.initSession() .

Obsługuj przechwytywanie wideo

Obecna architektura przedłużenia kamery obsługuje tylko podgląd i nadal przechwytuje przypadki użycia. Nie obsługujemy rozszerzenia na powierzchni MediaCodec lub MediaRecorder do nagrywania wideo. Jednak aplikacje mogą rejestrować dane wyjściowe podglądu.

Wspieranie powierzchni MediaCodec i MediaRecorder jest badane.

Metadane specyficzne dla rozszerzenia

W przypadku Androida 14 i wyższych metadanych specyficznych dla rozszerzenia pozwala klientom rozszerzenia kamery ustawiać i odbierać ustawienia i wyniki żądania przechwytywania specyficzne dla rozszerzenia. W szczególności klienci rozszerzenia kamery mogą użyć parametru żądania przechwytywania EXTENSION_STRENGTH do kontrolowania siły rozszerzenia i wyniku przechwytywania EXTENSION_CURRENT_TYPE , aby wskazać typ rozszerzenia włączonego.

Żądania przechwytywania

Parametr żądania przechwytywania EXTENSION_STRENGTH kontroluje wytrzymałość efektu rozszerzenia po przetwarzaniu. Odpowiedni wynik przechwytywania zawiera domyślną wartość siły, jeśli ten parametr nie jest jawnie ustawiony przez klienta. Ten parametr można zastosować w następujący sposób dla tych typów rozszerzeń:

  • BOKEH : kontroluje ilość rozmycia.
  • HDR i NIGHT : kontroluje ilość połączonych obrazów i jasność ostatecznego obrazu.
  • FACE_RETOUCH : Kontroluje ilość ulepszenia kosmetycznego i wygładzania skóry.

Obsługiwany zakres parametru EXTENSION_STRENGTH wynosi od 0 do 100 , przy czym 0 wskazuje na przetwarzanie przedłużenia lub proste przełom, a 100 wskazuje na maksymalną wytrzymałość przedłużenia efektu przetwarzania.

Aby dodać obsługę EXTENSION_STRENGTH , użyj interfejsu parametrów specyficznych dla dostawcy wprowadzonych w wersji 1.3.0 interfejsu biblioteki rozszerzenia. Aby uzyskać więcej informacji, zobacz getAvailableCaptureRequestKeys() .

Uchwycić wyniki

Wynik przechwytywania EXTENSION_CURRENT_TYPE pozwala implementacjom rozszerzenia Powiadomienie klientów o aktywnym typu rozszerzenia.

Ponieważ rozszerzenia przy użyciu typu AUTO dynamicznie przełączają się między typami rozszerzeń, takimi jak HDR i NIGHT , w zależności od warunków sceny, aplikacje rozszerzeń kamery mogą używać EXTENSION_CURRENT_TYPE do wyświetlania informacji o bieżącym rozszerzeniu wybranym przez rozszerzenie AUTO .

Wciąż rzeczywistość wciąż przechwytują oszacowanie opóźnień

W przypadku Androida 14 i wyższego klienci rozszerzenia kamery mogą zapytać o szacunki opóźnień w czasie rzeczywistym w oparciu o scenę i warunki środowiskowe za pomocą getRealtimeStillCaptureLatency() . Ta metoda zapewnia dokładniejsze szacunki niż metoda statyczna getEstimatedCaptureLatencyRangeMillis() . W oparciu o oszacowanie opóźnień aplikacje mogą zdecydować o pominięcie przetwarzania rozszerzenia lub wyświetlenia wskazania, aby powiadomić użytkowników o długotrwałej operacji.

CameraExtensionSession.StillCaptureLatency latency;

latency = extensionSession.getRealtimeStillCaptureLatency();

// The capture latency from ExtensionCaptureCallback#onCaptureStarted() until ExtensionCaptureCallback#onCaptureProcessStarted().

latency.getCaptureLatency();

// The processing latency from  ExtensionCaptureCallback#onCaptureProcessStarted() until  the processed frame returns to the client.

latency.getProcessingLatency();

Aby wesprzeć szacunki opóźnienia w czasie rzeczywistym, wdrożyć następujące:

Przechwytywanie oddzwonienia przetwarzania przetwarzania

W przypadku Androida 14 i wyższych klienci rozszerzenia kamery mogą odbierać zwrotnie od postępu działającego nadal przechwytywania operacji przetwarzania. Aplikacje mogą wyświetlać bieżące postępy użytkowników w celu poprawy ogólnej wrażenia użytkownika.

Aplikacje mogą użyć następującego kodu do zintegrowania tej funkcji:

import android.hardware.camera2.CameraExtensionSession.
ExtensionCaptureCallback;

{
…
  class AppCallbackImpl extends ExtensionCaptureCallback {
…
    @Override
    public void onCaptureProcessProgressed(
      @NonNull CameraExtensionSession session,
      @NonNull CaptureRequest request,
      @IntRange(from = 0, to = 100) int progress) {
      // Update app UI with current progress
    }
  }
…
}

Aby obsługiwać oddzwaniania do przetwarzania przetwarzania przetwarzania, Twoja implementacja dostawcy rozszerzenia musi wywołać następujące zwrotny zwrot z bieżącą wartością postępu:

PostView wciąż przechwytuj

W przypadku Androida 14 i wyższego przedłużenia kamery mogą dostarczyć PostView (obraz podglądu) za pomocą setPostviewOutputConfiguration . Aby poprawić wrażenia użytkownika, aplikacje mogą wyświetlać obraz PostView jako symbol zastępczy, gdy rozszerzenie ma większe opóźnienie przetwarzania i zastąpić obraz, gdy dostępny jest ostateczny obraz. Aplikacje mogą konfigurować i wydawać żądania przechwytywania PostView za pomocą następującego kodu referencyjnego:

{
…
if (!CameraExtensionCharacteristics.isPostviewAvailable()) {
    continue;
}
…
ExtensionSessionConfiguration extensionConfiguration = new
        ExtensionSessionConfiguration(
                CameraExtensionCharacteristics.EXTENSION_NIGHT,
                outputConfig,
                backgroundExecutor,
                extensionSessionStateCallback
    );

extensionConfiguration.setPostviewOutputConfiguration(
    postviewImageOutput);
…
CaptureRequest.Builder captureRequestBuilder =
    cameraDevice.createCaptureRequest(
        CameraDevice.TEMPLATE_STILL_CAPTURE);
captureRequestBuilder.addTarget(stillImageReader.getSurface());
captureRequestBuilder.addTarget(postviewImageSurface);

CaptureRequest captureRequest = captureRequestBuilder.build();
…
}

Aby obsługiwać PostView nadal przechwytywać, wdrożenie dostawcy musi wdrożyć następujące czynności:

Wsparcie wyjściowe SurfaceView

W przypadku Androida 14 i wyższego klienci rozszerzenia kamery mogą korzystać z optymalizowanych ścieżek renderowania zasilania i wydajności, rejestrując instancję SurfaceView do wyjścia podglądu do powtarzania żądań.

Aby obsługiwać wyjście SurfaceView , implementacja rozszerzenia dostawcy musi być zdolna do przesyłania strumieniowego i wyświetlania podglądu na instancje SurfaceView . Aby sprawdzić, czy jest to obsługiwane, uruchom moduł SurfaceViewExtensionPreviewTest.java CTS.

Specyficzne dla dostawcy typy sesji

Funkcja umożliwia implementacje rozszerzenia dostawcy wybór typu sesji specyficznego dla dostawcy, który zostanie ustawiony w wewnętrznej sesji przechwytywania kamery zamiast wartości domyślnej.

Funkcja działa całkowicie w stosie ram i dostawcy i nie ma wpływu API Visible Klient/Public.

Aby wybrać typ sesji specyficzny dla dostawcy, zaimplementuj następujące podawanie bibliotek rozszerzenia: * ExtenderStateListener.onSessionType() dla podstawowych rozszerzeń * Camera2SessionConfigImpl.getSessionType() dla zaawansowanych rozszerzeń

Historia wersji interfejsu rozszerzeń

Poniższa tabela pokazuje historię wersji interfejsu rozszerzenia kamery. Zawsze powinieneś zaimplementować bibliotekę dostawców z najnowszą wersją.

Wersja Dodano funkcje
1.0.0
  • Weryfikacja wersji
    • ExtensionVersionImpl
  • Podstawowy przedłużacz
    • PreviewExtenderImpl
    • ImageCaptureExtenderImpl
    • Processor
      • PreviewImageProcessorImpl
      • CaptureProcessorImpl
      • RequestUpdateProcessorImpl
1.1.0
  • Inicjalizacja biblioteki
    • InitializerImpl
  • Ujawniać obsługiwane rozdzielczości
    • PreviewExtenderImpl.getSupportedResolutions
    • ImageCaptureExtenderImpl.getSupportedResolutions
1.2.0
  • AdvancedExtender
    • AdvancedExtenderImpl
    • SessionProcessorImpl
  • Uzyskaj szacunkowe opóźnienie przechwytywania
    • ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange
1.3.0
  • Expose obsługiwane klawisze żądania przechwytywania/klucze wyników
    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys i getAvailableCaptureResultKeys
    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys i getAvailableCaptureResultKeys
    • Nowy process() wywołanie, które przyjmuje ProcessResultImpl w PreviewImageProcessorImpl i CaptureProcessorImpl
    • Żądanie typu obsługującego typ spustu
      • AdvancedExtenderImpl.startTrigger
1.4.0
  • Metadane specyficzne dla rozszerzenia
  • Dynamiczne wciąż przechwytujące szacunki opóźnienia
  • Przechwytywanie oddzwonienia przetwarzania przetwarzania
  • PostView wciąż przechwytuj
  • Obsługa wyjścia SurfaceView
  • Specyficzne dla dostawcy typy sesji

Wdrożenie referencyjne

Poniższe referencyjne implementacje biblioteki dostawców OEM są dostępne w frameworks/ex .

  • advancedSample : Podstawowa wdrożenie zaawansowanego przedłużacza.

  • sample : Podstawowa implementacja podstawowego przedłużacza.

  • service_based_sample : Implementacja, która pokazuje, jak hostować rozszerzenia kamery w Service . Ta implementacja zawiera następujące elementy:

    • oem_library : Kamera rozszerza bibliotekę OEM dla API Camera2 i Camerax Extensions, która implementuje Extensions-Interface . Działa to jako przełom, który przekazuje połączenia z Extensions-Interface do usługi. Ta biblioteka zawiera również pliki AIDL i klasy opakowania do komunikowania się z usługą.

      Advanced Extender jest domyślnie włączony. Aby włączyć podstawowe przedłużenie, zmień ExtensionsVersionImpl#isAdvancedExtenderImplemented , aby zwrócić false .

    • extensions_service : Przykładowa implementacja usługi rozszerzeń. Dodaj swoją implementację tutaj. Interfejs do wdrożenia w usłudze jest podobny do Extensions-Interface . Na przykład wdrożenie IAdvancedExtenderImpl.Stub wykonuje takie same operacje co AdvancedExtenderImpl . ImageWrapper i TotalCaptureResultWrapper są zobowiązani do wykonania Image i TotalCaptureResult parki.

Skonfiguruj bibliotekę dostawców na urządzeniu

Biblioteka dostawców OEM nie jest wbudowana w aplikację; Jest załadowany z urządzenia w czasie wykonywania przez Camera2/X. W Camerax <uses-library> Tag deklaruje, że biblioteka androidx.camera.extensions.impl , która jest zdefiniowana w pliku AndroidManifest.xml biblioteki camera-extensions , jest zależnością Camerax i musi być załadowana w czasie wykonania. W Camera2 Framework ładuje usługę rozszerzeń, która deklaruje również, że <uses-library> ładuje tę samą bibliotekę androidx.camera.extensions.impl w czasie wykonywania.

Umożliwia to aplikacje stron trzecich z wykorzystaniem rozszerzeń do automatycznego ładowania biblioteki dostawców OEM. Biblioteka OEM jest oznaczona jako opcjonalna, dzięki czemu aplikacje mogą działać na urządzeniach, które nie mają biblioteki na urządzeniu. Camera2/x obsługuje to zachowanie automatycznie, gdy aplikacja próbuje użyć rozszerzenia aparatu, o ile producent urządzenia umieści bibliotekę OEM na urządzeniu, aby mogła ją odkryć przez aplikację.

Aby skonfigurować bibliotekę OEM na urządzeniu, wykonaj następujące czynności:

  1. Dodaj plik uprawnienia, który jest wymagany przez znacznik <uses-library> , używając następującego formatu: /etc/permissions/ ANY_FILENAME .xml . Na przykład /etc/permissions/camera_extensions.xml . Pliki w tym katalogu zawierają mapowanie biblioteki o nazwisku w <uses-library> na rzeczywistą ścieżkę pliku na urządzeniu.
  2. Użyj poniższego przykładu, aby dodać wymagane informacje do pliku.

    • name musi być androidx.camera.extensions.impl jako biblioteka, której szuka kamerax.
    • file jest bezwzględną ścieżką pliku zawierającego implementację rozszerzeń (na przykład /system/framework/androidx.camera.extensions.impl.jar ).
    <?xml version="1.0" encoding="utf-8"?>
    <permissions>
        <library name="androidx.camera.extensions.impl"
                 file="OEM_IMPLEMENTED_JAR" />
    </permissions>
    

W Androida 12 lub nowszym urządzenia obsługujące rozszerzenia kamerax muszą mieć true właściwość ro.camerax.extensions.enabled , co pozwala na zapytanie o to, czy urządzenie obsługuje rozszerzenia. Aby to zrobić, dodaj następującą linię w urządzeniu, aby zrobić plik:

PRODUCT_VENDOR_PROPERTIES += \
    ro.camerax.extensions.enabled=true \

Walidacja

Aby przetestować wdrożenie biblioteki dostawców OEM podczas etapu programowania, użyj przykładowej aplikacji na androidx-main/camera/integration-tests/extensionstestapp/ , która przechodzi przez różne rozszerzenia dostawców.

Po zakończeniu implementacji użyj narzędzia sprawdzania poprawności rozszerzeń kamery , aby uruchamiać automatyczne i ręczne testy, aby sprawdzić, czy biblioteka dostawców jest poprawnie zaimplementowana.

Wydłużony tryb sceny w porównaniu do przedłużenia aparatu

W przypadku rozszerzenia Bokeh, oprócz ujawnienia go za pomocą rozszerzeń kamery, możesz ujawnić rozszerzenie za pomocą trybu rozszerzonego sceny, który jest włączony za pomocą klawisza CONTROL_EXTENDED_SCENE_MODE . Aby uzyskać więcej informacji na temat implementacji, zobacz Camera Bokeh .

Tryb rozszerzonej sceny ma mniej ograniczeń w porównaniu z przedłużeniami aparatu dla aplikacji Camera2. Na przykład możesz włączyć tryb sceny rozszerzonej w zwykłej instancji CameraCaptureSession , która obsługuje elastyczne kombinacje strumieni i przechwytywanie parametrów żądania. Natomiast rozszerzenia kamer obsługują tylko stały zestaw typów strumieniowych i mają ograniczoną obsługę parametrów żądania przechwytywania.

Minusem rozszerzonego trybu sceny jest to, że można go zaimplementować tylko w Camera HAL, co oznacza, że ​​należy go zweryfikować do pracy we wszystkich ortogonalnych sterowaniach dostępnych dla programistów aplikacji.

Zalecamy ujawnienie Bokeh za pomocą zarówno rozszerzonego trybu sceny, jak i przedłużenia aparatu, ponieważ aplikacje mogą korzystać z konkretnego interfejsu API, aby umożliwić Bokeh. Polecamy najpierw korzystanie z trybu sceny rozszerzonej, ponieważ jest to najbardziej elastyczny sposób dla aplikacji, aby umożliwić rozszerzenie Bokeh. Następnie możesz zaimplementować interfejs rozszerzeń kamery w oparciu o tryb rozszerzonego sceny. Jeśli wdrożenie Bokeh w kamery HAL jest na przykład trudne, ponieważ wymaga postu procesora działającego w warstwie aplikacji do przetwarzania obrazów, zalecamy wdrożenie rozszerzenia Bokeh za pomocą interfejsu Extensions Camera.

Często zadawane pytania (FAQ)

Czy są jakieś ograniczenia dotyczące poziomów API?

Tak. Zależy to od zestawu funkcji Android API, który jest wymagany przez implementację biblioteki dostawców OEM. Na przykład, ExtenderStateListener.onPresetSession() używa wywołania SessionConfiguration.setSessionParameters() , aby ustawić podstawowy zestaw tagów. To połączenie jest dostępne tylko na poziomie API 28 i wyższym. Szczegółowe informacje na temat określonych metod interfejsu można znaleźć w dokumentacji referencyjnej API .