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
:
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:
Rysunek 2. Implementacja przedłużenia nocnego
Weryfikacja wersji:
Camera2/X wywołuje
ExtensionVersionImpl.checkApiVersion()
, aby upewnić się, że wersjaextensions-interface
zaimplementowanego przez OEM jest zgodna z wersjami obsługiwanymi przez Camera2/X.Inicjalizacja biblioteki dostawcy:
InitializerImpl
ma metodęinit()
, która inicjuje bibliotekę dostawcy. Camera2/X kończy inicjalizację przed uzyskaniem dostępu do klas Extendera.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 metodaonInit()
w programie Basic Extender lubinitSession()
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
-
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.Zainicjuj urządzenie Extender za pomocą informacji o kamerze:
Camera2/X wywołuje
init()
w instancji Extender i przekazuje jej identyfikator kamery iCameraCharacteristics
.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.
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 |
Haki w rurociągu kamery |
|
|
Nadaje się do | Rozszerzenia zaimplementowane w kamerze HAL lub w procesorze przetwarzającym obrazy YUV. |
|
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 | 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 |
HDR | HdrPreviewExtenderImpl.java |
Automatyczny | AutoPreviewExtenderImpl.java |
Bokeh | BokehPreviewExtenderImpl.java |
Retusz twarzy | BeautyPreviewExtenderImpl.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
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
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
iPreviewExtenderImpl.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)
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 najnowszyTotalCaptureResult
.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ówYUV_420_888
i zapisywania wyników naPRIVATE
powierzchni.Musisz zaimplementować i zwrócić instancję
PreviewImageProcessorImpl
wPreviewExtenderImpl.getProcessor
. Procesor odpowiada za przetwarzanie obrazów wejściowychYUV_420_888
. Powinien zapisać dane wyjściowe w formaciePRIVATE
podglądu. Camera2/X używa powierzchniYUV_420_888
zamiastPRIVATE
do skonfigurowaniaCameraCaptureSession
do podglądu.Zobacz poniższą ilustrację przedstawiającą przepływ:
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 przypadkuPreviewImageProcessorImpl
imageFormat
jest formatem pikselowym, takim jakPixelFormat.RGBA_8888
.onResolutionUpdate(Size size)
ustawia rozmiar obrazu wejściowego.onImageFormatUpdate(int imageFormat)
ustawia format obrazu wejściowego. Obecnie może to być tylkoYUV_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:
Rysunek 7. Nadal przechwytuj przepływ za pomocą CaptureProcessorImpl
Camera2/X używa powierzchni w formacie
YUV_420_888
do przechwytywania zdjęć w celu skonfigurowania sesji przechwytywania. Camera2/X przygotowujeCaptureProcessorImpl
wywołując:-
CaptureProcessorImpl.onImageFormatUpdate()
zYUV_420_888
. -
CaptureProcessorImpl.onResolutionUpdate()
z rozmiarem obrazu wejściowego. -
CaptureProcessorImpl.onOutputSurface()
z powierzchnią wyjściowąYUV_420_888
.
-
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 instancjiCaptureStageImpl
, Camera2/X wysyła trzy żądania przechwytywania z odpowiednimi parametrami przechwytywania za pomocą interfejsu APIcaptureBurst
.Otrzymane obrazy i instancje
TotalCaptureResult
są łączone w pakiety i wysyłane doCaptureProcessorImpl
w celu przetworzenia.CaptureProcessorImpl
zapisuje wynikowy obraz (w formacieYUV_420_888
) na powierzchni wyjściowej określonej przez wywołanieonOutputSurface()
. 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ń
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
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 formatPRIVATE
.AdvancedExtenderImpl.getSupportedCaptureOutputResolutions()
zwraca obsługiwany format i rozmiary powierzchni przechwytywania nieruchomych obiektów. Producenci OEM muszą obsługiwać dane wyjściowe w formacieJPEG
iYUV_420_888
.AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions()
zwraca obsługiwane rozmiary dla dodatkowego strumieniaYUV_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
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.
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 jestAdvancedExtenderImpl.createSessionProcessor()
w celu zwrócenia instancjiSessionProcessorImpl
.initSession
SessionProcessorImpl.initSession()
inicjuje sesję dla rozszerzenia. W tym miejscu przydzielasz zasoby i zwracasz konfigurację sesji w celu przygotowaniaCameraCaptureSession
.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 wAdvancedExtenderImpl
:-
getSupportedPreviewOutputResolutions()
-
getSupportedCaptureOutputResolutions()
-
getSupportedYuvAnalysisResolutions()
Należy zwrócić instancję
Camera2SessionConfigImpl
, która składa się z listy instancjiCamera2OutputConfigImpl
i parametrów sesji używanych do konfigurowaniaCameraCaptureSession
. 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ą implementacjiSurfaceOutputConfigImpl
. 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 powierzchnieImageReader
doCameraCaptureSession
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 metodygetSurfaceSharingOutputConfigs()
innej instancjiCamera2OutputConfigImpl
. Format i rozmiar powierzchni muszą być identyczne.
Wszystkie
Camera2OutputConfigImpl
, w tymSurfaceOutputConfigImpl
iImageReaderOutputConfigImpl
, muszą mieć unikalny identyfikator (getId()
), który służy do określenia powierzchni docelowej i pobrania obrazu zImageReaderOutputConfigImpl
.-
onCaptureSessionStart
iRequestProcessorImpl
Po uruchomieniu
CameraCaptureSession
i wywołaniu struktury CameraonConfigured()
, Camera2/X wywołujeSessionProcessorImpl.onCaptureSessionStart()
z opakowaniem żądań Camera2RequestProcessImpl
. Camera2/X implementujeRequestProcessImpl
, który umożliwia wykonywanie żądań przechwytywania i pobieranie obrazów , jeśli używany jestImageReaderOutputConfigImpl
.Interfejsy API
RequestProcessImpl
są podobne do interfejsów API Camera2CameraCaptureSession
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 identyfikatoremCamera2OutputConfigImpl
, aby zarejestrować instancjęImageProcessorImpl
w celu odbierania obrazów.Instancja
RequestProcessImpl
staje się nieprawidłowa po wywołaniu przez Camera2/XSessionProcessorImpl.onCaptureSessionEnd()
.- Powierzchnia docelowa jest określona przez identyfikator instancji
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 odpowiednioSessionProcessorImpl#startRepeating
iSessionProcessorImpl#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
iCaptureRequest.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 listygetAvailableCaptureResultKeys
.-
startTrigger
SessionProcessorImpl.startTrigger()
jest wywoływana w celu uruchomienia wyzwalacza, takiego jakCaptureRequest.CONTROL_AF_TRIGGER
iCaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER
. Możesz zignorować wszelkie klucze żądania przechwytywania, które nie zostały ogłoszone wAdvancedExtenderImpl.getAvailableCaptureRequestKeys()
.startTrigger()
jest obsługiwana odextensions-interface
1.3.0. Umożliwia aplikacjom wdrażanie funkcji „dotknij, aby ustawić ostrość” i flashowanie z rozszerzeniami.Posprzątać
Po zakończeniu sesji przechwytywania wywoływana jest metoda
SessionProcessorImpl.onCaptureSessionEnd()
przed zamknięciemCameraCaptureSession
. Po zamknięciu sesji przechwytywaniadeInitSession()
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
iNIGHT
: 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:
- Podstawowe rozszerzenia:
ImageCaptureExtenderImpl.getRealtimeCaptureLatency()
- Rozszerzenia zaawansowane:
SessionProcessorImpl.getRealtimeCaptureLatency
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:
- Podstawowe rozszerzenia:
ProcessResultImpl.onCaptureProcessProgressed()
- Zaawansowane rozszerzenia:
CaptureCallback.onCaptureProcessProgressed()
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:
Podstawowe rozszerzenia:
CaptureProcessorImpl.onPostviewOutputSurface
iCaptureProcessorImpl.processWithPostview
Zaawansowane rozszerzenia:
SessionProcessorImpl.startCaptureWithPostview
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 |
|
1.1.0 |
|
1.2.0 |
|
1.3.0 |
|
1.4.0 |
|
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 wService
. Ta implementacja zawiera następujące elementy:oem_library
: Kamera rozszerza bibliotekę OEM dla API Camera2 i Camerax Extensions, która implementujeExtensions-Interface
. Działa to jako przełom, który przekazuje połączenia zExtensions-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 doExtensions-Interface
. Na przykład wdrożenieIAdvancedExtenderImpl.Stub
wykonuje takie same operacje coAdvancedExtenderImpl
.ImageWrapper
iTotalCaptureResultWrapper
są zobowiązani do wykonaniaImage
iTotalCaptureResult
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:
- 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. 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 .