Producenci urządzeń mogą udostępniać rozszerzenia, takie jak bokeh, tryb nocny i HDR, deweloperom zewnętrznym za pomocą interfejsu rozszerzeń aparatu udostępnianego przez bibliotekę OEM. Programiści mogą używać interfejsów Camera2 Extensions API i CameraX Extensions API, aby uzyskać dostęp do rozszerzeń zaimplementowanych w bibliotece dostawcy OEM.
Listę obsługiwanych rozszerzeń, która jest taka sama w przypadku interfejsów Camera2 i CameraX, znajdziesz w interfejsie CameraX Extensions API. Jeśli chcesz dodać rozszerzenie, zgłoś błąd za pomocą śledzika błędów.
Na tej stronie dowiesz się, jak wdrożyć na urządzeniach bibliotekę dostawcy OEM i ją włączyć.
Architektura
Na poniższym diagramie przedstawiono architekturę interfejsu rozszerzeń aparatu (extensions-interface
):
Rysunek 1. Schemat architektury rozszerzeń aparatu
Jak widać na diagramie, aby obsługiwać rozszerzenia aparatu, musisz zaimplementować extensions-interface
udostępniony przez bibliotekę OEM. Biblioteka OEM umożliwia korzystanie z 2 interfejsów API: CameraX Extensions API i Camera2 Extensions API, które są używane odpowiednio przez aplikacje CameraX i Camera2 do uzyskiwania dostępu do rozszerzeń dostawcy.
Implementowanie biblioteki dostawcy OEM
Aby zaimplementować bibliotekę OEM, skopiuj pliki camera-extensions-stub
do projektu biblioteki systemowej. Określają one interfejs rozszerzeń aparatu.
Pliki camera-extensions-stub
są podzielone na te kategorie:
Podstawowe 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 implementacje (dodaj swoją implementację)
ExtensionVersionImpl.java
InitializerImpl.java
Klasy rozszerzeń Bokeh (wdróż je, jeśli rozszerzenie Bokeh jest obsługiwane)
BokehImageCaptureExtenderImpl.java
BokehPreviewExtenderImpl.java
advanced/BokehAdvancedExtenderImpl.java
Zajęcia wydłużające noc (wprowadź je, jeśli obsługiwane jest rozszerzenie nocne)
NightImageCaptureExtenderImpl.java
NightPreviewExtenderImpl.java
advanced/NightAdvancedExtenderImpl.java
Klasy rozszerzaczy automatycznych (wdróż je, jeśli rozszerzanie automatyczne jest obsługiwane)
AutoImageCaptureExtenderImpl.java
AutoPreviewExtenderImpl.java
advanced/AutoAdvancedExtenderImpl.java
Klasy rozszerzeń HDR (wdrożyć, jeśli rozszerzenie HDR jest obsługiwane)
HdrImageCaptureExtenderImpl.java
HdrPreviewExtenderImpl.java
advanced/HdrAdvancedExtenderImpl.java
Klasy rozszerzeń retuszu twarzy (wdróż je, jeśli rozszerzenie retuszu twarzy jest obsługiwane)
BeautyImageCaptureExtenderImpl.java
BeautyPreviewExtenderImpl.java
advanced/BeautyAdvancedExtenderImpl.java
Programy narzędziowe (opcjonalnie, można je usunąć)
advanced/Camera2OutputConfigImplBuilder.java
advanced/Camera2SessionConfigImplBuilder.java
Nie musisz udostępniać implementacji w przypadku każdego rozszerzenia. Jeśli nie chcesz stosować rozszerzenia, ustaw isExtensionAvailable()
na false
lub usuń odpowiednie klasy Extender. Interfejsy API rozszerzeń Camera2 i CameraX informują aplikację, że rozszerzenie jest niedostępne.
Zobaczmy, jak interfejsy API Camera2 i CameraX Extensions współpracują z biblioteką dostawcy, aby włączyć rozszerzenie. Poniższy diagram przedstawia kompleksowy proces, w którym przykładowo użyto rozszerzenia Night:
Rysunek 2. Wdrożenie rozszerzenia nocnego
Weryfikacja wersji:
wywołania Camera2/X
ExtensionVersionImpl.checkApiVersion()
, aby zapewnić zgodność wersjiextensions-interface
implementowanej przez OEM-a z wersjami obsługiwanymi przez Camera2/X.Inicjowanie biblioteki dostawcy:
InitializerImpl
ma metodęinit()
, która inicjuje bibliotekę dostawcy. Camera2/X kończy inicjalizację przed uzyskaniem dostępu do klas Extender.Klasy instancji Extender:
Tworzy instancje klas Extendera dla rozszerzenia. Istnieją 2 typy rozszerzeń: podstawowe i zaawansowane. Musisz zaimplementować jeden typ rozszerzenia dla wszystkich rozszerzeń. Więcej informacji znajdziesz w artykule Urządzenie rozszerzające podstawowe i zaawansowane.
Camera2/X tworzy instancję klasy Extender i współpracuje z nią, aby pobrać informacje i włączyć rozszerzenie. W przypadku danego rozszerzenia Camera2/X może tworzyć instancje klas Extendera wielokrotnie. W związku z tym nie przeprowadzaj intensywności inicjowania w konstruktorze ani w wywołaniu
init()
. Wykonuj ciężkie zadania tylko wtedy, gdy sesja aparatu ma się rozpocząć, na przykład gdy wywołana jest funkcjaonInit()
w rozszerzeniu podstawowym lub funkcjainitSession()
w rozszerzeniu zaawansowanym.W przypadku rozszerzenia Night instancjonowane są te klasy Extendera dla typu Basic Extender:
NightImageCaptureExtenderImpl.java
NightPreviewExtenderImpl.java
W przypadku typu rozszerzenia Zaawansowany:
NightAdvancedExtenderImpl.java
Sprawdź dostępność rozszerzeń:
Przed włączeniem rozszerzenia
isExtensionAvailable()
sprawdza, czy rozszerzenie jest dostępne na określonym identyfikatorze kamery za pomocą instancji rozszerzenia.Zainicjuj Extender, podając informacje o kamerze:
Camera2/X wywołuje
init()
w instancji Extender i przekazuje do niej identyfikator kamery orazCameraCharacteristics
.Informacje o zapytaniu:
Wywołuje klasę Extender, aby pobrać informacje, takie jak obsługiwane rozdzielczości, nadal szacować opóźnienie i pobierać klucze żądań z rozszerzenia w ramach przygotowań do włączenia rozszerzenia.
Włącz rozszerzenie na urządzeniu rozszerzającym:
Klasa Extender udostępnia wszystkie interfejsy potrzebne do włączenia klasy. Oferuje on mechanizm, który umożliwia OEM-om implementację w systemie Camera2, np. wstrzykiwanie parametrów żądania rejestrowania lub włączanie procesora postprodukcyjnego.
W przypadku typu zaawansowanego przedłużenia Aparat2/X współdziała z
SessionProcessorImpl
, aby włączyć rozszerzenie. Camera2/X pobiera instancjęSessionProcessorImpl
, wywołując funkcjęcreateSessionProcessor()
w Extender.
W kolejnych sekcjach szczegółowo opisano proces rozszerzenia.
Weryfikacja wersji
Podczas wczytywania biblioteki dostawcy OEM z urządzenia w czasie wykonywania Camera2/X sprawdza, czy biblioteka jest zgodna z wersją extensions-interface
.
extensions-interface
używa wersji semantycznej, czyli GŁÓWNA.PODRZĘDNA.POPRAWKA, na przykład 1.1.0 lub 1.2.0. Podczas weryfikacji wersji używane są jednak tylko główne i podrzędne wersje.
Aby sprawdzić wersję, Camera2/X wywołuje ExtensionVersionImpl.checkApiVersion()
z obsługiwaną wersją extensions-interface
. Następnie Camera2/X używa wersji zgłoszonej przez bibliotekę OEM, aby określić, czy rozszerzenie może być włączone i jakie funkcje powinno wywoływać.
Zgodność z wersją główną
Jeśli główne wersje interfejsu rozszerzenia różnią się między Camera2/X a biblioteką dostawcy, rozszerzenie jest uważane za niezgodne i jest wyłączane.
Zgodność wsteczna
Dopóki wersja główna jest identyczna, Camera2/X zapewnia wsteczną zgodność z bibliotekami dostawców OEM utworzonymi w poprzednich wersjach extensions-interface
. Jeśli na przykład Camera2/X obsługuje extensions-interface
1.3.0, biblioteki OEM, które implementowały wersje 1.0.0, 1.1.0 i 1.2.0, nadal są zgodne. Oznacza to też, że po zaimplementowaniu konkretnej wersji biblioteki dostawcy Camera2/X zadba o to, aby była ona zgodna wstecznie z przyszłymi wersjami extension-interface
.
Zgodność z wyprzedzeniem
W przyszłości zgodność z bibliotekami dostawcy nowszej wersji extensions-interface
zależy od Ciebie, producenta OEM. Jeśli do wdrożenia rozszerzeń potrzebujesz pewnych funkcji, możesz włączyć rozszerzenia, rozpoczynając od określonej wersji. W takim przypadku możesz zwrócić obsługiwaną wersję extensions-interface
, jeśli wersja biblioteki Camera2/X spełnia wymagania. Jeśli wersje Camera2/X nie są obsługiwane, możesz przywrócić niezgodną wersję, np. 99.0.0, aby wyłączyć rozszerzenia.
Inicjowanie biblioteki dostawcy
Po zweryfikowaniu wersji extensions-interface
zaimplementowanej przez bibliotekę OEM Camera2/X rozpoczyna proces inicjalizacji. Metoda InitializerImpl.init()
sygnalizuje bibliotece OEM, że aplikacja próbuje używać rozszerzeń.
Aplikacja Camera2/X nie wykonuje żadnych innych wywołań biblioteki OEM (oprócz sprawdzania wersji) do momentu, gdy biblioteka OEM OnExtensionsInitializedCallback.onSuccess()
powiadomi o zakończeniu inicjalizacji.
Musisz wdrożyć InitializerImpl
w wersji extensions-interface
1.1.0. Camera2/X pomija etap inicjowania biblioteki, jeśli biblioteka dostawcy OEM wdrożyła extensions-interface
1.0.0.
Podstawowy a zaawansowany przedłużacz
Istnieją 2 typy implementacji extensions-interface
: rozszerzenie podstawowe i zaawansowane. Rozszerzenie zaawansowane jest obsługiwane od wersji extensions-interface
1.2.0.
Wdrożyć podstawowy rozszerzacz dla rozszerzeń, które przetwarzają obrazy w interfejsie HAL aparatu, lub użyć procesora końcowego zdolnego do przetwarzania strumieni YUV.
Zaimplementuj rozszerzenie Advanced Extender na potrzeby rozszerzeń, które muszą dostosować konfigurację strumienia Camera2 i w razie potrzeby wysyłać żądania zapisu.
Porównanie znajdziesz w tabeli poniżej:
Przedłużacz podstawowy | Rozszerzenie zaawansowane | |
---|---|---|
Konfiguracje transmisji | Rozwiązano Podgląd: PRIVATE lub YUV_420_888 (jeśli procesor istnieje) Nagrywanie zdjęć: JPEG lub YUV_420_888 (jeśli procesor istnieje)
|
Możliwość dostosowania przez OEM. |
Wysyłanie żądania przechwycenia | Żądania przechwytywania mogą wysyłać tylko aparaty Camera2/X. Możesz ustawić parametry tych żądań. Gdy procesor jest udostępniany do przechwytywania obrazu, Camera2/X może wysyłać wiele żądań przechwytywania i przesyłać wszystkie obrazy oraz wyniki przechwytywania do procesora. | Do wykonania żądania rejestrowania obrazu przez aparat 2 i uzyskania wyników oraz obrazu udostępniamy instancję RequestProcessorImpl .
Aplikacja Camera2/X wywołuje |
Blokady w ruchu kamery |
|
|
Odpowiednie dla | Rozszerzenia zaimplementowane w interfejsie HAL aparatu lub w procesorze, który przetwarza obrazy YUV. |
|
Obsługiwana wersja interfejsu 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 |
Przepływy aplikacji
W tabeli poniżej znajdziesz 3 typy przepływów w aplikacji i odpowiadające im wywołania interfejsu Camera Extensions API. Interfejsy Camera2/X udostępniają te interfejsy API, ale do obsługi tych przepływów należy prawidłowo wdrożyć bibliotekę dostawcy. Szczegółowo opisujemy to w dalszej sekcji.
Rozszerzenia Camera2 | Rozszerzenia CameraX | |
---|---|---|
Dostępność rozszerzeń zapytań | CameraExtensionCharacteristics
.getSupportedExtensions
|
ExtensionsManager.
isExtensionAvailable
|
Informacje o zapytaniu | CameraExtensionCharacteristics.
getExtensionSupportedSizes
CameraExtensionCharacteristics.
getEstimatedCaptureLatencyRangeMillis
CameraExtensionCharacteristics.
getAvailableCaptureRequestKeys
CameraExtensionCharacteristics.
getAvailableCaptureResultKeys
|
ExtensionsManager.
getEstimatedCaptureLatencyRange
CameraX zajmuje się pozostałymi informacjami w bibliotece. |
Podgląd i robienie zdjęć przy włączonej rozszerzonej rzeczywistości | CameraDevice.
createExtensionSession
|
val cameraSelector = ExtensionsManager.
getExtensionEnabledCameraSelector
|
Podstawowy przedłużacz
Interfejs podstawowego rozszerzenia zapewnia punkty podłączenia w kilku miejscach w przepływie danych z kamery. Każdy typ rozszerzenia ma odpowiadające mu klasy rozszerzeń, które muszą być zaimplementowane przez producentów OEM.
W tabeli poniżej podano klasy rozszerzeń, które muszą być zaimplementowane przez OEM-ów w przypadku każdego rozszerzenia:
Klasy rozszerzeń do wdrożenia | |
---|---|
Noc | NightPreviewExtenderImpl.java
|
HDR | HdrPreviewExtenderImpl.java
|
Auto | AutoPreviewExtenderImpl.java
|
Bokeh | BokehPreviewExtenderImpl.java
|
Retusz twarzy | BeautyPreviewExtenderImpl.java
|
W tym przykładzie używamy obiektów zastępczych PreviewExtenderImpl
i ImageCaptureExtenderImpl
. Zastąp je nazwami rzeczywistych plików, które implementujesz.
Basic Extender ma te możliwości:
- Wstrzyknij parametry sesji podczas konfigurowania
CameraCaptureSession
(onPresetSession
). - Informować o rozpoczęciu i zamknięciu sesji rejestrowania oraz wysyłać pojedyncze żądanie, aby powiadomić HAL o zwróconych parametrach (
onEnableSession
,onDisableSession
). - Wstrzyknij parametry rejestracji do zapytania (
PreviewExtenderImpl.getCaptureStage
,ImageCaptureExtenderImpl.getCaptureStages
). - Dodaj procesory do podglądu i przechwytywania zdjęć, które są w stanie przetwarzać strumień
YUV_420_888
.
Zobaczmy, jak Camera2/X wywołuje extensions-interface
, aby uzyskać 3 wymienione powyżej przepływy aplikacji.
Proces w aplikacji 1. Sprawdzanie dostępności rozszerzenia
Rysunek 3. Schemat działania aplikacji 1 w przypadku rozszerzenia podstawowego
W tym procesie Camera2/X bezpośrednio wywołuje metodę isExtensionAvailable()
zarówno w przypadku PreviewExtenderImpl
, jak i ImageCaptureExtenderImpl
bez wywoływania init()
. Aby włączyć rozszerzenia, obie klasy Extender muszą zwracać true
.
Często jest to pierwszy krok, który aplikacje wykonują, aby sprawdzić, czy dany typ rozszerzenia jest obsługiwany przez dany identyfikator kamery przed włączeniem rozszerzenia. Dzieje się tak, ponieważ niektóre rozszerzenia są obsługiwane tylko w przypadku niektórych identyfikatorów kamery.
Proces w aplikacji 2. Informacje o zapytaniach
Rysunek 4. Proces w aplikacji 2 w przypadku podstawowego rozszerzenia
Po ustaleniu, czy rozszerzenie jest dostępne, aplikacje powinny zapytać o te informacje, zanim włączą rozszerzenie.
Zakres opóźnienia rejestrowania zdjęć:
ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange
zwraca zakres opóźnienia rejestrowania w aplikacji, aby umożliwić jej ocenę, czy w danym scenariuszu warto włączyć rozszerzenie.Obsługiwane rozmiary platformy podglądu i rejestrowania:
ImageCaptureExtenderImpl.getSupportedResolutions
iPreviewExtenderImpl.getSupportedResolutions
zwracają listę formatów obrazów oraz rozmiary, które są obsługiwane w przypadku formatu i rozmiaru powierzchni.Obsługiwane klucze żądania i wyniku: Camera2/X wywołuje te metody, aby pobrać obsługiwane klucze żądania i wyniku z Twojej implementacji:
ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys
ImageCaptureExtenderImpl.getAvailableCapturetResultKeys
Przed wysłaniem zapytania o dodatkowe informacje Camera2/X zawsze wywołuje funkcję init()
w tych klasach Extendera.
Proces w aplikacji 3: podgląd/przechwytywanie obrazu z włączonym rozszerzeniem (implementacja HAL)
Rysunek 5. Krok 3 w aplikacji na urządzeniu Basic Extender
Powyższy diagram przedstawia główny proces włączania podglądu i robienia zdjęć za pomocą rozszerzenia bez procesora. Oznacza to, że rozszerzenie jest przetwarzane przez HAL aparatu.
W tym procesie Camera2/X najpierw wywołuje init()
, a potem onInit
, co powoduje wyświetlenie powiadomienia o tym, że za chwilę rozpocznie się sesja aparatu ze wskazanymi rozszerzeniami.
W funkcji onInit()
możesz przeprowadzić skomplikowaną inicjalizację.
Podczas konfigurowania CameraCaptureSession
Camera2/X wywołuje onPresetSession
, aby uzyskać parametry sesji. Po skonfigurowaniu sesji rejestrowania Camera2/X wywołuje funkcję onEnableSession
, zwracając wystąpienie CaptureStageImpl
zawierające parametry rejestrowania. Aplikacja Camera2/X natychmiast wysyła pojedyncze żądanie z tymi parametrami, aby powiadomić HAL. Podobnie przed zamknięciem sesji rejestrowania Camera2/X wywołuje funkcję onDisableSession
, a potem wysyła pojedyncze żądanie z zwróconymi parametrami rejestrowania.
Powtarzające się żądanie wywołane przez Camera2/X zawiera parametry żądania zwracane przez PreviewExtenderImpl.getCaptureStage()
. Poza tym żądanie przechwytywania nieruchomości zawiera parametry zwrócone przez ImageCaptureExtenderImpl.getCaptureStages()
.
Na koniec Camera2/X wywołuje onDeInit()
po zakończeniu sesji aparatu.
Zasoby możesz zwolnić w onDeinit()
.
Procesor podglądu
Oprócz HAL aparatu możesz też wdrażać rozszerzenia w procesorze.
Zaimplementuj PreviewExtenderImpl.getProcessorType
, aby określić typ procesora, w sposób opisany poniżej:
PROCESSOR_TYPE_NONE
: brak procesora. Obrazy są przetwarzane w aparacie HAL.PROCESSOR_TYPE_REQUEST_UPDATE_ONLY
: typ procesora umożliwia aktualizowanie powtarzających się żądań za pomocą nowych parametrów żądania przechwytywania na podstawie najnowszegoTotalCaptureResult
.Funkcja
PreviewExtenderImpl.getProcessor
musi zwracać instancjęRequestUpdateProcessorImpl
, która przetwarza instancjęTotalCaptureResult
i zwraca instancjęCaptureStageImpl
, aby zaktualizować powtarzającą się prośbę. FunkcjaPreviewExtenderImpl.getCaptureStage()
powinna również odzwierciedlać wynik przetwarzania i zwrócić najnowszą wartośćCaptureStageImpl
.PROCESSOR_TYPE_IMAGE_PROCESSOR
: ten typ umożliwia implementację procesora w celu przetwarzania obrazówYUV_420_888
i zapisywania danych wyjściowych na powierzchniPRIVATE
.W funkcji
PreviewExtenderImpl.getProcessor
musisz zaimplementować i zwrócić instancjęPreviewImageProcessorImpl
. Procesor jest odpowiedzialny za przetwarzanie obrazów wejściowychYUV_420_888
. Powinien zapisać dane wyjściowe w formacie podgląduPRIVATE
. Aparat2/X używa platformyYUV_420_888
zamiastPRIVATE
do skonfigurowania podgląduCameraCaptureSession
.Poniżej znajdziesz ilustrację przedstawiającą ten proces:
Rysunek 6. Podgląd procesu z użyciem PreviewImageProcessorImpl
Interfejs PreviewImageProcessorImpl
rozszerza ProcessImpl
i zawiera 3 ważne metody:
onOutputSurface(Surface surface, int imageFormat)
określa powierzchnię wyjściową dla procesora. W przypadkuPreviewImageProcessorImpl
wartośćimageFormat
to liczba pikseli, na przykładPixelFormat.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 do przechwytywania obrazu
W przypadku przechwytywania statycznych obrazów możesz zaimplementować procesor, zwracając instancję CaptureProcessorImpl
za pomocą funkcji ImageCaptureExtenderImpl.getCaptureProcessor
. Procesor jest odpowiedzialny za przetworzenie listy zarejestrowanych obrazów YUV_420_888
i wystąpieni TotalCaptureResult
oraz zapisanie danych wyjściowych na powierzchni YUV_420_888
.
Zanim wyślesz prośbę o przechwycenie obrazu, możesz założyć, że podgląd jest włączony i działa.
Proces ten przedstawia diagram poniżej:
Rysunek 7. Nadal rejestruj przepływ dzięki aplikacji CaptureProcessorImpl
Camera2/X używa powierzchni w formacie
YUV_420_888
do konfigurowania sesji rejestrowania zdjęć. Aparat2/X przygotowujeCaptureProcessorImpl
, wywołując:CaptureProcessorImpl.onImageFormatUpdate()
zYUV_420_888
.CaptureProcessorImpl.onResolutionUpdate()
z rozmiarem obrazu wejściowego.CaptureProcessorImpl.onOutputSurface()
z wyjściem na powierzchnięYUV_420_888
.
ImageCaptureExtenderImpl.getCaptureStages
zwraca listęCaptureStageImpl
, w której każdy element jest mapowany na instancjęCaptureRequest
z parametrami przechwytywania, które są wysyłane przez Camera2/X. Jeśli na przykład wyświetli listę 3 instancjiCaptureStageImpl
, Camera2/X wyśle 3 żądania przechwytywania z odpowiednimi parametrami przechwytywania za pomocą interfejsu APIcaptureBurst
.Odbierane obrazy i instancje (
TotalCaptureResult
) są grupowane i wysyłane doCaptureProcessorImpl
w celu przetworzenia.CaptureProcessorImpl
zapisuje wynikowy obraz (w formacieYUV_420_888
) na wyjściowej powierzchni określonej przez wywołanieonOutputSurface()
. W razie potrzeby aplikacja Camera2/X konwertuje je na obrazy JPEG.
Obsługa kluczy i wyników żądań rejestrowania
Oprócz podglądu i przechwytywania aparatu aplikacje mogą ustawiać zoom, parametry lampy błyskowej lub aktywować funkcję „dotknij, aby wyostrzyć”. Te parametry mogą być niezgodne z implementacją rozszerzenia.
Aby umożliwić Ci udostępnianie parametrów obsługiwanych przez Twoją implementację, do wersji extensions-interface
1.3.0 dodano te metody:
ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys()
zwraca klucze żądań rejestrowania obsługiwane przez Twoją implementację.ImageCaptureExtenderImpl.getAvailableCaptureResultKeys()
zwraca klucze efektów przechwycenia zawarte w efekcie przechwycenia.
Jeśli HAL aparatu przetwarza rozszerzenie, Camera2/X pobierze wyniki przechwytywania w formacie CameraCaptureSession.CaptureCallback
. Jeśli jednak procesor jest zaimplementowany, Camera2/X pobierze wyniki przechwytywania w ProcessResultImpl
, które są przekazywane do metody process()
w PreviewImageProcessorImpl
i CaptureProcessorImpl
.
Ponosisz odpowiedzialność za zgłoszenie wyniku przechwycenia za pomocą ProcessResultImpl
do Camera2/X.
Poniżej znajdziesz definicję interfejsu CaptureProcessorImpl
.
W wersji extensions-interface
1.3.0 lub nowszej wywoływana jest druga funkcja 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 działań związanych z aparatem, takich jak zoom, namierzanie ostrości, lampa błyskowa czy kompensacja ekspozycji, zalecamy obsługę tych klawiszy zarówno w przypadku żądania zapisu, jak i wyniku przechwytywania:
- Powiększenie:
CaptureRequest#CONTROL_ZOOM_RATIO
CaptureRequest#SCALER_CROP_REGION
- Kliknij, aby ustawić ostrość:
CaptureRequest#CONTROL_AF_MODE
CaptureRequest#CONTROL_AF_TRIGGER
CaptureRequest#CONTROL_AF_REGIONS
CaptureRequest#CONTROL_AE_REGIONS
CaptureRequest#CONTROL_AWB_REGIONS
- Flash:
CaptureRequest#CONTROL_AE_MODE
CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
CaptureRequest#FLASH_MODE
- Kompensacja ekspozycji:
CaptureRequest#CONTROL_AE_EXPOSURE_COMPENSATION
W przypadku rozszerzeń podstawowych, które implementują interfejs CameraX Extensions w wersji 1.2.0 lub starszej, interfejs CameraX Extensions obsługuje wszystkie wymienione powyżej klucze. W wersji extensions-interface
1.3.0 zarówno CameraX, jak i Camera2 uwzględniają zwracaną listę i obsługują tylko klucze na niej zawarte. Jeśli na przykład w wersji 1.3.0 zdecydujesz się zwrócić tylko CaptureRequest#CONTROL_ZOOM_RATIO
i CaptureRequest#SCALER_CROP_REGION
, oznacza to, że aplikacja obsługuje tylko zoom, a funkcja dotykania, aby ustawić ostrość, lampa błyskowa i kompensacja ekspozycji nie są dozwolone.
Rozszerzenie zaawansowane
Rozszerzenie zaawansowane to rodzaj implementacji przez dostawcę na podstawie interfejsu Camera2 API.
Ten typ rozszerzenia został dodany w wersji extensions-interface
1.2.0. W zależności od producenta urządzenia rozszerzenia mogą być wdrażane na poziomie aplikacji. To zależy od tych czynników:
Konfiguracja niestandardowego strumienia: skonfiguruj niestandardowe strumienie, takie jak strumień RAW, lub skonfiguruj kilka strumieni dla różnych identyfikatorów fizycznych kamer.
Możliwość wysyłania żądań Camera2: obsługa skomplikowanej logiki interakcji, która może wysyłać żądania przechwytywania z parametrami na podstawie wyników poprzednich żądań.
Advanced Extender udostępnia kod lub warstwę pośrednią, które pozwalają dostosowywać konfigurację strumienia i na żądanie wysyłać żądania przechwytywania.
Pliki do wdrożenia
Aby przełączyć się na implementację rozszerzacza zaawansowanego, metoda isAdvancedExtenderImplemented()
w ExtensionVersionImpl
musi zwracać true
. W przypadku każdego typu rozszerzenia OEM musi zaimplementować odpowiednie klasy rozszerzeń. Pliki implementacji rozszerzenia zaawansowanego znajdują się w pakiecie advanced.
Klasy rozszerzeń do implementacji | |
---|---|
Noc | advanced/NightAdvancedExtenderImpl.java
|
HDR | advanced/HdrAdvancedExtenderImpl.java
|
Auto | advanced/AutoAdvancedExtenderImpl.java
|
Bokeh | advanced/BokehAdvancedExtenderImpl.java
|
Retusz twarzy | advanced/BeautyAdvancedExtenderImpl.java
|
W przykładzie poniżej używamy zmiennej AdvancedExtenderImpl
jako zmiennej.
Zastąp go nazwą pliku Extendera rozszerzenia, które wdrażasz.
Zobaczmy, jak Camera2/X wywołuje extensions-interface
, aby uzyskać 3 przebiegi aplikacji.
Proces w aplikacji 1: sprawdzanie dostępności rozszerzeń
Rysunek 8. Proces instalacji aplikacji 1 w rozszerzeniu zaawansowanym
Najpierw aplikacja sprawdza, czy dane rozszerzenie jest obsługiwane.
Proces w aplikacji 2. Informacje o zapytaniach
Rysunek 9. Krok 2 w aplikacji na urządzeniu Advanced Extender
Po wywołaniu AdvancedExtenderImpl.init()
aplikacja może wysłać zapytanie do AdvancedExtenderImpl
z tymi informacjami:
Szacowany czas oczekiwania na przechwytywanie obrazu:
AdvancedExtenderImpl.getEstimatedCaptureLatencyRange()
zwraca zakres czasu oczekiwania na zapis, po którym aplikacja może ocenić, czy można włączyć rozszerzenie w obecnej sytuacji.Obsługiwane rozdzielczości podglądu i rejestrowania:
AdvancedExtenderImpl.getSupportedPreviewOutputResolutions()
zwraca mapę formatu obrazu na listę rozmiarów obsługiwanych w przypadku formatu i rozmiaru powierzchni podglądu. Producenci OEM muszą obsługiwać co najmniej formatPRIVATE
.AdvancedExtenderImpl.getSupportedCaptureOutputResolutions()
zwraca obsługiwane formaty i rozmiary powierzchni do przechwytywania zdjęć. Producenci OEM muszą obsługiwać formatyJPEG
iYUV_420_888
.AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions()
zwraca obsługiwane rozmiary dodatkowego strumieniaYUV_420_888
do analizy obrazu. Jeśli analiza obrazu nie obsługuje powierzchni YUV, funkcjagetSupportedYuvAnalysisResolutions()
powinna zwrócićnull
lub pustą listę.
Dostępne klucze żądań i ich wyniki (dodane w
extensions-interface
1.3.0): Aby pobrać obsługiwane klucze żądań i klucze wyników z Twojej implementacji, Camera2/X wywołuje te metody:AdvancedExtenderImpl.getAvailableCaptureRequestKeys
AdvancedExtenderImpl.getAvailableCaptureResultKeys
Więcej informacji znajdziesz w artykule Klucze i wyniki żądań do pomocy.
Proces w aplikacji 3: podgląd/zapisywanie obrazu z włączonym rozszerzeniem
Rysunek 10. Proces instalacji aplikacji 3 w rozszerzeniu zaawansowanym
Powyższy diagram przedstawia główny proces uruchamiania podglądu i przechwytywania obrazu w przypadku typu rozszerzacza zaawansowanego. Omówmy każdy krok po kroku.
SessionProcessorImpl
Główna implementacja rozszerzenia zaawansowanego znajduje się w
SessionProcessorImpl
, która odpowiada za dostarczanie niestandardowej konfiguracji sesji i wysyłanie żądań przechwytywania, aby zainicjować podgląd i przechwytywanie. FunkcjaAdvancedExtenderImpl.createSessionProcessor()
jest wywoływana, aby zwrócić instancjęSessionProcessorImpl
.initSession
SessionProcessorImpl.initSession()
inicjuje sesję rozszerzenia. Tutaj przydzielasz zasoby i zwracasz konfigurację sesji na potrzeby przygotowywaniaCameraCaptureSession
.W przypadku parametrów wejściowych Camera2/X określa konfiguracje powierzchni wyjściowej na potrzeby 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 za pomocą tych metod wAdvancedExtenderImpl
:getSupportedPreviewOutputResolutions()
getSupportedCaptureOutputResolutions()
getSupportedYuvAnalysisResolutions()
Musisz zwrócić instancję
Camera2SessionConfigImpl
, która zawiera listę instancjiCamera2OutputConfigImpl
i parametry sesji użyte do skonfigurowaniaCameraCaptureSession
. Odpowiadasz za wysyłanie prawidłowych obrazów z kamery na platformy wyjściowe przekazywane przez Aparat 2/X. Oto kilka opcji włączania danych wyjściowych:- Przetwarzanie w interfejsie aparatu HAL: możesz bezpośrednio dodawać powierzchnie wyjściowe do
CameraCaptureSession
za pomocą implementacjiSurfaceOutputConfigImpl
. Skonfiguruje to podłączoną powierzchnię wyjściową dla potoku przetwarzania aparatu i umożliwi procesowi HAL aparatu przetworzenie obrazu. Przetwarzanie pośredniej powierzchni
ImageReader
(RAW, YUV itp.): dodaj pośrednie platformyImageReader
doCameraCaptureSession
z wystąpieniemImageReaderOutputConfigImpl
.Musisz przetworzyć obrazy pośrednie i zapisać wynikowy obraz na powierzchni wyjściowej.
- Używanie udostępniania powierzchni w aplikacji Camera2: udostępnianie powierzchni innej aplikacji, dodając dowolny element
Camera2OutputConfigImpl
do metodygetSurfaceSharingOutputConfigs()
innej instancjiCamera2OutputConfigImpl
. Format i rozmiar powierzchni muszą być identyczne.
Wszystkie elementy
Camera2OutputConfigImpl
, w tymSurfaceOutputConfigImpl
iImageReaderOutputConfigImpl
, muszą mieć unikalny identyfikator (getId()
), który służy do określania powierzchni docelowej i pobierania obrazu z elementuImageReaderOutputConfigImpl
.onCaptureSessionStart
iRequestProcessorImpl
Gdy
CameraCaptureSession
uruchamia się i wywołuje interfejs Camera framework, Camera2/X wywołujeSessionProcessorImpl.onCaptureSessionStart()
za pomocą owijarki zapytań Camera2RequestProcessImpl
.onConfigured()
Aplikacja Camera2/X implementuje interfejsRequestProcessImpl
, który umożliwia wykonanie żądań wykonania i pobieranie zdjęć, jeśli używany jest interfejsImageReaderOutputConfigImpl
.Interfejsy API
RequestProcessImpl
są podobne do interfejsów API Camera2CameraCaptureSession
pod względem wykonywania żądań. Różnice to:- Docelowa powierzchnia jest określana przez identyfikator instancji
Camera2OutputConfigImpl
. - Możliwość pobrania obrazu
ImageReader
.
Aby zarejestrować instancję
ImageProcessorImpl
do odbierania obrazów, możesz wywołać funkcjęRequestProcessorImpl.setImageProcessor()
z określonym identyfikatoremCamera2OutputConfigImpl
.Po wywołaniu danych
SessionProcessorImpl.onCaptureSessionEnd()
przez Aparat 2/X instancjaRequestProcessImpl
stanie się nieprawidłowa.- Docelowa powierzchnia jest określana przez identyfikator instancji
Uruchamianie podglądu i zrobienie zdjęcia
W implementacji Advanced Extender można wysyłać żądania przechwytywania za pomocą interfejsu
RequestProcessorImpl
. Aplikacja Camera2/X powiadomi Cię o tym, aby rozpocząć powtarzające się żądanie podglądu lub sekwencję zdjęć, odpowiednio wywołującSessionProcessorImpl#startRepeating
lubSessionProcessorImpl#startCapture
. Należy wysyłać żądania przechwytywania, aby zrealizować żądania podglądu i rejestracji.Aplikacja Camera2/X ustawia też parametry żądania rejestrowania za pomocą interfejsu
SessionProcessorImpl#setParameters
. Musisz je ustawiać (jeśli są obsługiwane) zarówno w żądaniach cyklicznych, jak i pojedynczych.Musisz obsługiwać co najmniej
CaptureRequest.JPEG_ORIENTATION
iCaptureRequest.JPEG_QUALITY
.extensions-interface
1.3.0 obsługuje klucze żądania i wyniku, które są dostępne za pomocą tych metod:AdvancedExtenderImpl.getAvailableCaptureRequestKeys()
AdvancedExtenderImpl.getAvailableCaptureResultKeys()
Gdy deweloperzy ustawiają klucze na liście
getAvailableCaptureRequestKeys
, musisz włączyć parametry i zadbać o to, aby wynik przechwytywania zawierał klucze z listygetAvailableCaptureResultKeys
.startTrigger
SessionProcessorImpl.startTrigger()
jest wywoływany, aby uruchomić regułę, taką jakCaptureRequest.CONTROL_AF_TRIGGER
iCaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER
. Możesz zignorować klucze żądania przechwytywania, które nie były rozgłaszane wAdvancedExtenderImpl.getAvailableCaptureRequestKeys()
.Usługa
startTrigger()
jest obsługiwana odextensions-interface
w wersji 1.3.0. Umożliwia aplikacjom implementowanie funkcji „dotknij, aby wyostrzyć” i migania za pomocą rozszerzeń.Czyszczenie danych
Po zakończeniu sesji przechwytywania funkcja
SessionProcessorImpl.onCaptureSessionEnd()
jest wywoływana przed zamknięciem funkcjiCameraCaptureSession
. Po zakończeniu sesji przechwytywaniadeInitSession()
wykonuje czyszczenie.
obsługa podglądu, przechwytywania obrazu i analizy obrazu;
Rozszerzenie należy zastosować zarówno do podglądu, jak i do przypadków użycia związanych z przechwytywaniem. Jeśli jednak opóźnienie jest zbyt duże, aby można było płynnie wyświetlić podgląd, możesz zastosować rozszerzenie tylko do przechwytywania zdjęć.
W przypadku typu podstawowego rozszerzenia, niezależnie od włączenia rozszerzenia do podglądu, musisz zaimplementować zarówno ImageCaptureExtenderImpl
, jak i PreviewExtenderImpl
dla danego rozszerzenia. Aplikacja często używa też strumienia YUV do analizowania treści obrazu, np. do znajdowania kodów QR lub tekstu. Aby lepiej obsługiwać ten przypadek użycia, należy obsługiwać kombinację strumienia podglądu, strumienia obrazu stałego i strumienia YUV_420_888
w celu konfigurowania CameraCaptureSession
. Oznacza to, że jeśli wdrożes przetwarzania, musisz obsługiwać kombinację 3 strumieni YUV_420_888
.
W przypadku zaawansowanego przedłużenia kamery Aparat2/X przekazuje 3 platformy wyjściowe do wywołania SessionProcessorImpl.initSession()
. Te platformy wyjściowe służą odpowiednio do podglądu, przechwytywania obrazu i analizy obrazów. Musisz się upewnić, że podgląd i pliki wyjściowe z nagrania wyświetlają prawidłowe dane wyjściowe. W przypadku powierzchni wyjściowej analizy obrazu upewnij się jednak, że działa ona tylko wtedy, gdy nie jest pusta. Jeśli Twoja implementacja nie obsługuje strumienia analizy obrazu, możesz zwrócić pustą listę w AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions()
. Dzięki temu powierzchnia wyjściowa analizy obrazu jest zawsze pusta w elementach SessionProcessorImpl.initSession()
.
Obsługa nagrywania filmów
Obecna architektura rozszerzenia aparatu obsługuje tylko przypadki użycia polegające na podglądzie i robieniu zdjęć. Nie obsługujemy włączania rozszerzenia na powierzchniach MediaCodec
ani MediaRecorder
do nagrywania filmów. Aplikacje mogą jednak nagrywać podgląd.
Trwają prace nad obsługą platform MediaCodec
i MediaRecorder
.
Metadane dotyczące rozszerzenia
W Androidzie 14 i nowszych metadane dotyczące rozszerzeń umożliwiają klientom rozszerzeń aparatu ustawianie i odbieranie ustawień żądania rejestrowania i wyników dotyczących rozszerzenia. W szczególności klienci rozszerzenia kamery mogą używać parametru EXTENSION_STRENGTH
żądania przechwycenia, aby kontrolować siłę rozszerzenia, oraz parametru EXTENSION_CURRENT_TYPE
wyniku przechwycenia, aby wskazać włączony typ rozszerzenia.
Przechwytywanie żądań
Parametr żądania EXTENSION_STRENGTH
w żądaniu rejestrowania określa siłę efektu przetwarzania wtyczki. Odpowiednie wyniki przechwytywania zawierają domyślną wartość siły, jeśli parametr nie został jawnie ustawiony przez klienta. Ten parametr można stosować w ten sposób w przypadku tych typów rozszerzeń:
BOKEH
: określa stopień rozmycia.HDR
iNIGHT
: określają liczbę połączonych obrazów oraz jasność obrazu końcowego.FACE_RETOUCH
: kontroluje stopień poprawy kosmetyki i wygładzenie skóry.
Obsługiwany zakres parametru EXTENSION_STRENGTH
mieści się w zakresie od 0
do 100
, gdzie 0
oznacza brak przetwarzania rozszerzenia lub proste przekazywanie, a 100
wskazuje maksymalną siłę rozszerzenia efektu przetwarzania.
Aby dodać obsługę EXTENSION_STRENGTH
, użyj interfejsów API parametrów dostawcy wprowadzonych w wersji 1.3.0 interfejsu biblioteki rozszerzeń. Więcej informacji znajdziesz w sekcji getAvailableCaptureRequestKeys()
.
Wyniki rejestrowania
Wynik przechwytywania EXTENSION_CURRENT_TYPE
pozwala implementom rozszerzeń powiadamiać klientów o aktywnym typie rozszerzenia.
Rozszerzenia korzystające z typu AUTO
, takie jak HDR
i NIGHT
, dynamicznie przełączają się między typami rozszerzeń (np. HDR
i NIGHT
) w zależności od warunków scenerii, dlatego aplikacje rozszerzeń aparatu mogą używać EXTENSION_CURRENT_TYPE
do wyświetlania informacji o rozszerzeniu wybranym aktualnie przez rozszerzenie AUTO
.
Szacowany czas oczekiwania na przechwytywanie w czasie rzeczywistym
W Androidzie 14 i nowszych klienci rozszerzenia kamery mogą wysyłać zapytania o szacowane opóźnienia w chwytaniu zdjęć w czasie rzeczywistym na podstawie warunków sceny i otoczenia za pomocą getRealtimeStillCaptureLatency()
. Ta metoda zapewnia dokładniejsze szacunki niż metoda statyczna getEstimatedCaptureLatencyRangeMillis()
. Na podstawie oszacowania opóźnienia aplikacje mogą pominąć przetwarzanie rozszerzenia lub wyświetlić komunikat informujący 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 umożliwić szacowanie opóźnienia w przypadku ujęć statycznych w czasie rzeczywistym, wprowadź te rozwiązania:
- Podstawowe rozszerzenia:
ImageCaptureExtenderImpl.getRealtimeCaptureLatency()
- Rozszerzenia zaawansowane:
SessionProcessorImpl.getRealtimeCaptureLatency
Przechwytywanie wywołań zwrotnych dotyczących postępu przetwarzania
W Androidzie 14 i wyższych klienci rozszerzenia aparatu mogą otrzymywać wywołania zwrotne dotyczące postępu długotrwałych operacji przetwarzania zdjęć. Aplikacje mogą wyświetlać użytkownikom informacje o aktualnym postępie, aby polepszyć ogólną wygodę korzystania z usługi.
Aplikacje mogą używać tego 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ć wywołania zwrotne dotyczące postępu przetwarzania obrazu, implementacja dostawcy rozszerzenia musi wywoływać te wywołania zwrotne z bieżącą wartością postępu:
- Podstawowe rozszerzenia:
ProcessResultImpl.onCaptureProcessProgressed()
- Rozszerzenia zaawansowane:
CaptureCallback.onCaptureProcessProgressed()
Zapisanie filmu po obejrzeniu
W Androidzie 14 i nowszych rozszerzenia aparatu mogą dostarczać widok po zrobieniu zdjęcia (podgląd) za pomocą setPostviewOutputConfiguration
.
Aby zwiększyć wygodę użytkowników, aplikacje mogą wyświetlać obraz postview jako element zastępczy, gdy rozszerzenie ma wydłużony czas przetwarzania, a następnie zastąpić go obrazem końcowym, gdy będzie on dostępny. Aplikacje mogą konfigurować i wysyłać żądania przechwytywania po wyświetleniu za pomocą tego 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ć przechwytywanie obrazu po wyświetleniu, implementacja Twojego dostawcy musi uwzględniać te elementy:
Rozszerzenia podstawowe:
CaptureProcessorImpl.onPostviewOutputSurface
iCaptureProcessorImpl.processWithPostview
Rozszerzenia zaawansowane:
SessionProcessorImpl.startCaptureWithPostview
Obsługa danych wyjściowych SurfaceView
W Androidzie 14 i nowszych klienty rozszerzeń do aparatu mogą korzystać ze ścieżek renderowania podglądu zoptymalizowanych pod kątem zasilania i wydajności, rejestrując instancję SurfaceView
na potrzeby danych wyjściowych podglądu w przypadku powtarzających się żądań.
Aby obsługiwać dane wyjściowe SurfaceView
, implementacja rozszerzenia dostawcy musi umożliwiać przesyłanie strumieniowe i wyprowadzanie podglądu do instancji SurfaceView
. Aby sprawdzić, czy ta funkcja jest obsługiwana, uruchom moduł SurfaceViewExtensionPreviewTest.java
CTS.
Typy sesji związanych z dostawcą
Ta funkcja umożliwia implementacjom rozszerzeń dostawcy wybranie typu sesji konkretnego dostawcy, który zostanie ustawiony w sesji wewnętrznego przechwytywania obrazu z kamery zamiast wartości domyślnej.
Funkcja działa w całości w ramach platformy i stosu dostawców oraz nie ma wpływu na interfejs API widoczny publicznie ani dla klienta.
Aby wybrać typ sesji w przypadku konkretnego dostawcy, zaimplementuj te biblioteki w swoich bibliotekach rozszerzeń:
* ExtenderStateListener.onSessionType()
– rozszerzenia podstawowe;
* Camera2SessionConfigImpl.getSessionType()
w przypadku rozszerzeń zaawansowanych.
Historia wersji interfejsu rozszerzeń
W tabeli poniżej znajdziesz historię wersji interfejsu Rozszerzenia aparatu. Zawsze używaj najnowszej wersji biblioteki dostawcy.
Wersja | Dodane funkcje |
---|---|
1.0.0 |
|
1.1.0 |
|
1.2.0 |
|
1.3.0 |
|
1.4.0 |
|
Implementacja referencyjna
W frameworks/ex
dostępne są te referencyjne implementacje biblioteki OEM:
advancedSample
: podstawowa implementacja rozszerzenia zaawansowanego.sample
: podstawowa implementacja rozszerzenia podstawowego.service_based_sample
: implementacja pokazująca, jak hostować rozszerzenia aparatu wService
. Ta implementacja zawiera te komponenty:oem_library
: biblioteka OEM-owa rozszerzeń aparatu dla interfejsów API Camera2 i CameraX Extensions, która implementujeExtensions-Interface
. Działa on jako przekaźnik, który przekierowuje wywołania z poziomuExtensions-Interface
do usługi. Biblioteka ta zawiera też pliki AIDL i klasy opakowujące do komunikacji z usługą.Rozszerzenie zaawansowane jest domyślnie włączone. Aby włączyć rozszerzenie podstawowe, zmień wartość
ExtensionsVersionImpl#isAdvancedExtenderImplemented
nafalse
.extensions_service
: przykładowa implementacja usługi rozszerzeń. Tutaj możesz dodać implementację. Interfejs do wdrożenia w usłudze jest podobny doExtensions-Interface
. Na przykład implementacja funkcjiIAdvancedExtenderImpl.Stub
wykonuje te same operacje co funkcjaAdvancedExtenderImpl
. Aby można było dzielić na części obiektyImage
iTotalCaptureResult
, wymagane są obiektyImageWrapper
iTotalCaptureResultWrapper
.
Konfigurowanie biblioteki dostawcy na urządzeniu
Biblioteka OEM nie jest wbudowana w aplikację. Jest wczytywana z urządzenia w czasie działania przez Camera2/X. W CameraX tag <uses-library>
deklaruje, że biblioteka androidx.camera.extensions.impl
, zdefiniowana w pliku AndroidManifest.xml
biblioteki camera-extensions
, jest zależnością CameraX i musi zostać załadowana w czasie wykonywania. W Aparacie 2 platforma wczytuje usługę rozszerzeń, która deklaruje też, że <uses-library>
wczytuje tę samą bibliotekę androidx.camera.extensions.impl
w czasie działania.
Dzięki temu aplikacje innych firm korzystające z rozszerzeń mogą automatycznie wczytywać bibliotekę dostawcy OEM. Biblioteka OEM jest oznaczona jako opcjonalna, dzięki czemu aplikacje mogą działać na urządzeniach, które nie mają takiej biblioteki. Aplikacja Camera2/X obsługuje to zachowanie automatycznie, gdy próbuje użyć rozszerzenia aparatu, o ile producent urządzenia umieścił bibliotekę OEM na urządzeniu, aby aplikacja mogła ją wykryć.
Aby skonfigurować bibliotekę OEM na urządzeniu, wykonaj te czynności:
- Dodaj plik uprawnień, który jest wymagany przez tag
<uses-library>
, w tym formacie:/etc/permissions/ANY_FILENAME.xml
. Przykład:/etc/permissions/camera_extensions.xml
. Pliki w tym katalogu zapewniają mapowanie biblioteki o nazwie podanej w pliku<uses-library>
na rzeczywistą ścieżkę pliku na urządzeniu. Aby dodać wymagane informacje do pliku, skorzystaj z przykładu poniżej.
- Wartość
name
musi byćandroidx.camera.extensions.impl
, ponieważ jest to biblioteka wyszukiwana przez CameraX. file
to ścieżka bezwzględna do 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>
- Wartość
W Androidzie 12 lub nowszym właściwości ro.camerax.extensions.enabled
na urządzeniach obsługujących rozszerzenia CameraX muszą mieć wartość true
, co umożliwia sprawdzenie, czy urządzenie obsługuje rozszerzenia.
Aby to zrobić, dodaj ten wiersz w pliku producenta urządzenia:
PRODUCT_VENDOR_PROPERTIES += \
ro.camerax.extensions.enabled=true \
Weryfikacja
Aby przetestować implementację biblioteki OEM na etapie rozwoju, użyj przykładowej aplikacji androidx-main/camera/integration-tests/extensionstestapp/
, która obsługuje różne rozszerzenia dostawców.
Po zakończeniu implementacji użyj narzędzia do sprawdzania rozszerzeń aparatu, aby uruchomić testy automatyczne i ręczne, które pozwolą sprawdzić, czy biblioteka dostawcy została prawidłowo zaimplementowana.
Tryb rozszerzonego sceny a rozszerzenia aparatu
W przypadku rozszerzenia bokeh oprócz ustawienia ekspozycji za pomocą rozszerzeń aparatu możesz ustawić ekspozycję za pomocą rozszerzonego trybu sceny, który jest włączany za pomocą klawisza CONTROL_EXTENDED_SCENE_MODE
.
Więcej informacji o wdrożeniu znajdziesz w artykule Bokeh w aparacie.
Rozszerzony tryb scenerii ma mniej ograniczeń niż rozszerzenia aparatu w aplikacjach aparat2. Możesz na przykład włączyć rozszerzony tryb sceny w zwykłej instancji CameraCaptureSession
, która obsługuje elastyczne kombinacje strumieni i parametry żądania przechwytywania. Rozszerzenia kamery obsługują tylko określony zestaw typów strumieni i mają ograniczone wsparcie dla parametrów żądania rejestrowania.
Wadą rozszerzonego trybu sceny jest to, że można go zaimplementować tylko w interfejsie HAL aparatu, co oznacza, że musi on zostać zweryfikowany pod kątem działania we wszystkich elementach sterujących dostępnych dla deweloperów aplikacji.
Zalecamy stosowanie efektu bokeh przy użyciu zarówno rozszerzonego trybu sceny, jak i rozszerzeń aparatu, ponieważ aplikacje mogą preferować używanie określonego interfejsu API do włączenia bokeh. Zalecamy, by w pierwszej kolejności użyć trybu sceny rozszerzonej, bo jest to najbardziej elastyczny sposób na włączenie rozszerzenia bokeh. Następnie możesz zaimplementować interfejs rozszerzeń aparatu na podstawie rozszerzonego trybu sceny. Jeśli wdrożenie bokeh w interfejsie HAL aparatu jest trudne, na przykład dlatego, że wymaga przetworzenia zdjęć przez procesor działający na poziomie aplikacji, zalecamy wdrożenie rozszerzenia bokeh za pomocą interfejsu Camera Extensions.
Najczęstsze pytania
Czy istnieją jakieś ograniczenia dotyczące poziomów interfejsu API?
Tak. To zależy od zestawu funkcji interfejsu API Androida wymaganego przez implementację biblioteki dostawcy OEM. Na przykład ExtenderStateListener.onPresetSession()
używa wywołania SessionConfiguration.setSessionParameters()
do ustawienia podstawowego zestawu tagów. To wywołanie jest dostępne tylko w interfejsie API na poziomie 28 lub nowszym. Szczegółowe informacje o poszczególnych metodach interfejsu znajdziesz w dokumentacji referencyjnej interfejsu API.